WordPress Page Builder – Beaver Builder - Version 1.5.6

Version Description

Download this release

Release Info

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

Code changes from version 1.5.5 to 1.5.6

Files changed (101) hide show
  1. changelog.txt +21 -0
  2. classes/class-fl-builder-admin-posts.php +89 -89
  3. classes/class-fl-builder-admin-settings.php +452 -441
  4. classes/class-fl-builder-admin.php +232 -185
  5. classes/class-fl-builder-auto-suggest.php +230 -192
  6. classes/class-fl-builder-color.php +53 -37
  7. classes/class-fl-builder-icons.php +373 -328
  8. classes/class-fl-builder-loop.php +182 -160
  9. classes/class-fl-builder-model.php +2883 -2450
  10. classes/class-fl-builder-module.php +240 -220
  11. classes/class-fl-builder-photo.php +84 -67
  12. classes/class-fl-builder-service-aweber.php +166 -166
  13. classes/class-fl-builder-service-campaign-monitor.php +172 -172
  14. classes/class-fl-builder-service-constant-contact.php +216 -216
  15. classes/class-fl-builder-service-getresponse.php +133 -133
  16. classes/class-fl-builder-service-icontact.php +193 -193
  17. classes/class-fl-builder-service-madmimi.php +156 -156
  18. classes/class-fl-builder-service-mailchimp.php +143 -141
  19. classes/class-fl-builder-service-mailpoet.php +85 -85
  20. classes/class-fl-builder-service-sendinblue.php +229 -0
  21. classes/class-fl-builder-service.php +27 -27
  22. classes/class-fl-builder-services.php +220 -220
  23. classes/class-fl-builder-update.php +379 -345
  24. classes/class-fl-builder-utils.php +92 -36
  25. classes/class-fl-builder.php +1654 -1409
  26. classes/class-fl-jsmin.php +238 -238
  27. css/colorpicker.css +4 -4
  28. css/editor.css +1 -1
  29. css/fl-builder-admin-posts-legacy.css +12 -12
  30. css/fl-builder-admin-posts.css +56 -56
  31. css/fl-builder-admin-settings.css +59 -59
  32. css/fl-builder-layout-auto-spacing.css +12 -12
  33. css/fl-builder-layout-medium.css +2 -2
  34. css/fl-builder-layout-responsive.css +11 -11
  35. css/fl-builder-layout.css +185 -185
  36. css/fl-builder-rtl.css +14 -14
  37. css/fl-builder.css +694 -693
  38. css/fl-icon-selector.css +36 -36
  39. css/fl-lightbox.css +64 -64
  40. css/fl-slideshow.css +41 -41
  41. css/font-awesome.min.css +2 -2
  42. css/foundation-icons.css +17 -17
  43. css/jquery.bxslider.css +3 -3
  44. css/jquery.magnificpopup.css +286 -286
  45. css/jquery.nanoscroller.css +33 -33
  46. css/jquery.tiptip.css +1 -1
  47. fl-builder.php +7 -7
  48. fonts/FontAwesome.otf +0 -0
  49. fonts/fontawesome-webfont.eot +0 -0
  50. fonts/fontawesome-webfont.svg +53 -8
  51. fonts/fontawesome-webfont.ttf +0 -0
  52. fonts/fontawesome-webfont.woff +0 -0
  53. fonts/fontawesome-webfont.woff2 +0 -0
  54. includes/admin-posts.php +8 -8
  55. includes/admin-settings-cache.php +15 -15
  56. includes/admin-settings-editing.php +16 -16
  57. includes/admin-settings-js-config.php +2 -2
  58. includes/admin-settings-modules.php +43 -43
  59. includes/admin-settings-post-types.php +59 -59
  60. includes/admin-settings-uninstall.php +11 -11
  61. includes/admin-settings-upgrade.php +4 -4
  62. includes/admin-settings.php +7 -7
  63. includes/column-css.php +28 -28
  64. includes/column-group.php +7 -7
  65. includes/column-settings.php +369 -369
  66. includes/compatibility.php +27 -27
  67. includes/field-code.php +12 -12
  68. includes/field-color.php +5 -5
  69. includes/field-editor.php +56 -56
  70. includes/field-form.php +25 -25
  71. includes/field-icon.php +9 -9
  72. includes/field-layout.php +7 -7
  73. includes/field-link.php +6 -6
  74. includes/field-multiple-photos.php +9 -9
  75. includes/field-photo-sizes.php +7 -7
  76. includes/field-photo.php +14 -14
  77. includes/field-post-type.php +3 -3
  78. includes/field-select.php +13 -13
  79. includes/field-video.php +18 -18
  80. includes/field.php +38 -38
  81. includes/global-settings.php +147 -147
  82. includes/icon-selector.php +22 -22
  83. includes/jquery.php +2 -2
  84. includes/js-config.php +98 -98
  85. includes/loop-settings.php +93 -93
  86. includes/module-settings.php +130 -130
  87. includes/module.php +3 -3
  88. includes/row-css.php +24 -24
  89. includes/row-js.php +23 -23
  90. includes/row-settings.php +620 -620
  91. includes/row-video.php +5 -5
  92. includes/row.php +12 -12
  93. includes/service-settings.php +11 -11
  94. includes/settings.php +63 -63
  95. includes/ui.php +103 -103
  96. includes/updater-config.php +6 -6
  97. includes/updater/classes/class-fl-updater.php +211 -152
  98. includes/updater/includes/config.php +4 -4
  99. includes/updater/includes/form.php +23 -23
  100. includes/user-template-settings.php +18 -18
  101. includes/vendor/sendinblue/Mailin.php +173 -0
changelog.txt CHANGED
@@ -1,3 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  <h4>1.5.5 - 04/12/2015</h4>
2
  <p><strong>Enhancements</strong></p>
3
  <ul>
1
+ <h4>1.5.6 - 04/26/2015</h4>
2
+ <p><strong>Enhancements</strong></p>
3
+ <ul>
4
+ <li>Added SendinBlue integration.</li>
5
+ <li>Added filters for MailChimp single optin and disabling the welcome message.</li>
6
+ <li>Most of the builder's PHP and JavaScript files now have much better inline documentation of classes, properties and methods (we still need to do the modules).</li>
7
+ </ul>
8
+ <p><strong>Tweaks</strong></p>
9
+ <ul>
10
+ <li>Removed phone number validation from the Contact Form module to support international phone numbers.</li>
11
+ <li>Updated FontAwesome.</li>
12
+ <li>Tweaked the Heading module CSS to prevent Dynamik from overriding our styles.</li>
13
+ <li>Added CSS to fix margins issue with the WordPress editor link lightbox and some third party themes.</li>
14
+ </ul>
15
+ <p><strong>Bug Fixes</strong></p>
16
+ <ul>
17
+ <li>Fixed a bug that didn't allow backslashes to be saved.</li>
18
+ <li>Fixed a bug that prevented namespaced widgets from working.</li>
19
+ <li>Fixed a bug with the Posts module that prevented the date from being hidden in the gallery layout.</li>
20
+ </ul>
21
+
22
  <h4>1.5.5 - 04/12/2015</h4>
23
  <p><strong>Enhancements</strong></p>
24
  <ul>
classes/class-fl-builder-admin-posts.php CHANGED
@@ -3,51 +3,51 @@
3
  /**
4
  * Handles logic for the post edit screen.
5
  *
6
- * @since 1.5.0
7
  */
8
  final class FLBuilderAdminPosts {
9
-
10
- /**
11
  * Sets the body class, loads assets and renders the UI
12
  * if we are on a post type that supports the builder.
13
  *
14
- * @since 1.5.0
15
- * @return void
16
- */
17
- static public function init()
18
- {
19
- global $pagenow;
20
-
21
- if ( in_array( $pagenow, array( 'post.php', 'post-new.php') ) ) {
22
-
23
- $post_types = FLBuilderModel::get_post_types();
24
- $screen = get_current_screen();
25
 
26
- if ( in_array( $screen->post_type, $post_types ) ) {
27
- add_filter( 'admin_body_class', 'FLBuilderAdminPosts::body_class' );
28
- add_action( 'admin_enqueue_scripts', 'FLBuilderAdminPosts::styles_scripts' );
29
- add_action( 'edit_form_after_title', 'FLBuilderAdminPosts::render' );
30
- }
31
- }
32
- }
33
 
34
  /**
35
- * Enqueues the CSS/JS for the post edit screen.
36
- *
37
- * @since 1.5.0
38
- * @return void
39
- */
40
  static public function styles_scripts()
41
  {
42
- global $wp_version;
43
-
44
- // Styles
45
  wp_enqueue_style( 'fl-builder-admin-posts', FL_BUILDER_URL . 'css/fl-builder-admin-posts.css', array(), FL_BUILDER_VERSION );
46
 
47
  // Legacy WP Styles (3.7 and below)
48
- if ( version_compare( $wp_version, '3.7', '<=' ) ) {
49
- wp_enqueue_style( 'fl-builder-admin-posts-legacy', FL_BUILDER_URL . 'css/fl-builder-admin-posts-legacy.css', array(), FL_BUILDER_VERSION );
50
- }
51
 
52
  // Scripts
53
  wp_enqueue_script( 'json2' );
@@ -55,80 +55,80 @@ final class FLBuilderAdminPosts {
55
  }
56
 
57
  /**
58
- * Adds classes to the post edit screen body class.
59
- *
60
- * @since 1.5.0
61
  * @param string $classes The existing body classes.
62
- * @return string The body classes.
63
- */
64
  static public function body_class( $classes = '' )
65
  {
66
- global $wp_version;
67
-
68
- // Builder body class
69
- if ( FLBuilderModel::is_builder_enabled() ) {
70
- $classes .= ' fl-builder-enabled';
71
- }
72
-
73
- // Pre WP 3.8 body class
74
- if ( version_compare( $wp_version, '3.8', '<' ) ) {
75
- $classes .= ' fl-pre-wp-3-8';
76
- }
77
-
78
- return $classes;
79
  }
80
 
81
  /**
82
- * Renders the HTML for the post edit screen.
83
- *
84
- * @since 1.5.0
85
- * @return void
86
- */
87
  static public function render()
88
  {
89
- global $post;
90
-
91
- $enabled = FLBuilderModel::is_builder_enabled();
92
-
93
  include FL_BUILDER_DIR . 'includes/admin-posts.php';
94
  }
95
 
96
  /**
97
- * Renders the action link for post listing pages.
98
- *
99
- * @since 1.5.0
100
  * @param array $actions
101
- * @return array The array of action data.
102
- */
103
  static public function render_row_actions_link( $actions = array() )
104
- {
105
- global $post;
106
-
107
- if ( current_user_can( 'edit_post', $post->ID ) && wp_check_post_lock( $post->ID ) === false ) {
108
-
109
- $post_types = FLBuilderModel::get_post_types();
110
 
111
- if ( in_array( $post->post_type, $post_types ) ) {
112
- $actions['fl-builder'] = '<a href="' . FLBuilderModel::get_edit_url() . '">' . FLBuilderModel::get_branding() . '</a>';
113
- }
114
- }
115
-
116
- return $actions;
117
- }
118
 
119
  /**
120
- * Where to redirect this post on save.
121
- *
122
- * @since 1.5.0
123
  * @param string $location
124
- * @return string The location to redirect this post on save.
125
- */
126
  static public function redirect_post_location( $location )
127
- {
128
- if ( isset( $_POST['fl-builder-redirect'] ) ) {
129
- $location = $_POST['fl-builder-redirect'];
130
- }
131
-
132
- return $location;
133
- }
134
  }
3
  /**
4
  * Handles logic for the post edit screen.
5
  *
6
+ * @since 1.0
7
  */
8
  final class FLBuilderAdminPosts {
9
+
10
+ /**
11
  * Sets the body class, loads assets and renders the UI
12
  * if we are on a post type that supports the builder.
13
  *
14
+ * @since 1.0
15
+ * @return void
16
+ */
17
+ static public function init()
18
+ {
19
+ global $pagenow;
20
+
21
+ if ( in_array( $pagenow, array( 'post.php', 'post-new.php') ) ) {
22
+
23
+ $post_types = FLBuilderModel::get_post_types();
24
+ $screen = get_current_screen();
25
 
26
+ if ( in_array( $screen->post_type, $post_types ) ) {
27
+ add_filter( 'admin_body_class', 'FLBuilderAdminPosts::body_class' );
28
+ add_action( 'admin_enqueue_scripts', 'FLBuilderAdminPosts::styles_scripts' );
29
+ add_action( 'edit_form_after_title', 'FLBuilderAdminPosts::render' );
30
+ }
31
+ }
32
+ }
33
 
34
  /**
35
+ * Enqueues the CSS/JS for the post edit screen.
36
+ *
37
+ * @since 1.0
38
+ * @return void
39
+ */
40
  static public function styles_scripts()
41
  {
42
+ global $wp_version;
43
+
44
+ // Styles
45
  wp_enqueue_style( 'fl-builder-admin-posts', FL_BUILDER_URL . 'css/fl-builder-admin-posts.css', array(), FL_BUILDER_VERSION );
46
 
47
  // Legacy WP Styles (3.7 and below)
48
+ if ( version_compare( $wp_version, '3.7', '<=' ) ) {
49
+ wp_enqueue_style( 'fl-builder-admin-posts-legacy', FL_BUILDER_URL . 'css/fl-builder-admin-posts-legacy.css', array(), FL_BUILDER_VERSION );
50
+ }
51
 
52
  // Scripts
53
  wp_enqueue_script( 'json2' );
55
  }
56
 
57
  /**
58
+ * Adds classes to the post edit screen body class.
59
+ *
60
+ * @since 1.0
61
  * @param string $classes The existing body classes.
62
+ * @return string The body classes.
63
+ */
64
  static public function body_class( $classes = '' )
65
  {
66
+ global $wp_version;
67
+
68
+ // Builder body class
69
+ if ( FLBuilderModel::is_builder_enabled() ) {
70
+ $classes .= ' fl-builder-enabled';
71
+ }
72
+
73
+ // Pre WP 3.8 body class
74
+ if ( version_compare( $wp_version, '3.8', '<' ) ) {
75
+ $classes .= ' fl-pre-wp-3-8';
76
+ }
77
+
78
+ return $classes;
79
  }
80
 
81
  /**
82
+ * Renders the HTML for the post edit screen.
83
+ *
84
+ * @since 1.0
85
+ * @return void
86
+ */
87
  static public function render()
88
  {
89
+ global $post;
90
+
91
+ $enabled = FLBuilderModel::is_builder_enabled();
92
+
93
  include FL_BUILDER_DIR . 'includes/admin-posts.php';
94
  }
95
 
96
  /**
97
+ * Renders the action link for post listing pages.
98
+ *
99
+ * @since 1.0
100
  * @param array $actions
101
+ * @return array The array of action data.
102
+ */
103
  static public function render_row_actions_link( $actions = array() )
104
+ {
105
+ global $post;
106
+
107
+ if ( current_user_can( 'edit_post', $post->ID ) && wp_check_post_lock( $post->ID ) === false ) {
108
+
109
+ $post_types = FLBuilderModel::get_post_types();
110
 
111
+ if ( in_array( $post->post_type, $post_types ) ) {
112
+ $actions['fl-builder'] = '<a href="' . FLBuilderModel::get_edit_url() . '">' . FLBuilderModel::get_branding() . '</a>';
113
+ }
114
+ }
115
+
116
+ return $actions;
117
+ }
118
 
119
  /**
120
+ * Where to redirect this post on save.
121
+ *
122
+ * @since 1.0
123
  * @param string $location
124
+ * @return string The location to redirect this post on save.
125
+ */
126
  static public function redirect_post_location( $location )
127
+ {
128
+ if ( isset( $_POST['fl-builder-redirect'] ) ) {
129
+ $location = $_POST['fl-builder-redirect'];
130
+ }
131
+
132
+ return $location;
133
+ }
134
  }
classes/class-fl-builder-admin-settings.php CHANGED
@@ -3,7 +3,7 @@
3
  /**
4
  * Handles logic for the admin settings page.
5
  *
6
- * @since 1.5.0
7
  */
8
  final class FLBuilderAdminSettings {
9
 
@@ -11,37 +11,37 @@ final class FLBuilderAdminSettings {
11
  * Holds any errors that may arise from
12
  * saving admin settings.
13
  *
14
- * @since 1.5.0
15
  * @var array $errors
16
  */
17
  static public $errors = array();
18
-
19
- /**
20
  * Adds the admin menu and enqueues CSS/JS if we are on
21
  * the builder admin settings page.
22
  *
23
- * @since 1.5.0
24
- * @return void
25
- */
26
- static public function init()
27
- {
28
- add_action( 'admin_menu', 'FLBuilderAdminSettings::menu' );
29
-
30
- if ( isset( $_REQUEST['page'] ) && 'fl-builder-settings' == $_REQUEST['page'] ) {
31
- add_action( 'admin_enqueue_scripts', 'FLBuilderAdminSettings::styles_scripts' );
32
- self::save();
33
- }
34
- }
35
-
36
- /**
37
  * Enqueues the needed CSS/JS for the builder's admin settings page.
38
  *
39
- * @since 1.5.0
40
- * @return void
41
- */
42
  static public function styles_scripts()
43
  {
44
- // Styles
45
  wp_enqueue_style( 'fl-builder-admin-settings', FL_BUILDER_URL . 'css/fl-builder-admin-settings.css', array(), FL_BUILDER_VERSION );
46
 
47
  // Scripts
@@ -50,44 +50,44 @@ final class FLBuilderAdminSettings {
50
  // Media Uploader
51
  wp_enqueue_media();
52
  }
53
-
54
- /**
55
  * Renders the admin settings menu.
56
  *
57
- * @since 1.5.0
58
- * @return void
59
- */
60
  static public function menu()
61
  {
62
- if ( current_user_can( 'delete_plugins' ) ) {
63
-
64
- $title = FLBuilderModel::get_branding();
65
- $cap = 'delete_plugins';
66
- $slug = 'fl-builder-settings';
67
- $func = 'FLBuilderAdminSettings::render';
68
-
69
- add_submenu_page( 'options-general.php', $title, $title, $cap, $slug, $func );
70
  }
71
  }
72
-
73
- /**
74
  * Renders the admin settings.
75
  *
76
- * @since 1.5.0
77
- * @return void
78
- */
79
  static public function render()
80
  {
81
- include FL_BUILDER_DIR . 'includes/admin-settings-js-config.php';
82
  include FL_BUILDER_DIR . 'includes/admin-settings.php';
83
  }
84
-
85
- /**
86
  * Renders the page class for network installs and single site installs.
87
  *
88
- * @since 1.5.0
89
- * @return void
90
- */
91
  static public function render_page_class()
92
  {
93
  if ( self::multisite_support() ) {
@@ -97,13 +97,13 @@ final class FLBuilderAdminSettings {
97
  echo 'fl-settings-single-install';
98
  }
99
  }
100
-
101
- /**
102
  * Renders the admin settings page heading.
103
  *
104
- * @since 1.5.0
105
- * @return void
106
- */
107
  static public function render_page_heading()
108
  {
109
  $icon = FLBuilderModel::get_branding_icon();
@@ -115,13 +115,13 @@ final class FLBuilderAdminSettings {
115
 
116
  echo '<span>' . sprintf( _x( '%s Settings', '%s stands for custom branded "Page Builder" name.', 'fl-builder' ), FLBuilderModel::get_branding() ) . '</span>';
117
  }
118
-
119
- /**
120
  * Renders the update message.
121
  *
122
- * @since 1.5.0
123
- * @return void
124
- */
125
  static public function render_update_message()
126
  {
127
  if ( ! empty( self::$errors ) ) {
@@ -133,58 +133,58 @@ final class FLBuilderAdminSettings {
133
  echo '<div class="updated"><p>' . __( 'Settings updated!', 'fl-builder' ) . '</p></div>';
134
  }
135
  }
136
-
137
- /**
138
  * Renders the nav items for the admin settings menu.
139
  *
140
- * @since 1.5.0
141
- * @return void
142
- */
143
  static public function render_nav_items()
144
  {
145
  $item_data = array(
146
  'license' => array(
147
- 'title' => __( 'License', 'fl-builder' ),
148
  'show' => FL_BUILDER_LITE !== true && ( is_network_admin() || ! self::multisite_support() )
149
  ),
150
  'upgrade' => array(
151
- 'title' => __( 'Upgrade', 'fl-builder' ),
152
  'show' => FL_BUILDER_LITE === true
153
  ),
154
  'modules' => array(
155
- 'title' => __( 'Modules', 'fl-builder' ),
156
  'show' => true
157
  ),
158
  'templates' => array(
159
- 'title' => __( 'Templates', 'fl-builder' ),
160
  'show' => FL_BUILDER_LITE !== true
161
  ),
162
  'post-types' => array(
163
- 'title' => __( 'Post Types', 'fl-builder' ),
164
  'show' => true
165
  ),
166
  'icons' => array(
167
- 'title' => __( 'Icons', 'fl-builder' ),
168
  'show' => FL_BUILDER_LITE !== true
169
  ),
170
  'editing' => array(
171
- 'title' => __( 'Editing', 'fl-builder' ),
172
  'show' => true
173
  ),
174
  'branding' => array(
175
- 'title' => __( 'Branding', 'fl-builder' ),
176
  'show' => self::has_support( 'branding' ) && ( is_network_admin() || ! self::multisite_support() )
177
  ),
178
  'help-button' => array(
179
- 'title' => __( 'Help Button', 'fl-builder' ),
180
  'show' => self::has_support( 'help-button' ) && ( is_network_admin() || ! self::multisite_support() )
181
  ),
182
  'cache' => array(
183
- 'title' => __( 'Cache', 'fl-builder' ),
184
  'show' => true
185
  ),
186
  'uninstall' => array(
187
- 'title' => __( 'Uninstall', 'fl-builder' ),
188
  'show' => is_network_admin() || ! self::multisite_support()
189
  ),
190
  );
@@ -195,13 +195,13 @@ final class FLBuilderAdminSettings {
195
  }
196
  }
197
  }
198
-
199
- /**
200
  * Renders the admin settings forms.
201
  *
202
- * @since 1.5.0
203
- * @return void
204
- */
205
  static public function render_forms()
206
  {
207
  // License
@@ -210,7 +210,7 @@ final class FLBuilderAdminSettings {
210
  }
211
 
212
  // Upgrade
213
- if ( FL_BUILDER_LITE === true ) {
214
  self::render_form( 'upgrade' );
215
  }
216
 
@@ -241,28 +241,28 @@ final class FLBuilderAdminSettings {
241
  // Uninstall
242
  self::render_form( 'uninstall' );
243
  }
244
-
245
- /**
246
  * Renders an admin settings form based on the type specified.
247
  *
248
- * @since 1.5.0
249
  * @param string $type The type of form to render.
250
- * @return void
251
- */
252
  static public function render_form( $type )
253
  {
254
  if ( self::has_support( $type ) ) {
255
  include FL_BUILDER_DIR . 'includes/admin-settings-' . $type . '.php';
256
  }
257
  }
258
-
259
- /**
260
  * Renders the action for a form.
261
  *
262
- * @since 1.5.0
263
  * @param string $type The type of form being rendered.
264
- * @return void
265
- */
266
  static public function render_form_action( $type = '' )
267
  {
268
  if ( is_network_admin() ) {
@@ -272,14 +272,14 @@ final class FLBuilderAdminSettings {
272
  echo admin_url( '/options-general.php?page=fl-builder-settings#' . $type );
273
  }
274
  }
275
-
276
- /**
277
  * Returns the action for a form.
278
  *
279
- * @since 1.5.0
280
  * @param string $type The type of form being rendered.
281
- * @return string The URL for the form action.
282
- */
283
  static public function get_form_action( $type = '' )
284
  {
285
  if ( is_network_admin() ) {
@@ -289,55 +289,55 @@ final class FLBuilderAdminSettings {
289
  return admin_url( '/options-general.php?page=fl-builder-settings#' . $type );
290
  }
291
  }
292
-
293
- /**
294
  * Checks to see if a settings form is supported.
295
  *
296
- * @since 1.5.0
297
  * @param string $type The type of form to check.
298
- * @return bool
299
- */
300
  static public function has_support( $type )
301
  {
302
  return file_exists( FL_BUILDER_DIR . 'includes/admin-settings-' . $type . '.php' );
303
  }
304
-
305
- /**
306
  * Checks to see if multisite is supported.
307
  *
308
- * @since 1.5.0
309
- * @return bool
310
- */
311
  static public function multisite_support()
312
  {
313
  return is_multisite() && class_exists( 'FLBuilderMultisiteSettings' );
314
  }
315
-
316
- /**
317
  * Adds an error message to be rendered.
318
  *
319
- * @since 1.5.0
320
  * @param string $message The error message to add.
321
- * @return void
322
- */
323
  static public function add_error( $message )
324
  {
325
  self::$errors[] = $message;
326
  }
327
-
328
- /**
329
  * Saves the admin settings.
330
  *
331
- * @since 1.5.0
332
- * @return void
333
- */
334
  static public function save()
335
  {
336
- // Only admins can save settings.
337
- if(!current_user_can('delete_plugins')) {
338
- return;
339
- }
340
-
341
  self::save_enabled_modules();
342
  self::save_enabled_templates();
343
  self::save_enabled_post_types();
@@ -348,401 +348,412 @@ final class FLBuilderAdminSettings {
348
  self::clear_cache();
349
  self::uninstall();
350
  }
351
-
352
- /**
353
  * Saves the enabled modules.
354
  *
355
- * @since 1.5.0
356
- * @return void
357
- */
 
358
  static private function save_enabled_modules()
359
  {
360
- if ( isset( $_POST['fl-modules-nonce'] ) && wp_verify_nonce( $_POST['fl-modules-nonce'], 'modules' ) ) {
361
-
362
- $modules = array();
363
-
364
- if ( is_array( $_POST['fl-modules'] ) ) {
365
- $modules = array_map( 'sanitize_text_field', $_POST['fl-modules'] );
366
- }
367
-
368
- if ( is_network_admin() ) {
369
- update_site_option( '_fl_builder_enabled_modules', $modules );
370
- }
371
- else if ( self::multisite_support() && ! isset( $_POST['fl-override-ms'] ) ) {
372
- delete_option( '_fl_builder_enabled_modules' );
373
- }
374
- else {
375
- update_option( '_fl_builder_enabled_modules', $modules );
376
- }
377
- }
378
- }
379
-
380
- /**
381
  * Saves the enabled templates.
382
  *
383
- * @since 1.5.0
384
- * @return void
385
- */
 
386
  static private function save_enabled_templates()
387
  {
388
- if ( isset( $_POST['fl-templates-nonce'] ) && wp_verify_nonce( $_POST['fl-templates-nonce'], 'templates' ) ) {
389
-
390
- $enabled_templates = sanitize_text_field( $_POST['fl-template-settings'] );
391
-
392
- if ( is_network_admin() ) {
393
- update_site_option( '_fl_builder_enabled_templates', $enabled_templates );
394
- }
395
- else if ( self::multisite_support() && ! isset( $_POST['fl-override-ms'] ) ) {
396
- delete_option( '_fl_builder_enabled_templates' );
397
- }
398
- else {
399
- update_option( '_fl_builder_enabled_templates', $enabled_templates );
400
- }
401
- }
402
- }
403
-
404
- /**
405
  * Saves the enabled post types.
406
  *
407
- * @since 1.5.0
408
- * @return void
409
- */
 
410
  static private function save_enabled_post_types()
411
  {
412
- if ( isset( $_POST['fl-post-types-nonce'] ) && wp_verify_nonce( $_POST['fl-post-types-nonce'], 'post-types' ) ) {
413
-
414
- if ( is_network_admin() ) {
415
-
416
- $post_types = sanitize_text_field( $_POST['fl-post-types'] );
417
- $post_types = str_replace( ' ', '', $post_types );
418
- $post_types = explode( ',', $post_types );
419
-
420
- update_site_option( '_fl_builder_post_types', $post_types );
421
- }
422
- else if ( self::multisite_support() && ! isset($_POST['fl-override-ms'] ) ) {
423
- delete_option( '_fl_builder_post_types' );
424
- }
425
- else {
426
-
427
- $post_types = array();
428
-
429
- if ( is_array( $_POST['fl-post-types'] ) ) {
430
- $post_types = array_map( 'sanitize_text_field', $_POST['fl-post-types'] );
431
- }
432
-
433
- update_option( '_fl_builder_post_types', $post_types );
434
- }
435
- }
436
- }
437
-
438
- /**
439
  * Saves the enabled icons.
440
  *
441
- * @since 1.5.0
442
- * @return void
443
- */
 
444
  static private function save_enabled_icons()
445
  {
446
- if ( isset( $_POST['fl-icons-nonce'] ) && wp_verify_nonce( $_POST['fl-icons-nonce'], 'icons' ) ) {
447
 
448
  // Make sure we have at least one enabled icon set.
449
  if ( ! isset( $_POST['fl-enabled-icons'] ) && empty( $_POST['fl-new-icon-set'] ) ) {
450
  self::add_error( __( "Error! You must have at least one icon set enabled.", 'fl-builder' ) );
451
- return;
452
  }
453
-
454
- $filesystem = FLBuilderUtils::get_filesystem();
455
  $enabled_icons = array();
456
 
457
  // Sanitize the enabled icons.
458
  if ( isset( $_POST['fl-enabled-icons'] ) && is_array( $_POST['fl-enabled-icons'] ) ) {
459
- $enabled_icons = array_map( 'sanitize_text_field', $_POST['fl-enabled-icons'] );
460
- }
461
-
462
- // Update the enabled sets.
463
- self::update_enabled_icons( $enabled_icons );
464
-
465
- // Delete a set?
466
- if ( ! empty( $_POST['fl-delete-icon-set'] ) ) {
467
-
468
- $sets = FLBuilderIcons::get_sets();
469
- $key = sanitize_text_field( $_POST['fl-delete-icon-set'] );
470
- $index = array_search( $key, $enabled_icons );
471
-
472
- if ( false !== $index ) {
473
- unset( $enabled_icons[ $index ] );
474
- }
475
- if ( isset( $sets[ $key ] ) ) {
476
- $filesystem->rmdir( $sets[ $key ]['path'], true );
477
- FLBuilderIcons::remove_set( $key );
478
- }
479
- }
480
-
481
- // Upload a new set?
482
- if ( ! empty( $_POST['fl-new-icon-set'] ) ) {
483
 
484
- $dir = FLBuilderModel::get_cache_dir( 'icons' );
485
- $id = (int) $_POST['fl-new-icon-set'];
486
- $path = get_attached_file( $id );
487
- $new_path = $dir['path'] . 'icon-' . time() . '/';
488
- $unzipped = unzip_file( $path, $new_path );
489
-
490
- // Unzip failed.
491
- if ( ! $unzipped ) {
492
- self::add_error( __( "Error! Could not unzip file.", 'fl-builder' ) );
493
- return;
494
- }
495
-
496
- // Move files if unzipped into a subfolder.
497
- $files = $filesystem->dirlist( $new_path );
498
-
499
- if ( 1 == count( $files ) ) {
500
 
501
  $values = array_values( $files );
502
  $subfolder_info = array_shift( $values );
503
- $subfolder = $new_path . $subfolder_info['name'] . '/';
504
 
505
  if ( file_exists( $subfolder ) && is_dir( $subfolder ) ) {
506
 
507
- $files = $filesystem->dirlist( $subfolder );
508
-
509
- if ( $files ) {
510
- foreach ( $files as $file ) {
511
- $filesystem->move( $subfolder . $file['name'], $new_path . $file['name'] );
512
- }
513
- }
514
-
515
- $filesystem->rmdir( $subfolder );
516
  }
517
- }
518
-
519
- // Check for supported sets.
520
- $is_icomoon = file_exists( $new_path . 'selection.json' );
521
- $is_fontello = file_exists( $new_path . 'config.json' );
522
-
523
- // Show an error if we don't have a supported icon set.
524
- if ( ! $is_icomoon && ! $is_fontello ) {
525
- $filesystem->rmdir( $new_path, true );
526
- self::add_error( __( "Error! Please upload an icon set from either Icomoon or Fontello.", 'fl-builder' ) );
527
- return;
528
- }
529
-
530
- // Enable the new set.
531
- if ( is_array( $enabled_icons ) ) {
532
- $key = FLBuilderIcons::get_key_from_path( $new_path );
533
- $enabled_icons[] = $key;
534
- }
535
- }
536
-
537
- // Update the enabled sets again in case they have changed.
538
- self::update_enabled_icons( $enabled_icons );
539
- }
540
- }
541
-
542
- /**
543
  * Updates the enabled icons in the database.
544
  *
545
- * @since 1.5.0
546
- * @return void
547
- */
 
548
  static private function update_enabled_icons( $enabled_icons = array() )
549
  {
550
  if ( is_network_admin() ) {
551
- update_site_option( '_fl_builder_enabled_icons', $enabled_icons );
552
- update_option( '_fl_builder_enabled_icons', $enabled_icons );
553
- }
554
- else if ( self::multisite_support() && ! isset( $_POST['fl-override-ms'] ) ) {
555
- delete_option( '_fl_builder_enabled_icons' );
556
- }
557
- else {
558
- update_option( '_fl_builder_enabled_icons', $enabled_icons );
559
- }
560
  }
561
-
562
- /**
563
  * Saves the editing capability.
564
  *
565
- * @since 1.5.0
566
- * @return void
567
- */
 
568
  static private function save_editing_capability()
569
  {
570
- if ( isset( $_POST['fl-editing-nonce'] ) && wp_verify_nonce( $_POST['fl-editing-nonce'], 'editing' ) ) {
571
-
572
- $capability = sanitize_text_field( $_POST['fl-editing-capability'] );
573
-
574
- if ( is_network_admin() ) {
575
- update_site_option( '_fl_builder_editing_capability', $capability );
576
- }
577
- else if ( self::multisite_support() && ! isset( $_POST['fl-override-ms'] ) ) {
578
- delete_option( '_fl_builder_editing_capability' );
579
- }
580
- else {
581
- update_option( '_fl_builder_editing_capability', $capability );
582
- }
583
- }
584
- }
585
-
586
- /**
587
  * Saves the branding settings.
588
  *
589
- * @since 1.5.0
590
- * @return void
591
- */
 
592
  static private function save_branding()
593
  {
594
- if ( isset( $_POST['fl-branding-nonce'] ) && wp_verify_nonce( $_POST['fl-branding-nonce'], 'branding' ) ) {
595
-
596
- $branding = wp_kses_post( $_POST['fl-branding'] );
597
- $branding_icon = sanitize_text_field( $_POST['fl-branding-icon'] );
598
-
599
- if ( is_network_admin() ) {
600
  update_site_option( '_fl_builder_branding', $branding );
601
  update_site_option( '_fl_builder_branding_icon', $branding_icon );
602
- }
603
- else {
604
  update_option( '_fl_builder_branding', $branding );
605
  update_option( '_fl_builder_branding_icon', $branding_icon );
606
- }
607
- }
608
- }
609
-
610
- /**
611
  * Saves the help button settings.
612
  *
613
- * @since 1.5.0
614
- * @return void
615
- */
 
616
  static private function save_help_button()
617
  {
618
- if ( isset( $_POST['fl-help-button-nonce'] ) && wp_verify_nonce( $_POST['fl-help-button-nonce'], 'help-button' ) ) {
619
-
620
- $settings = FLBuilderModel::get_help_button_defaults();
621
- $settings['enabled'] = isset( $_POST['fl-help-button-enabled'] ) ? true : false;
622
- $settings['tour'] = isset( $_POST['fl-help-tour-enabled'] ) ? true : false;
623
- $settings['video'] = isset( $_POST['fl-help-video-enabled'] ) ? true : false;
624
- $settings['knowledge_base'] = isset( $_POST['fl-knowledge-base-enabled'] ) ? true : false;
625
- $settings['forums'] = isset( $_POST['fl-forums-enabled'] ) ? true : false;
626
-
627
- // Disable everything if the main button is disabled.
628
- if ( ! $settings['enabled'] ) {
629
- $settings['tour'] = false;
630
- $settings['video'] = false;
631
- $settings['knowledge_base'] = false;
632
- $settings['forums'] = false;
633
- }
634
-
635
- // Clean the video embed.
636
- $video_embed = wp_kses( $_POST['fl-help-video-embed'], array(
637
- 'iframe' => array(
638
- 'src' => array(),
639
- 'frameborder' => array(),
640
- 'webkitallowfullscreen' => array(),
641
- 'mozallowfullscreen' => array(),
642
- 'allowfullscreen' => array()
643
- )
644
- ));
645
-
646
- // Save the video embed.
647
- if ( ! empty( $video_embed ) && ! stristr( $video_embed, 'iframe' ) ) {
648
- self::add_error( __( "Error! Please enter an iframe for the video embed code.", 'fl-builder' ) );
649
- }
650
- else if ( ! empty( $video_embed ) ) {
651
- $settings['video_embed'] = $video_embed;
652
- }
653
-
654
- // Save the knowledge base URL.
655
- if ( ! empty( $_POST['fl-knowledge-base-url'] ) ) {
656
- $settings['knowledge_base_url'] = sanitize_text_field( $_POST['fl-knowledge-base-url'] );
657
- }
658
-
659
- // Save the forums URL.
660
- if ( ! empty( $_POST['fl-forums-url'] ) ) {
661
- $settings['forums_url'] = sanitize_text_field( $_POST['fl-forums-url'] );
662
- }
663
-
664
- // Make sure we have at least one help feature enabled.
665
- if ( $settings['enabled'] && ! $settings['tour'] && ! $settings['video'] && ! $settings['knowledge_base'] && ! $settings['forums'] ) {
666
- self::add_error( __( "Error! You must have at least one feature of the help button enabled.", 'fl-builder' ) );
667
- return;
668
- }
669
-
670
- // Save the settings.
671
- if ( is_network_admin() ) {
672
  update_site_option( '_fl_builder_help_button', $settings );
673
- }
674
- else {
675
  update_option( '_fl_builder_help_button', $settings );
676
- }
677
- }
678
- }
679
 
680
- /**
681
  * Clears the builder cache.
682
  *
683
  * @since 1.5.3
684
- * @return void
685
- */
 
686
  static private function clear_cache()
687
  {
688
- if ( ! current_user_can( 'delete_plugins' ) ) {
689
- return;
690
- }
691
- else if ( isset( $_POST['fl-cache-nonce'] ) && wp_verify_nonce( $_POST['fl-cache-nonce'], 'cache' ) ) {
692
- if ( is_network_admin() ) {
693
- self::clear_cache_for_all_sites();
694
- }
695
- else {
696
- FLBuilderModel::delete_all_asset_cache();
697
- }
698
- }
699
- }
700
 
701
- /**
702
  * Clears the builder cache for all sites on a network.
703
  *
704
  * @since 1.5.3
705
- * @return void
706
- */
 
707
  static private function clear_cache_for_all_sites()
708
  {
709
- global $blog_id;
710
- global $wpdb;
711
-
712
- // Save the original blog id.
713
- $original_blog_id = $blog_id;
714
-
715
- // Get all blog ids.
716
- $blog_ids = $wpdb->get_col( "SELECT blog_id FROM $wpdb->blogs" );
717
-
718
- // Loop through the blog ids and clear the cache.
719
- foreach ( $blog_ids as $id ) {
720
- switch_to_blog( $id );
721
- FLBuilderModel::delete_all_asset_cache();
722
- }
723
-
724
- // Revert to the original blog.
725
- switch_to_blog( $original_blog_id );
726
- }
727
 
728
- /**
729
  * Uninstalls the builder and all of its data.
730
  *
731
- * @since 1.5.0
732
- * @return void
733
- */
 
734
  static private function uninstall()
735
  {
736
- if ( ! current_user_can( 'delete_plugins' ) ) {
737
- return;
738
- }
739
- else if ( isset( $_POST['fl-uninstall'] ) && wp_verify_nonce( $_POST['fl-uninstall'], 'uninstall' ) ) {
740
- if ( is_multisite() && class_exists( 'FLBuilderMultisite' ) ) {
741
- FLBuilderMultisite::uninstall();
742
- }
743
- else {
744
- FLBuilderAdmin::uninstall();
745
- }
746
- }
747
- }
748
  }
3
  /**
4
  * Handles logic for the admin settings page.
5
  *
6
+ * @since 1.0
7
  */
8
  final class FLBuilderAdminSettings {
9
 
11
  * Holds any errors that may arise from
12
  * saving admin settings.
13
  *
14
+ * @since 1.0
15
  * @var array $errors
16
  */
17
  static public $errors = array();
18
+
19
+ /**
20
  * Adds the admin menu and enqueues CSS/JS if we are on
21
  * the builder admin settings page.
22
  *
23
+ * @since 1.0
24
+ * @return void
25
+ */
26
+ static public function init()
27
+ {
28
+ add_action( 'admin_menu', 'FLBuilderAdminSettings::menu' );
29
+
30
+ if ( isset( $_REQUEST['page'] ) && 'fl-builder-settings' == $_REQUEST['page'] ) {
31
+ add_action( 'admin_enqueue_scripts', 'FLBuilderAdminSettings::styles_scripts' );
32
+ self::save();
33
+ }
34
+ }
35
+
36
+ /**
37
  * Enqueues the needed CSS/JS for the builder's admin settings page.
38
  *
39
+ * @since 1.0
40
+ * @return void
41
+ */
42
  static public function styles_scripts()
43
  {
44
+ // Styles
45
  wp_enqueue_style( 'fl-builder-admin-settings', FL_BUILDER_URL . 'css/fl-builder-admin-settings.css', array(), FL_BUILDER_VERSION );
46
 
47
  // Scripts
50
  // Media Uploader
51
  wp_enqueue_media();
52
  }
53
+
54
+ /**
55
  * Renders the admin settings menu.
56
  *
57
+ * @since 1.0
58
+ * @return void
59
+ */
60
  static public function menu()
61
  {
62
+ if ( current_user_can( 'delete_plugins' ) ) {
63
+
64
+ $title = FLBuilderModel::get_branding();
65
+ $cap = 'delete_plugins';
66
+ $slug = 'fl-builder-settings';
67
+ $func = 'FLBuilderAdminSettings::render';
68
+
69
+ add_submenu_page( 'options-general.php', $title, $title, $cap, $slug, $func );
70
  }
71
  }
72
+
73
+ /**
74
  * Renders the admin settings.
75
  *
76
+ * @since 1.0
77
+ * @return void
78
+ */
79
  static public function render()
80
  {
81
+ include FL_BUILDER_DIR . 'includes/admin-settings-js-config.php';
82
  include FL_BUILDER_DIR . 'includes/admin-settings.php';
83
  }
84
+
85
+ /**
86
  * Renders the page class for network installs and single site installs.
87
  *
88
+ * @since 1.0
89
+ * @return void
90
+ */
91
  static public function render_page_class()
92
  {
93
  if ( self::multisite_support() ) {
97
  echo 'fl-settings-single-install';
98
  }
99
  }
100
+
101
+ /**
102
  * Renders the admin settings page heading.
103
  *
104
+ * @since 1.0
105
+ * @return void
106
+ */
107
  static public function render_page_heading()
108
  {
109
  $icon = FLBuilderModel::get_branding_icon();
115
 
116
  echo '<span>' . sprintf( _x( '%s Settings', '%s stands for custom branded "Page Builder" name.', 'fl-builder' ), FLBuilderModel::get_branding() ) . '</span>';
117
  }
118
+
119
+ /**
120
  * Renders the update message.
121
  *
122
+ * @since 1.0
123
+ * @return void
124
+ */
125
  static public function render_update_message()
126
  {
127
  if ( ! empty( self::$errors ) ) {
133
  echo '<div class="updated"><p>' . __( 'Settings updated!', 'fl-builder' ) . '</p></div>';
134
  }
135
  }
136
+
137
+ /**
138
  * Renders the nav items for the admin settings menu.
139
  *
140
+ * @since 1.0
141
+ * @return void
142
+ */
143
  static public function render_nav_items()
144
  {
145
  $item_data = array(
146
  'license' => array(
147
+ 'title' => __( 'License', 'fl-builder' ),
148
  'show' => FL_BUILDER_LITE !== true && ( is_network_admin() || ! self::multisite_support() )
149
  ),
150
  'upgrade' => array(
151
+ 'title' => __( 'Upgrade', 'fl-builder' ),
152
  'show' => FL_BUILDER_LITE === true
153
  ),
154
  'modules' => array(
155
+ 'title' => __( 'Modules', 'fl-builder' ),
156
  'show' => true
157
  ),
158
  'templates' => array(
159
+ 'title' => __( 'Templates', 'fl-builder' ),
160
  'show' => FL_BUILDER_LITE !== true
161
  ),
162
  'post-types' => array(
163
+ 'title' => __( 'Post Types', 'fl-builder' ),
164
  'show' => true
165
  ),
166
  'icons' => array(
167
+ 'title' => __( 'Icons', 'fl-builder' ),
168
  'show' => FL_BUILDER_LITE !== true
169
  ),
170
  'editing' => array(
171
+ 'title' => __( 'Editing', 'fl-builder' ),
172
  'show' => true
173
  ),
174
  'branding' => array(
175
+ 'title' => __( 'Branding', 'fl-builder' ),
176
  'show' => self::has_support( 'branding' ) && ( is_network_admin() || ! self::multisite_support() )
177
  ),
178
  'help-button' => array(
179
+ 'title' => __( 'Help Button', 'fl-builder' ),
180
  'show' => self::has_support( 'help-button' ) && ( is_network_admin() || ! self::multisite_support() )
181
  ),
182
  'cache' => array(
183
+ 'title' => __( 'Cache', 'fl-builder' ),
184
  'show' => true
185
  ),
186
  'uninstall' => array(
187
+ 'title' => __( 'Uninstall', 'fl-builder' ),
188
  'show' => is_network_admin() || ! self::multisite_support()
189
  ),
190
  );
195
  }
196
  }
197
  }
198
+
199
+ /**
200
  * Renders the admin settings forms.
201
  *
202
+ * @since 1.0
203
+ * @return void
204
+ */
205
  static public function render_forms()
206
  {
207
  // License
210
  }
211
 
212
  // Upgrade
213
+ if ( FL_BUILDER_LITE === true ) {
214
  self::render_form( 'upgrade' );
215
  }
216
 
241
  // Uninstall
242
  self::render_form( 'uninstall' );
243
  }
244
+
245
+ /**
246
  * Renders an admin settings form based on the type specified.
247
  *
248
+ * @since 1.0
249
  * @param string $type The type of form to render.
250
+ * @return void
251
+ */
252
  static public function render_form( $type )
253
  {
254
  if ( self::has_support( $type ) ) {
255
  include FL_BUILDER_DIR . 'includes/admin-settings-' . $type . '.php';
256
  }
257
  }
258
+
259
+ /**
260
  * Renders the action for a form.
261
  *
262
+ * @since 1.0
263
  * @param string $type The type of form being rendered.
264
+ * @return void
265
+ */
266
  static public function render_form_action( $type = '' )
267
  {
268
  if ( is_network_admin() ) {
272
  echo admin_url( '/options-general.php?page=fl-builder-settings#' . $type );
273
  }
274
  }
275
+
276
+ /**
277
  * Returns the action for a form.
278
  *
279
+ * @since 1.0
280
  * @param string $type The type of form being rendered.
281
+ * @return string The URL for the form action.
282
+ */
283
  static public function get_form_action( $type = '' )
284
  {
285
  if ( is_network_admin() ) {
289
  return admin_url( '/options-general.php?page=fl-builder-settings#' . $type );
290
  }
291
  }
292
+
293
+ /**
294
  * Checks to see if a settings form is supported.
295
  *
296
+ * @since 1.0
297
  * @param string $type The type of form to check.
298
+ * @return bool
299
+ */
300
  static public function has_support( $type )
301
  {
302
  return file_exists( FL_BUILDER_DIR . 'includes/admin-settings-' . $type . '.php' );
303
  }
304
+
305
+ /**
306
  * Checks to see if multisite is supported.
307
  *
308
+ * @since 1.0
309
+ * @return bool
310
+ */
311
  static public function multisite_support()
312
  {
313
  return is_multisite() && class_exists( 'FLBuilderMultisiteSettings' );
314
  }
315
+
316
+ /**
317
  * Adds an error message to be rendered.
318
  *
319
+ * @since 1.0
320
  * @param string $message The error message to add.
321
+ * @return void
322
+ */
323
  static public function add_error( $message )
324
  {
325
  self::$errors[] = $message;
326
  }
327
+
328
+ /**
329
  * Saves the admin settings.
330
  *
331
+ * @since 1.0
332
+ * @return void
333
+ */
334
  static public function save()
335
  {
336
+ // Only admins can save settings.
337
+ if(!current_user_can('delete_plugins')) {
338
+ return;
339
+ }
340
+
341
  self::save_enabled_modules();
342
  self::save_enabled_templates();
343
  self::save_enabled_post_types();
348
  self::clear_cache();
349
  self::uninstall();
350
  }
351
+
352
+ /**
353
  * Saves the enabled modules.
354
  *
355
+ * @since 1.0
356
+ * @access private
357
+ * @return void
358
+ */
359
  static private function save_enabled_modules()
360
  {
361
+ if ( isset( $_POST['fl-modules-nonce'] ) && wp_verify_nonce( $_POST['fl-modules-nonce'], 'modules' ) ) {
362
+
363
+ $modules = array();
364
+
365
+ if ( is_array( $_POST['fl-modules'] ) ) {
366
+ $modules = array_map( 'sanitize_text_field', $_POST['fl-modules'] );
367
+ }
368
+
369
+ if ( is_network_admin() ) {
370
+ update_site_option( '_fl_builder_enabled_modules', $modules );
371
+ }
372
+ else if ( self::multisite_support() && ! isset( $_POST['fl-override-ms'] ) ) {
373
+ delete_option( '_fl_builder_enabled_modules' );
374
+ }
375
+ else {
376
+ update_option( '_fl_builder_enabled_modules', $modules );
377
+ }
378
+ }
379
+ }
380
+
381
+ /**
382
  * Saves the enabled templates.
383
  *
384
+ * @since 1.0
385
+ * @access private
386
+ * @return void
387
+ */
388
  static private function save_enabled_templates()
389
  {
390
+ if ( isset( $_POST['fl-templates-nonce'] ) && wp_verify_nonce( $_POST['fl-templates-nonce'], 'templates' ) ) {
391
+
392
+ $enabled_templates = sanitize_text_field( $_POST['fl-template-settings'] );
393
+
394
+ if ( is_network_admin() ) {
395
+ update_site_option( '_fl_builder_enabled_templates', $enabled_templates );
396
+ }
397
+ else if ( self::multisite_support() && ! isset( $_POST['fl-override-ms'] ) ) {
398
+ delete_option( '_fl_builder_enabled_templates' );
399
+ }
400
+ else {
401
+ update_option( '_fl_builder_enabled_templates', $enabled_templates );
402
+ }
403
+ }
404
+ }
405
+
406
+ /**
407
  * Saves the enabled post types.
408
  *
409
+ * @since 1.0
410
+ * @access private
411
+ * @return void
412
+ */
413
  static private function save_enabled_post_types()
414
  {
415
+ if ( isset( $_POST['fl-post-types-nonce'] ) && wp_verify_nonce( $_POST['fl-post-types-nonce'], 'post-types' ) ) {
416
+
417
+ if ( is_network_admin() ) {
418
+
419
+ $post_types = sanitize_text_field( $_POST['fl-post-types'] );
420
+ $post_types = str_replace( ' ', '', $post_types );
421
+ $post_types = explode( ',', $post_types );
422
+
423
+ update_site_option( '_fl_builder_post_types', $post_types );
424
+ }
425
+ else if ( self::multisite_support() && ! isset($_POST['fl-override-ms'] ) ) {
426
+ delete_option( '_fl_builder_post_types' );
427
+ }
428
+ else {
429
+
430
+ $post_types = array();
431
+
432
+ if ( is_array( $_POST['fl-post-types'] ) ) {
433
+ $post_types = array_map( 'sanitize_text_field', $_POST['fl-post-types'] );
434
+ }
435
+
436
+ update_option( '_fl_builder_post_types', $post_types );
437
+ }
438
+ }
439
+ }
440
+
441
+ /**
442
  * Saves the enabled icons.
443
  *
444
+ * @since 1.0
445
+ * @access private
446
+ * @return void
447
+ */
448
  static private function save_enabled_icons()
449
  {
450
+ if ( isset( $_POST['fl-icons-nonce'] ) && wp_verify_nonce( $_POST['fl-icons-nonce'], 'icons' ) ) {
451
 
452
  // Make sure we have at least one enabled icon set.
453
  if ( ! isset( $_POST['fl-enabled-icons'] ) && empty( $_POST['fl-new-icon-set'] ) ) {
454
  self::add_error( __( "Error! You must have at least one icon set enabled.", 'fl-builder' ) );
455
+ return;
456
  }
457
+
458
+ $filesystem = FLBuilderUtils::get_filesystem();
459
  $enabled_icons = array();
460
 
461
  // Sanitize the enabled icons.
462
  if ( isset( $_POST['fl-enabled-icons'] ) && is_array( $_POST['fl-enabled-icons'] ) ) {
463
+ $enabled_icons = array_map( 'sanitize_text_field', $_POST['fl-enabled-icons'] );
464
+ }
465
+
466
+ // Update the enabled sets.
467
+ self::update_enabled_icons( $enabled_icons );
468
+
469
+ // Delete a set?
470
+ if ( ! empty( $_POST['fl-delete-icon-set'] ) ) {
471
+
472
+ $sets = FLBuilderIcons::get_sets();
473
+ $key = sanitize_text_field( $_POST['fl-delete-icon-set'] );
474
+ $index = array_search( $key, $enabled_icons );
475
+
476
+ if ( false !== $index ) {
477
+ unset( $enabled_icons[ $index ] );
478
+ }
479
+ if ( isset( $sets[ $key ] ) ) {
480
+ $filesystem->rmdir( $sets[ $key ]['path'], true );
481
+ FLBuilderIcons::remove_set( $key );
482
+ }
483
+ }
484
+
485
+ // Upload a new set?
486
+ if ( ! empty( $_POST['fl-new-icon-set'] ) ) {
487
 
488
+ $dir = FLBuilderModel::get_cache_dir( 'icons' );
489
+ $id = (int) $_POST['fl-new-icon-set'];
490
+ $path = get_attached_file( $id );
491
+ $new_path = $dir['path'] . 'icon-' . time() . '/';
492
+ $unzipped = unzip_file( $path, $new_path );
493
+
494
+ // Unzip failed.
495
+ if ( ! $unzipped ) {
496
+ self::add_error( __( "Error! Could not unzip file.", 'fl-builder' ) );
497
+ return;
498
+ }
499
+
500
+ // Move files if unzipped into a subfolder.
501
+ $files = $filesystem->dirlist( $new_path );
502
+
503
+ if ( 1 == count( $files ) ) {
504
 
505
  $values = array_values( $files );
506
  $subfolder_info = array_shift( $values );
507
+ $subfolder = $new_path . $subfolder_info['name'] . '/';
508
 
509
  if ( file_exists( $subfolder ) && is_dir( $subfolder ) ) {
510
 
511
+ $files = $filesystem->dirlist( $subfolder );
512
+
513
+ if ( $files ) {
514
+ foreach ( $files as $file ) {
515
+ $filesystem->move( $subfolder . $file['name'], $new_path . $file['name'] );
516
+ }
517
+ }
518
+
519
+ $filesystem->rmdir( $subfolder );
520
  }
521
+ }
522
+
523
+ // Check for supported sets.
524
+ $is_icomoon = file_exists( $new_path . 'selection.json' );
525
+ $is_fontello = file_exists( $new_path . 'config.json' );
526
+
527
+ // Show an error if we don't have a supported icon set.
528
+ if ( ! $is_icomoon && ! $is_fontello ) {
529
+ $filesystem->rmdir( $new_path, true );
530
+ self::add_error( __( "Error! Please upload an icon set from either Icomoon or Fontello.", 'fl-builder' ) );
531
+ return;
532
+ }
533
+
534
+ // Enable the new set.
535
+ if ( is_array( $enabled_icons ) ) {
536
+ $key = FLBuilderIcons::get_key_from_path( $new_path );
537
+ $enabled_icons[] = $key;
538
+ }
539
+ }
540
+
541
+ // Update the enabled sets again in case they have changed.
542
+ self::update_enabled_icons( $enabled_icons );
543
+ }
544
+ }
545
+
546
+ /**
547
  * Updates the enabled icons in the database.
548
  *
549
+ * @since 1.0
550
+ * @access private
551
+ * @return void
552
+ */
553
  static private function update_enabled_icons( $enabled_icons = array() )
554
  {
555
  if ( is_network_admin() ) {
556
+ update_site_option( '_fl_builder_enabled_icons', $enabled_icons );
557
+ update_option( '_fl_builder_enabled_icons', $enabled_icons );
558
+ }
559
+ else if ( self::multisite_support() && ! isset( $_POST['fl-override-ms'] ) ) {
560
+ delete_option( '_fl_builder_enabled_icons' );
561
+ }
562
+ else {
563
+ update_option( '_fl_builder_enabled_icons', $enabled_icons );
564
+ }
565
  }
566
+
567
+ /**
568
  * Saves the editing capability.
569
  *
570
+ * @since 1.0
571
+ * @access private
572
+ * @return void
573
+ */
574
  static private function save_editing_capability()
575
  {
576
+ if ( isset( $_POST['fl-editing-nonce'] ) && wp_verify_nonce( $_POST['fl-editing-nonce'], 'editing' ) ) {
577
+
578
+ $capability = sanitize_text_field( $_POST['fl-editing-capability'] );
579
+
580
+ if ( is_network_admin() ) {
581
+ update_site_option( '_fl_builder_editing_capability', $capability );
582
+ }
583
+ else if ( self::multisite_support() && ! isset( $_POST['fl-override-ms'] ) ) {
584
+ delete_option( '_fl_builder_editing_capability' );
585
+ }
586
+ else {
587
+ update_option( '_fl_builder_editing_capability', $capability );
588
+ }
589
+ }
590
+ }
591
+
592
+ /**
593
  * Saves the branding settings.
594
  *
595
+ * @since 1.0
596
+ * @access private
597
+ * @return void
598
+ */
599
  static private function save_branding()
600
  {
601
+ if ( isset( $_POST['fl-branding-nonce'] ) && wp_verify_nonce( $_POST['fl-branding-nonce'], 'branding' ) ) {
602
+
603
+ $branding = wp_kses_post( $_POST['fl-branding'] );
604
+ $branding_icon = sanitize_text_field( $_POST['fl-branding-icon'] );
605
+
606
+ if ( is_network_admin() ) {
607
  update_site_option( '_fl_builder_branding', $branding );
608
  update_site_option( '_fl_builder_branding_icon', $branding_icon );
609
+ }
610
+ else {
611
  update_option( '_fl_builder_branding', $branding );
612
  update_option( '_fl_builder_branding_icon', $branding_icon );
613
+ }
614
+ }
615
+ }
616
+
617
+ /**
618
  * Saves the help button settings.
619
  *
620
+ * @since 1.0
621
+ * @access private
622
+ * @return void
623
+ */
624
  static private function save_help_button()
625
  {
626
+ if ( isset( $_POST['fl-help-button-nonce'] ) && wp_verify_nonce( $_POST['fl-help-button-nonce'], 'help-button' ) ) {
627
+
628
+ $settings = FLBuilderModel::get_help_button_defaults();
629
+ $settings['enabled'] = isset( $_POST['fl-help-button-enabled'] ) ? true : false;
630
+ $settings['tour'] = isset( $_POST['fl-help-tour-enabled'] ) ? true : false;
631
+ $settings['video'] = isset( $_POST['fl-help-video-enabled'] ) ? true : false;
632
+ $settings['knowledge_base'] = isset( $_POST['fl-knowledge-base-enabled'] ) ? true : false;
633
+ $settings['forums'] = isset( $_POST['fl-forums-enabled'] ) ? true : false;
634
+
635
+ // Disable everything if the main button is disabled.
636
+ if ( ! $settings['enabled'] ) {
637
+ $settings['tour'] = false;
638
+ $settings['video'] = false;
639
+ $settings['knowledge_base'] = false;
640
+ $settings['forums'] = false;
641
+ }
642
+
643
+ // Clean the video embed.
644
+ $video_embed = wp_kses( $_POST['fl-help-video-embed'], array(
645
+ 'iframe' => array(
646
+ 'src' => array(),
647
+ 'frameborder' => array(),
648
+ 'webkitallowfullscreen' => array(),
649
+ 'mozallowfullscreen' => array(),
650
+ 'allowfullscreen' => array()
651
+ )
652
+ ));
653
+
654
+ // Save the video embed.
655
+ if ( ! empty( $video_embed ) && ! stristr( $video_embed, 'iframe' ) ) {
656
+ self::add_error( __( "Error! Please enter an iframe for the video embed code.", 'fl-builder' ) );
657
+ }
658
+ else if ( ! empty( $video_embed ) ) {
659
+ $settings['video_embed'] = $video_embed;
660
+ }
661
+
662
+ // Save the knowledge base URL.
663
+ if ( ! empty( $_POST['fl-knowledge-base-url'] ) ) {
664
+ $settings['knowledge_base_url'] = sanitize_text_field( $_POST['fl-knowledge-base-url'] );
665
+ }
666
+
667
+ // Save the forums URL.
668
+ if ( ! empty( $_POST['fl-forums-url'] ) ) {
669
+ $settings['forums_url'] = sanitize_text_field( $_POST['fl-forums-url'] );
670
+ }
671
+
672
+ // Make sure we have at least one help feature enabled.
673
+ if ( $settings['enabled'] && ! $settings['tour'] && ! $settings['video'] && ! $settings['knowledge_base'] && ! $settings['forums'] ) {
674
+ self::add_error( __( "Error! You must have at least one feature of the help button enabled.", 'fl-builder' ) );
675
+ return;
676
+ }
677
+
678
+ // Save the settings.
679
+ if ( is_network_admin() ) {
680
  update_site_option( '_fl_builder_help_button', $settings );
681
+ }
682
+ else {
683
  update_option( '_fl_builder_help_button', $settings );
684
+ }
685
+ }
686
+ }
687
 
688
+ /**
689
  * Clears the builder cache.
690
  *
691
  * @since 1.5.3
692
+ * @access private
693
+ * @return void
694
+ */
695
  static private function clear_cache()
696
  {
697
+ if ( ! current_user_can( 'delete_plugins' ) ) {
698
+ return;
699
+ }
700
+ else if ( isset( $_POST['fl-cache-nonce'] ) && wp_verify_nonce( $_POST['fl-cache-nonce'], 'cache' ) ) {
701
+ if ( is_network_admin() ) {
702
+ self::clear_cache_for_all_sites();
703
+ }
704
+ else {
705
+ FLBuilderModel::delete_all_asset_cache();
706
+ }
707
+ }
708
+ }
709
 
710
+ /**
711
  * Clears the builder cache for all sites on a network.
712
  *
713
  * @since 1.5.3
714
+ * @access private
715
+ * @return void
716
+ */
717
  static private function clear_cache_for_all_sites()
718
  {
719
+ global $blog_id;
720
+ global $wpdb;
721
+
722
+ // Save the original blog id.
723
+ $original_blog_id = $blog_id;
724
+
725
+ // Get all blog ids.
726
+ $blog_ids = $wpdb->get_col( "SELECT blog_id FROM $wpdb->blogs" );
727
+
728
+ // Loop through the blog ids and clear the cache.
729
+ foreach ( $blog_ids as $id ) {
730
+ switch_to_blog( $id );
731
+ FLBuilderModel::delete_all_asset_cache();
732
+ }
733
+
734
+ // Revert to the original blog.
735
+ switch_to_blog( $original_blog_id );
736
+ }
737
 
738
+ /**
739
  * Uninstalls the builder and all of its data.
740
  *
741
+ * @since 1.0
742
+ * @access private
743
+ * @return void
744
+ */
745
  static private function uninstall()
746
  {
747
+ if ( ! current_user_can( 'delete_plugins' ) ) {
748
+ return;
749
+ }
750
+ else if ( isset( $_POST['fl-uninstall'] ) && wp_verify_nonce( $_POST['fl-uninstall'], 'uninstall' ) ) {
751
+ if ( is_multisite() && class_exists( 'FLBuilderMultisite' ) ) {
752
+ FLBuilderMultisite::uninstall();
753
+ }
754
+ else {
755
+ FLBuilderAdmin::uninstall();
756
+ }
757
+ }
758
+ }
759
  }
classes/class-fl-builder-admin.php CHANGED
@@ -3,214 +3,261 @@
3
  /**
4
  * Main builder admin class.
5
  *
6
- * @class FLBuilderAdmin
7
  */
8
  final class FLBuilderAdmin {
9
 
10
  /**
11
- * @method activate
12
- */
13
- static public function activate()
14
- {
15
- global $wp_version;
16
-
17
- // Check for WordPress 3.5 and above.
18
- if(version_compare($wp_version, '3.5', '>=')) {
19
-
20
- // Check for multisite.
21
- if(is_multisite()) {
22
-
23
- // Init multisite support.
24
- self::init_classes();
25
- self::init_multisite();
26
-
27
- // This version has multisite support.
28
- if(class_exists('FLBuilderMultisite')) {
29
-
30
- if(is_network_admin()) {
31
- FLBuilderMultisite::install();
32
- }
33
- else {
34
- self::install();
35
- }
36
- }
37
- // This version doesn't have multisite support.
38
- else {
39
- $url = FLBuilderModel::get_upgrade_url( array( 'utm_source' => 'external', 'utm_medium' => 'builder', 'utm_campaign' => 'no-multisite-support' ) );
 
 
 
 
 
40
  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"' ) );
41
- }
42
- }
43
- // No multisite, standard install.
44
- else {
45
- self::install();
46
- }
47
- }
48
- // Wrong WordPress version.
49
- else {
50
- 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'));
51
- }
52
-
53
- // Success! Trigger the activation notice.
54
- if(FL_BUILDER_LITE !== true) {
55
- update_site_option('_fl_builder_activation_admin_notice', true);
56
- }
57
- }
58
 
59
  /**
60
- * @method show_activate_error
61
- */
62
- static public function show_activate_error($message)
63
- {
64
- deactivate_plugins( FLBuilderModel::plugin_basename(), false, is_network_admin() );
 
 
 
 
 
65
 
66
- die( $message );
67
- }
68
 
69
  /**
70
- * @method show_activate_notice
71
- */
72
- static public function show_activate_notice()
73
- {
74
- $notice = get_site_option('_fl_builder_activation_admin_notice');
75
-
76
- if($notice) {
77
- add_action('admin_notices', 'FLBuilderAdmin::activate_notice');
78
- add_action('network_admin_notices', 'FLBuilderAdmin::activate_notice');
79
- delete_site_option('_fl_builder_activation_admin_notice');
80
- }
81
- }
 
 
 
82
 
83
  /**
84
- * @method activate_notice
85
- */
86
- static public function activate_notice()
87
- {
88
- if ( class_exists('FLBuilderMultisiteSettings') && is_multisite() && current_user_can( 'manage_network_plugins' ) ) {
89
- $href = esc_url( network_admin_url( '/settings.php?page=fl-builder-multisite-settings#license' ) );
90
- }
91
- else {
92
- $href = esc_url( admin_url( '/options-general.php?page=fl-builder-settings#license' ) );
93
- }
94
-
95
- echo '<div class="updated" style="background: #d3ebc1;">';
 
 
 
96
  echo '<p><strong>' . sprintf( __( 'Page Builder activated! <a%s>Click here</a> to enable remote updates.', 'fl-builder' ), ' href="' . esc_url( $href ) . '"' ) . '</strong></p>';
97
- echo '</div>';
98
- }
 
 
 
 
 
 
 
 
 
99
 
100
  /**
101
- * @method install
102
- */
103
- static public function install() {}
 
 
 
 
 
 
104
 
105
  /**
106
- * @method uninstall
107
- */
108
- static public function uninstall()
109
- {
110
- FLBuilderModel::uninstall_database();
111
- }
112
-
113
- /**
114
- * @method init
115
- */
116
- static public function init()
117
- {
118
- self::init_classes();
119
- self::init_settings();
120
- self::init_multisite();
121
- self::init_templates();
122
- self::show_activate_notice();
123
- }
124
-
125
- /**
126
- * @method init_classes
127
- */
128
- static public function init_classes()
129
- {
130
- $templates_class = FL_BUILDER_DIR . 'classes/class-fl-builder-templates.php';
131
- $ms_class = FL_BUILDER_DIR . 'classes/class-fl-builder-multisite.php';
132
- $ms_settings_class = FL_BUILDER_DIR . 'classes/class-fl-builder-multisite-settings.php';
133
-
134
- if(file_exists($templates_class)) {
135
- require_once $templates_class;
136
- }
137
- if(is_multisite()) {
138
-
139
- if(file_exists($ms_class)) {
140
- require_once $ms_class;
141
- }
142
- if(file_exists($ms_settings_class)) {
143
- require_once $ms_settings_class;
144
- }
145
- }
146
-
147
- require_once FL_BUILDER_DIR . 'classes/class-fl-builder-admin-settings.php';
148
- }
149
-
150
- /**
151
- * @method init_settings
152
- */
153
- static public function init_settings()
154
- {
155
- FLBuilderAdminSettings::init();
156
- }
157
-
158
- /**
159
- * @method init_multisite
160
- */
161
- static public function init_multisite()
162
- {
163
- if(is_multisite()) {
164
-
165
- if(class_exists('FLBuilderMultisite')) {
166
- FLBuilderMultisite::init();
167
- }
168
- if(class_exists('FLBuilderMultisiteSettings')) {
169
- FLBuilderMultisiteSettings::init();
170
- }
171
- }
172
- }
173
-
174
- /**
175
- * @method init_templates
176
- */
177
- static public function init_templates()
178
- {
179
- if(class_exists('FLBuilderTemplates')) {
180
- FLBuilderTemplates::init();
181
- }
182
- }
183
 
184
  /**
185
- * @method render_plugin_action_links
186
- */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
187
  static public function render_plugin_action_links($actions)
188
- {
189
- if(FL_BUILDER_LITE === true) {
190
- $url = FLBuilderModel::get_upgrade_url( array( 'utm_source' => 'external', 'utm_medium' => 'builder', 'utm_campaign' => 'plugins-page' ) );
191
  $actions[] = '<a href="' . $url . '" style="color:#3db634;" target="_blank">' . _x( 'Upgrade', 'Plugin action link label.', 'fl-builder' ) . '</a>';
192
- }
193
 
194
- return $actions;
195
- }
196
 
197
  /**
198
- * @method white_label_plugins_page
199
- */
 
 
 
 
200
  static public function white_label_plugins_page($plugins)
201
- {
202
- $default = __( 'Page Builder', 'fl-builder' );
203
- $branding = FLBuilderModel::get_branding();
204
- $key = FLBuilderModel::plugin_basename();
205
-
206
- if ( isset( $plugins[ $key ] ) && $branding != $default ) {
207
- $plugins[ $key ]['Name'] = $branding;
208
- $plugins[ $key ]['Title'] = $branding;
209
- $plugins[ $key ]['Author'] = '';
210
- $plugins[ $key ]['AuthorName'] = '';
211
- $plugins[ $key ]['PluginURI'] = '';
212
- }
213
-
214
- return $plugins;
215
- }
216
  }
3
  /**
4
  * Main builder admin class.
5
  *
6
+ * @since 1.0
7
  */
8
  final class FLBuilderAdmin {
9
 
10
  /**
11
+ * Called on plugin activation and checks to see if the correct
12
+ * WordPress version is installed and multisite is supported. If
13
+ * all checks are passed the install method is called.
14
+ *
15
+ * @since 1.0
16
+ * @return void
17
+ */
18
+ static public function activate()
19
+ {
20
+ global $wp_version;
21
+
22
+ // Check for WordPress 3.5 and above.
23
+ if(version_compare($wp_version, '3.5', '>=')) {
24
+
25
+ // Check for multisite.
26
+ if(is_multisite()) {
27
+
28
+ // Init multisite support.
29
+ self::init_classes();
30
+ self::init_multisite();
31
+
32
+ // This version has multisite support.
33
+ if(class_exists('FLBuilderMultisite')) {
34
+
35
+ if(is_network_admin()) {
36
+ FLBuilderMultisite::install();
37
+ }
38
+ else {
39
+ self::install();
40
+ }
41
+ }
42
+ // This version doesn't have multisite support.
43
+ else {
44
+ $url = FLBuilderModel::get_upgrade_url( array( 'utm_source' => 'external', 'utm_medium' => 'builder', 'utm_campaign' => 'no-multisite-support' ) );
45
  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"' ) );
46
+ }
47
+ }
48
+ // No multisite, standard install.
49
+ else {
50
+ self::install();
51
+ }
52
+ }
53
+ // Wrong WordPress version.
54
+ else {
55
+ 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'));
56
+ }
57
+
58
+ // Success! Trigger the activation notice.
59
+ if(FL_BUILDER_LITE !== true) {
60
+ update_site_option('_fl_builder_activation_admin_notice', true);
61
+ }
62
+ }
63
 
64
  /**
65
+ * Show a message if there is an activation error and
66
+ * deactivates the plugin.
67
+ *
68
+ * @since 1.0
69
+ * @param string $message The message to show.
70
+ * @return void
71
+ */
72
+ static public function show_activate_error($message)
73
+ {
74
+ deactivate_plugins( FLBuilderModel::plugin_basename(), false, is_network_admin() );
75
 
76
+ die( $message );
77
+ }
78
 
79
  /**
80
+ * Sets the action to show the activation success message.
81
+ *
82
+ * @since 1.0
83
+ * @return void
84
+ */
85
+ static public function show_activate_notice()
86
+ {
87
+ $notice = get_site_option('_fl_builder_activation_admin_notice');
88
+
89
+ if($notice) {
90
+ add_action('admin_notices', 'FLBuilderAdmin::activate_notice');
91
+ add_action('network_admin_notices', 'FLBuilderAdmin::activate_notice');
92
+ delete_site_option('_fl_builder_activation_admin_notice');
93
+ }
94
+ }
95
 
96
  /**
97
+ * Shows the activation success message.
98
+ *
99
+ * @since 1.0
100
+ * @return void
101
+ */
102
+ static public function activate_notice()
103
+ {
104
+ if ( class_exists('FLBuilderMultisiteSettings') && is_multisite() && current_user_can( 'manage_network_plugins' ) ) {
105
+ $href = esc_url( network_admin_url( '/settings.php?page=fl-builder-multisite-settings#license' ) );
106
+ }
107
+ else {
108
+ $href = esc_url( admin_url( '/options-general.php?page=fl-builder-settings#license' ) );
109
+ }
110
+
111
+ echo '<div class="updated" style="background: #d3ebc1;">';
112
  echo '<p><strong>' . sprintf( __( 'Page Builder activated! <a%s>Click here</a> to enable remote updates.', 'fl-builder' ), ' href="' . esc_url( $href ) . '"' ) . '</strong></p>';
113
+ echo '</div>';
114
+ }
115
+
116
+ /**
117
+ * Installs the builder upon successful activation.
118
+ * Currently not used but may be in the future.
119
+ *
120
+ * @since 1.0
121
+ * @return void
122
+ */
123
+ static public function install() {}
124
 
125
  /**
126
+ * Uninstalls the builder.
127
+ *
128
+ * @since 1.0
129
+ * @return void
130
+ */
131
+ static public function uninstall()
132
+ {
133
+ FLBuilderModel::uninstall_database();
134
+ }
135
 
136
  /**
137
+ * Initializes builder logic for wp-admin.
138
+ *
139
+ * @since 1.0
140
+ * @return void
141
+ */
142
+ static public function init()
143
+ {
144
+ self::init_classes();
145
+ self::init_settings();
146
+ self::init_multisite();
147
+ self::init_templates();
148
+ self::show_activate_notice();
149
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
150
 
151
  /**
152
+ * Loads builder classes for wp-admin.
153
+ *
154
+ * @since 1.0
155
+ * @return void
156
+ */
157
+ static public function init_classes()
158
+ {
159
+ $templates_class = FL_BUILDER_DIR . 'classes/class-fl-builder-templates.php';
160
+ $ms_class = FL_BUILDER_DIR . 'classes/class-fl-builder-multisite.php';
161
+ $ms_settings_class = FL_BUILDER_DIR . 'classes/class-fl-builder-multisite-settings.php';
162
+
163
+ if(file_exists($templates_class)) {
164
+ require_once $templates_class;
165
+ }
166
+ if(is_multisite()) {
167
+
168
+ if(file_exists($ms_class)) {
169
+ require_once $ms_class;
170
+ }
171
+ if(file_exists($ms_settings_class)) {
172
+ require_once $ms_settings_class;
173
+ }
174
+ }
175
+
176
+ require_once FL_BUILDER_DIR . 'classes/class-fl-builder-admin-settings.php';
177
+ }
178
+
179
+ /**
180
+ * Initializes the builder admin settings page.
181
+ *
182
+ * @since 1.0
183
+ * @return void
184
+ */
185
+ static public function init_settings()
186
+ {
187
+ FLBuilderAdminSettings::init();
188
+ }
189
+
190
+ /**
191
+ * Initializes the builder network admin settings page
192
+ * and additional multisite logic.
193
+ *
194
+ * @since 1.0
195
+ * @return void
196
+ */
197
+ static public function init_multisite()
198
+ {
199
+ if(is_multisite()) {
200
+
201
+ if(class_exists('FLBuilderMultisite')) {
202
+ FLBuilderMultisite::init();
203
+ }
204
+ if(class_exists('FLBuilderMultisiteSettings')) {
205
+ FLBuilderMultisiteSettings::init();
206
+ }
207
+ }
208
+ }
209
+
210
+ /**
211
+ * Initializes the interface for core builder templates.
212
+ *
213
+ * @since 1.0
214
+ * @return void
215
+ */
216
+ static public function init_templates()
217
+ {
218
+ if(class_exists('FLBuilderTemplates')) {
219
+ FLBuilderTemplates::init();
220
+ }
221
+ }
222
+
223
+ /**
224
+ * Renders the link for the row actions on the plugins page.
225
+ *
226
+ * @since 1.0
227
+ * @param array $actions An array of row action links.
228
+ * @return array
229
+ */
230
  static public function render_plugin_action_links($actions)
231
+ {
232
+ if(FL_BUILDER_LITE === true) {
233
+ $url = FLBuilderModel::get_upgrade_url( array( 'utm_source' => 'external', 'utm_medium' => 'builder', 'utm_campaign' => 'plugins-page' ) );
234
  $actions[] = '<a href="' . $url . '" style="color:#3db634;" target="_blank">' . _x( 'Upgrade', 'Plugin action link label.', 'fl-builder' ) . '</a>';
235
+ }
236
 
237
+ return $actions;
238
+ }
239
 
240
  /**
241
+ * White labels the builder on the plugins page.
242
+ *
243
+ * @since 1.0
244
+ * @param array $plugins An array data for each plugin.
245
+ * @return array
246
+ */
247
  static public function white_label_plugins_page($plugins)
248
+ {
249
+ $default = __( 'Page Builder', 'fl-builder' );
250
+ $branding = FLBuilderModel::get_branding();
251
+ $key = FLBuilderModel::plugin_basename();
252
+
253
+ if ( isset( $plugins[ $key ] ) && $branding != $default ) {
254
+ $plugins[ $key ]['Name'] = $branding;
255
+ $plugins[ $key ]['Title'] = $branding;
256
+ $plugins[ $key ]['Author'] = '';
257
+ $plugins[ $key ]['AuthorName'] = '';
258
+ $plugins[ $key ]['PluginURI'] = '';
259
+ }
260
+
261
+ return $plugins;
262
+ }
263
  }
classes/class-fl-builder-auto-suggest.php CHANGED
@@ -1,79 +1,92 @@
1
  <?php
2
 
3
  /**
4
- * A class for working with auto suggest requests.
5
  *
6
- * @class FLBuilderAutoSuggest
7
  */
8
  final class FLBuilderAutoSuggest {
9
 
10
- /**
11
- * @method init
12
- */
 
 
 
 
13
  static public function init()
14
  {
15
- if(isset($_REQUEST['fl_as_action']) && isset($_REQUEST['fl_as_query'])) {
16
-
17
- switch($_REQUEST['fl_as_action']) {
18
-
19
- case 'fl_as_posts':
20
- $data = self::posts();
21
- break;
22
-
23
- case 'fl_as_terms':
24
- $data = self::terms();
25
- break;
26
-
27
- case 'fl_as_users':
28
- $data = self::users();
29
- break;
30
-
31
- case 'fl_as_links':
32
- $data = self::links();
33
- break;
34
- }
35
-
36
- if(isset($data)) {
37
- echo json_encode($data);
38
- die();
39
- }
40
- }
41
  }
42
 
43
  /**
44
- * @method init
45
- */
 
 
 
 
 
 
46
  static public function get_value($action = '', $value = '', $data = '')
47
  {
48
- switch($action) {
49
-
50
- case 'fl_as_posts':
51
- $data = self::posts_value($value, $data);
52
- break;
53
-
54
- case 'fl_as_terms':
55
- $data = self::terms_value($value, $data);
56
- break;
57
-
58
- case 'fl_as_users':
59
- $data = self::users_value($value);
60
- break;
61
-
62
- default :
63
-
64
- if(function_exists($action . '_value')) {
65
- $data = call_user_func_array($action . '_value', array($value, $data));
66
- }
67
-
68
- break;
69
- }
70
-
71
- return isset($data) ? json_encode($data) : '';
72
  }
73
 
74
  /**
75
- * @method get_like
76
- */
 
 
 
77
  static public function get_like()
78
  {
79
  global $wpdb;
@@ -81,168 +94,193 @@ final class FLBuilderAutoSuggest {
81
  $like = urldecode( $_REQUEST['fl_as_query'] );
82
 
83
  if ( method_exists( $wpdb, 'esc_like' ) ) {
84
- $like = esc_sql( $wpdb->esc_like( $like ) );
85
- }
86
- else {
87
  $like = like_escape( esc_sql( $like ) );
88
- }
89
-
90
- return $like;
91
  }
92
 
93
- /**
94
- * @method posts
95
- */
 
 
 
96
  static public function posts()
97
  {
98
- global $wpdb;
99
-
100
- $data = array();
101
- $like = self::get_like();
102
- $type = esc_sql($_REQUEST['fl_as_action_data']);
103
-
104
- $posts = $wpdb->get_results("
105
- SELECT ID, post_title FROM {$wpdb->posts}
106
- WHERE post_title LIKE '%{$like}%'
107
- AND post_type = '{$type}'
108
- AND post_status = 'publish'
109
- ");
110
-
111
- foreach($posts as $post) {
112
- $data[] = array('name' => $post->post_title, 'value' => $post->ID);
113
- }
114
-
115
- return $data;
116
  }
117
 
118
- /**
119
- * @method posts_value
120
- */
121
- static public function posts_value($ids, $type)
 
 
 
 
122
  {
123
- global $wpdb;
124
-
125
- $data = array();
126
-
127
- if(!empty($ids)) {
128
-
129
- $posts = $wpdb->get_results("SELECT ID, post_title FROM {$wpdb->posts} WHERE ID IN ({$ids})");
130
-
131
- foreach($posts as $post) {
132
- $data[] = array('name' => $post->post_title, 'value' => $post->ID);
133
- }
134
- }
135
-
136
- return $data;
137
  }
138
 
139
- /**
140
- * @method terms
141
- */
 
 
 
142
  static public function terms()
143
  {
144
- $data = array();
145
- $cats = get_categories(array(
146
- 'hide_empty' => 0,
147
- 'taxonomy' => $_REQUEST['fl_as_action_data']
148
- ));
149
-
150
- foreach($cats as $cat) {
151
- $data[] = array('name' => $cat->name, 'value' => $cat->term_id);
152
- }
153
-
154
- return $data;
155
  }
156
 
157
- /**
158
- * @method terms_value
159
- */
 
 
 
 
 
160
  static public function terms_value($ids, $taxonomy)
161
  {
162
- $data = array();
163
-
164
- if(!empty($ids)) {
165
 
166
- $cats = get_categories(array(
167
- 'hide_empty' => 0,
168
- 'taxonomy' => $taxonomy,
169
- 'include' => $ids
170
- ));
171
-
172
- foreach($cats as $cat) {
173
- $data[] = array('name' => $cat->name, 'value' => $cat->term_id);
174
- }
175
- }
176
-
177
- return $data;
178
  }
179
 
180
- /**
181
- * @method users
182
- */
 
 
 
183
  static public function users()
184
  {
185
- global $wpdb;
186
-
187
- $data = array();
188
- $like = self::get_like();
189
- $users = $wpdb->get_results("SELECT * FROM {$wpdb->users} WHERE user_login LIKE '%{$like}%'");
190
-
191
- foreach($users as $user) {
192
- $data[] = array('name' => $user->user_login, 'value' => $user->ID);
193
- }
194
-
195
- return $data;
196
  }
197
 
198
- /**
199
- * @method users_value
200
- */
 
 
 
 
201
  static public function users_value($ids)
202
  {
203
- global $wpdb;
204
-
205
- $data = array();
206
-
207
- if(!empty($ids)) {
208
-
209
- $users = $wpdb->get_results("SELECT * FROM {$wpdb->users} WHERE ID IN ({$ids})");
210
-
211
- foreach($users as $user) {
212
- $data[] = array('name' => $user->user_login, 'value' => $user->ID);
213
- }
214
- }
215
-
216
- return $data;
217
  }
218
 
219
- /**
220
- * @method links
221
- */
 
 
 
222
  static public function links()
223
  {
224
- global $wpdb;
225
-
226
- $data = array();
227
- $like = self::get_like();
228
- $types = FLBuilderLoop::post_types();
229
- $slugs = array();
230
 
231
- foreach($types as $slug => $type) {
232
- $slugs[] = esc_sql($slug);
233
- }
234
-
235
- $posts = $wpdb->get_results("
236
- SELECT ID, post_title FROM {$wpdb->posts}
237
- WHERE post_title LIKE '%{$like}%'
238
- AND post_type IN ('" . implode("','", $slugs) . "')
239
- AND post_status = 'publish'
240
- ");
241
-
242
- foreach($posts as $post) {
243
- $data[] = array('name' => $post->post_title, 'value' => get_permalink($post->ID));
244
- }
245
-
246
- return $data;
247
  }
248
  }
1
  <?php
2
 
3
  /**
4
+ * A class for working with auto suggest AJAX requests.
5
  *
6
+ * @since 1.2.3
7
  */
8
  final class FLBuilderAutoSuggest {
9
 
10
+ /**
11
+ * Checks for an auto suggest request. If one is found
12
+ * the data will be echoed as a JSON response.
13
+ *
14
+ * @since 1.2.3
15
+ * @return void
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
+ echo json_encode($data);
42
+ die();
43
+ }
44
+ }
45
  }
46
 
47
  /**
48
+ * Returns a JSON encoded value for a suggest field.
49
+ *
50
+ * @since 1.2.3
51
+ * @param string $action The type of auto suggest action.
52
+ * @param string $value The current value.
53
+ * @param string $data Additional auto suggest data.
54
+ * @return string The JSON encoded value.
55
+ */
56
  static public function get_value($action = '', $value = '', $data = '')
57
  {
58
+ switch($action) {
59
+
60
+ case 'fl_as_posts':
61
+ $data = self::posts_value($value);
62
+ break;
63
+
64
+ case 'fl_as_terms':
65
+ $data = self::terms_value($value, $data);
66
+ break;
67
+
68
+ case 'fl_as_users':
69
+ $data = self::users_value($value);
70
+ break;
71
+
72
+ default :
73
+
74
+ if(function_exists($action . '_value')) {
75
+ $data = call_user_func_array($action . '_value', array($value, $data));
76
+ }
77
+
78
+ break;
79
+ }
80
+
81
+ return isset($data) ? json_encode($data) : '';
82
  }
83
 
84
  /**
85
+ * Returns the SQL escaped like value for auto suggest queries.
86
+ *
87
+ * @since 1.2.3
88
+ * @return string
89
+ */
90
  static public function get_like()
91
  {
92
  global $wpdb;
94
  $like = urldecode( $_REQUEST['fl_as_query'] );
95
 
96
  if ( method_exists( $wpdb, 'esc_like' ) ) {
97
+ $like = esc_sql( $wpdb->esc_like( $like ) );
98
+ }
99
+ else {
100
  $like = like_escape( esc_sql( $like ) );
101
+ }
102
+
103
+ return $like;
104
  }
105
 
106
+ /**
107
+ * Returns data for post auto suggest queries.
108
+ *
109
+ * @since 1.2.3
110
+ * @return array
111
+ */
112
  static public function posts()
113
  {
114
+ global $wpdb;
115
+
116
+ $data = array();
117
+ $like = self::get_like();
118
+ $type = esc_sql($_REQUEST['fl_as_action_data']);
119
+
120
+ $posts = $wpdb->get_results("
121
+ SELECT ID, post_title FROM {$wpdb->posts}
122
+ WHERE post_title LIKE '%{$like}%'
123
+ AND post_type = '{$type}'
124
+ AND post_status = 'publish'
125
+ ");
126
+
127
+ foreach($posts as $post) {
128
+ $data[] = array('name' => $post->post_title, 'value' => $post->ID);
129
+ }
130
+
131
+ return $data;
132
  }
133
 
134
+ /**
135
+ * Returns data for selected posts.
136
+ *
137
+ * @since 1.2.3
138
+ * @param string $ids The selected post ids.
139
+ * @return array An array of post data.
140
+ */
141
+ static public function posts_value($ids)
142
  {
143
+ global $wpdb;
144
+
145
+ $data = array();
146
+
147
+ if(!empty($ids)) {
148
+
149
+ $posts = $wpdb->get_results("SELECT ID, post_title FROM {$wpdb->posts} WHERE ID IN ({$ids})");
150
+
151
+ foreach($posts as $post) {
152
+ $data[] = array('name' => $post->post_title, 'value' => $post->ID);
153
+ }
154
+ }
155
+
156
+ return $data;
157
  }
158
 
159
+ /**
160
+ * Returns data for term auto suggest queries.
161
+ *
162
+ * @since 1.2.3
163
+ * @return array
164
+ */
165
  static public function terms()
166
  {
167
+ $data = array();
168
+ $cats = get_categories(array(
169
+ 'hide_empty' => 0,
170
+ 'taxonomy' => $_REQUEST['fl_as_action_data']
171
+ ));
172
+
173
+ foreach($cats as $cat) {
174
+ $data[] = array('name' => $cat->name, 'value' => $cat->term_id);
175
+ }
176
+
177
+ return $data;
178
  }
179
 
180
+ /**
181
+ * Returns data for selected terms.
182
+ *
183
+ * @since 1.2.3
184
+ * @param string $ids The selected term ids.
185
+ * @param string $taxonomy The taxonomy to look in.
186
+ * @return array An array of term data.
187
+ */
188
  static public function terms_value($ids, $taxonomy)
189
  {
190
+ $data = array();
191
+
192
+ if(!empty($ids)) {
193
 
194
+ $cats = get_categories(array(
195
+ 'hide_empty' => 0,
196
+ 'taxonomy' => $taxonomy,
197
+ 'include' => $ids
198
+ ));
199
+
200
+ foreach($cats as $cat) {
201
+ $data[] = array('name' => $cat->name, 'value' => $cat->term_id);
202
+ }
203
+ }
204
+
205
+ return $data;
206
  }
207
 
208
+ /**
209
+ * Returns data for user auto suggest queries.
210
+ *
211
+ * @since 1.2.3
212
+ * @return array
213
+ */
214
  static public function users()
215
  {
216
+ global $wpdb;
217
+
218
+ $data = array();
219
+ $like = self::get_like();
220
+ $users = $wpdb->get_results("SELECT * FROM {$wpdb->users} WHERE user_login LIKE '%{$like}%'");
221
+
222
+ foreach($users as $user) {
223
+ $data[] = array('name' => $user->user_login, 'value' => $user->ID);
224
+ }
225
+
226
+ return $data;
227
  }
228
 
229
+ /**
230
+ * Returns data for selected users.
231
+ *
232
+ * @since 1.2.3
233
+ * @param string $ids The selected user ids.
234
+ * @return array An array of user data.
235
+ */
236
  static public function users_value($ids)
237
  {
238
+ global $wpdb;
239
+
240
+ $data = array();
241
+
242
+ if(!empty($ids)) {
243
+
244
+ $users = $wpdb->get_results("SELECT * FROM {$wpdb->users} WHERE ID IN ({$ids})");
245
+
246
+ foreach($users as $user) {
247
+ $data[] = array('name' => $user->user_login, 'value' => $user->ID);
248
+ }
249
+ }
250
+
251
+ return $data;
252
  }
253
 
254
+ /**
255
+ * Returns data for link auto suggest queries.
256
+ *
257
+ * @since 1.3.9
258
+ * @return array
259
+ */
260
  static public function links()
261
  {
262
+ global $wpdb;
263
+
264
+ $data = array();
265
+ $like = self::get_like();
266
+ $types = FLBuilderLoop::post_types();
267
+ $slugs = array();
268
 
269
+ foreach($types as $slug => $type) {
270
+ $slugs[] = esc_sql($slug);
271
+ }
272
+
273
+ $posts = $wpdb->get_results("
274
+ SELECT ID, post_title FROM {$wpdb->posts}
275
+ WHERE post_title LIKE '%{$like}%'
276
+ AND post_type IN ('" . implode("','", $slugs) . "')
277
+ AND post_status = 'publish'
278
+ ");
279
+
280
+ foreach($posts as $post) {
281
+ $data[] = array('name' => $post->post_title, 'value' => get_permalink($post->ID));
282
+ }
283
+
284
+ return $data;
285
  }
286
  }
classes/class-fl-builder-color.php CHANGED
@@ -1,46 +1,62 @@
1
  <?php
2
 
3
  /**
4
- * Helper class for working with colors.
5
  *
6
- * @class FLBuilderColor
7
  */
8
-
9
  final class FLBuilderColor {
10
 
11
- static public function hex_to_rgb($hex)
12
- {
13
- return array(
14
- 'r' => hexdec(substr($hex,0,2)),
15
- 'g' => hexdec(substr($hex,2,2)),
16
- 'b' => hexdec(substr($hex,4,2))
17
- );
18
- }
 
 
 
 
 
 
 
19
 
20
- static public function adjust_brightness($hex, $steps, $type)
21
- {
22
- // Get rgb vars.
23
- extract(self::hex_to_rgb($hex));
24
-
25
- // Should we darken the color?
26
- if($type == 'reverse' && $r + $g + $b > 382){
27
- $steps = -$steps;
28
- }
29
- else if($type == 'darken') {
30
- $steps = -$steps;
31
- }
32
-
33
- // Build the new color.
34
- $steps = max(-255, min(255, $steps));
35
-
36
- $r = max(0,min(255,$r + $steps));
37
- $g = max(0,min(255,$g + $steps));
38
- $b = max(0,min(255,$b + $steps));
39
-
40
- $r_hex = str_pad(dechex($r), 2, '0', STR_PAD_LEFT);
41
- $g_hex = str_pad(dechex($g), 2, '0', STR_PAD_LEFT);
42
- $b_hex = str_pad(dechex($b), 2, '0', STR_PAD_LEFT);
43
-
44
- return $r_hex . $g_hex . $b_hex;
45
- }
 
 
 
 
 
 
 
 
 
 
46
  }
1
  <?php
2
 
3
  /**
4
+ * Helper class for working with color values.
5
  *
6
+ * @since 1.0
7
  */
 
8
  final class FLBuilderColor {
9
 
10
+ /**
11
+ * Converts a hex string into an array of RGB values.
12
+ *
13
+ * @since 1.0
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
31
+ * @param string $hex A hex color value without the # sign.
32
+ * @param int $steps The number of steps to adjust the color.
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
+ extract(self::hex_to_rgb($hex));
40
+
41
+ // Should we darken the color?
42
+ if($type == 'reverse' && $r + $g + $b > 382){
43
+ $steps = -$steps;
44
+ }
45
+ else if($type == 'darken') {
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-icons.php CHANGED
@@ -3,351 +3,396 @@
3
  /**
4
  * Helper class for working with icons.
5
  *
6
- * @class FLBuilderIcons
7
  */
8
 
9
  final class FLBuilderIcons {
10
-
11
- /**
12
- * @property $sets
13
- * @private
14
- */
15
- static private $sets = null;
16
-
17
- /**
18
- * @method get_sets
19
- */
20
- static public function get_sets()
21
- {
22
- // Return the sets if already registered.
23
- if ( self::$sets ) {
24
- return self::$sets;
25
- }
26
-
27
- // Check to see if we should pull sets from the main site.
28
- if ( is_multisite()) {
29
-
30
- $blog_id = defined( 'BLOG_ID_CURRENT_SITE' ) ? BLOG_ID_CURRENT_SITE : 1;
31
- $enabled_icons = get_option( '_fl_builder_enabled_icons' );
32
-
 
 
 
 
 
 
33
  if ( empty( $enabled_icons ) ) {
34
  switch_to_blog( $blog_id );
35
  }
36
- }
37
-
38
- // Register the icon sets.
39
- self::register_custom_sets();
40
- self::register_core_sets();
41
-
42
- // Revert to the current site if we pulled from the main site.
43
- if ( is_multisite() && empty( $enabled_icons ) ) {
44
- restore_current_blog();
45
- }
46
-
47
- // Return the sets.
48
- return self::$sets;
49
- }
50
-
51
- /**
52
- * @method get_sets
53
- */
54
- static public function get_sets_for_current_site()
55
- {
56
- if ( ! is_multisite() ) {
57
- return self::get_sets();
58
- }
59
-
60
- // Store the original sets.
61
- $original_sets = self::$sets;
62
-
63
- // Register the icon sets.
64
- self::register_custom_sets();
65
- self::register_core_sets();
66
-
67
- // Get the new sets.
68
- $sets = self::$sets;
69
-
70
- // Revert to the original sets.
71
- self::$sets = $original_sets;
72
-
73
- // Return the sets.
74
- return $sets;
75
- }
76
-
77
- /**
78
- * @method remove_set
79
- */
80
- static public function remove_set( $key )
81
- {
82
- if ( self::$sets && isset( self::$sets[ $key ] ) ) {
83
- unset( self::$sets[ $key ] );
84
- }
85
- }
86
-
87
- /**
88
- * @method get_key_from_path
89
- */
90
- static public function get_key_from_path( $path )
91
- {
92
- $sets = self::get_sets();
93
-
94
- foreach ( $sets as $key => $set ) {
95
- if ( $path == $set['path'] ) {
96
- return $key;
97
- }
98
- }
99
- }
 
 
 
 
 
 
 
 
 
 
 
 
100
 
101
- /**
102
- * @method register_core_sets
103
- * @private
104
- */
105
- static private function register_core_sets()
106
- {
107
- $enabled_icons = FLBuilderModel::get_enabled_icons();
108
- $core_sets = array(
109
- 'font-awesome' => array(
110
- 'name' => 'Font Awesome',
111
- 'prefix' => 'fa'
112
- ),
113
- 'foundation-icons' => array(
114
- 'name' => 'Foundation Icons',
115
- 'prefix' => ''
116
- ),
117
- 'dashicons' => array(
118
- 'name' => 'WordPress Dashicons',
119
- 'prefix' => 'dashicons dashicons-before'
120
- )
121
- );
122
-
123
- // Add the core sets.
124
- foreach ( $core_sets as $set_key => $set_data ) {
125
- if ( is_admin() || in_array( $set_key, $enabled_icons ) ) {
126
- self::$sets[ $set_key ] = array(
127
- 'name' => $set_data['name'],
128
- 'prefix' => $set_data['prefix'],
129
- 'type' => 'core'
130
- );
131
- }
132
- }
133
-
134
- // Loop through core sets and add icons.
135
- foreach ( self::$sets as $set_key => $set_data ) {
136
- if ( 'core' == $set_data['type'] ) {
137
- $icons = json_decode( file_get_contents( FL_BUILDER_DIR . 'json/' . $set_key . '.json' ) );
 
 
 
138
  self::$sets[ $set_key ]['icons'] = $icons;
139
  }
140
- }
141
  }
142
 
143
- /**
144
- * @method register_custom_sets
145
- * @private
146
- */
147
- static private function register_custom_sets()
148
- {
149
- // Get uploaded sets.
150
- $enabled_icons = FLBuilderModel::get_enabled_icons();
151
- $upload_info = FLBuilderModel::get_cache_dir( 'icons' );
152
- $folders = glob( $upload_info['path'] . '*' );
153
-
154
- // Make sure we have an array.
155
- if( ! is_array( $folders ) ) {
156
- return;
157
- }
158
-
159
- // Loop through uploaded sets.
160
- foreach ( $folders as $folder ) {
161
-
162
- $folder = trailingslashit( $folder );
163
-
164
- // This is an Icomoon font.
165
- if ( file_exists( $folder . 'selection.json' ) ) {
166
-
167
- $data = json_decode( file_get_contents( $folder . 'selection.json' ) );
168
- $key = basename( $folder );
169
- $url = str_ireplace( $upload_info['path'], $upload_info['url'], $folder );
170
-
171
- if ( isset( $data->icons ) ) {
172
-
173
- if ( is_admin() || in_array( $key, $enabled_icons ) ) {
174
-
175
- self::$sets[ $key ] = array(
176
- 'name' => $data->metadata->name,
177
- 'prefix' => '',
178
- 'type' => 'icomoon',
179
- 'path' => $folder,
180
- 'url' => $url,
 
 
 
181
  'stylesheet' => $url . 'style.css',
182
- 'icons' => array()
183
- );
184
-
185
- foreach ( $data->icons as $icon ) {
186
-
187
- $prefs = $data->preferences->fontPref;
188
- $postfix = isset( $prefs->postfix ) ? $prefs->postfix : '';
189
-
190
- if ( isset( $prefs->selector ) && 'class' == $prefs->selector ) {
191
- $selector = trim( str_replace( '.', ' ', $prefs->classSelector ) ) . ' ';
192
- }
193
- else {
194
- $selector = '';
195
- }
196
-
197
- self::$sets[ $key ]['icons'][] = $selector . $prefs->prefix . $icon->properties->name . $postfix;
198
- }
199
- }
200
- }
201
- }
202
- // This is a Fontello font.
203
- else if ( file_exists( $folder . 'config.json' ) ) {
204
-
205
- $data = json_decode( file_get_contents( $folder . 'config.json' ) );
206
- $key = basename( $folder );
207
- $name = empty( $data->name ) ? 'Fontello' : $data->name;
208
- $url = str_ireplace( $upload_info['path'], $upload_info['url'], $folder );
209
- $style = empty( $data->name ) ? 'fontello' : $data->name;
210
-
211
- // Append the date to the name?
212
- if ( empty( $data->name ) ) {
213
- $time = str_replace( 'icon-', '', $key );
214
- $date_format = get_option( 'date_format' );
215
- $time_format = get_option( 'time_format' );
216
- $date = date( $date_format . ' ' . $time_format );
217
- $name .= ' (' . $date . ')';
218
- }
219
-
220
- if ( isset( $data->glyphs ) ) {
221
-
222
- if ( is_admin() || in_array( $key, $enabled_icons ) ) {
223
-
224
- self::$sets[ $key ] = array(
225
- 'name' => $name,
226
- 'prefix' => '',
227
- 'type' => 'fontello',
228
- 'path' => $folder,
229
- 'url' => $url,
230
  'stylesheet' => $url . 'css/' . $style . '.css',
231
- 'icons' => array()
232
- );
233
-
234
- foreach ( $data->glyphs as $icon ) {
235
- if ( $data->css_use_suffix ) {
236
- self::$sets[ $key ]['icons'][] = $icon->css . $data->css_prefix_text;
237
- }
238
- else {
239
- self::$sets[ $key ]['icons'][] = $data->css_prefix_text . $icon->css;
240
- }
241
- }
242
- }
243
- }
244
- }
245
- }
246
  }
247
 
248
- /**
249
- * @method enqueue_all_custom_icons_styles
250
- */
251
- static public function enqueue_all_custom_icons_styles()
252
- {
253
- $sets = self::get_sets();
254
-
255
- foreach ( $sets as $key => $data ) {
256
-
257
- // Don't enqueue core icons.
258
- if ( 'core' == $data['type'] ) {
259
- continue;
260
- }
261
-
262
- // Enqueue the custom icon styles.
263
- self::enqueue_custom_styles_by_key( $key );
264
- }
265
- }
 
 
 
266
 
267
- /**
268
- * @method enqueue_styles_for_module
269
- */
270
- static public function enqueue_styles_for_module( $module )
271
- {
272
- $fields = FLBuilderModel::get_settings_form_fields( $module->form );
273
-
274
- foreach ( $fields as $name => $field ) {
275
- if ( isset( $field['multiple'] ) && true === $field['multiple'] ) {
276
- $form = FLBuilderModel::$settings_forms[ $field['form'] ];
277
- self::enqueue_styles_for_module_multiple( $module, $form['tabs'], $name );
278
- }
279
- else if ( $field['type'] == 'icon' && isset( $module->settings->$name ) ) {
280
- self::enqueue_styles_for_icon( $module->settings->$name );
281
- }
282
- }
283
- }
 
 
 
 
284
 
285
- /**
286
- * @method enqueue_styles_for_module_multiple
287
- * @private
288
- */
289
- static private function enqueue_styles_for_module_multiple( $module, $form, $setting )
290
- {
291
- $fields = FLBuilderModel::get_settings_form_fields( $form );
292
-
293
- foreach ( $fields as $name => $field ) {
294
- if ( $field['type'] == 'icon' ) {
295
- foreach ( $module->settings->$setting as $key => $val ) {
296
- if ( isset( $val->$name ) ) {
297
- self::enqueue_styles_for_icon( $val->$name );
298
- }
299
- }
300
- }
301
- }
302
- }
 
 
 
 
 
 
303
 
304
- /**
305
- * @method enqueue_styles_for_icon
306
- * @private
307
- */
308
- static private function enqueue_styles_for_icon( $icon )
309
- {
310
- // Is this a core icon?
311
- if ( stristr( $icon, 'fa-' ) ) {
312
- wp_enqueue_style( 'font-awesome' );
313
- }
314
- else if ( stristr( $icon, 'fi-' ) ) {
315
- wp_enqueue_style( 'foundation-icons' );
316
- }
317
- else if ( stristr( $icon, 'dashicon' ) ) {
318
- wp_enqueue_style( 'dashicons' );
319
- }
320
- // It must be a custom icon.
321
- else {
322
-
323
- $sets = self::get_sets();
324
-
325
- foreach ( $sets as $key => $data ) {
326
- if ( in_array( $icon, $data['icons'] ) ) {
327
- self::enqueue_custom_styles_by_key( $key );
328
- }
329
- }
330
- }
331
- }
 
 
 
 
332
 
333
- /**
334
- * @method enqueue_custom_styles_by_key
335
- * @private
336
- */
337
- static private function enqueue_custom_styles_by_key( $key )
338
- {
339
- $sets = self::get_sets();
340
-
341
- if ( isset( $sets[ $key ] ) ) {
342
-
343
- $set = $sets[ $key ];
344
-
345
- if ( 'icomoon' == $set['type'] ) {
346
- wp_enqueue_style( $key, $set['stylesheet'], array(), FL_BUILDER_VERSION );
347
- }
348
- if ( 'fontello' == $set['type'] ) {
349
- wp_enqueue_style( $key, $set['stylesheet'], array(), FL_BUILDER_VERSION );
350
- }
351
- }
352
- }
 
 
 
 
353
  }
3
  /**
4
  * Helper class for working with icons.
5
  *
6
+ * @since 1.4.6
7
  */
8
 
9
  final class FLBuilderIcons {
10
+
11
+ /**
12
+ * An array of data for each icon set.
13
+ *
14
+ * @since 1.4.6
15
+ * @access private
16
+ * @var array $sets
17
+ */
18
+ static private $sets = null;
19
+
20
+ /**
21
+ * Gets an array of data for core and custom icon sets.
22
+ *
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' );
38
+
39
  if ( empty( $enabled_icons ) ) {
40
  switch_to_blog( $blog_id );
41
  }
42
+ }
43
+
44
+ // Register the icon sets.
45
+ self::register_custom_sets();
46
+ self::register_core_sets();
47
+
48
+ // Revert to the current site if we pulled from the main site.
49
+ if ( is_multisite() && empty( $enabled_icons ) ) {
50
+ restore_current_blog();
51
+ }
52
+
53
+ // Return the sets.
54
+ return self::$sets;
55
+ }
56
+
57
+ /**
58
+ * Gets an array of data for icon sets of the current
59
+ * site on a multisite install.
60
+ *
61
+ * @since 1.4.6
62
+ * @return array An array of data for each icon set.
63
+ */
64
+ static public function get_sets_for_current_site()
65
+ {
66
+ if ( ! is_multisite() ) {
67
+ return self::get_sets();
68
+ }
69
+
70
+ // Store the original sets.
71
+ $original_sets = self::$sets;
72
+
73
+ // Register the icon sets.
74
+ self::register_custom_sets();
75
+ self::register_core_sets();
76
+
77
+ // Get the new sets.
78
+ $sets = self::$sets;
79
+
80
+ // Revert to the original sets.
81
+ self::$sets = $original_sets;
82
+
83
+ // Return the sets.
84
+ return $sets;
85
+ }
86
+
87
+ /**
88
+ * Remove an icon set from the internal sets array.
89
+ *
90
+ * @since 1.4.6
91
+ * @param string $key The key for the set to remove.
92
+ * @return void
93
+ */
94
+ static public function remove_set( $key )
95
+ {
96
+ if ( self::$sets && isset( self::$sets[ $key ] ) ) {
97
+ unset( self::$sets[ $key ] );
98
+ }
99
+ }
100
+
101
+ /**
102
+ * Get the key for an icon set from the path to an icon set stylesheet.
103
+ *
104
+ * @since 1.4.6
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
+ {
110
+ $sets = self::get_sets();
111
+
112
+ foreach ( $sets as $key => $set ) {
113
+ if ( $path == $set['path'] ) {
114
+ return $key;
115
+ }
116
+ }
117
+ }
118
 
119
+ /**
120
+ * Register core icon set data in the internal sets array.
121
+ *
122
+ * @since 1.4.6
123
+ * @access private
124
+ * @return void
125
+ */
126
+ static private function register_core_sets()
127
+ {
128
+ $enabled_icons = FLBuilderModel::get_enabled_icons();
129
+ $core_sets = array(
130
+ 'font-awesome' => array(
131
+ 'name' => 'Font Awesome',
132
+ 'prefix' => 'fa'
133
+ ),
134
+ 'foundation-icons' => array(
135
+ 'name' => 'Foundation Icons',
136
+ 'prefix' => ''
137
+ ),
138
+ 'dashicons' => array(
139
+ 'name' => 'WordPress Dashicons',
140
+ 'prefix' => 'dashicons dashicons-before'
141
+ )
142
+ );
143
+
144
+ // Add the core sets.
145
+ foreach ( $core_sets as $set_key => $set_data ) {
146
+ if ( is_admin() || in_array( $set_key, $enabled_icons ) ) {
147
+ self::$sets[ $set_key ] = array(
148
+ 'name' => $set_data['name'],
149
+ 'prefix' => $set_data['prefix'],
150
+ 'type' => 'core'
151
+ );
152
+ }
153
+ }
154
+
155
+ // Loop through core sets and add icons.
156
+ foreach ( self::$sets as $set_key => $set_data ) {
157
+ if ( 'core' == $set_data['type'] ) {
158
+ $icons = json_decode( file_get_contents( FL_BUILDER_DIR . 'json/' . $set_key . '.json' ) );
159
  self::$sets[ $set_key ]['icons'] = $icons;
160
  }
161
+ }
162
  }
163
 
164
+ /**
165
+ * Register custom icon set data in the internal sets array.
166
+ *
167
+ * @since 1.4.6
168
+ * @access private
169
+ * @return void
170
+ */
171
+ static private function register_custom_sets()
172
+ {
173
+ // Get uploaded sets.
174
+ $enabled_icons = FLBuilderModel::get_enabled_icons();
175
+ $upload_info = FLBuilderModel::get_cache_dir( 'icons' );
176
+ $folders = glob( $upload_info['path'] . '*' );
177
+
178
+ // Make sure we have an array.
179
+ if( ! is_array( $folders ) ) {
180
+ return;
181
+ }
182
+
183
+ // Loop through uploaded sets.
184
+ foreach ( $folders as $folder ) {
185
+
186
+ $folder = trailingslashit( $folder );
187
+
188
+ // This is an Icomoon font.
189
+ if ( file_exists( $folder . 'selection.json' ) ) {
190
+
191
+ $data = json_decode( file_get_contents( $folder . 'selection.json' ) );
192
+ $key = basename( $folder );
193
+ $url = str_ireplace( $upload_info['path'], $upload_info['url'], $folder );
194
+
195
+ if ( isset( $data->icons ) ) {
196
+
197
+ if ( is_admin() || in_array( $key, $enabled_icons ) ) {
198
+
199
+ self::$sets[ $key ] = array(
200
+ 'name' => $data->metadata->name,
201
+ 'prefix' => '',
202
+ 'type' => 'icomoon',
203
+ 'path' => $folder,
204
+ 'url' => $url,
205
  'stylesheet' => $url . 'style.css',
206
+ 'icons' => array()
207
+ );
208
+
209
+ foreach ( $data->icons as $icon ) {
210
+
211
+ $prefs = $data->preferences->fontPref;
212
+ $postfix = isset( $prefs->postfix ) ? $prefs->postfix : '';
213
+
214
+ if ( isset( $prefs->selector ) && 'class' == $prefs->selector ) {
215
+ $selector = trim( str_replace( '.', ' ', $prefs->classSelector ) ) . ' ';
216
+ }
217
+ else {
218
+ $selector = '';
219
+ }
220
+
221
+ self::$sets[ $key ]['icons'][] = $selector . $prefs->prefix . $icon->properties->name . $postfix;
222
+ }
223
+ }
224
+ }
225
+ }
226
+ // This is a Fontello font.
227
+ else if ( file_exists( $folder . 'config.json' ) ) {
228
+
229
+ $data = json_decode( file_get_contents( $folder . 'config.json' ) );
230
+ $key = basename( $folder );
231
+ $name = empty( $data->name ) ? 'Fontello' : $data->name;
232
+ $url = str_ireplace( $upload_info['path'], $upload_info['url'], $folder );
233
+ $style = empty( $data->name ) ? 'fontello' : $data->name;
234
+
235
+ // Append the date to the name?
236
+ if ( empty( $data->name ) ) {
237
+ $time = str_replace( 'icon-', '', $key );
238
+ $date_format = get_option( 'date_format' );
239
+ $time_format = get_option( 'time_format' );
240
+ $date = date( $date_format . ' ' . $time_format );
241
+ $name .= ' (' . $date . ')';
242
+ }
243
+
244
+ if ( isset( $data->glyphs ) ) {
245
+
246
+ if ( is_admin() || in_array( $key, $enabled_icons ) ) {
247
+
248
+ self::$sets[ $key ] = array(
249
+ 'name' => $name,
250
+ 'prefix' => '',
251
+ 'type' => 'fontello',
252
+ 'path' => $folder,
253
+ 'url' => $url,
254
  'stylesheet' => $url . 'css/' . $style . '.css',
255
+ 'icons' => array()
256
+ );
257
+
258
+ foreach ( $data->glyphs as $icon ) {
259
+ if ( $data->css_use_suffix ) {
260
+ self::$sets[ $key ]['icons'][] = $icon->css . $data->css_prefix_text;
261
+ }
262
+ else {
263
+ self::$sets[ $key ]['icons'][] = $data->css_prefix_text . $icon->css;
264
+ }
265
+ }
266
+ }
267
+ }
268
+ }
269
+ }
270
  }
271
 
272
+ /**
273
+ * Enqueue the stylesheets for all icon sets.
274
+ *
275
+ * @since 1.4.6
276
+ * @return void
277
+ */
278
+ static public function enqueue_all_custom_icons_styles()
279
+ {
280
+ $sets = self::get_sets();
281
+
282
+ foreach ( $sets as $key => $data ) {
283
+
284
+ // Don't enqueue core icons.
285
+ if ( 'core' == $data['type'] ) {
286
+ continue;
287
+ }
288
+
289
+ // Enqueue the custom icon styles.
290
+ self::enqueue_custom_styles_by_key( $key );
291
+ }
292
+ }
293
 
294
+ /**
295
+ * Enqueue the stylesheet(s) for icons in a module.
296
+ *
297
+ * @since 1.4.6
298
+ * @param object $module The module to enqueue for.
299
+ * @return void
300
+ */
301
+ static public function enqueue_styles_for_module( $module )
302
+ {
303
+ $fields = FLBuilderModel::get_settings_form_fields( $module->form );
304
+
305
+ foreach ( $fields as $name => $field ) {
306
+ if ( isset( $field['multiple'] ) && true === $field['multiple'] ) {
307
+ $form = FLBuilderModel::$settings_forms[ $field['form'] ];
308
+ self::enqueue_styles_for_module_multiple( $module, $form['tabs'], $name );
309
+ }
310
+ else if ( $field['type'] == 'icon' && isset( $module->settings->$name ) ) {
311
+ self::enqueue_styles_for_icon( $module->settings->$name );
312
+ }
313
+ }
314
+ }
315
 
316
+ /**
317
+ * Enqueue the stylesheet(s) for icons in a multiple field.
318
+ *
319
+ * @since 1.4.6
320
+ * @access private
321
+ * @param object $module The module to enqueue for.
322
+ * @param array $form The multiple field form.
323
+ * @param string $setting The multiple field setting key.
324
+ * @return void
325
+ */
326
+ static private function enqueue_styles_for_module_multiple( $module, $form, $setting )
327
+ {
328
+ $fields = FLBuilderModel::get_settings_form_fields( $form );
329
+
330
+ foreach ( $fields as $name => $field ) {
331
+ if ( $field['type'] == 'icon' ) {
332
+ foreach ( $module->settings->$setting as $key => $val ) {
333
+ if ( isset( $val->$name ) ) {
334
+ self::enqueue_styles_for_icon( $val->$name );
335
+ }
336
+ }
337
+ }
338
+ }
339
+ }
340
 
341
+ /**
342
+ * Enqueue the stylesheet for an icon.
343
+ *
344
+ * @since 1.4.6
345
+ * @access private
346
+ * @param string $icon The icon CSS classname.
347
+ * @return void
348
+ */
349
+ static private function enqueue_styles_for_icon( $icon )
350
+ {
351
+ // Is this a core icon?
352
+ if ( stristr( $icon, 'fa-' ) ) {
353
+ wp_enqueue_style( 'font-awesome' );
354
+ }
355
+ else if ( stristr( $icon, 'fi-' ) ) {
356
+ wp_enqueue_style( 'foundation-icons' );
357
+ }
358
+ else if ( stristr( $icon, 'dashicon' ) ) {
359
+ wp_enqueue_style( 'dashicons' );
360
+ }
361
+ // It must be a custom icon.
362
+ else {
363
+
364
+ $sets = self::get_sets();
365
+
366
+ foreach ( $sets as $key => $data ) {
367
+ if ( in_array( $icon, $data['icons'] ) ) {
368
+ self::enqueue_custom_styles_by_key( $key );
369
+ }
370
+ }
371
+ }
372
+ }
373
 
374
+ /**
375
+ * Enqueue the stylesheet for an icon set by key.
376
+ *
377
+ * @since 1.4.6
378
+ * @access private
379
+ * @param string $key The icon set key.
380
+ * @return void
381
+ */
382
+ static private function enqueue_custom_styles_by_key( $key )
383
+ {
384
+ $sets = self::get_sets();
385
+
386
+ if ( isset( $sets[ $key ] ) ) {
387
+
388
+ $set = $sets[ $key ];
389
+
390
+ if ( 'icomoon' == $set['type'] ) {
391
+ wp_enqueue_style( $key, $set['stylesheet'], array(), FL_BUILDER_VERSION );
392
+ }
393
+ if ( 'fontello' == $set['type'] ) {
394
+ wp_enqueue_style( $key, $set['stylesheet'], array(), FL_BUILDER_VERSION );
395
+ }
396
+ }
397
+ }
398
  }
classes/class-fl-builder-loop.php CHANGED
@@ -1,176 +1,198 @@
1
  <?php
2
 
3
  /**
4
- * Helper class for building custom loops.
5
  *
6
- * @class FLBuilderLoop
7
  */
8
-
9
  final class FLBuilderLoop {
10
 
11
  /**
12
- * @method query
13
- */
14
- static public function query($settings)
15
- {
16
- $posts_per_page = empty($settings->posts_per_page) ? 10 : $settings->posts_per_page;
17
- $post_type = empty($settings->post_type) ? 'post' : $settings->post_type;
18
- $order_by = empty($settings->order_by) ? 'date' : $settings->order_by;
19
- $order = empty($settings->order) ? 'DESC' : $settings->order;
20
- $users = empty($settings->users) ? '' : $settings->users;
21
- $paged = is_front_page() ? get_query_var('page') : get_query_var('paged');
22
-
23
- // Get the offset.
24
- if ( ! isset( $settings->offset ) || ! is_int( ( int )$settings->offset ) ) {
25
- $offset = 0;
26
- }
27
- else {
28
- $offset = $settings->offset;
29
- }
30
-
31
- // Get the paged offset.
32
- if ( $paged < 2 ) {
33
- $paged_offset = $offset;
34
- }
35
- else {
36
- $paged_offset = $offset + ( ( $paged - 1 ) * $posts_per_page );
37
- }
38
-
39
- // Build the query args.
40
- $args = array(
41
- 'paged' => $paged,
42
- 'posts_per_page' => $posts_per_page,
43
- 'post_type' => $post_type,
44
- 'orderby' => $order_by,
45
- 'order' => $order,
46
- 'author' => $users,
47
- 'tax_query' => array('relation' => 'AND'),
48
- 'ignore_sticky_posts' => true,
49
- 'offset' => $paged_offset,
50
- 'fl_original_offset' => $offset,
51
- 'fl_builder_loop' => true
52
- );
53
-
54
- // Build the taxonomy query.
55
- $taxonomies = self::taxonomies($post_type);
56
-
57
- foreach($taxonomies as $tax_slug => $tax) {
58
-
59
- $tax_value = '';
60
-
61
- // New settings slug.
62
- if(isset($settings->{'tax_' . $post_type . '_' . $tax_slug})) {
63
- $tax_value = $settings->{'tax_' . $post_type . '_' . $tax_slug};
64
- }
65
- // Legacy settings slug.
66
- else if(isset($settings->{'tax_' . $tax_slug})) {
67
- $tax_value = $settings->{'tax_' . $tax_slug};
68
- }
69
-
70
- if(!empty($tax_value)) {
71
-
72
- $args['tax_query'][] = array(
73
- 'taxonomy' => $tax_slug,
74
- 'field' => 'id',
75
- 'terms' => explode(',', $tax_value)
76
- );
77
- }
78
- }
79
-
80
- // Post in query.
81
- if(isset($settings->{'posts_' . $post_type})) {
82
-
83
- $ids = $settings->{'posts_' . $post_type};
84
-
85
- if(!empty($ids)) {
86
- $args['post__in'] = explode(',', $settings->{'posts_' . $post_type});
87
- }
88
- }
89
-
90
- // Build the query.
91
- $query = new WP_Query($args);
92
-
93
- // Return the query.
94
- return $query;
95
- }
 
 
 
 
 
96
 
97
  /**
98
- * @method found_posts
99
- */
100
- static public function found_posts( $found_posts, $query )
101
- {
102
- if ( isset( $query->query ) && isset( $query->query['fl_builder_loop'] ) ) {
103
- return $found_posts - $query->query['fl_original_offset'];
104
- }
105
-
106
- return $found_posts;
 
 
 
 
 
 
107
  }
108
-
109
  /**
110
- * @method pagination
111
- */
112
- static public function pagination($query)
113
- {
114
- $total_pages = $query->max_num_pages;
115
- $permalink_structure = get_option('permalink_structure');
116
- $paged = is_front_page() ? get_query_var('page') : get_query_var('paged');
117
-
118
- if($total_pages > 1) {
119
-
120
- if(!$current_page = $paged) {
121
- $current_page = 1;
122
- }
123
-
124
- if(empty($permalink_structure)) {
125
- $format = '&paged=%#%';
126
- }
127
- else {
128
- $format = 'page/%#%/';
129
- }
130
-
131
- echo paginate_links(array(
132
- 'base' => get_pagenum_link(1) . '%_%',
133
- 'format' => $format,
134
- 'current' => $current_page,
135
- 'total' => $total_pages,
136
- 'type' => 'list'
137
- ));
138
- }
139
- }
 
 
 
 
140
 
141
  /**
142
- * @method post_types
143
- */
144
- static public function post_types()
145
- {
146
- $post_types = get_post_types(array(
147
- 'public' => true,
148
- 'show_ui' => true
149
- ), 'objects');
150
-
151
- unset($post_types['attachment']);
152
- unset($post_types['fl-builder-template']);
153
-
154
- return $post_types;
155
- }
156
-
 
 
 
 
157
  /**
158
- * @method taxonomies
159
- */
160
- static public function taxonomies($post_type)
161
- {
162
- $taxonomies = get_object_taxonomies($post_type, 'objects');
163
- $data = array();
164
-
165
- foreach($taxonomies as $tax_slug => $tax) {
166
-
167
- if(!$tax->public || !$tax->show_ui) {
168
- continue;
169
- }
170
-
171
- $data[$tax_slug] = $tax;
172
- }
173
-
174
- return $data;
175
- }
 
 
 
 
176
  }
1
  <?php
2
 
3
  /**
4
+ * Helper class for building custom WordPress loops.
5
  *
6
+ * @since 1.2.3
7
  */
 
8
  final class FLBuilderLoop {
9
 
10
  /**
11
+ * Returns a new instance of WP_Query based on
12
+ * the provided module settings.
13
+ *
14
+ * @since 1.2.3
15
+ * @param object $settings Module settings to use for the query.
16
+ * @return object A WP_Query instance.
17
+ */
18
+ static public function query($settings)
19
+ {
20
+ $posts_per_page = empty($settings->posts_per_page) ? 10 : $settings->posts_per_page;
21
+ $post_type = empty($settings->post_type) ? 'post' : $settings->post_type;
22
+ $order_by = empty($settings->order_by) ? 'date' : $settings->order_by;
23
+ $order = empty($settings->order) ? 'DESC' : $settings->order;
24
+ $users = empty($settings->users) ? '' : $settings->users;
25
+ $paged = is_front_page() ? get_query_var('page') : get_query_var('paged');
26
+
27
+ // Get the offset.
28
+ if ( ! isset( $settings->offset ) || ! is_int( ( int )$settings->offset ) ) {
29
+ $offset = 0;
30
+ }
31
+ else {
32
+ $offset = $settings->offset;
33
+ }
34
+
35
+ // Get the paged offset.
36
+ if ( $paged < 2 ) {
37
+ $paged_offset = $offset;
38
+ }
39
+ else {
40
+ $paged_offset = $offset + ( ( $paged - 1 ) * $posts_per_page );
41
+ }
42
+
43
+ // Build the query args.
44
+ $args = array(
45
+ 'paged' => $paged,
46
+ 'posts_per_page' => $posts_per_page,
47
+ 'post_type' => $post_type,
48
+ 'orderby' => $order_by,
49
+ 'order' => $order,
50
+ 'author' => $users,
51
+ 'tax_query' => array('relation' => 'AND'),
52
+ 'ignore_sticky_posts' => true,
53
+ 'offset' => $paged_offset,
54
+ 'fl_original_offset' => $offset,
55
+ 'fl_builder_loop' => true
56
+ );
57
+
58
+ // Build the taxonomy query.
59
+ $taxonomies = self::taxonomies($post_type);
60
+
61
+ foreach($taxonomies as $tax_slug => $tax) {
62
+
63
+ $tax_value = '';
64
+
65
+ // New settings slug.
66
+ if(isset($settings->{'tax_' . $post_type . '_' . $tax_slug})) {
67
+ $tax_value = $settings->{'tax_' . $post_type . '_' . $tax_slug};
68
+ }
69
+ // Legacy settings slug.
70
+ else if(isset($settings->{'tax_' . $tax_slug})) {
71
+ $tax_value = $settings->{'tax_' . $tax_slug};
72
+ }
73
+
74
+ if(!empty($tax_value)) {
75
+
76
+ $args['tax_query'][] = array(
77
+ 'taxonomy' => $tax_slug,
78
+ 'field' => 'id',
79
+ 'terms' => explode(',', $tax_value)
80
+ );
81
+ }
82
+ }
83
+
84
+ // Post in query.
85
+ if(isset($settings->{'posts_' . $post_type})) {
86
+
87
+ $ids = $settings->{'posts_' . $post_type};
88
+
89
+ if(!empty($ids)) {
90
+ $args['post__in'] = explode(',', $settings->{'posts_' . $post_type});
91
+ }
92
+ }
93
+
94
+ // Build the query.
95
+ $query = new WP_Query($args);
96
+
97
+ // Return the query.
98
+ return $query;
99
+ }
100
 
101
  /**
102
+ * Called by the found_posts filter to adjust the number of posts
103
+ * found based on the user defined offset.
104
+ *
105
+ * @since 1.2.3
106
+ * @param int $found_posts The number of found posts.
107
+ * @param object $query An instance of WP_Query.
108
+ * @return int
109
+ */
110
+ static public function found_posts( $found_posts, $query )
111
+ {
112
+ if ( isset( $query->query ) && isset( $query->query['fl_builder_loop'] ) ) {
113
+ return $found_posts - $query->query['fl_original_offset'];
114
+ }
115
+
116
+ return $found_posts;
117
  }
118
+
119
  /**
120
+ * Builds and renders the pagination for a query.
121
+ *
122
+ * @since 1.2.3
123
+ * @param object $query An instance of WP_Query.
124
+ * @return void
125
+ */
126
+ static public function pagination($query)
127
+ {
128
+ $total_pages = $query->max_num_pages;
129
+ $permalink_structure = get_option('permalink_structure');
130
+ $paged = is_front_page() ? get_query_var('page') : get_query_var('paged');
131
+
132
+ if($total_pages > 1) {
133
+
134
+ if(!$current_page = $paged) {
135
+ $current_page = 1;
136
+ }
137
+
138
+ if(empty($permalink_structure)) {
139
+ $format = '&paged=%#%';
140
+ }
141
+ else {
142
+ $format = 'page/%#%/';
143
+ }
144
+
145
+ echo paginate_links(array(
146
+ 'base' => get_pagenum_link(1) . '%_%',
147
+ 'format' => $format,
148
+ 'current' => $current_page,
149
+ 'total' => $total_pages,
150
+ 'type' => 'list'
151
+ ));
152
+ }
153
+ }
154
 
155
  /**
156
+ * Returns an array of data for post types supported
157
+ * by module loop settings.
158
+ *
159
+ * @since 1.2.3
160
+ * @return array
161
+ */
162
+ static public function post_types()
163
+ {
164
+ $post_types = get_post_types(array(
165
+ 'public' => true,
166
+ 'show_ui' => true
167
+ ), 'objects');
168
+
169
+ unset($post_types['attachment']);
170
+ unset($post_types['fl-builder-template']);
171
+
172
+ return $post_types;
173
+ }
174
+
175
  /**
176
+ * Get an array of supported taxonomy data for a post type.
177
+ *
178
+ * @since 1.2.3
179
+ * @param string $post_type The post type to get taxonomies for.
180
+ * @return array
181
+ */
182
+ static public function taxonomies($post_type)
183
+ {
184
+ $taxonomies = get_object_taxonomies($post_type, 'objects');
185
+ $data = array();
186
+
187
+ foreach($taxonomies as $tax_slug => $tax) {
188
+
189
+ if(!$tax->public || !$tax->show_ui) {
190
+ continue;
191
+ }
192
+
193
+ $data[$tax_slug] = $tax;
194
+ }
195
+
196
+ return $data;
197
+ }
198
  }
classes/class-fl-builder-model.php CHANGED
@@ -4,383 +4,434 @@
4
  * Builder data handling class that deals
5
  * with all database operations.
6
  *
7
- * @class FLBuilderModel
8
  */
9
  final class FLBuilderModel {
10
 
11
- /**
12
- * @property $row_layouts
13
- * @type array
14
- */
15
- static public $row_layouts = array(
16
- '1-col' => array(100),
17
- '2-cols' => array(50, 50),
18
- '3-cols' => array(33.33, 33.33, 33.33),
19
- '4-cols' => array(25, 25, 25, 25),
20
- '5-cols' => array(20, 20, 20, 20, 20),
21
- '6-cols' => array(16.65, 16.65, 16.65, 16.65, 16.65, 16.65),
22
- 'left-sidebar' => array(33.33, 66.66),
23
- 'right-sidebar' => array(66.66, 33.33),
24
- 'left-right-sidebar' => array(25, 50, 25)
25
- );
26
-
27
- /**
28
- * @property $settings_forms
29
- * @type array
30
- */
31
- static public $settings_forms = array();
32
-
33
- /**
34
- * @property $settings_form_defaults
35
- * @type array
36
- */
37
- static public $settings_form_defaults = array();
38
-
39
- /**
40
- * @property $modules
41
- * @type array
42
- */
43
- static public $modules = array();
44
-
45
- /**
46
- * The last node id that was generated by the builder.
47
- * This is saved to ensure the next node id is unique.
48
- *
49
- * @property $last_generated_node_id
50
- * @type string
51
- * @private
52
- */
53
- static private $last_generated_node_id = null;
54
-
55
- /**
56
- * Cached post data from either the $_POST array
57
- * or from the json decoded fl_builder_data post variable.
58
- *
59
- * @property $post_data
60
- * @type array
61
- * @private
62
- */
63
- static private $post_data = null;
64
-
65
- /**
66
- * An array of cached published layout data by post_id.
67
- *
68
- * @property $published_layout_data
69
- * @type array
70
- * @private
71
- */
72
- static private $published_layout_data = array();
73
-
74
- /**
75
- * An array of cached draft layout data by post_id.
76
- *
77
- * @property $draft_layout_data
78
- * @type array
79
- * @private
80
- */
81
- static private $draft_layout_data = array();
 
 
 
 
 
 
 
 
 
82
 
83
  /**
84
  * All database updates should be made through
85
  * this method for security.
86
  *
87
- * @method update
88
- */
 
 
 
89
  static public function update($method = null, $params = array())
90
  {
91
- $post_data = self::get_post_data();
92
- $method = isset($post_data['method']) ? $post_data['method'] : $method;
93
- $post_id = self::get_post_id();
94
-
95
- // User can't edit this post.
96
- if($post_id && !current_user_can('edit_post', $post_id)) {
97
- return false;
98
- }
99
-
100
- // Method doesn't exist.
101
- else if(!$method) {
102
- return false;
103
- }
104
-
105
- // Method exists.
106
- else if(method_exists('FLBuilderModel', $method)) {
107
-
108
- // Call the method.
109
- $result = call_user_func_array('FLBuilderModel::' . $method, $params);
110
-
111
- // Render new assets.
112
- if(!isset($post_data['render_assets']) || $post_data['render_assets'] == 1) {
113
- FLBuilder::render_css();
114
- FLBuilder::render_js();
115
- }
116
-
117
- // Return the result.
118
- if(defined('DOING_AJAX')) {
119
- echo json_encode($result);
120
- die();
121
- }
122
- else {
123
- return $result;
124
- }
125
- }
126
-
127
- return false;
128
- }
129
-
130
- /**
131
- * @method get_edit_url
132
- */
133
- static public function get_edit_url( $post_id = false )
134
- {
135
- global $post;
136
-
137
- if ( false === $post_id ) {
138
- $post_id = $post->ID;
139
- }
140
-
141
- $url = add_query_arg( 'fl_builder', '', get_permalink( $post_id ) );
142
-
143
- if ( class_exists( 'WPMinify' ) ) {
144
- $url = add_query_arg( 'wp-minify-off', '1', $url );
145
- }
146
-
147
- return set_url_scheme( $url );
148
- }
149
-
150
- /**
151
- * @method get_upgrade_url
152
- */
153
- static public function get_upgrade_url( $params = array() )
154
- {
 
 
 
 
 
 
 
 
 
 
155
  $url = FL_BUILDER_UPGRADE_URL . '?' . http_build_query( $params, '', '&' );
156
 
157
  return apply_filters( 'fl_builder_upgrade_url', $url );
158
- }
159
 
160
  /**
161
- * @method get_post_data
162
- */
 
 
 
 
163
  static public function get_post_data()
164
  {
165
- if(!self::$post_data) {
166
-
167
- self::$post_data = array();
168
 
169
- if(isset($_POST['fl_builder_data'])) {
170
 
171
- $data = self::json_decode_settings($_POST['fl_builder_data']);
172
-
173
- foreach($data as $key => $val) {
174
- self::$post_data[$key] = $val;
175
- }
176
- }
177
- else if(isset($_POST)) {
 
 
178
 
179
- foreach($_POST as $key => $val) {
180
- self::$post_data[$key] = $val;
181
- }
182
- }
183
- }
184
 
185
- return self::$post_data;
186
  }
187
 
188
  /**
189
- * @method update_post_data
190
- */
 
 
 
 
 
191
  static public function update_post_data($key, $value)
192
  {
193
- $post_data = self::get_post_data();
194
- $post_data[$key] = $value;
195
- self::$post_data = $post_data;
196
  }
197
 
198
  /**
199
- * @method get_post_types
200
- */
 
 
 
 
201
  static public function get_post_types()
202
  {
203
- $key = '_fl_builder_post_types';
204
- $default = array('page', 'fl-builder-template');
205
-
206
- // Get the value.
207
- if(is_network_admin()) {
208
- $value = get_site_option($key);
209
- }
210
- else if(class_exists('FLBuilderMultisiteSettings')) {
211
- $value = get_option($key);
212
- $value = !$value ? get_site_option($key) : $value;
213
- }
214
- else {
215
- $value = get_option($key);
216
- }
217
-
218
- // Return the value.
219
- if(!$value) {
220
- return $default;
221
- }
222
- else {
223
- $value[] = 'fl-builder-template';
224
- return $value;
225
- }
226
- }
227
-
228
- /**
229
- * @method get_global_posts
230
- */
 
 
 
 
231
  static public function get_global_posts()
232
  {
233
- return apply_filters('fl_builder_global_posts', array());
234
  }
235
 
236
  /**
237
- * @method get_post_id
238
- */
 
 
 
 
239
  static public function get_post_id()
240
  {
241
- global $post;
242
-
243
- $post_data = self::get_post_data();
244
-
245
- if(isset($post_data['post_id'])) {
246
- return $post_data['post_id'];
247
- }
248
- else if(isset($post)) {
249
- return $post->ID;
250
- }
251
- else {
252
- return false;
253
- }
254
- }
255
-
256
- /**
257
- * @method is_ssl
258
- */
259
- static public function is_ssl()
260
- {
261
- if ( is_ssl() ) {
262
- return true;
263
- }
264
- else if ( 0 === stripos( get_option( 'siteurl' ), 'https://' ) ) {
265
- return true;
266
- }
267
- else if ( isset( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) && 'https' == $_SERVER['HTTP_X_FORWARDED_PROTO'] ) {
268
- return true;
269
- }
270
-
271
- return false;
272
- }
273
-
274
- /**
275
- * Checks to see if the builder can be enabled for
276
- * the current post in the main query.
277
- *
278
- * @method is_post_editable
279
- */
280
- static public function is_post_editable()
281
- {
282
- global $wp_the_query;
283
-
284
- if ( is_singular() && isset( $wp_the_query->post ) ) {
285
-
286
- $post = $wp_the_query->post;
287
- $post_types = self::get_post_types();
288
- $user_can = current_user_can( 'edit_post', $post->ID );
289
-
290
- if ( in_array( $post->post_type, $post_types ) && $user_can ) {
291
- return true;
292
- }
293
- }
294
-
295
- return false;
296
- }
297
-
298
- /**
299
- * Called by the heartbeat API. Lock the current post
300
- * so only the current user can edit it.
301
- *
302
- * @method lock_post
303
- */
304
- static public function lock_post($response, $data)
305
- {
306
- if(isset($data['fl_builder_post_lock'])) {
307
-
308
- require_once ABSPATH . 'wp-admin/includes/post.php';
309
-
310
- wp_set_post_lock($data['fl_builder_post_lock']['post_id']);
311
- }
312
- }
 
 
 
 
 
313
 
314
  /**
315
  * Checks to see if the builder layout is enabled
316
  * for the current post.
317
  *
318
- * @method is_builder_enabled
319
- */
 
320
  static public function is_builder_enabled()
321
  {
322
- if(!is_admin() && post_password_required()) {
323
- return false;
324
- }
325
- else if(self::is_builder_active()) {
326
- return true;
327
- }
328
- else {
329
 
330
- $post_types = self::get_post_types();
331
- $post = get_post(self::get_post_id());
332
 
333
- if($post && in_array($post->post_type, $post_types)) {
334
- return get_post_meta(self::get_post_id(), '_fl_builder_enabled', true);
335
- }
336
- }
337
 
338
- return false;
339
  }
340
 
341
  /**
342
  * Checks to see if the builder UI is active for
343
  * the current post in the main query.
344
  *
345
- * @method is_builder_active
346
- */
 
347
  static public function is_builder_active()
348
  {
349
- if ( self::is_post_editable() && ! is_admin() && ! post_password_required() ) {
350
 
351
- $post_data = self::get_post_data();
352
 
353
- if ( isset( $_GET['fl_builder'] ) ) {
354
- return true;
355
- }
356
- else if ( isset( $post_data['fl_builder'] ) ) {
357
- return true;
358
- }
359
- }
360
 
361
- return false;
362
  }
363
 
364
  /**
365
  * Checks to see if this is the first time
366
  * a user has launched the builder.
367
  *
368
- * @method is_new_user
369
- */
 
370
  static public function is_new_user()
371
  {
372
- if ( self::is_builder_active() ) {
373
 
374
- $current_user = wp_get_current_user();
375
- $launched = get_user_meta( $current_user->ID, '_fl_builder_launched', true );
376
-
377
- if ( empty( $launched ) ) {
378
- update_user_meta( $current_user->ID, '_fl_builder_launched', 1 );
379
- return true;
380
- }
381
- }
382
 
383
- return false;
384
  }
385
 
386
  /**
@@ -388,1100 +439,1281 @@ final class FLBuilderModel {
388
  * the database. Returns draft if the builder is active,
389
  * otherwise it returns published.
390
  *
391
- * @method get_node_status
392
- */
 
393
  static public function get_node_status()
394
  {
395
- return self::is_builder_active() ? 'draft' : 'published';
396
  }
397
 
398
  /**
399
  * Enable the builder layout for the current post.
400
  *
401
- * @method enable
402
- */
 
403
  static public function enable()
404
  {
405
- update_post_meta(self::get_post_id(), '_fl_builder_enabled', true);
406
  }
407
 
408
  /**
409
  * Disable the builder layout for the current post.
410
  *
411
- * @method disable
412
- */
 
413
  static public function disable()
414
  {
415
- update_post_meta(self::get_post_id(), '_fl_builder_enabled', false);
416
  }
417
 
418
  /**
419
  * Enable the builder editor for the main post in the query.
420
  *
421
- * @method enable_editing
422
- */
 
423
  static public function enable_editing()
424
  {
425
- global $wp_the_query;
426
 
427
- if ( self::is_post_editable() ) {
428
 
429
- $post = $wp_the_query->post;
430
- $published = self::get_layout_data( 'published' );
431
- $draft = self::get_layout_data( 'draft' );
432
 
433
- // Migrate existing post content to the builder?
434
- if ( empty( $published ) && empty( $draft ) && ! empty( $post->post_content ) ) {
435
 
436
- $row = self::add_row();
437
- $cols = self::get_nodes( 'column' );
438
- $col = array_shift( $cols );
439
- $settings = self::get_module_defaults( 'rich-text' );
440
- $settings->text = wpautop( $post->post_content );
441
 
442
- self::add_module( 'rich-text', $settings, $col->node );
443
- }
444
- // Create a new draft?
445
- else if ( empty( $draft ) ) {
446
- self::update_layout_data( $published, 'draft', $post->ID );
447
- }
448
 
449
- // Delete old draft asset cache.
450
- self::delete_asset_cache();
451
 
452
- // Lock the post.
453
- require_once ABSPATH . 'wp-admin/includes/post.php';
454
- wp_set_post_lock( $post->ID );
455
- }
456
  }
457
 
458
  /**
459
- * @method get_upload_dir
460
- */
 
 
 
 
461
  static public function get_upload_dir()
462
  {
463
- $wp_info = wp_upload_dir();
464
- $dir_name = basename( FL_BUILDER_DIR );
465
-
466
- // We use bb-plugin for the lite version as well.
467
- if ( $dir_name == 'beaver-builder-lite-version' ) {
468
- $dir_name = 'bb-plugin';
469
- }
470
 
471
- // SSL workaround.
472
- if ( self::is_ssl() ) {
473
- $wp_info['baseurl'] = str_ireplace( 'http://', 'https://', $wp_info['baseurl'] );
474
- }
475
 
476
- // Build the paths.
477
- $dir_info = array(
478
- 'path' => $wp_info['basedir'] . '/' . $dir_name . '/',
479
- 'url' => $wp_info['baseurl'] . '/' . $dir_name . '/'
480
- );
481
 
482
- // Create the upload dir if it doesn't exist.
483
- if ( ! file_exists( $dir_info['path'] ) ) {
484
- mkdir( $dir_info['path'] );
485
- }
486
 
487
- return $dir_info;
488
- }
489
 
490
  /**
491
- * @method get_cache_dir
492
- */
 
 
 
 
 
493
  static public function get_cache_dir( $name = 'cache' )
494
  {
495
- $upload_info = self::get_upload_dir();
496
- $allowed = array( 'cache', 'icons' );
497
-
498
- // Make sure the dir name is allowed.
499
- if ( ! in_array( $name, $allowed ) ) {
500
- return false;
501
- }
502
 
503
- // Build the paths.
504
- $dir_info = array(
505
- 'path' => $upload_info['path'] . $name . '/',
506
- 'url' => $upload_info['url'] . $name . '/'
507
- );
508
 
509
- // Create the cache dir if it doesn't exist.
510
- if( ! file_exists( $dir_info['path'] ) ) {
511
- mkdir( $dir_info['path'] );
512
- }
513
 
514
- return $dir_info;
515
- }
516
 
517
  /**
518
- * @method get_asset_version
519
- */
 
 
 
 
 
 
520
  static public function get_asset_version()
521
  {
522
- $post_id = self::get_post_id();
523
- $active = self::is_builder_active();
524
 
525
- if($active) {
526
- return md5(uniqid());
527
- }
528
- else {
529
- return md5(get_post_modified_time('U', false, $post_id));
530
- }
531
  }
532
 
533
  /**
534
- * @method get_asset_info
535
- */
 
 
 
 
536
  static public function get_asset_info()
537
  {
538
- $post_data = self::get_post_data();
539
- $post_id = self::get_post_id();
540
- $cache_dir = self::get_cache_dir();
541
-
542
- if(isset($post_data['node_preview'])) {
543
- $suffix = '-layout-preview';
544
- }
545
- else if(self::is_builder_active()) {
546
- $suffix = '-layout-draft';
547
- }
548
- else {
549
- $suffix = '-layout';
550
- }
551
-
552
- $info = array(
553
- 'css' => $cache_dir['path'] . $post_id . $suffix . '.css',
554
- 'css_url' => $cache_dir['url'] . $post_id . $suffix . '.css',
555
- 'js' => $cache_dir['path'] . $post_id . $suffix . '.js',
556
- 'js_url' => $cache_dir['url'] . $post_id . $suffix . '.js'
557
- );
558
-
559
- return $info;
560
- }
561
-
562
- /**
563
- * @method delete_asset_cache
564
- */
 
 
 
 
565
  static public function delete_asset_cache($type = 'all')
566
  {
567
- $info = self::get_asset_info();
568
 
569
- if(($type == 'css' || $type == 'all') && file_exists($info['css'])) {
570
- unlink($info['css']);
571
- }
572
- if(($type == 'js' || $type == 'all') && file_exists($info['js'])) {
573
- unlink($info['js']);
574
- }
575
  }
576
 
577
  /**
578
- * @method delete_all_asset_cache
579
- */
 
 
 
 
 
 
580
  static public function delete_all_asset_cache($post_id = null)
581
  {
582
- $post_id = $post_id == null ? self::get_post_id() : $post_id;
583
- $cache_dir = self::get_cache_dir();
584
-
585
- if($post_id == null) {
586
-
587
- $css = glob( $cache_dir['path'] . '*.css' );
588
- $js = glob( $cache_dir['path'] . '*.js' );
589
-
590
- if ( is_array( $css ) ) {
591
- array_map( 'unlink', $css );
592
- }
593
- if ( is_array( $js ) ) {
594
- array_map( 'unlink', $js );
595
- }
596
- }
597
- else {
598
-
599
- $css = $cache_dir['path'] . $post_id . '-layout.css';
600
- $css_draft = $cache_dir['path'] . $post_id . '-layout-draft.css';
601
- $css_preview = $cache_dir['path'] . $post_id . '-layout-preview.css';
602
- $js = $cache_dir['path'] . $post_id . '-layout.js';
603
- $js_draft = $cache_dir['path'] . $post_id . '-layout-draft.js';
604
- $js_preview = $cache_dir['path'] . $post_id . '-layout-preview.js';
605
-
606
- if(file_exists($css)) {
607
- unlink($css);
608
- }
609
- if(file_exists($css_draft)) {
610
- unlink($css_draft);
611
- }
612
- if(file_exists($css_preview)) {
613
- unlink($css_preview);
614
- }
615
- if(file_exists($js)) {
616
- unlink($js);
617
- }
618
- if(file_exists($js_draft)) {
619
- unlink($js_draft);
620
- }
621
- if(file_exists($js_preview)) {
622
- unlink($js_preview);
623
- }
624
- }
625
- }
626
-
627
- /**
628
- * @method generate_node_id
629
- */
630
- static public function generate_node_id()
631
- {
632
- $node_id = uniqid();
633
-
634
- if($node_id == self::$last_generated_node_id) {
635
- return self::generate_node_id();
636
- }
637
-
638
- self::$last_generated_node_id = $node_id;
639
-
640
- return $node_id;
641
- }
642
-
643
- /**
644
- * @method generate_new_node_ids
645
- */
646
- static public function generate_new_node_ids($data)
647
- {
648
- $map = array();
649
- $nodes = array();
650
-
651
- // Map the new node ids to the old.
652
- foreach($data as $node_id => $node) {
653
- $map[$node_id] = self::generate_node_id();
654
- }
655
-
656
- // Replace the old node ids.
657
- foreach($data as $node_id => $node) {
658
-
659
- $nodes[$map[$node_id]] = $node;
660
- $nodes[$map[$node_id]]->node = $map[$node_id];
661
-
662
- if(!empty($node->parent) && isset($map[$node->parent])) {
663
- $nodes[$map[$node_id]]->parent = $map[$node->parent];
664
- }
665
- }
666
-
667
- return $nodes;
668
- }
669
-
670
- /**
671
- * @method get_node
672
- */
 
 
 
 
 
 
 
 
 
 
 
 
 
673
  static public function get_node($node_id = null, $status = null)
674
  {
675
- $data = self::get_layout_data($status);
676
- $node = $data[$node_id];
677
 
678
- if(isset($node) && !empty($node->settings)) {
679
- $node->settings = self::get_node_settings($node);
680
- }
681
 
682
- return $node;
683
  }
684
 
685
  /**
686
- * @method get_child_nodes
687
- */
 
 
 
 
 
688
  static public function get_child_nodes($parent_id, $status = null)
689
  {
690
- $data = self::get_layout_data($status);
691
- $nodes = array();
692
 
693
- foreach($data as $node_id => $node) {
694
 
695
- if($node->parent == $parent_id) {
696
- $nodes[$node_id] = $node;
697
- }
698
- }
699
 
700
- return $nodes;
701
  }
702
 
703
  /**
704
- * @method get_nodes
705
- */
 
 
 
 
 
 
706
  static public function get_nodes($type = null, $parent_id = null, $status = null)
707
  {
708
- $nodes = array();
709
 
710
- // Get the layout data.
711
- if($parent_id == null) {
712
- $data = self::get_layout_data($status);
713
- }
714
- else {
715
- $data = self::get_child_nodes($parent_id, $status);
716
- }
717
 
718
- // Return all nodes?
719
- if($type == null) {
720
- $nodes = $data;
721
- }
722
- // Return nodes of a certain type.
723
- else {
724
 
725
- foreach($data as $node_id => $node) {
726
 
727
- if($node->type == $type) {
728
- $nodes[$node_id] = $node;
729
- }
730
- }
731
 
732
- uasort($nodes, array('FLBuilderModel', 'order_nodes'));
733
- }
734
 
735
- // Merge default settings.
736
- foreach($nodes as $node_id => $node) {
737
 
738
- if(!empty($node->settings)) {
739
- $nodes[$node_id]->settings = self::get_node_settings($nodes[$node_id]);
740
- }
741
- }
742
 
743
- // Return the nodes.
744
- return $nodes;
745
  }
746
 
747
  /**
748
- * @method get_node_settings
749
- */
 
 
 
 
 
750
  static public function get_node_settings($node)
751
  {
752
- $post_data = self::get_post_data();
753
 
754
- if(isset($post_data['node_preview']) && isset($post_data['node_id']) && $post_data['node_id'] == $node->node) {
755
 
756
- if(!isset($post_data['node_preview_processed_settings'])) {
757
- $settings = $post_data['node_preview'];
758
- $settings = (object)array_merge((array)$node->settings, (array)$settings);
759
- $settings = self::process_node_settings($node, $settings);
760
- self::update_post_data('node_preview_processed_settings', $settings);
761
- }
762
- else {
763
- $settings = $post_data['node_preview_processed_settings'];
764
- }
765
- }
766
- else {
767
- $defaults = self::get_node_defaults($node);
768
- $settings = (object)array_merge((array)$defaults, (array)$node->settings);
769
- }
770
 
771
- return $settings;
772
  }
773
 
774
  /**
775
- * @method process_node_settings
776
- */
 
 
 
 
 
 
777
  static public function process_node_settings($node, $new_settings)
778
  {
779
- if($node->type == 'row') {
780
- $new_settings = self::process_row_settings($node, $new_settings);
781
- }
782
- if($node->type == 'column') {
783
- $new_settings = self::process_col_settings($node, $new_settings);
784
- }
785
- if($node->type == 'module') {
786
- $new_settings = self::process_module_settings($node, $new_settings);
787
- }
788
 
789
- return $new_settings;
790
  }
791
 
792
  /**
793
- * @method get_node_defaults
794
- */
 
 
 
 
795
  static public function get_node_defaults($node)
796
  {
797
- $defaults = array();
798
 
799
- if($node->type == 'row') {
800
- $defaults = self::get_row_defaults();
801
- }
802
- else if($node->type == 'column') {
803
- $defaults = self::get_col_defaults();
804
- }
805
- else if($node->type == 'module') {
806
- $defaults = self::get_module_defaults($node->settings->type);
807
- }
808
 
809
- return $defaults;
810
  }
811
 
812
  /**
813
- * @method order_nodes
814
- */
 
 
 
 
 
815
  static public function order_nodes($a, $b)
816
  {
817
- return (int)$a->position - (int)$b->position;
818
  }
819
 
820
  /**
821
- * @method count_nodes
822
- */
 
 
 
 
 
823
  static public function count_nodes($type = 'row', $parent_id = null)
824
  {
825
- return count(self::get_nodes($type, $parent_id));
826
  }
827
 
828
  /**
829
- * @method next_node_position
830
- */
 
 
 
 
 
 
831
  static public function next_node_position($type = 'row', $parent_id = null)
832
  {
833
- $nodes = self::get_nodes($type, $parent_id);
834
- $last = array_pop($nodes);
835
-
836
- return $last ? $last->position + 1 : 0;
837
  }
838
 
839
- /**
840
- * @method delete_node
841
- */
842
- static public function delete_node($node_id = null)
843
- {
844
- // Get the post data.
845
- $post_data = self::get_post_data();
 
 
 
 
846
 
847
- // Get the layout data.
848
- $data = self::get_layout_data();
849
 
850
- // Get the node id.
851
- if(!$node_id && isset($post_data['node_id'])) {
852
- $node_id = $post_data['node_id'];
853
- }
854
 
855
- // Return if the node doesn't exist.
856
- if(!isset($data[$node_id])) {
857
- return;
858
- }
859
 
860
- // Get the node.
861
- $node = $data[$node_id];
862
 
863
- // Call the delete method if we're deleting a module.
864
- self::call_module_delete($node);
865
-
866
- // Delete the node.
867
- unset($data[$node_id]);
868
-
869
- // Update the layout data.
870
- self::update_layout_data($data);
871
-
872
- // Reorder existing nodes.
873
- self::reorder_nodes($node->type, $node->parent);
874
-
875
- // Delete the node's children.
876
- self::delete_child_nodes($node_id);
877
- }
878
-
879
- /**
880
- * @method delete_child_nodes
881
- */
882
- static public function delete_child_nodes($parent_id = null)
883
- {
884
- $children = self::get_nodes(null, $parent_id);
885
-
886
- foreach($children as $child) {
887
- self::delete_node($child->node);
888
- }
889
- }
890
-
891
- /**
892
- * @method call_module_delete
893
- */
894
- static public function call_module_delete($node)
895
- {
896
- if($node->type == 'module' && isset(self::$modules[$node->settings->type])) {
897
- $class = get_class(self::$modules[$node->settings->type]);
898
- $instance = new $class();
899
- $instance->settings = $node->settings;
900
- $instance->delete();
901
- }
902
- }
903
-
904
- /**
905
- * @method reorder_node
906
- */
907
- static public function reorder_node($node_id = null, $position = 0)
908
- {
909
- $post_data = self::get_post_data();
910
- $data = self::get_layout_data();
911
- $node_id = $node_id != null ? $node_id : $post_data['node_id'];
912
- $node = $data[$node_id];
913
- $nodes = self::get_nodes($node->type, $node->parent);
914
- $position = isset($post_data['position']) ? (int)$post_data['position'] : $position;
915
- $new_pos = 0;
916
-
917
- // Make sure node positions start at zero.
918
- foreach($nodes as $node) {
919
- $data[$node->node]->position = $new_pos;
920
- $new_pos++;
921
- }
922
-
923
- // Get the node and remove it from the array.
924
- $node = $data[$node_id];
925
- $removed = array_splice($nodes, $node->position, 1);
926
- $new_pos = 0;
927
-
928
- // Reposition it in the array.
929
- array_splice($nodes, $position, 0, $removed);
930
-
931
- // Update the position data.
932
- foreach($nodes as $node) {
933
- $data[$node->node]->position = $new_pos;
934
- $new_pos++;
935
- }
936
-
937
- // Update the layout data.
938
- self::update_layout_data($data);
939
- }
940
-
941
- /**
942
- * @method reorder_nodes
943
- */
944
- static public function reorder_nodes($type = 'row', $parent_id = null)
945
- {
946
- $data = self::get_layout_data();
947
- $nodes = self::get_nodes($type, $parent_id);
948
- $pos = 0;
949
-
950
- foreach($nodes as $node_id => $node) {
951
- $data[$node_id]->position = $pos;
952
- $pos++;
953
- }
954
-
955
- self::update_layout_data($data);
956
- }
957
-
958
- /**
959
- * @method move_node
960
- */
961
- static public function move_node($node_id = null, $new_parent_id = null, $position = 0)
962
- {
963
- $post_data = self::get_post_data();
964
- $data = self::get_layout_data();
965
- $node_id = isset($post_data['node_id']) ? $post_data['node_id'] : $node_id;
966
- $new_parent_id = isset($post_data['new_parent']) ? $post_data['new_parent'] : $new_parent_id;
967
- $position = isset($post_data['position']) ? $post_data['position'] : $position;
968
- $new_parent = self::get_node($new_parent_id);
969
- $node = self::get_node($node_id);
970
-
971
- // Set the node's new parent.
972
- $data[$node_id]->parent = $new_parent->node;
973
-
974
- // Update the layout data.
975
- self::update_layout_data($data);
976
-
977
- // Set the node's new order.
978
- self::reorder_node($node_id, $position);
979
- }
980
-
981
- /**
982
- * @method add_row
983
- */
984
- static public function add_row($cols = '1-col', $position = false)
985
- {
986
- $post_data = self::get_post_data();
987
- $data = self::get_layout_data();
988
- $cols = isset($post_data['cols']) ? $post_data['cols'] : $cols;
989
- $position = isset($post_data['position']) ? (int)$post_data['position'] : $position;
990
- $settings = self::get_row_defaults();
991
- $row_node_id = self::generate_node_id();
992
-
993
- // Add the row.
994
- $data[$row_node_id] = new StdClass();
995
- $data[$row_node_id]->node = $row_node_id;
996
- $data[$row_node_id]->type = 'row';
997
- $data[$row_node_id]->parent = null;
998
- $data[$row_node_id]->position = self::next_node_position('row');
999
- $data[$row_node_id]->settings = $settings;
1000
-
1001
- // Update the layout data.
1002
- self::update_layout_data($data);
1003
-
1004
- // Position the row.
1005
- if($position !== false) {
1006
- self::reorder_node($row_node_id, $position);
1007
- }
1008
-
1009
- // Add a column group.
1010
- self::add_col_group($row_node_id, $cols, 0);
1011
-
1012
- // Return the updated row.
1013
- return self::get_node($row_node_id);
1014
- }
1015
-
1016
- /**
1017
- * @method copy_row
1018
- */
1019
- static public function copy_row($node_id = null)
1020
- {
1021
- $post_data = self::get_post_data();
1022
- $node_id = isset($post_data['node_id']) ? $post_data['node_id'] : $node_id;
1023
- $layout_data = self::get_layout_data();
1024
- $row = self::get_node($node_id);
1025
- $new_row_id = self::generate_node_id();
1026
- $col_groups = self::get_child_nodes($node_id);
1027
- $new_nodes = array();
1028
-
1029
- // Add the new row.
1030
- $layout_data[$new_row_id] = clone $row;
1031
- $layout_data[$new_row_id]->settings = clone $row->settings;
1032
- $layout_data[$new_row_id]->node = $new_row_id;
1033
-
1034
- // Get the new child nodes.
1035
- foreach($col_groups as $col_group_id => $col_group) {
1036
-
1037
- $new_nodes[$col_group_id] = clone $col_group;
1038
- $cols = self::get_child_nodes($col_group_id);
1039
-
1040
- foreach($cols as $col_id => $col) {
1041
-
1042
- $new_nodes[$col_id] = clone $col;
1043
- $new_nodes[$col_id]->settings = clone $col->settings;
1044
- $modules = self::get_child_nodes($col_id);
1045
-
1046
- foreach($modules as $module_id => $module) {
1047
- $new_nodes[$module_id] = clone $module;
1048
- $new_nodes[$module_id]->settings = clone $module->settings;
1049
- }
1050
- }
1051
- }
1052
 
1053
- // Generate new child ids.
1054
- $new_nodes = self::generate_new_node_ids($new_nodes);
1055
-
1056
- // Set col group parent ids to the new row id.
1057
- foreach($new_nodes as $child_node_id => $child) {
1058
- if($child->type == 'column-group') {
1059
- $new_nodes[$child_node_id]->parent = $new_row_id;
1060
- }
1061
- }
1062
-
1063
- // Merge the child data.
1064
- $layout_data = array_merge($layout_data, $new_nodes);
1065
-
1066
- // Update the layout data.
1067
- self::update_layout_data($layout_data);
1068
-
1069
- // Position the new row.
1070
- self::reorder_node($new_row_id, $row->position + 1);
1071
- }
1072
-
1073
- /**
1074
- * @method get_row_defaults
1075
- */
1076
- static public function get_row_defaults()
1077
- {
1078
- return self::get_settings_form_defaults( 'row' );
1079
- }
1080
-
1081
- /**
1082
- * @method process_row_settings
1083
- */
1084
- static public function process_row_settings($row, $new_settings)
1085
- {
1086
- // Cache background video data.
1087
- if($new_settings->bg_type == 'video') {
1088
-
1089
- // Video
1090
- $video = FLBuilderPhoto::get_attachment_data($new_settings->bg_video);
1091
-
1092
- if($video) {
1093
-
1094
- $parts = explode('.', $video->filename);
1095
- $video->extension = array_pop($parts);
1096
- $new_settings->bg_video_data = $video;
1097
-
1098
- // Fallback
1099
- if(!empty($new_settings->bg_video_fallback_src)) {
1100
- $new_settings->bg_video_data->fallback = $new_settings->bg_video_fallback_src;
1101
- }
1102
- else {
1103
- $new_settings->bg_video_data->fallback = '';
1104
- }
1105
- }
1106
- }
1107
-
1108
- // Cache background slideshow data.
1109
- if($new_settings->bg_type == 'slideshow' && $new_settings->ss_source == 'wordpress') {
1110
-
1111
- // Make sure we have a photo data object.
1112
- if(!isset($row->settings->ss_photo_data)) {
1113
- $row->settings->ss_photo_data = new StdClass();
1114
- }
1115
-
1116
- // Hijack the slideshow module to get WordPress photo data.
1117
- $ss = new FLSlideshowModule();
1118
- $ss->settings = new StdClass();
1119
- $ss->settings->photos = $new_settings->ss_photos;
1120
- $ss->settings->photo_data = $row->settings->ss_photo_data;
1121
- $new_settings->ss_photo_data = $ss->get_wordpress_photos();
1122
- }
1123
-
1124
- return $new_settings;
1125
- }
1126
-
1127
- /**
1128
- * @method get_row_bg_data
1129
- */
1130
- static public function get_row_bg_data($row)
1131
- {
1132
- $data = null;
1133
-
1134
- // Background Video
1135
- if($row->settings->bg_type == 'video' && isset($row->settings->bg_video_data)) {
1136
- $data = $row->settings->bg_video_data;
1137
- }
1138
-
1139
- // Background Slideshow
1140
- else if($row->settings->bg_type == 'slideshow' && isset($row->settings->ss_photo_data)) {
1141
- $data = $row->settings->ss_photo_data;
1142
- }
1143
-
1144
- return $data;
1145
- }
1146
-
1147
- /**
1148
- * @method get_row_slideshow_source
1149
- */
1150
- static public function get_row_slideshow_source($row)
1151
- {
1152
- // Make sure we have a photo data object.
1153
- if(!isset($row->settings->ss_photo_data)) {
1154
- $row->settings->ss_photo_data = new StdClass();
1155
- }
1156
-
1157
- // Hijack the slideshow module to get the source.
1158
- $ss = new FLSlideshowModule();
1159
- $ss->settings = new StdClass();
1160
- $ss->settings->source = $row->settings->ss_source;
1161
- $ss->settings->photos = $row->settings->ss_photos;
1162
- $ss->settings->feed_url = $row->settings->ss_feed_url;
1163
- $ss->settings->photo_data = $row->settings->ss_photo_data;
1164
-
1165
- // Return the slideshow source.
1166
- return $ss->get_source();
1167
- }
1168
-
1169
- /**
1170
- * @method add_col_group
1171
- */
1172
- static public function add_col_group($node_id = null, $cols = '1-col', $position = false)
1173
- {
1174
- $post_data = self::get_post_data();
1175
- $data = self::get_layout_data();
1176
- $node_id = isset($post_data['node_id']) ? $post_data['node_id'] : $node_id;
1177
- $cols = isset($post_data['cols']) ? $post_data['cols'] : $cols;
1178
- $position = isset($post_data['position']) ? (int)$post_data['position'] : $position;
1179
- $group_node_id = self::generate_node_id();
1180
-
1181
- // Add the column group.
1182
- $data[$group_node_id] = new StdClass();
1183
- $data[$group_node_id]->node = $group_node_id;
1184
- $data[$group_node_id]->type = 'column-group';
1185
- $data[$group_node_id]->parent = $node_id;
1186
- $data[$group_node_id]->position = self::next_node_position('column-group', $node_id);
1187
- $data[$group_node_id]->settings = '';
1188
-
1189
- // Add the columns.
1190
- for($i = 0; $i < count(self::$row_layouts[$cols]); $i++) {
1191
-
1192
- $col_node_id = self::generate_node_id();
1193
- $data[$col_node_id] = new StdClass();
1194
- $data[$col_node_id]->node = $col_node_id;
1195
- $data[$col_node_id]->type = 'column';
1196
- $data[$col_node_id]->parent = $group_node_id;
1197
- $data[$col_node_id]->position = $i;
1198
- $data[$col_node_id]->settings = new StdClass();
1199
- $data[$col_node_id]->settings->size = self::$row_layouts[$cols][$i];
1200
- }
1201
-
1202
- // Update the layout data.
1203
- self::update_layout_data($data);
1204
-
1205
- // Position the column group.
1206
- if($position !== false) {
1207
- self::reorder_node($group_node_id, $position);
1208
- }
1209
-
1210
- // Return the column group.
1211
- return self::get_node($group_node_id);
1212
- }
1213
-
1214
- /**
1215
- * @method process_col_settings
1216
- */
1217
- static public function process_col_settings($col, $new_settings)
1218
- {
1219
- $new_settings->size = self::resize_col($col->node, $new_settings->size);
1220
-
1221
- return $new_settings;
1222
- }
1223
-
1224
- /**
1225
- * @method delete_col
1226
- */
1227
- static public function delete_col($node_id = null, $new_width = 100)
1228
- {
1229
- $post_data = self::get_post_data();
1230
- $node_id = isset($post_data['node_id']) ? $post_data['node_id'] : $node_id;
1231
- $new_width = isset($post_data['new_width']) ? $post_data['new_width'] : $new_width;
1232
- $col = self::get_node($node_id);
1233
-
1234
- // Delete the column.
1235
- self::delete_node($node_id);
1236
-
1237
- // Get the group
1238
- $group = self::get_node($col->parent);
1239
-
1240
- // Get the group children.
1241
- $cols = self::get_nodes('column', $group->node);
1242
-
1243
- // Delete the group if empty.
1244
- if(count($cols) === 0) {
1245
- self::delete_node($group->node);
1246
- }
1247
-
1248
- // Resize the remaining columns.
1249
- else {
1250
-
1251
- // Get the layout data.
1252
- $data = self::get_layout_data();
1253
-
1254
- // Loop through the columns.
1255
- foreach($cols as $col_id => $col) {
1256
-
1257
- // Set the new size.
1258
- $data[$col_id]->settings->size = round($new_width, 2);
1259
- }
1260
-
1261
- // Update the layout data.
1262
- self::update_layout_data($data);
1263
- }
1264
- }
1265
-
1266
- /**
1267
- * @method resize_col
1268
- */
1269
- static public function resize_col($node_id = null, $new_width = 100)
1270
- {
1271
- $data = self::get_layout_data();
1272
- $col = $data[$node_id];
1273
- $group = $data[$col->parent];
1274
- $cols = array_values(self::get_nodes('column', $group->node));
1275
- $pos = $col->position;
1276
- $siblings = array();
1277
- $siblings_width = 0;
1278
- $num_cols = count($cols);
1279
- $min_width = 10;
1280
- $max_width = 100 - $min_width;
1281
-
1282
- // Don't resize if only one column or width isn't a number.
1283
- if($num_cols == 1 || !is_numeric($new_width)) {
1284
- return $col->settings->size;
1285
- }
1286
-
1287
- // Find the sibling column to absorb this resize.
1288
- if($pos === 0) {
1289
- $sibling = $cols[1];
1290
- }
1291
- else if($pos == $num_cols - 1) {
1292
- $sibling = $cols[$num_cols - 2];
1293
- }
1294
- else {
1295
- $sibling = $cols[$pos + 1];
1296
- }
1297
-
1298
- // Find other siblings.
1299
- foreach($cols as $c) {
1300
-
1301
- if($col->node == $c->node) {
1302
- continue;
1303
- }
1304
- if($sibling->node == $c->node) {
1305
- continue;
1306
- }
1307
-
1308
- $siblings[] = $c;
1309
- $max_width -= $c->settings->size;
1310
- $siblings_width += $c->settings->size;
1311
- }
1312
-
1313
- // Make sure the new width isn't too small.
1314
- if($new_width < $min_width) {
1315
- $new_width = $min_width;
1316
- }
1317
-
1318
- // Make sure the new width isn't too big.
1319
- if($new_width > $max_width) {
1320
- $new_width = $max_width;
1321
- }
1322
-
1323
- // Save new sibling size.
1324
- $data[$sibling->node]->settings->size = round(100 - $siblings_width - $new_width, 2);
1325
-
1326
- // Save new column size.
1327
- $data[$col->node]->settings->size = $new_width;
1328
-
1329
- // Update the layout data.
1330
- self::update_layout_data($data);
1331
-
1332
- // Return the new size.
1333
- return $new_width;
1334
- }
1335
-
1336
- /**
1337
- * @method get_col_defaults
1338
- */
1339
- static public function get_col_defaults()
1340
- {
1341
- return self::get_settings_form_defaults( 'col' );
1342
- }
1343
-
1344
- /**
1345
- * @method load_modules
1346
- */
1347
- static public function load_modules()
1348
- {
1349
- $path = FL_BUILDER_DIR . 'modules/';
1350
- $dir = dir($path);
1351
- $module_path = '';
1352
-
1353
- while(false !== ($entry = $dir->read())) {
1354
-
1355
- if(!is_dir($path . $entry) || $entry == '.' || $entry == '..') {
1356
- continue;
1357
- }
1358
-
1359
- // Paths to check.
1360
- $module_path = $entry . '/' . $entry . '.php';
1361
- $child_path = get_stylesheet_directory() . '/fl-builder/modules/' . $module_path;
1362
- $theme_path = get_template_directory() . '/fl-builder/modules/' . $module_path;
1363
- $builder_path = FL_BUILDER_DIR . 'modules/' . $module_path;
1364
-
1365
- // Check for the module class in a child theme.
1366
- if(is_child_theme() && file_exists($child_path)) {
1367
- require_once $child_path;
1368
- }
1369
-
1370
- // Check for the module class in a parent theme.
1371
- else if(file_exists($theme_path)) {
1372
- require_once $theme_path;
1373
- }
1374
-
1375
- // Check for the module class in the builder directory.
1376
- else if(file_exists($builder_path)) {
1377
- require_once $builder_path;
1378
- }
1379
- }
1380
- }
1381
-
1382
- /**
1383
- * @method register_module
1384
- */
1385
- static public function register_module($class, $form)
1386
- {
1387
- if(class_exists($class)) {
1388
-
1389
- // Create a new instance of the module.
1390
- $instance = new $class();
1391
-
1392
- // Log an error if a module with this slug already exists.
1393
- if ( isset( self::$modules[ $instance->slug ] ) ) {
1394
- error_log( sprintf( _x( 'A module with the filename %s.php already exists! Please namespace your module filenames to ensure compatibility with Beaver Builder.', '%s stands for the module filename', 'fl-builder' ), $instance->slug ) );
1395
- return;
1396
- }
1397
-
1398
- // See if the module is enabled or not.
1399
- $enabled = apply_filters( 'fl_builder_register_module', $instance->enabled, $instance );
1400
-
1401
- // Only register modules that are enabled.
1402
- if( $enabled ) {
1403
-
1404
- // Save the instance in the modules array.
1405
- self::$modules[$instance->slug] = $instance;
1406
-
1407
- // Add the form to the instance.
1408
- self::$modules[$instance->slug]->form = $form;
1409
- self::$modules[$instance->slug]->form['advanced'] = self::$settings_forms['module_advanced'];
1410
- }
1411
- }
1412
- }
1413
-
1414
- /**
1415
- * @method get_enabled_modules
1416
- */
1417
- static public function get_enabled_modules()
1418
- {
1419
- $key = '_fl_builder_enabled_modules';
1420
- $default = array_keys(self::$modules);
1421
- $default[] = 'all';
1422
-
1423
- // Get the value.
1424
- if(is_network_admin()) {
1425
- $value = get_site_option($key);
1426
- }
1427
- else if(class_exists('FLBuilderMultisiteSettings')) {
1428
- $value = get_option($key);
1429
- $value = !$value ? get_site_option($key) : $value;
1430
- }
1431
- else {
1432
- $value = get_option($key);
1433
- }
1434
-
1435
- // Return the value.
1436
- if(!$value || in_array('all', $value)) {
1437
- return $default;
1438
- }
1439
- else {
1440
- return $value;
1441
- }
1442
- }
1443
-
1444
- /**
1445
- * @method get_categorized_modules
1446
- */
1447
- static public function get_categorized_modules( $show_disabled = false )
1448
- {
1449
- $enabled_modules = self::get_enabled_modules();
1450
-
1451
- // Get the core category keys.
1452
- $basic_key = __('Basic Modules', 'fl-builder');
1453
- $advanced_key = __('Advanced Modules', 'fl-builder');
1454
- $other_key = __('Other Modules', 'fl-builder');
1455
- $widgets_key = __('WordPress Widgets', 'fl-builder');
1456
 
1457
- // Build the default category arrays.
1458
- $categories = array();
1459
- $categories[ $basic_key ] = array();
1460
- $categories[ $advanced_key ] = array();
1461
- $categories[ $other_key ] = array();
1462
- $categories[ $widgets_key ] = array();
1463
 
1464
- // Build the categories array.
1465
- foreach(self::$modules as $module) {
1466
 
1467
- if(!in_array($module->slug, $enabled_modules) && !$show_disabled) {
1468
- continue;
1469
- }
1470
- else if($module->slug == 'widget') {
1471
- $categories[$widgets_key] = self::get_wp_widgets();
1472
- }
1473
- else if(isset($module->category)) {
1474
 
1475
- if(!isset($categories[$module->category])) {
1476
- $categories[$module->category] = array();
1477
- }
1478
-
1479
- $categories[$module->category][$module->name] = $module;
1480
- }
1481
- else {
1482
- $categories[$other_key][$module->name] = $module;
1483
- }
1484
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1485
 
1486
  // Sort the modules.
1487
  foreach($categories as $title => $modules) {
@@ -1495,554 +1727,633 @@ final class FLBuilderModel {
1495
 
1496
  // Return sorted categories.
1497
  return $categories;
1498
- }
1499
-
1500
- /**
1501
- * @method get_module_category_slug
1502
- */
1503
- static public function get_module_category_slug( $name )
1504
- {
1505
- // Get the core category keys.
1506
- $basic_key = __('Basic Modules', 'fl-builder');
1507
- $advanced_key = __('Advanced Modules', 'fl-builder');
1508
- $other_key = __('Other Modules', 'fl-builder');
1509
- $widgets_key = __('WordPress Widgets', 'fl-builder');
1510
-
1511
- if ( $name == $basic_key ) {
1512
- return 'basic';
1513
- }
1514
- if ( $name == $advanced_key ) {
1515
- return 'advanced';
1516
- }
1517
- if ( $name == $other_key ) {
1518
- return 'other';
1519
- }
1520
- if ( $name == $widgets_key ) {
1521
- return 'widgets';
1522
- }
1523
-
1524
- return sanitize_html_class( $name );
1525
- }
1526
-
1527
- /**
1528
- * @method get_module
1529
- */
1530
- static public function get_module($node_id)
1531
- {
1532
- $module = self::get_node($node_id);
1533
-
1534
- if(isset(self::$modules[$module->settings->type])) {
1535
-
1536
- $class = get_class(self::$modules[$module->settings->type]);
1537
- $instance = new $class();
1538
- $instance->node = $module->node;
1539
- $instance->parent = $module->parent;
1540
- $instance->position = $module->position;
1541
- $instance->settings = $module->settings;
1542
- $instance->type = 'module';
1543
- $instance->form = self::$modules[$module->settings->type]->form;
1544
-
1545
- return $instance;
1546
- }
1547
-
1548
- return false;
1549
- }
1550
-
1551
- /**
1552
- * @method get_modules
1553
- */
1554
- static public function get_modules($col_id = null)
1555
- {
1556
- $modules = self::get_nodes('module', $col_id);
1557
- $instances = array();
1558
- $i = 0;
1559
-
1560
- foreach($modules as $module) {
1561
-
1562
- if(isset(self::$modules[$module->settings->type])) {
1563
-
1564
- $class = get_class(self::$modules[$module->settings->type]);
1565
- $instances[$i] = new $class();
1566
- $instances[$i]->node = $module->node;
1567
- $instances[$i]->parent = $module->parent;
1568
- $instances[$i]->position = $module->position;
1569
- $instances[$i]->settings = $module->settings;
1570
- $instances[$i]->type = 'module';
1571
- $instances[$i]->form = self::$modules[$module->settings->type]->form;
1572
- $i++;
1573
- }
1574
- }
1575
-
1576
- return $instances;
1577
- }
1578
-
1579
- /**
1580
- * @method get_all_modules
1581
- */
1582
- static public function get_all_modules()
1583
- {
1584
- return self::get_modules();
1585
- }
1586
-
1587
- /**
1588
- * @method add_module
1589
- */
1590
- static public function add_module($type = null, $settings = array(), $parent_id = null, $position = false)
1591
- {
1592
- $post_data = self::get_post_data();
1593
- $data = self::get_layout_data();
1594
- $type = isset($post_data['type']) ? $post_data['type'] : $type;
1595
- $settings = isset($post_data['settings']) ? $post_data['settings'] : $settings;
1596
- $parent_id = isset($post_data['parent_id']) ? $post_data['parent_id'] : $parent_id;
1597
- $position = isset($post_data['position']) ? (int)$post_data['position'] : $position;
1598
- $module_node_id = self::generate_node_id();
1599
- $settings->type = $type;
1600
-
1601
- // Run module update method.
1602
- $class = get_class(self::$modules[$type]);
1603
- $instance = new $class();
1604
- $instance->settings = $settings;
1605
- $settings = $instance->update($settings);
1606
-
1607
- // Save the module.
1608
- $data[$module_node_id] = new StdClass();
1609
- $data[$module_node_id]->node = $module_node_id;
1610
- $data[$module_node_id]->type = 'module';
1611
- $data[$module_node_id]->parent = $parent_id;
1612
- $data[$module_node_id]->position = self::next_node_position('module', $parent_id);
1613
- $data[$module_node_id]->settings = $settings;
1614
-
1615
- // Update the layout data.
1616
- self::update_layout_data($data);
1617
-
1618
- // Position the module.
1619
- if($position !== false) {
1620
- self::reorder_node($module_node_id, $position);
1621
- }
1622
-
1623
- // Send back the inserted module.
1624
- return self::get_module($module_node_id);
1625
- }
1626
-
1627
- /**
1628
- * @method add_default_module
1629
- */
1630
- static public function add_default_module($parent_id = null, $type = null, $position = false)
1631
- {
1632
- $post_data = self::get_post_data();
1633
- $parent_id = isset($post_data['parent_id']) ? $post_data['parent_id'] : $parent_id;
1634
- $parent = $parent_id == 0 ? null : self::get_node($parent_id);
1635
- $type = isset($post_data['type']) ? $post_data['type'] : $type;
1636
- $position = isset($post_data['position']) ? (int)$post_data['position'] : $position;
1637
- $settings = self::get_module_defaults($type);
1638
- $module_node_id = self::generate_node_id();
1639
-
1640
- // Add a new row if we don't have a parent.
1641
- if(!$parent) {
1642
- $row = self::add_row('1-col', $position);
1643
- $col_groups = self::get_nodes('column-group', $row->node);
1644
- $col_group = array_shift($col_groups);
1645
- $cols = self::get_nodes('column', $col_group->node);
1646
- $parent = array_shift($cols);
1647
- $parent_id = $parent->node;
1648
- $position = null;
1649
- }
1650
-
1651
- // Add a new column if the parent is a row.
1652
- else if($parent->type == 'row') {
1653
- $col_group = self::add_col_group($parent->node, '1-col', $position);
1654
- $cols = self::get_nodes('column', $col_group->node);
1655
- $parent = array_shift($cols);
1656
- $parent_id = $parent->node;
1657
- $position = null;
1658
- }
1659
-
1660
- // Run module update method.
1661
- $class = get_class(self::$modules[$type]);
1662
- $instance = new $class();
1663
- $instance->settings = $settings;
1664
- $settings = $instance->update($settings);
1665
-
1666
- // Save the module.
1667
- $data = self::get_layout_data();
1668
- $data[$module_node_id] = new StdClass();
1669
- $data[$module_node_id]->node = $module_node_id;
1670
- $data[$module_node_id]->type = 'module';
1671
- $data[$module_node_id]->parent = $parent_id;
1672
- $data[$module_node_id]->position = self::next_node_position('module', $parent_id);
1673
- $data[$module_node_id]->settings = $settings;
1674
-
1675
- // Update the layout data.
1676
- self::update_layout_data($data);
1677
-
1678
- // Position the module.
1679
- if($position !== false) {
1680
- self::reorder_node($module_node_id, $position);
1681
- }
1682
-
1683
- // Send back the inserted module.
1684
- return self::get_module($module_node_id);
1685
- }
1686
-
1687
- /**
1688
- * @method copy_module
1689
- */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1690
  static public function copy_module($node_id = null)
1691
  {
1692
- $post_data = self::get_post_data();
1693
- $node_id = isset($post_data['node_id']) ? $post_data['node_id'] : $node_id;
1694
- $module = self::get_module($node_id);
1695
-
1696
- return self::add_module($module->settings->type, $module->settings, $module->parent, $module->position + 1);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1697
  }
1698
 
1699
  /**
1700
- * @method process_module_settings
1701
- */
1702
- static public function process_module_settings($module, $new_settings)
 
 
 
1703
  {
1704
- // Get a new node instance to work with.
1705
- $class = get_class(self::$modules[$module->settings->type]);
1706
- $instance = new $class();
1707
 
1708
- // Run node delete to clear any cache.
1709
- $instance->settings = $module->settings;
1710
- $instance->delete();
1711
-
1712
- // Run node update.
1713
- $instance->settings = $new_settings;
1714
- $new_settings = $instance->update($new_settings);
1715
 
1716
- return $new_settings;
1717
  }
1718
 
1719
- /**
1720
- * @method get_module_defaults
1721
- */
1722
- static public function get_module_defaults($type)
1723
- {
1724
- $defaults = new StdClass();
1725
-
1726
- if(isset(self::$modules[$type]->form)) {
1727
- $defaults = self::get_settings_form_defaults( $type );
1728
- $defaults->type = $type;
1729
- }
1730
-
1731
- return $defaults;
1732
- }
1733
-
1734
- /**
1735
- * @method get_wp_widgets
1736
- */
1737
- static public function get_wp_widgets()
1738
- {
1739
- global $wp_widget_factory;
1740
-
1741
- $widgets = array();
1742
-
1743
- foreach($wp_widget_factory->widgets as $class => $widget) {
1744
- $widget->class = $class;
1745
- $widgets[$widget->name] = $widget;
1746
- }
1747
-
1748
- ksort($widgets);
1749
-
1750
- return $widgets;
1751
- }
1752
-
1753
- /**
1754
- * @method get_wp_sidebars
1755
- */
1756
- static public function get_wp_sidebars()
1757
- {
1758
- global $wp_registered_sidebars;
1759
-
1760
- $sidebars = array();
1761
-
1762
- foreach($wp_registered_sidebars as $sidebar) {
1763
- $sidebars[$sidebar['name']] = $sidebar;
1764
- }
1765
-
1766
- ksort($sidebars);
1767
 
1768
- return $sidebars;
1769
- }
1770
 
1771
  /**
1772
- * @method load_settings
1773
- */
1774
- static public function load_settings()
 
 
 
1775
  {
1776
- require_once FL_BUILDER_DIR . 'includes/global-settings.php';
1777
- require_once FL_BUILDER_DIR . 'includes/row-settings.php';
1778
- require_once FL_BUILDER_DIR . 'includes/column-settings.php';
1779
- require_once FL_BUILDER_DIR . 'includes/module-settings.php';
1780
- require_once FL_BUILDER_DIR . 'includes/user-template-settings.php';
1781
- }
1782
-
1783
- /**
1784
- * @method register_settings_form
1785
- */
1786
- static public function register_settings_form($id, $form)
1787
- {
1788
- self::$settings_forms[$id] = $form;
1789
- }
1790
-
1791
- /**
1792
- * @method get_settings_form
1793
- */
1794
- static public function get_settings_form( $id )
1795
- {
1796
- return self::$settings_forms[ $id ];
1797
- }
1798
-
1799
- /**
1800
- * @method get_settings_form_fields
1801
- */
1802
- static public function get_settings_form_fields($form)
1803
- {
1804
- $fields = array();
1805
-
1806
- foreach ( $form as $tab ) {
1807
- if ( isset( $tab['sections'] ) ) {
1808
- foreach ( $tab['sections'] as $section ) {
1809
- if ( isset( $section['fields'] ) ) {
1810
- foreach ( $section['fields'] as $name => $field ) {
1811
- $fields[ $name ] = $field;
1812
- }
1813
- }
1814
- }
1815
- }
1816
- }
1817
-
1818
- return $fields;
1819
- }
1820
-
1821
- /**
1822
- * @method get_settings_form_defaults
1823
- */
1824
- static public function get_settings_form_defaults( $type )
1825
- {
1826
- // Check to see if the defaults are cached first.
1827
- if ( isset( self::$settings_form_defaults[ $type ] ) ) {
1828
- return self::$settings_form_defaults[ $type ];
1829
- }
1830
-
1831
- // They aren't cached, let's get them.
1832
- $defaults = new StdClass();
1833
-
1834
- // Check the registered forms first.
1835
- if ( isset( self::$settings_forms[ $type ] ) ) {
1836
- $form_type = $type;
1837
- $tabs = self::$settings_forms[ $type ]['tabs'];
1838
- }
1839
- // If it's not a registered form, it must be a module form.
1840
- else if ( isset( self::$modules[ $type ] ) ) {
1841
- $form_type = $type . '-module';
1842
- $tabs = self::$modules[ $type ]->form;
1843
- }
1844
- // The form can't be found.
1845
- else {
1846
- return $defaults;
1847
- }
1848
-
1849
- // Loop through the tabs and get the defaults.
1850
- foreach($tabs as $tab) {
1851
- if(isset($tab['sections'])) {
1852
- foreach($tab['sections'] as $section) {
1853
- if(isset($section['fields'])) {
1854
- foreach($section['fields'] as $name => $field) {
1855
-
1856
- $default = isset($field['default']) ? $field['default'] : '';
1857
- $is_multiple = isset($field['multiple']) && $field['multiple'] === true;
1858
- $supports_multiple = $field['type'] != 'editor' && $field['type'] != 'photo';
1859
-
1860
- if($is_multiple && $supports_multiple) {
1861
- $defaults->$name = array($default);
1862
- }
1863
- else {
1864
- $defaults->$name = $default;
1865
- }
1866
- }
1867
- }
1868
- }
1869
- }
1870
- }
1871
-
1872
- // Cache the defaults.
1873
- self::$settings_form_defaults[ $type ] = apply_filters( 'fl_builder_settings_form_defaults', $defaults, $form_type );
1874
-
1875
- return self::$settings_form_defaults[ $type ];
1876
- }
1877
-
1878
- /**
1879
- * @method save_settings
1880
- */
1881
- static public function save_settings($node_id = null, $settings = null)
1882
- {
1883
- $post_data = self::get_post_data();
1884
- $node_id = isset($post_data['node_id']) ? $post_data['node_id'] : $node_id;
1885
- $settings = isset($post_data['settings']) ? $post_data['settings'] : $settings;
1886
- $node = self::get_node($node_id);
1887
- $new_settings = (object)array_merge((array)$node->settings, (array)$settings);
1888
-
1889
- // Process the settings.
1890
- $new_settings = self::process_node_settings($node, $new_settings);
1891
-
1892
- // Save the settings to the node.
1893
- $data = self::get_layout_data();
1894
- $data[$node_id]->settings = $new_settings;
1895
-
1896
- // Update the layout data.
1897
- self::update_layout_data($data);
1898
-
1899
- // Return the new layout.
1900
- if(defined('DOING_AJAX')) {
1901
- FLBuilder::render_css();
1902
- FLBuilder::render_js();
1903
- FLBuilder::render_layout();
1904
- }
1905
- }
1906
-
1907
- /**
1908
- * @method json_decode_settings
1909
- */
1910
- static public function json_decode_settings($data)
1911
- {
1912
- if(is_string($data)) {
1913
- $data = json_decode(stripcslashes($data));
1914
- }
1915
- if(is_object($data) || is_array($data)) {
1916
-
1917
- foreach($data as $key => $val) {
1918
-
1919
- $new_val = null;
1920
-
1921
- if(is_string($val)) {
1922
-
1923
- $decoded = json_decode(stripcslashes($val));
1924
-
1925
- if(is_object($decoded) || is_array($decoded)) {
1926
- $new_val = $decoded;
1927
- }
1928
- }
1929
- else if(is_object($val) || is_array($val)) {
1930
- $new_val = self::json_decode_settings($val);
1931
- }
1932
-
1933
- if($new_val) {
1934
-
1935
- if(is_object($data)) {
1936
- $data->{$key} = $new_val;
1937
- }
1938
- else if(is_array($data)) {
1939
- $data[$key] = $new_val;
1940
- }
1941
- }
1942
- }
1943
- }
1944
-
1945
- return $data;
1946
- }
1947
-
1948
- /**
1949
- * @method default_settings
1950
- */
1951
- static public function default_settings(&$settings, $defaults)
1952
- {
1953
- foreach($defaults as $name => $value) {
1954
- if(!isset($settings->$name)) {
1955
- $settings->$name = $value;
1956
- }
1957
- }
1958
- }
1959
-
1960
- /**
1961
- * @method get_global_defaults
1962
- */
1963
- static public function get_global_defaults()
1964
- {
1965
- return self::get_settings_form_defaults( 'global' );
1966
- }
1967
-
1968
- /**
1969
- * @method get_global_settings
1970
- */
1971
- static public function get_global_settings()
1972
- {
1973
- $settings = get_option('_fl_builder_settings');
1974
- $defaults = self::get_global_defaults();
1975
-
1976
- if(!$settings) {
1977
- $settings = new StdClass();
1978
- }
1979
-
1980
- return (object)array_merge((array)$defaults, (array)$settings);
1981
- }
1982
-
1983
- /**
1984
- * @method save_global_settings
1985
- */
1986
- static public function save_global_settings($settings = array())
1987
- {
1988
- $post_data = self::get_post_data();
1989
- $settings = isset($post_data['settings']) ? $post_data['settings'] : $settings;
1990
- $old_settings = self::get_global_settings();
1991
- $new_settings = (object)array_merge((array)$old_settings, (array)$settings);
1992
-
1993
- return update_option('_fl_builder_settings', $settings);
1994
- }
1995
-
1996
- /**
1997
- * @method duplicate_post
1998
- */
1999
- static public function duplicate_post()
2000
- {
2001
- global $wpdb;
2002
-
2003
- $post_id = self::get_post_id();
2004
- $post = get_post($post_id);
2005
- $current_user = wp_get_current_user();
2006
 
2007
  // Duplicate the post.
2008
  $data = array(
2009
  'comment_status' => $post->comment_status,
2010
- 'ping_status' => $post->ping_status,
2011
- 'post_author' => $current_user->ID,
2012
- 'post_content' => $post->post_content,
2013
- 'post_excerpt' => $post->post_excerpt,
2014
- 'post_name' => $post->post_name,
2015
- 'post_parent' => $post->post_parent,
2016
- 'post_password' => $post->post_password,
2017
- 'post_status' => 'draft',
2018
- 'post_title' => sprintf( _x( 'Copy of %s', '%s stands for post/page title.', 'fl-builder' ), $post->post_title ),
2019
- 'post_type' => $post->post_type,
2020
- 'to_ping' => $post->to_ping,
2021
- 'menu_order' => $post->menu_order
2022
  );
2023
 
2024
- // Get the new post id.
2025
- $new_post_id = wp_insert_post($data);
2026
 
2027
- // Duplicate post meta.
2028
- $post_meta = $wpdb->get_results("SELECT meta_key, meta_value FROM {$wpdb->postmeta} WHERE post_id= {$post_id}");
2029
 
2030
- if(count($post_meta) !== 0) {
2031
 
2032
- $sql = "INSERT INTO {$wpdb->postmeta} (post_id, meta_key, meta_value) ";
2033
 
2034
- foreach($post_meta as $meta_info) {
2035
- $meta_key = $meta_info->meta_key;
2036
- $meta_value = addslashes($meta_info->meta_value);
2037
- $sql_select[] = "SELECT {$new_post_id}, '{$meta_key}', '{$meta_value}'";
2038
- }
2039
 
2040
- $sql .= implode(" UNION ALL ", $sql_select);
2041
- $wpdb->query($sql);
2042
- }
2043
 
2044
- // Duplicate post terms.
2045
- $taxonomies = get_object_taxonomies($post->post_type);
2046
 
2047
  foreach($taxonomies as $taxonomy) {
2048
 
@@ -2062,166 +2373,193 @@ final class FLBuilderModel {
2062
  // Save the duplicated layout data.
2063
  self::update_layout_data($data, 'published', $new_post_id);
2064
 
2065
- // Return the new post id.
2066
- return $new_post_id;
2067
- }
2068
 
2069
  /**
2070
- * @method delete_post
2071
- */
2072
- static public function delete_post($post_id)
2073
- {
2074
- // Delete all published and draft data.
2075
- self::delete_layout_data('published', $post_id);
2076
- self::delete_layout_data('draft', $post_id);
 
 
 
 
2077
 
2078
- // Delete all css and js.
2079
- self::delete_all_asset_cache($post_id);
2080
- }
2081
 
2082
  /**
2083
- * @method save_revision
2084
- */
2085
- static public function save_revision($post_id)
2086
- {
2087
- $parent_id = wp_is_post_revision($post_id);
 
 
 
 
2088
 
2089
- if($parent_id) {
2090
 
2091
- $parent = get_post($parent_id);
2092
- $data = self::get_layout_data('published', $parent->ID);
2093
 
2094
- if(!empty($data)) {
2095
- self::update_layout_data($data, 'published', $post_id);
2096
- }
2097
- }
2098
- }
2099
 
2100
  /**
2101
- * @method restore_revision
2102
- */
2103
- static public function restore_revision($post_id, $revision_id)
2104
- {
2105
- $post = get_post($post_id);
2106
- $revision = get_post($revision_id);
 
 
 
 
 
2107
 
2108
- if($revision) {
2109
 
2110
- $data = self::get_layout_data('published', $revision->ID);
2111
 
2112
- if(!empty($data)) {
2113
- self::update_layout_data($data, 'published', $post_id);
2114
- self::update_layout_data($data, 'draft', $post_id);
2115
- }
2116
- else {
2117
- self::delete_layout_data('published', $post_id);
2118
- self::delete_layout_data('draft', $post_id);
2119
- }
2120
 
2121
- self::delete_all_asset_cache();
2122
- }
2123
- }
2124
 
2125
  /**
2126
- * We use get_metadata here instead of get_post_meta,
2127
- * to ensure revisions are queried accordingly.
2128
- *
2129
- * @method get_layout_data
2130
- */
 
 
 
2131
  static public function get_layout_data($status = null, $post_id = null)
2132
  {
2133
- $post_id = !$post_id ? self::get_post_id() : $post_id;
2134
- $status = !$status ? self::get_node_status() : $status;
2135
-
2136
- // Get published data?
2137
- if($status == 'published') {
2138
- if(isset(self::$published_layout_data[$post_id])) {
2139
- $data = self::$published_layout_data[$post_id];
2140
- }
2141
- else {
2142
- $data = get_metadata('post', $post_id, '_fl_builder_data', true);
2143
- self::$published_layout_data[$post_id] = self::clean_layout_data( $data );
2144
- }
2145
- }
2146
- // Get draft data?
2147
- else if($status == 'draft') {
2148
- if(isset(self::$draft_layout_data[$post_id])) {
2149
- $data = self::$draft_layout_data[$post_id];
2150
- }
2151
- else {
2152
- $data = get_metadata('post', $post_id, '_fl_builder_draft', true);
2153
- self::$draft_layout_data[$post_id] = self::clean_layout_data( $data );
2154
- }
2155
- }
2156
-
2157
- // Make sure we have an array.
2158
- if(empty($data)) {
2159
- $data = array();
2160
- }
2161
-
2162
- // Clone the layout data to ensure the cache remains intact.
2163
- foreach($data as $node_id => $node) {
2164
- $data[$node_id] = clone $node;
2165
- }
2166
-
2167
- // Return the data.
2168
- return $data;
2169
- }
2170
-
2171
- /**
2172
- * We use update_metadata here instead of update_post_meta,
2173
- * to ensure revisions are updated accordingly.
2174
- *
2175
- * @method update_layout_data
2176
- */
 
 
 
 
2177
  static public function update_layout_data($data, $status = null, $post_id = null)
2178
  {
2179
- $post_id = !$post_id ? self::get_post_id() : $post_id;
2180
- $status = !$status ? self::get_node_status() : $status;
2181
- $data = self::clean_layout_data( $data );
2182
-
2183
- // Update published data?
2184
- if($status == 'published') {
2185
- update_metadata('post', $post_id, '_fl_builder_data', $data);
2186
- self::$published_layout_data[$post_id] = $data;
2187
- }
2188
- // Update draft data?
2189
- else if($status == 'draft') {
2190
- update_metadata('post', $post_id, '_fl_builder_draft', $data);
2191
- self::$draft_layout_data[$post_id] = $data;
2192
- }
2193
  }
2194
 
2195
  /**
2196
- * @method delete_layout_data
2197
- */
 
 
 
 
 
2198
  static public function delete_layout_data($status = null, $post_id = null)
2199
  {
2200
- // Make sure we have a status to delete.
2201
- if(!$status) {
2202
- return;
2203
- }
2204
 
2205
- // Get the post id.
2206
- $post_id = !$post_id ? self::get_post_id() : $post_id;
2207
 
2208
- // Get the data to delete.
2209
- $data = self::get_layout_data($status, $post_id);
2210
 
2211
- // Delete the nodes.
2212
- foreach($data as $node) {
2213
- self::call_module_delete($node);
2214
- }
2215
 
2216
- // Update the layout data.
2217
- self::update_layout_data(array(), $status, $post_id);
2218
  }
2219
 
2220
  /**
2221
  * Ensures the integrity of layout data key/value pairs.
2222
  *
2223
- * @method clean_layout_data
2224
- */
 
 
2225
  static public function clean_layout_data( $data = array() )
2226
  {
2227
  $cleaned = array();
@@ -2234,137 +2572,153 @@ final class FLBuilderModel {
2234
 
2235
  return $cleaned;
2236
  }
2237
-
2238
  /**
2239
- * @method clear_draft_layout
2240
- */
2241
- static public function clear_draft_layout()
2242
- {
2243
- $post_id = self::get_post_id();
2244
- $data = self::get_layout_data('published', $post_id);
 
 
 
 
2245
 
2246
- // Delete the old draft layout.
2247
- self::delete_layout_data('draft');
2248
 
2249
- // Save the new draft layout.
2250
- self::update_layout_data($data, 'draft', $post_id);
2251
 
2252
- // Clear the asset cache.
2253
- self::delete_all_asset_cache($post_id);
2254
- }
2255
 
2256
  /**
2257
- * @method save_layout
2258
- */
2259
- static public function save_layout()
2260
- {
2261
- $editor_content = FLBuilder::render_editor_content();
2262
- $post_id = self::get_post_id();
2263
- $data = self::get_layout_data('draft', $post_id);
 
 
 
2264
 
2265
- // Delete the old published layout.
2266
- self::delete_layout_data('published', $post_id);
2267
 
2268
- // Save the new published layout.
2269
- self::update_layout_data($data, 'published', $post_id);
2270
 
2271
- // Clear the asset cache.
2272
- self::delete_all_asset_cache($post_id);
2273
 
2274
- // Enable the builder to take over the post content.
2275
- self::enable();
2276
 
2277
- // Get the post status.
2278
- $post_status = get_post_status($post_id);
2279
- $post_status = strstr($post_status, 'draft') ? 'publish' : $post_status;
2280
 
2281
- // Update the post with stripped down content.
2282
- wp_update_post(array(
2283
- 'ID' => self::get_post_id(),
2284
- 'post_status' => $post_status,
2285
- 'post_content' => $editor_content
2286
- ));
2287
- }
2288
 
2289
  /**
2290
  * Duplicates a layout for WPML when the copy from original
2291
  * button has been clicked.
2292
  *
2293
- * @method duplicate_wpml_layout
2294
- */
2295
- static public function duplicate_wpml_layout($original_post_id = null, $new_post_id = null)
2296
- {
2297
- $post_data = self::get_post_data();
2298
- $original_post_id = isset($post_data['original_post_id']) ? $post_data['original_post_id'] : $original_post_id;
2299
- $new_post_id = isset($post_data['post_id']) ? $post_data['post_id'] : $new_post_id;
2300
- $enabled = get_post_meta($original_post_id, '_fl_builder_enabled', true);
2301
- $published = self::get_layout_data('published', $original_post_id);
2302
- $draft = self::get_layout_data('draft', $original_post_id);
2303
-
2304
- $response = array(
2305
- 'enabled' => false,
2306
- 'has_layout' => false
2307
- );
2308
-
2309
- if(!empty($enabled)) {
2310
- update_post_meta($new_post_id, '_fl_builder_enabled', true);
2311
- $response['enabled'] = true;
2312
- }
2313
- if(!empty($published)) {
2314
- self::update_layout_data($published, 'published', $new_post_id);
2315
- $response['has_layout'] = true;
2316
- }
2317
- if(!empty($draft)) {
2318
- self::update_layout_data($draft, 'draft', $new_post_id);
2319
- $response['has_layout'] = true;
2320
- }
2321
-
2322
- return $response;
2323
- }
2324
-
2325
- /**
2326
- * @method get_enabled_templates
2327
- */
 
 
 
 
 
 
2328
  static public function get_enabled_templates()
2329
  {
2330
- $key = '_fl_builder_enabled_templates';
2331
- $default = 'enabled';
2332
-
2333
- // Get the value.
2334
- if(is_network_admin()) {
2335
- $value = get_site_option($key);
2336
- }
2337
- else if(class_exists('FLBuilderMultisiteSettings')) {
2338
- $value = get_option($key);
2339
- $value = !$value ? get_site_option($key) : $value;
2340
- }
2341
- else {
2342
- $value = get_option($key);
2343
- }
2344
-
2345
- // Return the value.
2346
- if(!$value) {
2347
- return $default;
2348
- }
2349
- else {
2350
- return $value;
2351
- }
2352
- }
2353
-
2354
- /**
2355
- * @method save_user_template
2356
- */
2357
- static public function save_user_template()
2358
- {
2359
- $post_data = self::get_post_data();
2360
-
2361
- $post_id = wp_insert_post(array(
2362
- 'post_title' => $post_data['template_name'],
2363
- 'post_type' => 'fl-builder-template',
2364
- 'post_status' => 'publish',
2365
- 'ping_status' => 'closed',
2366
- 'comment_status' => 'closed'
2367
- ));
 
 
 
2368
 
2369
  // Get the layout data to copy.
2370
  $data = self::get_layout_data();
@@ -2374,467 +2728,546 @@ final class FLBuilderModel {
2374
 
2375
  // Save the template layout data.
2376
  self::update_layout_data($data, 'published', $post_id);
2377
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2378
 
2379
  /**
2380
- * @method get_user_templates
2381
- */
2382
- static public function get_user_templates()
2383
- {
2384
- return get_posts('post_type=fl-builder-template&orderby=title&order=ASC&posts_per_page=-1');
2385
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2386
 
2387
  /**
2388
- * @method delete_user_template
2389
- */
2390
- static public function delete_user_template($template_id = null)
2391
- {
2392
- $post_data = self::get_post_data();
2393
- $template_id = isset($post_data['template_id']) ? $post_data['template_id'] : $template_id;
 
 
 
 
 
 
 
2394
 
2395
- if(isset($template_id)) {
2396
- wp_delete_post($template_id, true);
2397
- }
2398
- }
2399
 
2400
  /**
2401
- * @method apply_user_template
2402
- */
2403
- static public function apply_user_template($template_id = null, $append = false)
2404
- {
2405
- $post_data = self::get_post_data();
2406
- $template_id = isset($post_data['template_id']) ? $post_data['template_id'] : $template_id;
2407
- $append = isset($post_data['append']) ? $post_data['append'] : $append;
2408
- $row_position = self::next_node_position('row');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2409
 
2410
- if(isset($template_id)) {
 
2411
 
2412
- // Delete existing nodes?
2413
- if(!$append) {
2414
- self::delete_layout_data('draft');
2415
- }
2416
 
2417
- // Insert new nodes if this is not a blank template.
2418
- if($template_id != 'blank') {
2419
 
2420
- // Get the template data.
2421
- $template_data = self::get_layout_data('published', $template_id);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2422
 
2423
- // Get new ids for the template nodes.
2424
- $template_data = self::generate_new_node_ids($template_data);
2425
 
2426
- // Get the existing layout data.
2427
- $layout_data = self::get_layout_data();
 
 
 
 
 
 
 
2428
 
2429
- // Reposition rows?
2430
- if($append) {
2431
 
2432
- foreach($template_data as $node_id => $node) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2433
 
2434
- if($node->type == 'row') {
2435
- $template_data[$node_id]->position += $row_position;
2436
- }
2437
- }
2438
- }
2439
 
2440
- // Merge the data.
2441
- $data = array_merge($layout_data, $template_data);
 
 
 
 
 
 
 
 
2442
 
2443
- // Update the layout data.
2444
- self::update_layout_data($data);
2445
- }
 
 
 
 
2446
 
2447
- // Delete old asset cache.
2448
- self::delete_all_asset_cache();
2449
- }
2450
- }
 
 
 
 
2451
 
2452
  /**
2453
- * @method save_template
2454
- */
2455
- static public function save_template($settings)
2456
- {
2457
- // Get the layout data.
2458
- $data = self::get_layout_data();
 
 
 
 
 
 
 
 
 
 
 
2459
 
2460
- // Get the templates array.
2461
- $templates = self::get_templates();
2462
-
2463
- // Make sure we have an object.
2464
- $settings = ( object )$settings;
 
 
 
2465
 
2466
- // Get new ids for the nodes.
2467
- $settings->nodes = self::generate_new_node_ids($data);
 
 
 
 
 
 
 
 
2468
 
2469
- // Insert the template into the templates array.
2470
- array_splice($templates, $settings->index, 0, array($settings));
 
 
 
 
 
 
 
 
 
2471
 
2472
- // Save the templates array.
2473
- self::save_templates($templates);
2474
- }
 
 
 
 
 
2475
 
2476
  /**
2477
- * @method update_template
2478
- */
2479
- static public function update_template($old_index, $settings)
2480
- {
2481
- // Get the templates array.
2482
- $templates = self::get_templates();
 
 
 
 
2483
 
2484
- // Remove the template from its old position.
2485
- $template = array_splice($templates, $old_index, 1);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2486
 
2487
- // Update the settings
2488
- foreach($settings as $key => $val) {
2489
- $template[0]->$key = $val;
2490
- }
 
 
 
 
 
 
2491
 
2492
- // Add the template to its new position.
2493
- array_splice($templates, $settings->index, 0, $template);
 
 
 
 
 
2494
 
2495
- // Save the templates array.
2496
- self::save_templates($templates);
2497
- }
 
 
 
 
 
2498
 
2499
  /**
2500
- * @method delete_template
2501
- */
2502
- static public function delete_template($index)
2503
- {
2504
- // Get the templates array.
2505
- $templates = self::get_templates();
 
 
 
2506
 
2507
- // Remove the template.
2508
- array_splice($templates, $index, 1);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2509
 
2510
- // Save the templates array.
2511
- self::save_templates($templates);
2512
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2513
 
2514
  /**
2515
- * @method apply_template
2516
- */
2517
- static public function apply_template($index = 0, $append = false)
2518
- {
2519
- $post_data = self::get_post_data();
2520
- $index = isset($post_data['index']) ? $post_data['index'] : $index;
2521
- $append = isset($post_data['append']) ? $post_data['append'] : $append;
2522
- $template = self::get_template($index);
2523
- $row_position = self::next_node_position('row');
2524
 
2525
- // Delete existing nodes?
2526
- if(!$append) {
2527
- self::delete_layout_data('draft');
2528
- }
2529
-
2530
- // Only move forward if we have template nodes.
2531
- if(isset($template->nodes)) {
2532
-
2533
- // Get new ids for the template nodes.
2534
- $template_data = self::generate_new_node_ids($template->nodes);
2535
-
2536
- // Get the existing layout data.
2537
- $layout_data = self::get_layout_data();
2538
-
2539
- // Reposition rows?
2540
- if($append) {
2541
-
2542
- foreach($template_data as $node_id => $node) {
2543
-
2544
- if($node->type == 'row') {
2545
- $template_data[$node_id]->position += $row_position;
2546
- }
2547
- }
2548
- }
2549
-
2550
- // Merge the data.
2551
- $data = array_merge($layout_data, $template_data);
2552
-
2553
- // Update the layout data.
2554
- self::update_layout_data($data);
2555
- }
2556
-
2557
- // Delete old asset cache.
2558
- self::delete_all_asset_cache();
2559
- }
2560
-
2561
- /**
2562
- * @method get_template
2563
- */
2564
- static public function get_template($index)
2565
- {
2566
- $templates = self::get_templates();
2567
-
2568
- return $templates[$index];
2569
- }
2570
-
2571
- /**
2572
- * @method get_templates
2573
- */
2574
- static public function get_templates()
2575
- {
2576
- $templates = unserialize(file_get_contents(FL_BUILDER_DIR . 'data/templates.dat'));
2577
-
2578
- return is_array($templates) ? $templates : array();
2579
- }
2580
-
2581
- /**
2582
- * @method save_templates
2583
- */
2584
- static public function save_templates($templates = array())
2585
- {
2586
- // Update the indexes for proper positioning.
2587
- $i = 0;
2588
- $updated = array();
2589
-
2590
- foreach($templates as $template) {
2591
- $template->index = $i;
2592
- $updated[$i] = $template;
2593
- $i++;
2594
- }
2595
-
2596
- // Save the templates array.
2597
- file_put_contents(FL_BUILDER_DIR . 'data/templates.dat', serialize($updated));
2598
- }
2599
-
2600
- /**
2601
- * @method get_branding
2602
- */
2603
- static public function get_branding()
2604
- {
2605
- $key = '_fl_builder_branding';
2606
- $default = __('Page Builder', 'fl-builder');
2607
-
2608
- // Get the value.
2609
- if(is_network_admin() || class_exists('FLBuilderMultisiteSettings')) {
2610
- $value = get_site_option($key);
2611
- }
2612
- else {
2613
- $value = get_option($key);
2614
- }
2615
-
2616
- // Return the value.
2617
- if(!$value) {
2618
- return $default;
2619
- }
2620
- else {
2621
- return stripcslashes($value);
2622
- }
2623
- }
2624
-
2625
- /**
2626
- * @method get_branding_icon
2627
- */
2628
- static public function get_branding_icon()
2629
- {
2630
- $key = '_fl_builder_branding_icon';
2631
- $default = FL_BUILDER_URL . 'img/beaver.png';
2632
-
2633
- // Get the value.
2634
- if(is_network_admin() || class_exists('FLBuilderMultisiteSettings')) {
2635
- $value = get_site_option($key);
2636
- }
2637
- else {
2638
- $value = get_option($key);
2639
- }
2640
-
2641
- // Return the value.
2642
- if($value === false) {
2643
- return $default;
2644
- }
2645
- else {
2646
- return $value;
2647
- }
2648
- }
2649
-
2650
- /**
2651
- * @method get_enabled_icons
2652
- */
2653
- static public function get_enabled_icons()
2654
- {
2655
- $key = '_fl_builder_enabled_icons';
2656
- $default = array( 'font-awesome', 'foundation-icons', 'dashicons' );
2657
-
2658
- // Get the value.
2659
- if(is_network_admin()) {
2660
- $value = get_site_option($key);
2661
- }
2662
- else if(class_exists('FLBuilderMultisiteSettings')) {
2663
- $value = get_option($key);
2664
- $value = !$value ? get_site_option($key) : $value;
2665
- }
2666
- else {
2667
- $value = get_option($key);
2668
- }
2669
-
2670
- // Return the value.
2671
- if(!$value) {
2672
- return $default;
2673
- }
2674
- else {
2675
- return $value;
2676
- }
2677
- }
2678
-
2679
- /**
2680
- * @method get_editing_capability
2681
- */
2682
- static public function get_editing_capability()
2683
- {
2684
- $key = '_fl_builder_editing_capability';
2685
- $default = 'edit_posts';
2686
-
2687
- // Get the value.
2688
- if(is_network_admin()) {
2689
- $value = get_site_option($key);
2690
- }
2691
- else if(class_exists('FLBuilderMultisiteSettings')) {
2692
- $value = get_option($key);
2693
- $value = !$value ? get_site_option($key) : $value;
2694
- }
2695
- else {
2696
- $value = get_option($key);
2697
- }
2698
-
2699
- // Return the value.
2700
- if(!$value) {
2701
- return $default;
2702
- }
2703
- else {
2704
- return $value;
2705
- }
2706
- }
2707
-
2708
- /**
2709
- * @method get_help_button_defaults
2710
- */
2711
- static public function get_help_button_defaults()
2712
- {
2713
- $defaults = array(
2714
- 'enabled' => true,
2715
- 'tour' => true,
2716
- 'video' => true,
2717
- 'video_embed' => '<iframe src="https://player.vimeo.com/video/124230072?autoplay=1" width="420" height="315" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>',
2718
- 'knowledge_base' => true,
2719
- 'knowledge_base_url' => 'https://www.wpbeaverbuilder.com/knowledge-base/?utm_source=external&utm_medium=builder&utm_campaign=docs-button',
2720
- 'forums' => true,
2721
- 'forums_url' => 'https://www.wpbeaverbuilder.com/support/?utm_source=external&utm_medium=builder&utm_campaign=forums-button',
2722
- );
2723
-
2724
- return $defaults;
2725
- }
2726
-
2727
- /**
2728
- * @method get_help_button_settings
2729
- */
2730
- static public function get_help_button_settings()
2731
- {
2732
- $key = '_fl_builder_help_button';
2733
- $defaults = self::get_help_button_defaults();
2734
-
2735
- // Get the value.
2736
- if ( is_network_admin() || class_exists( 'FLBuilderMultisiteSettings' ) ) {
2737
- $value = get_site_option( $key );
2738
- }
2739
- else {
2740
- $value = get_option( $key );
2741
- }
2742
-
2743
- // Return the value.
2744
- if ( false === $value ) {
2745
- return $defaults;
2746
- }
2747
- else {
2748
- return $value;
2749
- }
2750
- }
2751
-
2752
- /**
2753
- * @method get_services
2754
- */
2755
- static public function get_services()
2756
- {
2757
- return get_option( '_fl_builder_services', array() );
2758
- }
2759
-
2760
- /**
2761
- * @method update_services
2762
- */
2763
- static public function update_services( $service, $account, $data )
2764
- {
2765
- $services = self::get_services();
2766
- $account = sanitize_text_field( $account );
2767
-
2768
- if ( ! isset( $services[ $service ] ) ) {
2769
- $services[ $service ] = array();
2770
- }
2771
-
2772
- $services[ $service ][ $account ] = $data;
2773
-
2774
- update_option( '_fl_builder_services', $services );
2775
- }
2776
-
2777
- /**
2778
- * @method delete_service_account
2779
- */
2780
- static public function delete_service_account( $service, $account )
2781
- {
2782
- $services = self::get_services();
2783
-
2784
- if ( isset( $services[ $service ][ $account ] ) ) {
2785
- unset( $services[ $service ][ $account ] );
2786
- }
2787
- if ( 0 === count( $services[ $service ] ) ) {
2788
- unset( $services[ $service ] );
2789
- }
2790
-
2791
- update_option( '_fl_builder_services', $services );
2792
- }
2793
-
2794
- /**
2795
- * @method plugin_basename
2796
- */
2797
- static public function plugin_basename()
2798
- {
2799
- return plugin_basename( FL_BUILDER_DIR . 'fl-builder.php' );
2800
- }
2801
-
2802
- /**
2803
- * We don't delete _fl_builder_enabled, _fl_builder_data and _fl_builder_draft
2804
- * so layouts can be recovered should the plugin be installed again.
2805
- *
2806
- * @method uninstall_database
2807
- */
2808
- static public function uninstall_database()
2809
- {
2810
- if(current_user_can('delete_plugins')) {
2811
-
2812
- // Delete builder options.
2813
- delete_option('_fl_builder_settings');
2814
- delete_option('_fl_builder_enabled_modules');
2815
- delete_option('_fl_builder_enabled_templates');
2816
- delete_option('_fl_builder_post_types');
2817
- delete_option('_fl_builder_enabled_icons');
2818
- delete_option('_fl_builder_branding');
2819
- delete_option('_fl_builder_editing_capability');
2820
- delete_option('_fl_builder_help_button');
2821
-
2822
- // Delete builder user meta.
2823
- delete_metadata('user', 0, '_fl_builder_launched', 1, true);
2824
-
2825
- // Delete uploaded files and folders.
2826
- $upload_dir = self::get_upload_dir();
2827
- $filesystem = FLBuilderUtils::get_filesystem();
2828
- $filesystem->rmdir( $upload_dir['path'], true );
2829
-
2830
- // Deactivate and delete the plugin.
2831
- deactivate_plugins(array(self::plugin_basename()), false, is_network_admin());
2832
- delete_plugins(array(self::plugin_basename()));
2833
-
2834
- // Redirect to the plugins page.
2835
- wp_redirect(admin_url('plugins.php?deleted=true&plugin_status=all&paged=1&s='));
2836
-
2837
- exit;
2838
- }
2839
- }
2840
  }
4
  * Builder data handling class that deals
5
  * with all database operations.
6
  *
7
+ * @since 1.0
8
  */
9
  final class FLBuilderModel {
10
 
11
+ /**
12
+ * An array that contains the sizes for columns
13
+ * in each row layout.
14
+ *
15
+ * @since 1.0
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
+ /**
31
+ * An array that contains data for each registered settings form.
32
+ *
33
+ * @since 1.0
34
+ * @var array $settings_forms
35
+ */
36
+ static public $settings_forms = array();
37
+
38
+ /**
39
+ * An array used to cache default values for settings forms.
40
+ *
41
+ * @since 1.0
42
+ * @var array $settings_form_defaults
43
+ */
44
+ static public $settings_form_defaults = array();
45
+
46
+ /**
47
+ * An array that instances for each registered module.
48
+ *
49
+ * @since 1.0
50
+ * @var array $modules
51
+ */
52
+ static public $modules = array();
53
+
54
+ /**
55
+ * The last node id that was generated by the builder.
56
+ * This is saved to ensure the next node id is unique.
57
+ *
58
+ * @since 1.0
59
+ * @access private
60
+ * @var string $last_generated_node_id
61
+ */
62
+ static private $last_generated_node_id = null;
63
+
64
+ /**
65
+ * Cached post data from either the $_POST array
66
+ * or from the fl_builder_data post variable.
67
+ *
68
+ * @since 1.0
69
+ * @access private
70
+ * @var array $post_data
71
+ */
72
+ static private $post_data = null;
73
+
74
+ /**
75
+ * An array of cached published layout data by post_id.
76
+ *
77
+ * @since 1.0
78
+ * @access private
79
+ * @var array $published_layout_data
80
+ */
81
+ static private $published_layout_data = array();
82
+
83
+ /**
84
+ * An array of cached draft layout data by post_id.
85
+ *
86
+ * @since 1.0
87
+ * @access private
88
+ * @var array $draft_layout_data
89
+ */
90
+ static private $draft_layout_data = array();
91
 
92
  /**
93
  * All database updates should be made through
94
  * this method for security.
95
  *
96
+ * @since 1.0
97
+ * @param string $method The update method to call.
98
+ * @param array $params Additional params to pass to the update method.
99
+ * @return mixed
100
+ */
101
  static public function update($method = null, $params = array())
102
  {
103
+ $post_data = self::get_post_data();
104
+ $method = isset($post_data['method']) ? $post_data['method'] : $method;
105
+ $post_id = self::get_post_id();
106
+
107
+ // User can't edit this post.
108
+ if($post_id && !current_user_can('edit_post', $post_id)) {
109
+ return false;
110
+ }
111
+
112
+ // Method doesn't exist.
113
+ else if(!$method) {
114
+ return false;
115
+ }
116
+
117
+ // Method exists.
118
+ else if(method_exists('FLBuilderModel', $method)) {
119
+
120
+ // Call the method.
121
+ $result = call_user_func_array('FLBuilderModel::' . $method, $params);
122
+
123
+ // Render new assets.
124
+ if(!isset($post_data['render_assets']) || $post_data['render_assets'] == 1) {
125
+ FLBuilder::render_css();
126
+ FLBuilder::render_js();
127
+ }
128
+
129
+ // Return the result.
130
+ if(defined('DOING_AJAX')) {
131
+ echo json_encode($result);
132
+ die();
133
+ }
134
+ else {
135
+ return $result;
136
+ }
137
+ }
138
+
139
+ return false;
140
+ }
141
+
142
+ /**
143
+ * Returns a builder edit URL for a post.
144
+ *
145
+ * @since 1.0
146
+ * @param int $post_id The post id to get an edit url for.
147
+ * @return string
148
+ */
149
+ static public function get_edit_url( $post_id = false )
150
+ {
151
+ global $post;
152
+
153
+ if ( false === $post_id ) {
154
+ $post_id = $post->ID;
155
+ }
156
+
157
+ $url = add_query_arg( 'fl_builder', '', get_permalink( $post_id ) );
158
+
159
+ if ( class_exists( 'WPMinify' ) ) {
160
+ $url = add_query_arg( 'wp-minify-off', '1', $url );
161
+ }
162
+
163
+ return set_url_scheme( $url );
164
+ }
165
+
166
+ /**
167
+ * Returns the URL to upgrade the builder to the premium version.
168
+ * Can be overridden by theme developers to use their affiliate
169
+ * link using the fl_builder_upgrade_url filter.
170
+ *
171
+ * @since 1.0
172
+ * @param array $params An array of key/value params to add to the query string.
173
+ * @return string
174
+ */
175
+ static public function get_upgrade_url( $params = array() )
176
+ {
177
  $url = FL_BUILDER_UPGRADE_URL . '?' . http_build_query( $params, '', '&' );
178
 
179
  return apply_filters( 'fl_builder_upgrade_url', $url );
180
+ }
181
 
182
  /**
183
+ * Returns an array of post data from either $_POST['fl_builder_data']
184
+ * or $_POST if that is not set.
185
+ *
186
+ * @since 1.0
187
+ * @return array
188
+ */
189
  static public function get_post_data()
190
  {
191
+ if(!self::$post_data) {
 
 
192
 
193
+ self::$post_data = array();
194
 
195
+ if(isset($_POST['fl_builder_data'])) {
196
+
197
+ $data = FLBuilderUtils::json_decode_deep( wp_unslash( $_POST['fl_builder_data'] ) );
198
+
199
+ foreach($data as $key => $val) {
200
+ self::$post_data[$key] = $val;
201
+ }
202
+ }
203
+ else if(isset($_POST)) {
204
 
205
+ foreach($_POST as $key => $val) {
206
+ self::$post_data[$key] = $val;
207
+ }
208
+ }
209
+ }
210
 
211
+ return self::$post_data;
212
  }
213
 
214
  /**
215
+ * Update a value in the $post_data array.
216
+ *
217
+ * @since 1.0
218
+ * @param string $key The post data key.
219
+ * @param mixed $value The value to update.
220
+ * @return void
221
+ */
222
  static public function update_post_data($key, $value)
223
  {
224
+ $post_data = self::get_post_data();
225
+ $post_data[$key] = $value;
226
+ self::$post_data = $post_data;
227
  }
228
 
229
  /**
230
+ * Return an array of post types that the builder
231
+ * is enabled to work with.
232
+ *
233
+ * @since 1.0
234
+ * @return array
235
+ */
236
  static public function get_post_types()
237
  {
238
+ $key = '_fl_builder_post_types';
239
+ $default = array('page', 'fl-builder-template');
240
+
241
+ // Get the value.
242
+ if(is_network_admin()) {
243
+ $value = get_site_option($key);
244
+ }
245
+ else if(class_exists('FLBuilderMultisiteSettings')) {
246
+ $value = get_option($key);
247
+ $value = !$value ? get_site_option($key) : $value;
248
+ }
249
+ else {
250
+ $value = get_option($key);
251
+ }
252
+
253
+ // Return the value.
254
+ if(!$value) {
255
+ return $default;
256
+ }
257
+ else {
258
+ $value[] = 'fl-builder-template';
259
+ return $value;
260
+ }
261
+ }
262
+
263
+ /**
264
+ * Return an array of post ids that should have their
265
+ * builder assets loaded globally.
266
+ *
267
+ * @since 1.0
268
+ * @return array
269
+ */
270
  static public function get_global_posts()
271
  {
272
+ return apply_filters('fl_builder_global_posts', array());
273
  }
274
 
275
  /**
276
+ * Returns the post id for the current post that
277
+ * is being worked on.
278
+ *
279
+ * @since 1.0
280
+ * @return int|bool The post id or false.
281
+ */
282
  static public function get_post_id()
283
  {
284
+ global $post;
285
+
286
+ $post_data = self::get_post_data();
287
+
288
+ if(isset($post_data['post_id'])) {
289
+ return $post_data['post_id'];
290
+ }
291
+ else if(isset($post)) {
292
+ return $post->ID;
293
+ }
294
+ else {
295
+ return false;
296
+ }
297
+ }
298
+
299
+ /**
300
+ * Checks to see if the site has SSL enabled or not.
301
+ *
302
+ * @since 1.0
303
+ * @return bool
304
+ */
305
+ static public function is_ssl()
306
+ {
307
+ if ( is_ssl() ) {
308
+ return true;
309
+ }
310
+ else if ( 0 === stripos( get_option( 'siteurl' ), 'https://' ) ) {
311
+ return true;
312
+ }
313
+ else if ( isset( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) && 'https' == $_SERVER['HTTP_X_FORWARDED_PROTO'] ) {
314
+ return true;
315
+ }
316
+
317
+ return false;
318
+ }
319
+
320
+ /**
321
+ * Checks to see if the builder can be enabled for
322
+ * the current post in the main query.
323
+ *
324
+ * @since 1.0
325
+ * @return bool
326
+ */
327
+ static public function is_post_editable()
328
+ {
329
+ global $wp_the_query;
330
+
331
+ if ( is_singular() && isset( $wp_the_query->post ) ) {
332
+
333
+ $post = $wp_the_query->post;
334
+ $post_types = self::get_post_types();
335
+ $user_can = current_user_can( 'edit_post', $post->ID );
336
+
337
+ if ( in_array( $post->post_type, $post_types ) && $user_can ) {
338
+ return true;
339
+ }
340
+ }
341
+
342
+ return false;
343
+ }
344
+
345
+ /**
346
+ * Called by the heartbeat API. Lock the current post
347
+ * so only the current user can edit it.
348
+ *
349
+ * @since 1.0
350
+ * @return void
351
+ */
352
+ static public function lock_post($response, $data)
353
+ {
354
+ if(isset($data['fl_builder_post_lock'])) {
355
+
356
+ require_once ABSPATH . 'wp-admin/includes/post.php';
357
+
358
+ wp_set_post_lock($data['fl_builder_post_lock']['post_id']);
359
+ }
360
+ }
361
 
362
  /**
363
  * Checks to see if the builder layout is enabled
364
  * for the current post.
365
  *
366
+ * @since 1.0
367
+ * @return bool
368
+ */
369
  static public function is_builder_enabled()
370
  {
371
+ if(!is_admin() && post_password_required()) {
372
+ return false;
373
+ }
374
+ else if(self::is_builder_active()) {
375
+ return true;
376
+ }
377
+ else {
378
 
379
+ $post_types = self::get_post_types();
380
+ $post = get_post(self::get_post_id());
381
 
382
+ if($post && in_array($post->post_type, $post_types)) {
383
+ return get_post_meta(self::get_post_id(), '_fl_builder_enabled', true);
384
+ }
385
+ }
386
 
387
+ return false;
388
  }
389
 
390
  /**
391
  * Checks to see if the builder UI is active for
392
  * the current post in the main query.
393
  *
394
+ * @since 1.0
395
+ * @return bool
396
+ */
397
  static public function is_builder_active()
398
  {
399
+ if ( self::is_post_editable() && ! is_admin() && ! post_password_required() ) {
400
 
401
+ $post_data = self::get_post_data();
402
 
403
+ if ( isset( $_GET['fl_builder'] ) ) {
404
+ return true;
405
+ }
406
+ else if ( isset( $post_data['fl_builder'] ) ) {
407
+ return true;
408
+ }
409
+ }
410
 
411
+ return false;
412
  }
413
 
414
  /**
415
  * Checks to see if this is the first time
416
  * a user has launched the builder.
417
  *
418
+ * @since 1.4.9
419
+ * @return bool
420
+ */
421
  static public function is_new_user()
422
  {
423
+ if ( self::is_builder_active() ) {
424
 
425
+ $current_user = wp_get_current_user();
426
+ $launched = get_user_meta( $current_user->ID, '_fl_builder_launched', true );
427
+
428
+ if ( empty( $launched ) ) {
429
+ update_user_meta( $current_user->ID, '_fl_builder_launched', 1 );
430
+ return true;
431
+ }
432
+ }
433
 
434
+ return false;
435
  }
436
 
437
  /**
439
  * the database. Returns draft if the builder is active,
440
  * otherwise it returns published.
441
  *
442
+ * @since 1.0
443
+ * @return string
444
+ */
445
  static public function get_node_status()
446
  {
447
+ return self::is_builder_active() ? 'draft' : 'published';
448
  }
449
 
450
  /**
451
  * Enable the builder layout for the current post.
452
  *
453
+ * @since 1.0
454
+ * @return void
455
+ */
456
  static public function enable()
457
  {
458
+ update_post_meta(self::get_post_id(), '_fl_builder_enabled', true);
459
  }
460
 
461
  /**
462
  * Disable the builder layout for the current post.
463
  *
464
+ * @since 1.0
465
+ * @return void
466
+ */
467
  static public function disable()
468
  {
469
+ update_post_meta(self::get_post_id(), '_fl_builder_enabled', false);
470
  }
471
 
472
  /**
473
  * Enable the builder editor for the main post in the query.
474
  *
475
+ * @since 1.0
476
+ * @return void
477
+ */
478
  static public function enable_editing()
479
  {
480
+ global $wp_the_query;
481
 
482
+ if ( self::is_post_editable() ) {
483
 
484
+ $post = $wp_the_query->post;
485
+ $published = self::get_layout_data( 'published' );
486
+ $draft = self::get_layout_data( 'draft' );
487
 
488
+ // Migrate existing post content to the builder?
489
+ if ( empty( $published ) && empty( $draft ) && ! empty( $post->post_content ) ) {
490
 
491
+ $row = self::add_row();
492
+ $cols = self::get_nodes( 'column' );
493
+ $col = array_shift( $cols );
494
+ $settings = self::get_module_defaults( 'rich-text' );
495
+ $settings->text = wpautop( $post->post_content );
496
 
497
+ self::add_module( 'rich-text', $settings, $col->node );
498
+ }
499
+ // Create a new draft?
500
+ else if ( empty( $draft ) ) {
501
+ self::update_layout_data( $published, 'draft', $post->ID );
502
+ }
503
 
504
+ // Delete old draft asset cache.
505
+ self::delete_asset_cache();
506
 
507
+ // Lock the post.
508
+ require_once ABSPATH . 'wp-admin/includes/post.php';
509
+ wp_set_post_lock( $post->ID );
510
+ }
511
  }
512
 
513
  /**
514
+ * Returns an array of paths for the upload directory
515
+ * of the current site.
516
+ *
517
+ * @since 1.0
518
+ * @return array
519
+ */
520
  static public function get_upload_dir()
521
  {
522
+ $wp_info = wp_upload_dir();
523
+ $dir_name = basename( FL_BUILDER_DIR );
524
+
525
+ // We use bb-plugin for the lite version as well.
526
+ if ( $dir_name == 'beaver-builder-lite-version' ) {
527
+ $dir_name = 'bb-plugin';
528
+ }
529
 
530
+ // SSL workaround.
531
+ if ( self::is_ssl() ) {
532
+ $wp_info['baseurl'] = str_ireplace( 'http://', 'https://', $wp_info['baseurl'] );
533
+ }
534
 
535
+ // Build the paths.
536
+ $dir_info = array(
537
+ 'path' => $wp_info['basedir'] . '/' . $dir_name . '/',
538
+ 'url' => $wp_info['baseurl'] . '/' . $dir_name . '/'
539
+ );
540
 
541
+ // Create the upload dir if it doesn't exist.
542
+ if ( ! file_exists( $dir_info['path'] ) ) {
543
+ mkdir( $dir_info['path'] );
544
+ }
545
 
546
+ return $dir_info;
547
+ }
548
 
549
  /**
550
+ * Returns an array of paths for the cache directory
551
+ * of the current site.
552
+ *
553
+ * @since 1.0
554
+ * @param string $name The name of the cache directory to get paths for.
555
+ * @return array
556
+ */
557
  static public function get_cache_dir( $name = 'cache' )
558
  {
559
+ $upload_info = self::get_upload_dir();
560
+ $allowed = array( 'cache', 'icons' );
561
+
562
+ // Make sure the dir name is allowed.
563
+ if ( ! in_array( $name, $allowed ) ) {
564
+ return false;
565
+ }
566
 
567
+ // Build the paths.
568
+ $dir_info = array(
569
+ 'path' => $upload_info['path'] . $name . '/',
570
+ 'url' => $upload_info['url'] . $name . '/'
571
+ );
572
 
573
+ // Create the cache dir if it doesn't exist.
574
+ if( ! file_exists( $dir_info['path'] ) ) {
575
+ mkdir( $dir_info['path'] );
576
+ }
577
 
578
+ return $dir_info;
579
+ }
580
 
581
  /**
582
+ * Returns the version number to be applied to the query string
583
+ * of a CSS or JS asset. If the builder is active a random hash
584
+ * is returned to prevent caching, otherwise a hash of the post
585
+ * update time is returned.
586
+ *
587
+ * @since 1.0
588
+ * @return string
589
+ */
590
  static public function get_asset_version()
591
  {
592
+ $post_id = self::get_post_id();
593
+ $active = self::is_builder_active();
594
 
595
+ if($active) {
596
+ return md5(uniqid());
597
+ }
598
+ else {
599
+ return md5(get_post_modified_time('U', false, $post_id));
600
+ }
601
  }
602
 
603
  /**
604
+ * Returns an array of paths for the CSS and JS assets
605
+ * of the current post.
606
+ *
607
+ * @since 1.0
608
+ * @return array
609
+ */
610
  static public function get_asset_info()
611
  {
612
+ $post_data = self::get_post_data();
613
+ $post_id = self::get_post_id();
614
+ $cache_dir = self::get_cache_dir();
615
+
616
+ if(isset($post_data['node_preview'])) {
617
+ $suffix = '-layout-preview';
618
+ }
619
+ else if(self::is_builder_active()) {
620
+ $suffix = '-layout-draft';
621
+ }
622
+ else {
623
+ $suffix = '-layout';
624
+ }
625
+
626
+ $info = array(
627
+ 'css' => $cache_dir['path'] . $post_id . $suffix . '.css',
628
+ 'css_url' => $cache_dir['url'] . $post_id . $suffix . '.css',
629
+ 'js' => $cache_dir['path'] . $post_id . $suffix . '.js',
630
+ 'js_url' => $cache_dir['url'] . $post_id . $suffix . '.js'
631
+ );
632
+
633
+ return $info;
634
+ }
635
+
636
+ /**
637
+ * Deletes the CSS and/or JS asset cache for the current post.
638
+ *
639
+ * @since 1.0
640
+ * @param string $type The type of cache to delete. Either all, css or js.
641
+ * @return void
642
+ */
643
  static public function delete_asset_cache($type = 'all')
644
  {
645
+ $info = self::get_asset_info();
646
 
647
+ if(($type == 'css' || $type == 'all') && file_exists($info['css'])) {
648
+ unlink($info['css']);
649
+ }
650
+ if(($type == 'js' || $type == 'all') && file_exists($info['js'])) {
651
+ unlink($info['js']);
652
+ }
653
  }
654
 
655
  /**
656
+ * If no post id is supplied, this method will delete the asset
657
+ * cache for all builder posts. If a post id is supplied it will
658
+ * delete all asset cache (including drafts) for only that post.
659
+ *
660
+ * @since 1.0
661
+ * @param int $post_id
662
+ * @return void
663
+ */
664
  static public function delete_all_asset_cache($post_id = null)
665
  {
666
+ $post_id = $post_id == null ? self::get_post_id() : $post_id;
667
+ $cache_dir = self::get_cache_dir();
668
+
669
+ if($post_id == null) {
670
+
671
+ $css = glob( $cache_dir['path'] . '*.css' );
672
+ $js = glob( $cache_dir['path'] . '*.js' );
673
+
674
+ if ( is_array( $css ) ) {
675
+ array_map( 'unlink', $css );
676
+ }
677
+ if ( is_array( $js ) ) {
678
+ array_map( 'unlink', $js );
679
+ }
680
+ }
681
+ else {
682
+
683
+ $css = $cache_dir['path'] . $post_id . '-layout.css';
684
+ $css_draft = $cache_dir['path'] . $post_id . '-layout-draft.css';
685
+ $css_preview = $cache_dir['path'] . $post_id . '-layout-preview.css';
686
+ $js = $cache_dir['path'] . $post_id . '-layout.js';
687
+ $js_draft = $cache_dir['path'] . $post_id . '-layout-draft.js';
688
+ $js_preview = $cache_dir['path'] . $post_id . '-layout-preview.js';
689
+
690
+ if(file_exists($css)) {
691
+ unlink($css);
692
+ }
693
+ if(file_exists($css_draft)) {
694
+ unlink($css_draft);
695
+ }
696
+ if(file_exists($css_preview)) {
697
+ unlink($css_preview);
698
+ }
699
+ if(file_exists($js)) {
700
+ unlink($js);
701
+ }
702
+ if(file_exists($js_draft)) {
703
+ unlink($js_draft);
704
+ }
705
+ if(file_exists($js_preview)) {
706
+ unlink($js_preview);
707
+ }
708
+ }
709
+ }
710
+
711
+ /**
712
+ * Generates a unique id for a builder node such as a
713
+ * row, column or module.
714
+ *
715
+ * @since 1.0
716
+ * @return string
717
+ */
718
+ static public function generate_node_id()
719
+ {
720
+ $node_id = uniqid();
721
+
722
+ if($node_id == self::$last_generated_node_id) {
723
+ return self::generate_node_id();
724
+ }
725
+
726
+ self::$last_generated_node_id = $node_id;
727
+
728
+ return $node_id;
729
+ }
730
+
731
+ /**
732
+ * Generates new node ids for an array of nodes.
733
+ *
734
+ * @since 1.0
735
+ * @param array $data An array of node data.
736
+ * @return array
737
+ */
738
+ static public function generate_new_node_ids($data)
739
+ {
740
+ $map = array();
741
+ $nodes = array();
742
+
743
+ // Map the new node ids to the old.
744
+ foreach($data as $node_id => $node) {
745
+ $map[$node_id] = self::generate_node_id();
746
+ }
747
+
748
+ // Replace the old node ids.
749
+ foreach($data as $node_id => $node) {
750
+
751
+ $nodes[$map[$node_id]] = $node;
752
+ $nodes[$map[$node_id]]->node = $map[$node_id];
753
+
754
+ if(!empty($node->parent) && isset($map[$node->parent])) {
755
+ $nodes[$map[$node_id]]->parent = $map[$node->parent];
756
+ }
757
+ }
758
+
759
+ return $nodes;
760
+ }
761
+
762
+ /**
763
+ * Returns a single node.
764
+ *
765
+ * @since 1.0
766
+ * @param string $node_id A node id.
767
+ * @param string $status The node status. Either draft or published.
768
+ * @return object
769
+ */
770
  static public function get_node($node_id = null, $status = null)
771
  {
772
+ $data = self::get_layout_data($status);
773
+ $node = $data[$node_id];
774
 
775
+ if(isset($node) && !empty($node->settings)) {
776
+ $node->settings = self::get_node_settings($node);
777
+ }
778
 
779
+ return $node;
780
  }
781
 
782
  /**
783
+ * Returns an array of child nodes for a parent.
784
+ *
785
+ * @since 1.0
786
+ * @param string $parent_id The parent node id.
787
+ * @param string $status The node status. Either draft or published.
788
+ * @return array
789
+ */
790
  static public function get_child_nodes($parent_id, $status = null)
791
  {
792
+ $data = self::get_layout_data($status);
793
+ $nodes = array();
794
 
795
+ foreach($data as $node_id => $node) {
796
 
797
+ if($node->parent == $parent_id) {
798
+ $nodes[$node_id] = $node;
799
+ }
800
+ }
801
 
802
+ return $nodes;
803
  }
804
 
805
  /**
806
+ * Returns an array of nodes.
807
+ *
808
+ * @since 1.0
809
+ * @param string $type The type of nodes to return.
810
+ * @param string $parent_id The parent node id.
811
+ * @param string $status The node status. Either draft or published.
812
+ * @return array
813
+ */
814
  static public function get_nodes($type = null, $parent_id = null, $status = null)
815
  {
816
+ $nodes = array();
817
 
818
+ // Get the layout data.
819
+ if($parent_id == null) {
820
+ $data = self::get_layout_data($status);
821
+ }
822
+ else {
823
+ $data = self::get_child_nodes($parent_id, $status);
824
+ }
825
 
826
+ // Return all nodes?
827
+ if($type == null) {
828
+ $nodes = $data;
829
+ }
830
+ // Return nodes of a certain type.
831
+ else {
832
 
833
+ foreach($data as $node_id => $node) {
834
 
835
+ if($node->type == $type) {
836
+ $nodes[$node_id] = $node;
837
+ }
838
+ }
839
 
840
+ uasort($nodes, array('FLBuilderModel', 'order_nodes'));
841
+ }
842
 
843
+ // Merge default settings.
844
+ foreach($nodes as $node_id => $node) {
845
 
846
+ if(!empty($node->settings)) {
847
+ $nodes[$node_id]->settings = self::get_node_settings($nodes[$node_id]);
848
+ }
849
+ }
850
 
851
+ // Return the nodes.
852
+ return $nodes;
853
  }
854
 
855
  /**
856
+ * Returns node settings that are merged with the
857
+ * default or preview settings.
858
+ *
859
+ * @since 1.0
860
+ * @param object $node A node object.
861
+ * @return object
862
+ */
863
  static public function get_node_settings($node)
864
  {
865
+ $post_data = self::get_post_data();
866
 
867
+ if(isset($post_data['node_preview']) && isset($post_data['node_id']) && $post_data['node_id'] == $node->node) {
868
 
869
+ if(!isset($post_data['node_preview_processed_settings'])) {
870
+ $settings = $post_data['node_preview'];
871
+ $settings = (object)array_merge((array)$node->settings, (array)$settings);
872
+ $settings = self::process_node_settings($node, $settings);
873
+ self::update_post_data('node_preview_processed_settings', $settings);
874
+ }
875
+ else {
876
+ $settings = $post_data['node_preview_processed_settings'];
877
+ }
878
+ }
879
+ else {
880
+ $defaults = self::get_node_defaults($node);
881
+ $settings = (object)array_merge((array)$defaults, (array)$node->settings);
882
+ }
883
 
884
+ return $settings;
885
  }
886
 
887
  /**
888
+ * Returns node settings that have been processed with
889
+ * specific logic based on the type of node.
890
+ *
891
+ * @since 1.0
892
+ * @param object $node A node object.
893
+ * @param object $new_settings The new node settings.
894
+ * @return object
895
+ */
896
  static public function process_node_settings($node, $new_settings)
897
  {
898
+ if($node->type == 'row') {
899
+ $new_settings = self::process_row_settings($node, $new_settings);
900
+ }
901
+ if($node->type == 'column') {
902
+ $new_settings = self::process_col_settings($node, $new_settings);
903
+ }
904
+ if($node->type == 'module') {
905
+ $new_settings = self::process_module_settings($node, $new_settings);
906
+ }
907
 
908
+ return $new_settings;
909
  }
910
 
911
  /**
912
+ * Returns the default settings for a node.
913
+ *
914
+ * @since 1.0
915
+ * @param object $node A node object.
916
+ * @return object
917
+ */
918
  static public function get_node_defaults($node)
919
  {
920
+ $defaults = array();
921
 
922
+ if($node->type == 'row') {
923
+ $defaults = self::get_row_defaults();
924
+ }
925
+ else if($node->type == 'column') {
926
+ $defaults = self::get_col_defaults();
927
+ }
928
+ else if($node->type == 'module') {
929
+ $defaults = self::get_module_defaults($node->settings->type);
930
+ }
931
 
932
+ return $defaults;
933
  }
934
 
935
  /**
936
+ * Callback for the uasort function.
937
+ *
938
+ * @since 1.0
939
+ * @param int $a The first position.
940
+ * @param int $b The second position.
941
+ * @return int
942
+ */
943
  static public function order_nodes($a, $b)
944
  {
945
+ return (int)$a->position - (int)$b->position;
946
  }
947
 
948
  /**
949
+ * Counts the number of nodes in a parent.
950
+ *
951
+ * @since 1.0
952
+ * @param string $type The type of nodes to count.
953
+ * @param string $parent_id The parent node id.
954
+ * @return int
955
+ */
956
  static public function count_nodes($type = 'row', $parent_id = null)
957
  {
958
+ return count(self::get_nodes($type, $parent_id));
959
  }
960
 
961
  /**
962
+ * Returns the index of the next available
963
+ * position in a parent node.
964
+ *
965
+ * @since 1.0
966
+ * @param string $type The type of nodes to count.
967
+ * @param string $parent_id The parent node id.
968
+ * @return int
969
+ */
970
  static public function next_node_position($type = 'row', $parent_id = null)
971
  {
972
+ $nodes = self::get_nodes($type, $parent_id);
973
+ $last = array_pop($nodes);
974
+
975
+ return $last ? $last->position + 1 : 0;
976
  }
977
 
978
+ /**
979
+ * Deletes a node.
980
+ *
981
+ * @since 1.0
982
+ * @param string $node_id The ID of the node to delete.
983
+ * @return void
984
+ */
985
+ static public function delete_node($node_id = null)
986
+ {
987
+ // Get the post data.
988
+ $post_data = self::get_post_data();
989
 
990
+ // Get the layout data.
991
+ $data = self::get_layout_data();
992
 
993
+ // Get the node id.
994
+ if(!$node_id && isset($post_data['node_id'])) {
995
+ $node_id = $post_data['node_id'];
996
+ }
997
 
998
+ // Return if the node doesn't exist.
999
+ if(!isset($data[$node_id])) {
1000
+ return;
1001
+ }
1002
 
1003
+ // Get the node.
1004
+ $node = $data[$node_id];
1005
 
1006
+ // Call the delete method if we're deleting a module.
1007
+ self::call_module_delete($node);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1008
 
1009
+ // Delete the node.
1010
+ unset($data[$node_id]);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1011
 
1012
+ // Update the layout data.
1013
+ self::update_layout_data($data);
 
 
 
 
1014
 
1015
+ // Reorder existing nodes.
1016
+ self::reorder_nodes($node->type, $node->parent);
1017
 
1018
+ // Delete the node's children.
1019
+ self::delete_child_nodes($node_id);
1020
+ }
 
 
 
 
1021
 
1022
+ /**
1023
+ * Deletes all child nodes for a parent.
1024
+ *
1025
+ * @since 1.0
1026
+ * @param string $parent_id The parent node ID.
1027
+ * @return void
1028
+ */
1029
+ static public function delete_child_nodes($parent_id = null)
1030
+ {
1031
+ $children = self::get_nodes(null, $parent_id);
1032
+
1033
+ foreach($children as $child) {
1034
+ self::delete_node($child->node);
1035
+ }
1036
+ }
1037
+
1038
+ /**
1039
+ * Calls the delete method for a node
1040
+ * that is a module.
1041
+ *
1042
+ * @since 1.0
1043
+ * @param object $node A module node.
1044
+ * @return void
1045
+ */
1046
+ static public function call_module_delete($node)
1047
+ {
1048
+ if($node->type == 'module' && isset(self::$modules[$node->settings->type])) {
1049
+ $class = get_class(self::$modules[$node->settings->type]);
1050
+ $instance = new $class();
1051
+ $instance->settings = $node->settings;
1052
+ $instance->delete();
1053
+ }
1054
+ }
1055
+
1056
+ /**
1057
+ * Repositions a node within a parent.
1058
+ *
1059
+ * @since 1.0
1060
+ * @param string $node_id A node ID.
1061
+ * @param int $position The new position.
1062
+ * @return void
1063
+ */
1064
+ static public function reorder_node($node_id = null, $position = 0)
1065
+ {
1066
+ $post_data = self::get_post_data();
1067
+ $data = self::get_layout_data();
1068
+ $node_id = $node_id != null ? $node_id : $post_data['node_id'];
1069
+ $node = $data[$node_id];
1070
+ $nodes = self::get_nodes($node->type, $node->parent);
1071
+ $position = isset($post_data['position']) ? (int)$post_data['position'] : $position;
1072
+ $new_pos = 0;
1073
+
1074
+ // Make sure node positions start at zero.
1075
+ foreach($nodes as $node) {
1076
+ $data[$node->node]->position = $new_pos;
1077
+ $new_pos++;
1078
+ }
1079
+
1080
+ // Get the node and remove it from the array.
1081
+ $node = $data[$node_id];
1082
+ $removed = array_splice($nodes, $node->position, 1);
1083
+ $new_pos = 0;
1084
+
1085
+ // Reposition it in the array.
1086
+ array_splice($nodes, $position, 0, $removed);
1087
+
1088
+ // Update the position data.
1089
+ foreach($nodes as $node) {
1090
+ $data[$node->node]->position = $new_pos;
1091
+ $new_pos++;
1092
+ }
1093
+
1094
+ // Update the layout data.
1095
+ self::update_layout_data($data);
1096
+ }
1097
+
1098
+ /**
1099
+ * Repositions all nodes within a parent.
1100
+ *
1101
+ * @since 1.0
1102
+ * @param string $type The type of nodes.
1103
+ * @param string $parent_id The parent ID.
1104
+ * @return void
1105
+ */
1106
+ static public function reorder_nodes($type = 'row', $parent_id = null)
1107
+ {
1108
+ $data = self::get_layout_data();
1109
+ $nodes = self::get_nodes($type, $parent_id);
1110
+ $pos = 0;
1111
+
1112
+ foreach($nodes as $node_id => $node) {
1113
+ $data[$node_id]->position = $pos;
1114
+ $pos++;
1115
+ }
1116
+
1117
+ self::update_layout_data($data);
1118
+ }
1119
+
1120
+ /**
1121
+ * Moves a node to another parent.
1122
+ *
1123
+ * @since 1.0
1124
+ * @param string $node_id ID of the node to move.
1125
+ * @param int $new_parent_id ID of the new parent.
1126
+ * @param int $position The position in the new parent.
1127
+ * @return void
1128
+ */
1129
+ static public function move_node($node_id = null, $new_parent_id = null, $position = 0)
1130
+ {
1131
+ $post_data = self::get_post_data();
1132
+ $data = self::get_layout_data();
1133
+ $node_id = isset($post_data['node_id']) ? $post_data['node_id'] : $node_id;
1134
+ $new_parent_id = isset($post_data['new_parent']) ? $post_data['new_parent'] : $new_parent_id;
1135
+ $position = isset($post_data['position']) ? $post_data['position'] : $position;
1136
+ $new_parent = self::get_node($new_parent_id);
1137
+ $node = self::get_node($node_id);
1138
+
1139
+ // Set the node's new parent.
1140
+ $data[$node_id]->parent = $new_parent->node;
1141
+
1142
+ // Update the layout data.
1143
+ self::update_layout_data($data);
1144
+
1145
+ // Set the node's new order.
1146
+ self::reorder_node($node_id, $position);
1147
+ }
1148
+
1149
+ /**
1150
+ * Adds a row to the current layout.
1151
+ *
1152
+ * @since 1.0
1153
+ * @param string $cols The type of column layout to use.
1154
+ * @param int $position The position of the new row.
1155
+ * @return object The new row object.
1156
+ */
1157
+ static public function add_row($cols = '1-col', $position = false)
1158
+ {
1159
+ $post_data = self::get_post_data();
1160
+ $data = self::get_layout_data();
1161
+ $cols = isset($post_data['cols']) ? $post_data['cols'] : $cols;
1162
+ $position = isset($post_data['position']) ? (int)$post_data['position'] : $position;
1163
+ $settings = self::get_row_defaults();
1164
+ $row_node_id = self::generate_node_id();
1165
+
1166
+ // Add the row.
1167
+ $data[$row_node_id] = new StdClass();
1168
+ $data[$row_node_id]->node = $row_node_id;
1169
+ $data[$row_node_id]->type = 'row';
1170
+ $data[$row_node_id]->parent = null;
1171
+ $data[$row_node_id]->position = self::next_node_position('row');
1172
+ $data[$row_node_id]->settings = $settings;
1173
+
1174
+ // Update the layout data.
1175
+ self::update_layout_data($data);
1176
+
1177
+ // Position the row.
1178
+ if($position !== false) {
1179
+ self::reorder_node($row_node_id, $position);
1180
+ }
1181
+
1182
+ // Add a column group.
1183
+ self::add_col_group($row_node_id, $cols, 0);
1184
+
1185
+ // Return the updated row.
1186
+ return self::get_node($row_node_id);
1187
+ }
1188
+
1189
+ /**
1190
+ * Copys a row and adds it to the current layout.
1191
+ *
1192
+ * @since 1.0
1193
+ * @param string $node_id Node ID of the row to copy.
1194
+ * @return void
1195
+ */
1196
+ static public function copy_row($node_id = null)
1197
+ {
1198
+ $post_data = self::get_post_data();
1199
+ $node_id = isset($post_data['node_id']) ? $post_data['node_id'] : $node_id;
1200
+ $layout_data = self::get_layout_data();
1201
+ $row = self::get_node($node_id);
1202
+ $new_row_id = self::generate_node_id();
1203
+ $col_groups = self::get_child_nodes($node_id);
1204
+ $new_nodes = array();
1205
+
1206
+ // Add the new row.
1207
+ $layout_data[$new_row_id] = clone $row;
1208
+ $layout_data[$new_row_id]->settings = clone $row->settings;
1209
+ $layout_data[$new_row_id]->node = $new_row_id;
1210
+
1211
+ // Get the new child nodes.
1212
+ foreach($col_groups as $col_group_id => $col_group) {
1213
+
1214
+ $new_nodes[$col_group_id] = clone $col_group;
1215
+ $cols = self::get_child_nodes($col_group_id);
1216
+
1217
+ foreach($cols as $col_id => $col) {
1218
+
1219
+ $new_nodes[$col_id] = clone $col;
1220
+ $new_nodes[$col_id]->settings = clone $col->settings;
1221
+ $modules = self::get_child_nodes($col_id);
1222
+
1223
+ foreach($modules as $module_id => $module) {
1224
+ $new_nodes[$module_id] = clone $module;
1225
+ $new_nodes[$module_id]->settings = clone $module->settings;
1226
+ }
1227
+ }
1228
+ }
1229
+
1230
+ // Generate new child ids.
1231
+ $new_nodes = self::generate_new_node_ids($new_nodes);
1232
+
1233
+ // Set col group parent ids to the new row id.
1234
+ foreach($new_nodes as $child_node_id => $child) {
1235
+ if($child->type == 'column-group') {
1236
+ $new_nodes[$child_node_id]->parent = $new_row_id;
1237
+ }
1238
+ }
1239
+
1240
+ // Merge the child data.
1241
+ $layout_data = array_merge($layout_data, $new_nodes);
1242
+
1243
+ // Update the layout data.
1244
+ self::update_layout_data($layout_data);
1245
+
1246
+ // Position the new row.
1247
+ self::reorder_node($new_row_id, $row->position + 1);
1248
+ }
1249
+
1250
+ /**
1251
+ * Returns the default settings for row nodes.
1252
+ *
1253
+ * @since 1.0
1254
+ * @return object
1255
+ */
1256
+ static public function get_row_defaults()
1257
+ {
1258
+ return self::get_settings_form_defaults( 'row' );
1259
+ }
1260
+
1261
+ /**
1262
+ * Runs row specific logic on new row settings.
1263
+ *
1264
+ * @since 1.0
1265
+ * @param object $row A row node.
1266
+ * @param object $new_settings The new settings object.
1267
+ * @return object
1268
+ */
1269
+ static public function process_row_settings($row, $new_settings)
1270
+ {
1271
+ // Cache background video data.
1272
+ if($new_settings->bg_type == 'video') {
1273
+
1274
+ // Video
1275
+ $video = FLBuilderPhoto::get_attachment_data($new_settings->bg_video);
1276
+
1277
+ if($video) {
1278
+
1279
+ $parts = explode('.', $video->filename);
1280
+ $video->extension = array_pop($parts);
1281
+ $new_settings->bg_video_data = $video;
1282
+
1283
+ // Fallback
1284
+ if(!empty($new_settings->bg_video_fallback_src)) {
1285
+ $new_settings->bg_video_data->fallback = $new_settings->bg_video_fallback_src;
1286
+ }
1287
+ else {
1288
+ $new_settings->bg_video_data->fallback = '';
1289
+ }
1290
+ }
1291
+ }
1292
+
1293
+ // Cache background slideshow data.
1294
+ if($new_settings->bg_type == 'slideshow' && $new_settings->ss_source == 'wordpress') {
1295
+
1296
+ // Make sure we have a photo data object.
1297
+ if(!isset($row->settings->ss_photo_data)) {
1298
+ $row->settings->ss_photo_data = new StdClass();
1299
+ }
1300
+
1301
+ // Hijack the slideshow module to get WordPress photo data.
1302
+ $ss = new FLSlideshowModule();
1303
+ $ss->settings = new StdClass();
1304
+ $ss->settings->photos = $new_settings->ss_photos;
1305
+ $ss->settings->photo_data = $row->settings->ss_photo_data;
1306
+ $new_settings->ss_photo_data = $ss->get_wordpress_photos();
1307
+ }
1308
+
1309
+ return $new_settings;
1310
+ }
1311
+
1312
+ /**
1313
+ * Returns background data for a row.
1314
+ *
1315
+ * @since 1.0
1316
+ * @param object $row A row node.
1317
+ * @return object
1318
+ */
1319
+ static public function get_row_bg_data($row)
1320
+ {
1321
+ $data = null;
1322
+
1323
+ // Background Video
1324
+ if($row->settings->bg_type == 'video' && isset($row->settings->bg_video_data)) {
1325
+ $data = $row->settings->bg_video_data;
1326
+ }
1327
+
1328
+ // Background Slideshow
1329
+ else if($row->settings->bg_type == 'slideshow' && isset($row->settings->ss_photo_data)) {
1330
+ $data = $row->settings->ss_photo_data;
1331
+ }
1332
+
1333
+ return $data;
1334
+ }
1335
+
1336
+ /**
1337
+ * Returns the source for a row background slideshow.
1338
+ *
1339
+ * @since 1.0
1340
+ * @param object $row A row node.
1341
+ * @return string
1342
+ */
1343
+ static public function get_row_slideshow_source($row)
1344
+ {
1345
+ // Make sure we have a photo data object.
1346
+ if(!isset($row->settings->ss_photo_data)) {
1347
+ $row->settings->ss_photo_data = new StdClass();
1348
+ }
1349
+
1350
+ // Hijack the slideshow module to get the source.
1351
+ $ss = new FLSlideshowModule();
1352
+ $ss->settings = new StdClass();
1353
+ $ss->settings->source = $row->settings->ss_source;
1354
+ $ss->settings->photos = $row->settings->ss_photos;
1355
+ $ss->settings->feed_url = $row->settings->ss_feed_url;
1356
+ $ss->settings->photo_data = $row->settings->ss_photo_data;
1357
+
1358
+ // Return the slideshow source.
1359
+ return $ss->get_source();
1360
+ }
1361
+
1362
+ /**
1363
+ * Adds a column group to a row in the current layout.
1364
+ *
1365
+ * @since 1.0
1366
+ * @param string $node_id A row node ID.
1367
+ * @param string $cols The type of column group layout.
1368
+ * @param int $position The position of the new column group.
1369
+ * @return object The new column group object.
1370
+ */
1371
+ static public function add_col_group($node_id = null, $cols = '1-col', $position = false)
1372
+ {
1373
+ $post_data = self::get_post_data();
1374
+ $data = self::get_layout_data();
1375
+ $node_id = isset($post_data['node_id']) ? $post_data['node_id'] : $node_id;
1376
+ $cols = isset($post_data['cols']) ? $post_data['cols'] : $cols;
1377
+ $position = isset($post_data['position']) ? (int)$post_data['position'] : $position;
1378
+ $group_node_id = self::generate_node_id();
1379
+
1380
+ // Add the column group.
1381
+ $data[$group_node_id] = new StdClass();
1382
+ $data[$group_node_id]->node = $group_node_id;
1383
+ $data[$group_node_id]->type = 'column-group';
1384
+ $data[$group_node_id]->parent = $node_id;
1385
+ $data[$group_node_id]->position = self::next_node_position('column-group', $node_id);
1386
+ $data[$group_node_id]->settings = '';
1387
+
1388
+ // Add the columns.
1389
+ for($i = 0; $i < count(self::$row_layouts[$cols]); $i++) {
1390
+
1391
+ $col_node_id = self::generate_node_id();
1392
+ $data[$col_node_id] = new StdClass();
1393
+ $data[$col_node_id]->node = $col_node_id;
1394
+ $data[$col_node_id]->type = 'column';
1395
+ $data[$col_node_id]->parent = $group_node_id;
1396
+ $data[$col_node_id]->position = $i;
1397
+ $data[$col_node_id]->settings = new StdClass();
1398
+ $data[$col_node_id]->settings->size = self::$row_layouts[$cols][$i];
1399
+ }
1400
+
1401
+ // Update the layout data.
1402
+ self::update_layout_data($data);
1403
+
1404
+ // Position the column group.
1405
+ if($position !== false) {
1406
+ self::reorder_node($group_node_id, $position);
1407
+ }
1408
+
1409
+ // Return the column group.
1410
+ return self::get_node($group_node_id);
1411
+ }
1412
+
1413
+ /**
1414
+ * Runs column specific logic on new column settings.
1415
+ *
1416
+ * @since 1.0
1417
+ * @param object $col A column node.
1418
+ * @param object $new_settings The new settings object.
1419
+ * @return object
1420
+ */
1421
+ static public function process_col_settings($col, $new_settings)
1422
+ {
1423
+ $new_settings->size = self::resize_col($col->node, $new_settings->size);
1424
+
1425
+ return $new_settings;
1426
+ }
1427
+
1428
+ /**
1429
+ * Deletes a column.
1430
+ *
1431
+ * @since 1.0
1432
+ * @param string $node_id Node ID of the column to delete.
1433
+ * @param int $new_width New width of the remaining columns.
1434
+ * @return void
1435
+ */
1436
+ static public function delete_col($node_id = null, $new_width = 100)
1437
+ {
1438
+ $post_data = self::get_post_data();
1439
+ $node_id = isset($post_data['node_id']) ? $post_data['node_id'] : $node_id;
1440
+ $new_width = isset($post_data['new_width']) ? $post_data['new_width'] : $new_width;
1441
+ $col = self::get_node($node_id);
1442
+
1443
+ // Delete the column.
1444
+ self::delete_node($node_id);
1445
+
1446
+ // Get the group
1447
+ $group = self::get_node($col->parent);
1448
+
1449
+ // Get the group children.
1450
+ $cols = self::get_nodes('column', $group->node);
1451
+
1452
+ // Delete the group if empty.
1453
+ if(count($cols) === 0) {
1454
+ self::delete_node($group->node);
1455
+ }
1456
+
1457
+ // Resize the remaining columns.
1458
+ else {
1459
+
1460
+ // Get the layout data.
1461
+ $data = self::get_layout_data();
1462
+
1463
+ // Loop through the columns.
1464
+ foreach($cols as $col_id => $col) {
1465
+
1466
+ // Set the new size.
1467
+ $data[$col_id]->settings->size = round($new_width, 2);
1468
+ }
1469
+
1470
+ // Update the layout data.
1471
+ self::update_layout_data($data);
1472
+ }
1473
+ }
1474
+
1475
+ /**
1476
+ * Resizes a column.
1477
+ *
1478
+ * @since 1.0
1479
+ * @param string $node_id Node ID of the column to resize.
1480
+ * @param int $new_width New width of the column.
1481
+ * @return int The new width
1482
+ */
1483
+ static public function resize_col($node_id = null, $new_width = 100)
1484
+ {
1485
+ $data = self::get_layout_data();
1486
+ $col = $data[$node_id];
1487
+ $group = $data[$col->parent];
1488
+ $cols = array_values(self::get_nodes('column', $group->node));
1489
+ $pos = $col->position;
1490
+ $siblings = array();
1491
+ $siblings_width = 0;
1492
+ $num_cols = count($cols);
1493
+ $min_width = 10;
1494
+ $max_width = 100 - $min_width;
1495
+
1496
+ // Don't resize if only one column or width isn't a number.
1497
+ if($num_cols == 1 || !is_numeric($new_width)) {
1498
+ return $col->settings->size;
1499
+ }
1500
+
1501
+ // Find the sibling column to absorb this resize.
1502
+ if($pos === 0) {
1503
+ $sibling = $cols[1];
1504
+ }
1505
+ else if($pos == $num_cols - 1) {
1506
+ $sibling = $cols[$num_cols - 2];
1507
+ }
1508
+ else {
1509
+ $sibling = $cols[$pos + 1];
1510
+ }
1511
+
1512
+ // Find other siblings.
1513
+ foreach($cols as $c) {
1514
+
1515
+ if($col->node == $c->node) {
1516
+ continue;
1517
+ }
1518
+ if($sibling->node == $c->node) {
1519
+ continue;
1520
+ }
1521
+
1522
+ $siblings[] = $c;
1523
+ $max_width -= $c->settings->size;
1524
+ $siblings_width += $c->settings->size;
1525
+ }
1526
+
1527
+ // Make sure the new width isn't too small.
1528
+ if($new_width < $min_width) {
1529
+ $new_width = $min_width;
1530
+ }
1531
+
1532
+ // Make sure the new width isn't too big.
1533
+ if($new_width > $max_width) {
1534
+ $new_width = $max_width;
1535
+ }
1536
+
1537
+ // Save new sibling size.
1538
+ $data[$sibling->node]->settings->size = round(100 - $siblings_width - $new_width, 2);
1539
+
1540
+ // Save new column size.
1541
+ $data[$col->node]->settings->size = $new_width;
1542
+
1543
+ // Update the layout data.
1544
+ self::update_layout_data($data);
1545
+
1546
+ // Return the new size.
1547
+ return $new_width;
1548
+ }
1549
+
1550
+ /**
1551
+ * Returns the default settings for column nodes.
1552
+ *
1553
+ * @since 1.0
1554
+ * @return object
1555
+ */
1556
+ static public function get_col_defaults()
1557
+ {
1558
+ return self::get_settings_form_defaults( 'col' );
1559
+ }
1560
+
1561
+ /**
1562
+ * Loads the classes for core builder modules.
1563
+ *
1564
+ * @since 1.0
1565
+ * @return void
1566
+ */
1567
+ static public function load_modules()
1568
+ {
1569
+ $path = FL_BUILDER_DIR . 'modules/';
1570
+ $dir = dir($path);
1571
+ $module_path = '';
1572
+
1573
+ while(false !== ($entry = $dir->read())) {
1574
+
1575
+ if(!is_dir($path . $entry) || $entry == '.' || $entry == '..') {
1576
+ continue;
1577
+ }
1578
+
1579
+ // Paths to check.
1580
+ $module_path = $entry . '/' . $entry . '.php';
1581
+ $child_path = get_stylesheet_directory() . '/fl-builder/modules/' . $module_path;
1582
+ $theme_path = get_template_directory() . '/fl-builder/modules/' . $module_path;
1583
+ $builder_path = FL_BUILDER_DIR . 'modules/' . $module_path;
1584
+
1585
+ // Check for the module class in a child theme.
1586
+ if(is_child_theme() && file_exists($child_path)) {
1587
+ require_once $child_path;
1588
+ }
1589
+
1590
+ // Check for the module class in a parent theme.
1591
+ else if(file_exists($theme_path)) {
1592
+ require_once $theme_path;
1593
+ }
1594
+
1595
+ // Check for the module class in the builder directory.
1596
+ else if(file_exists($builder_path)) {
1597
+ require_once $builder_path;
1598
+ }
1599
+ }
1600
+ }
1601
+
1602
+ /**
1603
+ * Registers a module with the builder.
1604
+ *
1605
+ * @since 1.0
1606
+ * @param string $class The module's PHP class name.
1607
+ * @param array $form The module's settings form.
1608
+ * @return void
1609
+ */
1610
+ static public function register_module($class, $form)
1611
+ {
1612
+ if(class_exists($class)) {
1613
+
1614
+ // Create a new instance of the module.
1615
+ $instance = new $class();
1616
+
1617
+ // Log an error if a module with this slug already exists.
1618
+ if ( isset( self::$modules[ $instance->slug ] ) ) {
1619
+ error_log( sprintf( _x( 'A module with the filename %s.php already exists! Please namespace your module filenames to ensure compatibility with Beaver Builder.', '%s stands for the module filename', 'fl-builder' ), $instance->slug ) );
1620
+ return;
1621
+ }
1622
+
1623
+ // See if the module is enabled or not.
1624
+ $enabled = apply_filters( 'fl_builder_register_module', $instance->enabled, $instance );
1625
+
1626
+ // Only register modules that are enabled.
1627
+ if( $enabled ) {
1628
+
1629
+ // Save the instance in the modules array.
1630
+ self::$modules[$instance->slug] = $instance;
1631
+
1632
+ // Add the form to the instance.
1633
+ self::$modules[$instance->slug]->form = $form;
1634
+ self::$modules[$instance->slug]->form['advanced'] = self::$settings_forms['module_advanced'];
1635
+ }
1636
+ }
1637
+ }
1638
+
1639
+ /**
1640
+ * Returns an array of all modules that are enabled.
1641
+ *
1642
+ * @since 1.0
1643
+ * @return array
1644
+ */
1645
+ static public function get_enabled_modules()
1646
+ {
1647
+ $key = '_fl_builder_enabled_modules';
1648
+ $default = array_keys(self::$modules);
1649
+ $default[] = 'all';
1650
+
1651
+ // Get the value.
1652
+ if(is_network_admin()) {
1653
+ $value = get_site_option($key);
1654
+ }
1655
+ else if(class_exists('FLBuilderMultisiteSettings')) {
1656
+ $value = get_option($key);
1657
+ $value = !$value ? get_site_option($key) : $value;
1658
+ }
1659
+ else {
1660
+ $value = get_option($key);
1661
+ }
1662
+
1663
+ // Return the value.
1664
+ if(!$value || in_array('all', $value)) {
1665
+ return $default;
1666
+ }
1667
+ else {
1668
+ return $value;
1669
+ }
1670
+ }
1671
+
1672
+ /**
1673
+ * Returns an array of categorized modules.
1674
+ *
1675
+ * @since 1.0
1676
+ * @param bool $show_disabled Whether to include disabled modules in the result.
1677
+ * @return array
1678
+ */
1679
+ static public function get_categorized_modules( $show_disabled = false )
1680
+ {
1681
+ $enabled_modules = self::get_enabled_modules();
1682
+
1683
+ // Get the core category keys.
1684
+ $basic_key = __('Basic Modules', 'fl-builder');
1685
+ $advanced_key = __('Advanced Modules', 'fl-builder');
1686
+ $other_key = __('Other Modules', 'fl-builder');
1687
+ $widgets_key = __('WordPress Widgets', 'fl-builder');
1688
+
1689
+ // Build the default category arrays.
1690
+ $categories = array();
1691
+ $categories[ $basic_key ] = array();
1692
+ $categories[ $advanced_key ] = array();
1693
+ $categories[ $other_key ] = array();
1694
+ $categories[ $widgets_key ] = array();
1695
+
1696
+ // Build the categories array.
1697
+ foreach(self::$modules as $module) {
1698
+
1699
+ if(!in_array($module->slug, $enabled_modules) && !$show_disabled) {
1700
+ continue;
1701
+ }
1702
+ else if($module->slug == 'widget') {
1703
+ $categories[$widgets_key] = self::get_wp_widgets();
1704
+ }
1705
+ else if(isset($module->category)) {
1706
+
1707
+ if(!isset($categories[$module->category])) {
1708
+ $categories[$module->category] = array();
1709
+ }
1710
+
1711
+ $categories[$module->category][$module->name] = $module;
1712
+ }
1713
+ else {
1714
+ $categories[$other_key][$module->name] = $module;
1715
+ }
1716
+ }
1717
 
1718
  // Sort the modules.
1719
  foreach($categories as $title => $modules) {
1727
 
1728
  // Return sorted categories.
1729
  return $categories;
1730
+ }
1731
+
1732
+ /**
1733
+ * Returns the slug for a module category.
1734
+ *
1735
+ * @since 1.0
1736
+ * @param string $name The category name.
1737
+ * @return string
1738
+ */
1739
+ static public function get_module_category_slug( $name )
1740
+ {
1741
+ // Get the core category keys.
1742
+ $basic_key = __('Basic Modules', 'fl-builder');
1743
+ $advanced_key = __('Advanced Modules', 'fl-builder');
1744
+ $other_key = __('Other Modules', 'fl-builder');
1745
+ $widgets_key = __('WordPress Widgets', 'fl-builder');
1746
+
1747
+ if ( $name == $basic_key ) {
1748
+ return 'basic';
1749
+ }
1750
+ if ( $name == $advanced_key ) {
1751
+ return 'advanced';
1752
+ }
1753
+ if ( $name == $other_key ) {
1754
+ return 'other';
1755
+ }
1756
+ if ( $name == $widgets_key ) {
1757
+ return 'widgets';
1758
+ }
1759
+
1760
+ return sanitize_html_class( $name );
1761
+ }
1762
+
1763
+ /**
1764
+ * Returns an instance of a module.
1765
+ *
1766
+ * @since 1.0
1767
+ * @param string $node_id A module node ID.
1768
+ * @return object|bool The module or false if it doesn't exist.
1769
+ */
1770
+ static public function get_module($node_id)
1771
+ {
1772
+ $module = self::get_node($node_id);
1773
+
1774
+ if(isset(self::$modules[$module->settings->type])) {
1775
+
1776
+ $class = get_class(self::$modules[$module->settings->type]);
1777
+ $instance = new $class();
1778
+ $instance->node = $module->node;
1779
+ $instance->parent = $module->parent;
1780
+ $instance->position = $module->position;
1781
+ $instance->settings = $module->settings;
1782
+ $instance->type = 'module';
1783
+ $instance->form = self::$modules[$module->settings->type]->form;
1784
+
1785
+ return $instance;
1786
+ }
1787
+
1788
+ return false;
1789
+ }
1790
+
1791
+ /**
1792
+ * Returns an array of all modules in the current layout
1793
+ * or in a column if a column id is supplied.
1794
+ *
1795
+ * @since 1.0
1796
+ * @param int $col_id A column node ID.
1797
+ * @return array
1798
+ */
1799
+ static public function get_modules($col_id = null)
1800
+ {
1801
+ $modules = self::get_nodes('module', $col_id);
1802
+ $instances = array();
1803
+ $i = 0;
1804
+
1805
+ foreach($modules as $module) {
1806
+
1807
+ if(isset(self::$modules[$module->settings->type])) {
1808
+
1809
+ $class = get_class(self::$modules[$module->settings->type]);
1810
+ $instances[$i] = new $class();
1811
+ $instances[$i]->node = $module->node;
1812
+ $instances[$i]->parent = $module->parent;
1813
+ $instances[$i]->position = $module->position;
1814
+ $instances[$i]->settings = $module->settings;
1815
+ $instances[$i]->type = 'module';
1816
+ $instances[$i]->form = self::$modules[$module->settings->type]->form;
1817
+ $i++;
1818
+ }
1819
+ }
1820
+
1821
+ return $instances;
1822
+ }
1823
+
1824
+ /**
1825
+ * Returns an array of all modules in the current layout.
1826
+ *
1827
+ * @since 1.0
1828
+ * @return array
1829
+ */
1830
+ static public function get_all_modules()
1831
+ {
1832
+ return self::get_modules();
1833
+ }
1834
+
1835
+ /**
1836
+ * Add a new module to a column in the current layout.
1837
+ *
1838
+ * @since 1.0
1839
+ * @param string $type The type of module to add.
1840
+ * @param array $settings The new module's settings.
1841
+ * @param string $parent_id The new module's parent node ID.
1842
+ * @param int $position The new module's position.
1843
+ * @return object The new module object.
1844
+ */
1845
+ static public function add_module($type = null, $settings = array(), $parent_id = null, $position = false)
1846
+ {
1847
+ $post_data = self::get_post_data();
1848
+ $data = self::get_layout_data();
1849
+ $type = isset($post_data['type']) ? $post_data['type'] : $type;
1850
+ $settings = isset($post_data['settings']) ? $post_data['settings'] : $settings;
1851
+ $parent_id = isset($post_data['parent_id']) ? $post_data['parent_id'] : $parent_id;
1852
+ $position = isset($post_data['position']) ? (int)$post_data['position'] : $position;
1853
+ $module_node_id = self::generate_node_id();
1854
+ $settings->type = $type;
1855
+
1856
+ // Run module update method.
1857
+ $class = get_class(self::$modules[$type]);
1858
+ $instance = new $class();
1859
+ $instance->settings = $settings;
1860
+ $settings = $instance->update($settings);
1861
+
1862
+ // Save the module.
1863
+ $data[$module_node_id] = new StdClass();
1864
+ $data[$module_node_id]->node = $module_node_id;
1865
+ $data[$module_node_id]->type = 'module';
1866
+ $data[$module_node_id]->parent = $parent_id;
1867
+ $data[$module_node_id]->position = self::next_node_position('module', $parent_id);
1868
+ $data[$module_node_id]->settings = $settings;
1869
+
1870
+ // Update the layout data.
1871
+ self::update_layout_data($data);
1872
+
1873
+ // Position the module.
1874
+ if($position !== false) {
1875
+ self::reorder_node($module_node_id, $position);
1876
+ }
1877
+
1878
+ // Send back the inserted module.
1879
+ return self::get_module($module_node_id);
1880
+ }
1881
+
1882
+ /**
1883
+ * Add a new module with default settings to a column
1884
+ * in the current layout.
1885
+ *
1886
+ * @since 1.0
1887
+ * @param string $parent_id The new module's parent node ID.
1888
+ * @param string $type The type of module to add.
1889
+ * @param int $position The new module's position.
1890
+ * @return object The new module object.
1891
+ */
1892
+ static public function add_default_module($parent_id = null, $type = null, $position = false)
1893
+ {
1894
+ $post_data = self::get_post_data();
1895
+ $parent_id = isset($post_data['parent_id']) ? $post_data['parent_id'] : $parent_id;
1896
+ $parent = $parent_id == 0 ? null : self::get_node($parent_id);
1897
+ $type = isset($post_data['type']) ? $post_data['type'] : $type;
1898
+ $position = isset($post_data['position']) ? (int)$post_data['position'] : $position;
1899
+ $settings = self::get_module_defaults($type);
1900
+ $module_node_id = self::generate_node_id();
1901
+
1902
+ // Add a new row if we don't have a parent.
1903
+ if(!$parent) {
1904
+ $row = self::add_row('1-col', $position);
1905
+ $col_groups = self::get_nodes('column-group', $row->node);
1906
+ $col_group = array_shift($col_groups);
1907
+ $cols = self::get_nodes('column', $col_group->node);
1908
+ $parent = array_shift($cols);
1909
+ $parent_id = $parent->node;
1910
+ $position = null;
1911
+ }
1912
+
1913
+ // Add a new column if the parent is a row.
1914
+ else if($parent->type == 'row') {
1915
+ $col_group = self::add_col_group($parent->node, '1-col', $position);
1916
+ $cols = self::get_nodes('column', $col_group->node);
1917
+ $parent = array_shift($cols);
1918
+ $parent_id = $parent->node;
1919
+ $position = null;
1920
+ }
1921
+
1922
+ // Run module update method.
1923
+ $class = get_class(self::$modules[$type]);
1924
+ $instance = new $class();
1925
+ $instance->settings = $settings;
1926
+ $settings = $instance->update($settings);
1927
+
1928
+ // Save the module.
1929
+ $data = self::get_layout_data();
1930
+ $data[$module_node_id] = new StdClass();
1931
+ $data[$module_node_id]->node = $module_node_id;
1932
+ $data[$module_node_id]->type = 'module';
1933
+ $data[$module_node_id]->parent = $parent_id;
1934
+ $data[$module_node_id]->position = self::next_node_position('module', $parent_id);
1935
+ $data[$module_node_id]->settings = $settings;
1936
+
1937
+ // Update the layout data.
1938
+ self::update_layout_data($data);
1939
+
1940
+ // Position the module.
1941
+ if($position !== false) {
1942
+ self::reorder_node($module_node_id, $position);
1943
+ }
1944
+
1945
+ // Send back the inserted module.
1946
+ return self::get_module($module_node_id);
1947
+ }
1948
+
1949
+ /**
1950
+ * Make a copy of a module.
1951
+ *
1952
+ * @since 1.0
1953
+ * @param string $node_id Node ID of the module to copy.
1954
+ * @return object The new module object.
1955
+ */
1956
  static public function copy_module($node_id = null)
1957
  {
1958
+ $post_data = self::get_post_data();
1959
+ $node_id = isset($post_data['node_id']) ? $post_data['node_id'] : $node_id;
1960
+ $module = self::get_module($node_id);
1961
+
1962
+ return self::add_module($module->settings->type, $module->settings, $module->parent, $module->position + 1);
1963
+ }
1964
+
1965
+ /**
1966
+ * Run module specific logic on new node settings.
1967
+ *
1968
+ * @since 1.0
1969
+ * @param object $module A module node object.
1970
+ * @param object $new_settings The new settings.
1971
+ * @return object
1972
+ */
1973
+ static public function process_module_settings($module, $new_settings)
1974
+ {
1975
+ // Get a new node instance to work with.
1976
+ $class = get_class(self::$modules[$module->settings->type]);
1977
+ $instance = new $class();
1978
+
1979
+ // Run node delete to clear any cache.
1980
+ $instance->settings = $module->settings;
1981
+ $instance->delete();
1982
+
1983
+ // Run node update.
1984
+ $instance->settings = $new_settings;
1985
+ $new_settings = $instance->update($new_settings);
1986
+
1987
+ return $new_settings;
1988
+ }
1989
+
1990
+ /**
1991
+ * Returns the default settings for a module.
1992
+ *
1993
+ * @since 1.0
1994
+ * @param string $type The type of module.
1995
+ * @return object
1996
+ */
1997
+ static public function get_module_defaults($type)
1998
+ {
1999
+ $defaults = new StdClass();
2000
+
2001
+ if(isset(self::$modules[$type]->form)) {
2002
+ $defaults = self::get_settings_form_defaults( $type );
2003
+ $defaults->type = $type;
2004
+ }
2005
+
2006
+ return $defaults;
2007
+ }
2008
+
2009
+ /**
2010
+ * Returns an array of data for each core WordPress widget.
2011
+ *
2012
+ * @since 1.0
2013
+ * @return array
2014
+ */
2015
+ static public function get_wp_widgets()
2016
+ {
2017
+ global $wp_widget_factory;
2018
+
2019
+ $widgets = array();
2020
+
2021
+ foreach($wp_widget_factory->widgets as $class => $widget) {
2022
+ $widget->class = $class;
2023
+ $widgets[$widget->name] = $widget;
2024
+ }
2025
+
2026
+ ksort($widgets);
2027
+
2028
+ return $widgets;
2029
+ }
2030
+
2031
+ /**
2032
+ * Returns an array of data for all registered sidebars.
2033
+ *
2034
+ * @since 1.0
2035
+ * @return array
2036
+ */
2037
+ static public function get_wp_sidebars()
2038
+ {
2039
+ global $wp_registered_sidebars;
2040
+
2041
+ $sidebars = array();
2042
+
2043
+ foreach($wp_registered_sidebars as $sidebar) {
2044
+ $sidebars[$sidebar['name']] = $sidebar;
2045
+ }
2046
+
2047
+ ksort($sidebars);
2048
+
2049
+ return $sidebars;
2050
+ }
2051
+
2052
+ /**
2053
+ * Loads the files for all core builder settings.
2054
+ *
2055
+ * @since 1.0
2056
+ * @return void
2057
+ */
2058
+ static public function load_settings()
2059
+ {
2060
+ require_once FL_BUILDER_DIR . 'includes/global-settings.php';
2061
+ require_once FL_BUILDER_DIR . 'includes/row-settings.php';
2062
+ require_once FL_BUILDER_DIR . 'includes/column-settings.php';
2063
+ require_once FL_BUILDER_DIR . 'includes/module-settings.php';
2064
+ require_once FL_BUILDER_DIR . 'includes/user-template-settings.php';
2065
+ }
2066
+
2067
+ /**
2068
+ * Register a settings form with the builder.
2069
+ *
2070
+ * @since 1.0
2071
+ * @param string $id The form id.
2072
+ * @param array $form The form data.
2073
+ * @return void
2074
+ */
2075
+ static public function register_settings_form($id, $form)
2076
+ {
2077
+ self::$settings_forms[$id] = $form;
2078
+ }
2079
+
2080
+ /**
2081
+ * Returns the data for a settings form.
2082
+ *
2083
+ * @since 1.0
2084
+ * @param string $id The form id.
2085
+ * @return array
2086
+ */
2087
+ static public function get_settings_form( $id )
2088
+ {
2089
+ return self::$settings_forms[ $id ];
2090
+ }
2091
+
2092
+ /**
2093
+ * Returns an array of fields in a settings form.
2094
+ *
2095
+ * @since 1.0
2096
+ * @param array $form The form data array.
2097
+ * @return array
2098
+ */
2099
+ static public function get_settings_form_fields($form)
2100
+ {
2101
+ $fields = array();
2102
+
2103
+ foreach ( $form as $tab ) {
2104
+ if ( isset( $tab['sections'] ) ) {
2105
+ foreach ( $tab['sections'] as $section ) {
2106
+ if ( isset( $section['fields'] ) ) {
2107
+ foreach ( $section['fields'] as $name => $field ) {
2108
+ $fields[ $name ] = $field;
2109
+ }
2110
+ }
2111
+ }
2112
+ }
2113
+ }
2114
+
2115
+ return $fields;
2116
+ }
2117
+
2118
+ /**
2119
+ * Returns a settings object with the defaults for a form.
2120
+ *
2121
+ * @since 1.0
2122
+ * @param string $type The type of form.
2123
+ * @return object
2124
+ */
2125
+ static public function get_settings_form_defaults( $type )
2126
+ {
2127
+ // Check to see if the defaults are cached first.
2128
+ if ( isset( self::$settings_form_defaults[ $type ] ) ) {
2129
+ return self::$settings_form_defaults[ $type ];
2130
+ }
2131
+
2132
+ // They aren't cached, let's get them.
2133
+ $defaults = new StdClass();
2134
+
2135
+ // Check the registered forms first.
2136
+ if ( isset( self::$settings_forms[ $type ] ) ) {
2137
+ $form_type = $type;
2138
+ $tabs = self::$settings_forms[ $type ]['tabs'];
2139
+ }
2140
+ // If it's not a registered form, it must be a module form.
2141
+ else if ( isset( self::$modules[ $type ] ) ) {
2142
+ $form_type = $type . '-module';
2143
+ $tabs = self::$modules[ $type ]->form;
2144
+ }
2145
+ // The form can't be found.
2146
+ else {
2147
+ return $defaults;
2148
+ }
2149
+
2150
+ // Loop through the tabs and get the defaults.
2151
+ foreach($tabs as $tab) {
2152
+ if(isset($tab['sections'])) {
2153
+ foreach($tab['sections'] as $section) {
2154
+ if(isset($section['fields'])) {
2155
+ foreach($section['fields'] as $name => $field) {
2156
+
2157
+ $default = isset($field['default']) ? $field['default'] : '';
2158
+ $is_multiple = isset($field['multiple']) && $field['multiple'] === true;
2159
+ $supports_multiple = $field['type'] != 'editor' && $field['type'] != 'photo';
2160
+
2161
+ if($is_multiple && $supports_multiple) {
2162
+ $defaults->$name = array($default);
2163
+ }
2164
+ else {
2165
+ $defaults->$name = $default;
2166
+ }
2167
+ }
2168
+ }
2169
+ }
2170
+ }
2171
+ }
2172
+
2173
+ // Cache the defaults.
2174
+ self::$settings_form_defaults[ $type ] = apply_filters( 'fl_builder_settings_form_defaults', $defaults, $form_type );
2175
+
2176
+ return self::$settings_form_defaults[ $type ];
2177
+ }
2178
+
2179
+ /**
2180
+ * Save the settings for a node.
2181
+ *
2182
+ * @since 1.0
2183
+ * @param string $node_id The node ID.
2184
+ * @param object $settings The settings to save.
2185
+ * @return void
2186
+ */
2187
+ static public function save_settings($node_id = null, $settings = null)
2188
+ {
2189
+ $post_data = self::get_post_data();
2190
+ $node_id = isset($post_data['node_id']) ? $post_data['node_id'] : $node_id;
2191
+ $settings = isset($post_data['settings']) ? $post_data['settings'] : $settings;
2192
+ $node = self::get_node($node_id);
2193
+ $new_settings = (object)array_merge((array)$node->settings, (array)$settings);
2194
+
2195
+ // Process the settings.
2196
+ $new_settings = self::process_node_settings($node, $new_settings);
2197
+
2198
+ // Save the settings to the node.
2199
+ $data = self::get_layout_data();
2200
+ $data[$node_id]->settings = $new_settings;
2201
+
2202
+ // Update the layout data.
2203
+ self::update_layout_data($data);
2204
+
2205
+ // Return the new layout.
2206
+ if(defined('DOING_AJAX')) {
2207
+ FLBuilder::render_css();
2208
+ FLBuilder::render_js();
2209
+ FLBuilder::render_layout();
2210
+ }
2211
+ }
2212
+
2213
+ /**
2214
+ * Adds slashes to settings going into the database as WordPress
2215
+ * removes them when we save using update_metadata. This is done
2216
+ * to ensure slashes in user input aren't removed.
2217
+ *
2218
+ * @since 1.5.6
2219
+ * @param mixed $data The data to slash.
2220
+ * @return mixed The slashed data.
2221
+ */
2222
+ static public function slash_settings( $data )
2223
+ {
2224
+ if ( is_array( $data ) ) {
2225
+ foreach ( $data as $key => $val ) {
2226
+ $data[ $key ] = self::slash_settings( $val );
2227
+ }
2228
+ }
2229
+ else if ( is_object( $data ) ) {
2230
+ foreach ( $data as $key => $val ) {
2231
+ $data->$key = self::slash_settings( $val );
2232
+ }
2233
+ }
2234
+ else if ( is_string( $data ) ) {
2235
+ $data = wp_slash( $data );
2236
+ }
2237
+
2238
+ return $data;
2239
+ }
2240
+
2241
+ /**
2242
+ * Merge defaults into a settings object.
2243
+ *
2244
+ * @since 1.0
2245
+ * @param object $settings Reference to a settings object.
2246
+ * @param array $defaults The defaults to merge in.
2247
+ * @return void
2248
+ */
2249
+ static public function default_settings(&$settings, $defaults)
2250
+ {
2251
+ foreach($defaults as $name => $value) {
2252
+ if(!isset($settings->$name)) {
2253
+ $settings->$name = $value;
2254
+ }
2255
+ }
2256
+ }
2257
+
2258
+ /**
2259
+ * Get the default settings for the global settings form.
2260
+ *
2261
+ * @since 1.0
2262
+ * @return object
2263
+ */
2264
+ static public function get_global_defaults()
2265
+ {
2266
+ return self::get_settings_form_defaults( 'global' );
2267
  }
2268
 
2269
  /**
2270
+ * Get the global builder settings.
2271
+ *
2272
+ * @since 1.0
2273
+ * @return object
2274
+ */
2275
+ static public function get_global_settings()
2276
  {
2277
+ $settings = get_option('_fl_builder_settings');
2278
+ $defaults = self::get_global_defaults();
 
2279
 
2280
+ if(!$settings) {
2281
+ $settings = new StdClass();
2282
+ }
 
 
 
 
2283
 
2284
+ return (object)array_merge((array)$defaults, (array)$settings);
2285
  }
2286
 
2287
+ /**
2288
+ * Save the global builder settings.
2289
+ *
2290
+ * @since 1.0
2291
+ * @param array $settings The new global settings.
2292
+ * @return object
2293
+ */
2294
+ static public function save_global_settings($settings = array())
2295
+ {
2296
+ $post_data = self::get_post_data();
2297
+ $settings = isset($post_data['settings']) ? $post_data['settings'] : $settings;
2298
+ $old_settings = self::get_global_settings();
2299
+ $new_settings = (object)array_merge((array)$old_settings, (array)$settings);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2300
 
2301
+ return update_option('_fl_builder_settings', $settings);
2302
+ }
2303
 
2304
  /**
2305
+ * Duplicate the current post.
2306
+ *
2307
+ * @since 1.0
2308
+ * @return int The new post ID.
2309
+ */
2310
+ static public function duplicate_post()
2311
  {
2312
+ global $wpdb;
2313
+
2314
+ $post_id = self::get_post_id();
2315
+ $post = get_post($post_id);
2316
+ $current_user = wp_get_current_user();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2317
 
2318
  // Duplicate the post.
2319
  $data = array(
2320
  'comment_status' => $post->comment_status,
2321
+ 'ping_status' => $post->ping_status,
2322
+ 'post_author' => $current_user->ID,
2323
+ 'post_content' => $post->post_content,
2324
+ 'post_excerpt' => $post->post_excerpt,
2325
+ 'post_name' => $post->post_name,
2326
+ 'post_parent' => $post->post_parent,
2327
+ 'post_password' => $post->post_password,
2328
+ 'post_status' => 'draft',
2329
+ 'post_title' => sprintf( _x( 'Copy of %s', '%s stands for post/page title.', 'fl-builder' ), $post->post_title ),
2330
+ 'post_type' => $post->post_type,
2331
+ 'to_ping' => $post->to_ping,
2332
+ 'menu_order' => $post->menu_order
2333
  );
2334
 
2335
+ // Get the new post id.
2336
+ $new_post_id = wp_insert_post($data);
2337
 
2338
+ // Duplicate post meta.
2339
+ $post_meta = $wpdb->get_results("SELECT meta_key, meta_value FROM {$wpdb->postmeta} WHERE post_id= {$post_id}");
2340
 
2341
+ if(count($post_meta) !== 0) {
2342
 
2343
+ $sql = "INSERT INTO {$wpdb->postmeta} (post_id, meta_key, meta_value) ";
2344
 
2345
+ foreach($post_meta as $meta_info) {
2346
+ $meta_key = $meta_info->meta_key;
2347
+ $meta_value = addslashes($meta_info->meta_value);
2348
+ $sql_select[] = "SELECT {$new_post_id}, '{$meta_key}', '{$meta_value}'";
2349
+ }
2350
 
2351
+ $sql .= implode(" UNION ALL ", $sql_select);
2352
+ $wpdb->query($sql);
2353
+ }
2354
 
2355
+ // Duplicate post terms.
2356
+ $taxonomies = get_object_taxonomies($post->post_type);
2357
 
2358
  foreach($taxonomies as $taxonomy) {
2359
 
2373
  // Save the duplicated layout data.
2374
  self::update_layout_data($data, 'published', $new_post_id);
2375
 
2376
+ // Return the new post id.
2377
+ return $new_post_id;
2378
+ }
2379
 
2380
  /**
2381
+ * Deletes all layout data and asset cache for a post.
2382
+ *
2383
+ * @since 1.0
2384
+ * @param int $post_id The post ID to delete data and cache for.
2385
+ * @return void
2386
+ */
2387
+ static public function delete_post($post_id)
2388
+ {
2389
+ // Delete all published and draft data.
2390
+ self::delete_layout_data('published', $post_id);
2391
+ self::delete_layout_data('draft', $post_id);
2392
 
2393
+ // Delete all css and js.
2394
+ self::delete_all_asset_cache($post_id);
2395
+ }
2396
 
2397
  /**
2398
+ * Save a revision of a builder layout.
2399
+ *
2400
+ * @since 1.0
2401
+ * @param int $post_id
2402
+ * @return void
2403
+ */
2404
+ static public function save_revision($post_id)
2405
+ {
2406
+ $parent_id = wp_is_post_revision($post_id);
2407
 
2408
+ if($parent_id) {
2409
 
2410
+ $parent = get_post($parent_id);
2411
+ $data = self::get_layout_data('published', $parent->ID);
2412
 
2413
+ if(!empty($data)) {
2414
+ self::update_layout_data($data, 'published', $post_id);
2415
+ }
2416
+ }
2417
+ }
2418
 
2419
  /**
2420
+ * Restore a revision of a builder layout.
2421
+ *
2422
+ * @since 1.0
2423
+ * @param int $post_id
2424
+ * @param int $revision_id
2425
+ * @return void
2426
+ */
2427
+ static public function restore_revision($post_id, $revision_id)
2428
+ {
2429
+ $post = get_post($post_id);
2430
+ $revision = get_post($revision_id);
2431
 
2432
+ if($revision) {
2433
 
2434
+ $data = self::get_layout_data('published', $revision->ID);
2435
 
2436
+ if(!empty($data)) {
2437
+ self::update_layout_data($data, 'published', $post_id);
2438
+ self::update_layout_data($data, 'draft', $post_id);
2439
+ }
2440
+ else {
2441
+ self::delete_layout_data('published', $post_id);
2442
+ self::delete_layout_data('draft', $post_id);
2443
+ }
2444
 
2445
+ self::delete_all_asset_cache();
2446
+ }
2447
+ }
2448
 
2449
  /**
2450
+ * Get all of the layout data for a post. We use get_metadata
2451
+ * here instead of get_post_meta to ensure revisions are queried accordingly.
2452
+ *
2453
+ * @since 1.0
2454
+ * @param string $status Either published or draft.
2455
+ * @param int $post_id The ID of the post to get data for.
2456
+ * @return array
2457
+ */
2458
  static public function get_layout_data($status = null, $post_id = null)
2459
  {
2460
+ $post_id = !$post_id ? self::get_post_id() : $post_id;
2461
+ $status = !$status ? self::get_node_status() : $status;
2462
+
2463
+ // Get published data?
2464
+ if($status == 'published') {
2465
+ if(isset(self::$published_layout_data[$post_id])) {
2466
+ $data = self::$published_layout_data[$post_id];
2467
+ }
2468
+ else {
2469
+ $data = get_metadata('post', $post_id, '_fl_builder_data', true);
2470
+ self::$published_layout_data[$post_id] = self::clean_layout_data( $data );
2471
+ }
2472
+ }
2473
+ // Get draft data?
2474
+ else if($status == 'draft') {
2475
+ if(isset(self::$draft_layout_data[$post_id])) {
2476
+ $data = self::$draft_layout_data[$post_id];
2477
+ }
2478
+ else {
2479
+ $data = get_metadata('post', $post_id, '_fl_builder_draft', true);
2480
+ self::$draft_layout_data[$post_id] = self::clean_layout_data( $data );
2481
+ }
2482
+ }
2483
+
2484
+ // Make sure we have an array.
2485
+ if(empty($data)) {
2486
+ $data = array();
2487
+ }
2488
+
2489
+ // Clone the layout data to ensure the cache remains intact.
2490
+ foreach($data as $node_id => $node) {
2491
+ $data[$node_id] = clone $node;
2492
+ }
2493
+
2494
+ // Return the data.
2495
+ return $data;
2496
+ }
2497
+
2498
+ /**
2499
+ * Update the layout data for a post. We use update_metadata
2500
+ * here instead of update_post_meta to ensure revisions are updated accordingly.
2501
+ *
2502
+ * @since 1.0
2503
+ * @param array $data The layout data to update.
2504
+ * @param string $status Either published or draft.
2505
+ * @param int $post_id The ID of the post to update.
2506
+ * @return void
2507
+ */
2508
  static public function update_layout_data($data, $status = null, $post_id = null)
2509
  {
2510
+ $post_id = !$post_id ? self::get_post_id() : $post_id;
2511
+ $status = !$status ? self::get_node_status() : $status;
2512
+ $data = self::slash_settings( self::clean_layout_data( $data ) );
2513
+
2514
+ // Update published data?
2515
+ if($status == 'published') {
2516
+ update_metadata('post', $post_id, '_fl_builder_data', $data);
2517
+ self::$published_layout_data[$post_id] = $data;
2518
+ }
2519
+ // Update draft data?
2520
+ else if($status == 'draft') {
2521
+ update_metadata('post', $post_id, '_fl_builder_draft', $data);
2522
+ self::$draft_layout_data[$post_id] = $data;
2523
+ }
2524
  }
2525
 
2526
  /**
2527
+ * Delete the layout data for a post.
2528
+ *
2529
+ * @since 1.0
2530
+ * @param string $status Either published or draft.
2531
+ * @param int $post_id The ID of the post to delete data.
2532
+ * @return void
2533
+ */
2534
  static public function delete_layout_data($status = null, $post_id = null)
2535
  {
2536
+ // Make sure we have a status to delete.
2537
+ if(!$status) {
2538
+ return;
2539
+ }
2540
 
2541
+ // Get the post id.
2542
+ $post_id = !$post_id ? self::get_post_id() : $post_id;
2543
 
2544
+ // Get the data to delete.
2545
+ $data = self::get_layout_data($status, $post_id);
2546
 
2547
+ // Delete the nodes.
2548
+ foreach($data as $node) {
2549
+ self::call_module_delete($node);
2550
+ }
2551
 
2552
+ // Update the layout data.
2553
+ self::update_layout_data(array(), $status, $post_id);
2554
  }
2555
 
2556
  /**
2557
  * Ensures the integrity of layout data key/value pairs.
2558
  *
2559
+ * @since 1.0
2560
+ * @param array $data An array of layout data.
2561
+ * @return array
2562
+ */
2563
  static public function clean_layout_data( $data = array() )
2564
  {
2565
  $cleaned = array();
2572
 
2573
  return $cleaned;
2574
  }
2575
+
2576
  /**
2577
+ * Clears a draft layout and saves a new draft using
2578
+ * the currently published layout data.
2579
+ *
2580
+ * @since 1.0
2581
+ * @return void
2582
+ */
2583
+ static public function clear_draft_layout()
2584
+ {
2585
+ $post_id = self::get_post_id();
2586
+ $data = self::get_layout_data('published', $post_id);
2587
 
2588
+ // Delete the old draft layout.
2589
+ self::delete_layout_data('draft');
2590
 
2591
+ // Save the new draft layout.
2592
+ self::update_layout_data($data, 'draft', $post_id);
2593
 
2594
+ // Clear the asset cache.
2595
+ self::delete_all_asset_cache($post_id);
2596
+ }
2597
 
2598
  /**
2599
+ * Saves layout data when a user chooses to publish.
2600
+ *
2601
+ * @since 1.0
2602
+ * @return void
2603
+ */
2604
+ static public function save_layout()
2605
+ {
2606
+ $editor_content = FLBuilder::render_editor_content();
2607
+ $post_id = self::get_post_id();
2608
+ $data = self::get_layout_data('draft', $post_id);
2609
 
2610
+ // Delete the old published layout.
2611
+ self::delete_layout_data('published', $post_id);
2612
 
2613
+ // Save the new published layout.
2614
+ self::update_layout_data($data, 'published', $post_id);
2615
 
2616
+ // Clear the asset cache.
2617
+ self::delete_all_asset_cache($post_id);
2618
 
2619
+ // Enable the builder to take over the post content.
2620
+ self::enable();
2621
 
2622
+ // Get the post status.
2623
+ $post_status = get_post_status($post_id);
2624
+ $post_status = strstr($post_status, 'draft') ? 'publish' : $post_status;
2625
 
2626
+ // Update the post with stripped down content.
2627
+ wp_update_post(array(
2628
+ 'ID' => self::get_post_id(),
2629
+ 'post_status' => $post_status,
2630
+ 'post_content' => $editor_content
2631
+ ));
2632
+ }
2633
 
2634
  /**
2635
  * Duplicates a layout for WPML when the copy from original
2636
  * button has been clicked.
2637
  *
2638
+ * @since 1.1.7
2639
+ * @param int $original_post_id
2640
+ * @param int $new_post_id
2641
+ * @return array
2642
+ */
2643
+ static public function duplicate_wpml_layout($original_post_id = null, $new_post_id = null)
2644
+ {
2645
+ $post_data = self::get_post_data();
2646
+ $original_post_id = isset($post_data['original_post_id']) ? $post_data['original_post_id'] : $original_post_id;
2647
+ $new_post_id = isset($post_data['post_id']) ? $post_data['post_id'] : $new_post_id;
2648
+ $enabled = get_post_meta($original_post_id, '_fl_builder_enabled', true);
2649
+ $published = self::get_layout_data('published', $original_post_id);
2650
+ $draft = self::get_layout_data('draft', $original_post_id);
2651
+
2652
+ $response = array(
2653
+ 'enabled' => false,
2654
+ 'has_layout' => false
2655
+ );
2656
+
2657
+ if(!empty($enabled)) {
2658
+ update_post_meta($new_post_id, '_fl_builder_enabled', true);
2659
+ $response['enabled'] = true;
2660
+ }
2661
+ if(!empty($published)) {
2662
+ self::update_layout_data($published, 'published', $new_post_id);
2663
+ $response['has_layout'] = true;
2664
+ }
2665
+ if(!empty($draft)) {
2666
+ self::update_layout_data($draft, 'draft', $new_post_id);
2667
+ $response['has_layout'] = true;
2668
+ }
2669
+
2670
+ return $response;
2671
+ }
2672
+
2673
+ /**
2674
+ * Returns the type of templates that are enabled.
2675
+ *
2676
+ * @since 1.1.3
2677
+ * @return string
2678
+ */
2679
  static public function get_enabled_templates()
2680
  {
2681
+ $key = '_fl_builder_enabled_templates';
2682
+ $default = 'enabled';
2683
+
2684
+ // Get the value.
2685
+ if(is_network_admin()) {
2686
+ $value = get_site_option($key);
2687
+ }
2688
+ else if(class_exists('FLBuilderMultisiteSettings')) {
2689
+ $value = get_option($key);
2690
+ $value = !$value ? get_site_option($key) : $value;
2691
+ }
2692
+ else {
2693
+ $value = get_option($key);
2694
+ }
2695
+
2696
+ // Return the value.
2697
+ if(!$value) {
2698
+ return $default;
2699
+ }
2700
+ else {
2701
+ return $value;
2702
+ }
2703
+ }
2704
+
2705
+ /**
2706
+ * Saves a user defined template via AJAX.
2707
+ *
2708
+ * @since 1.1.3
2709
+ * @return void
2710
+ */
2711
+ static public function save_user_template()
2712
+ {
2713
+ $post_data = self::get_post_data();
2714
+
2715
+ $post_id = wp_insert_post(array(
2716
+ 'post_title' => $post_data['template_name'],
2717
+ 'post_type' => 'fl-builder-template',
2718
+ 'post_status' => 'publish',
2719
+ 'ping_status' => 'closed',
2720
+ 'comment_status' => 'closed'
2721
+ ));
2722
 
2723
  // Get the layout data to copy.
2724
  $data = self::get_layout_data();
2728
 
2729
  // Save the template layout data.
2730
  self::update_layout_data($data, 'published', $post_id);
2731
+ }
2732
+
2733
+ /**
2734
+ * Returns data for all user defined templates.
2735
+ *
2736
+ * @since 1.1.3
2737
+ * @return array
2738
+ */
2739
+ static public function get_user_templates()
2740
+ {
2741
+ return get_posts('post_type=fl-builder-template&orderby=title&order=ASC&posts_per_page=-1');
2742
+ }
2743
+
2744
+ /**
2745
+ * Delete a user defined template.
2746
+ *
2747
+ * @since 1.1.3
2748
+ * @param int $template_id The post ID of the template to delete.
2749
+ * @return void
2750
+ */
2751
+ static public function delete_user_template($template_id = null)
2752
+ {
2753
+ $post_data = self::get_post_data();
2754
+ $template_id = isset($post_data['template_id']) ? $post_data['template_id'] : $template_id;
2755
+
2756
+ if(isset($template_id)) {
2757
+ wp_delete_post($template_id, true);
2758
+ }
2759
+ }
2760
+
2761
+ /**
2762
+ * Apply a user defined template to the current layout.
2763
+ *
2764
+ * @since 1.1.3
2765
+ * @param int $template_id The post ID of the template to apply.
2766
+ * @param bool $append Whether to append the new template or replacing the existing layout.
2767
+ * @return void
2768
+ */
2769
+ static public function apply_user_template($template_id = null, $append = false)
2770
+ {
2771
+ $post_data = self::get_post_data();
2772
+ $template_id = isset($post_data['template_id']) ? $post_data['template_id'] : $template_id;
2773
+ $append = isset($post_data['append']) ? $post_data['append'] : $append;
2774
+ $row_position = self::next_node_position('row');
2775
+
2776
+ if(isset($template_id)) {
2777
+
2778
+ // Delete existing nodes?
2779
+ if(!$append) {
2780
+ self::delete_layout_data('draft');
2781
+ }
2782
+
2783
+ // Insert new nodes if this is not a blank template.
2784
+ if($template_id != 'blank') {
2785
+
2786
+ // Get the template data.
2787
+ $template_data = self::get_layout_data('published', $template_id);
2788
+
2789
+ // Get new ids for the template nodes.
2790
+ $template_data = self::generate_new_node_ids($template_data);
2791
+
2792
+ // Get the existing layout data.
2793
+ $layout_data = self::get_layout_data();
2794
+
2795
+ // Reposition rows?
2796
+ if($append) {
2797
+
2798
+ foreach($template_data as $node_id => $node) {
2799
+
2800
+ if($node->type == 'row') {
2801
+ $template_data[$node_id]->position += $row_position;
2802
+ }
2803
+ }
2804
+ }
2805
+
2806
+ // Merge the data.
2807
+ $data = array_merge($layout_data, $template_data);
2808
+
2809
+ // Update the layout data.
2810
+ self::update_layout_data($data);
2811
+ }
2812
+
2813
+ // Delete old asset cache.
2814
+ self::delete_all_asset_cache();
2815
+ }
2816
+ }
2817
+
2818
+ /**
2819
+ * Save a core template.
2820
+ *
2821
+ * @since 1.0
2822
+ * @param object $settings The new template settings.
2823
+ * @return void
2824
+ */
2825
+ static public function save_template($settings)
2826
+ {
2827
+ // Get the layout data.
2828
+ $data = self::get_layout_data();
2829
+
2830
+ // Get the templates array.
2831
+ $templates = self::get_templates();
2832
+
2833
+ // Make sure we have an object.
2834
+ $settings = ( object )$settings;
2835
+
2836
+ // Get new ids for the nodes.
2837
+ $settings->nodes = self::generate_new_node_ids($data);
2838
+
2839
+ // Insert the template into the templates array.
2840
+ array_splice($templates, $settings->index, 0, array($settings));
2841
+
2842
+ // Save the templates array.
2843
+ self::save_templates($templates);
2844
+ }
2845
 
2846
  /**
2847
+ * Update a core template.
2848
+ *
2849
+ * @since 1.0
2850
+ * @param int $old_index The old template index.
2851
+ * @param object $settings The template settings.
2852
+ * @return void
2853
+ */
2854
+ static public function update_template($old_index, $settings)
2855
+ {
2856
+ // Get the templates array.
2857
+ $templates = self::get_templates();
2858
+
2859
+ // Remove the template from its old position.
2860
+ $template = array_splice($templates, $old_index, 1);
2861
+
2862
+ // Update the settings
2863
+ foreach($settings as $key => $val) {
2864
+ $template[0]->$key = $val;
2865
+ }
2866
+
2867
+ // Add the template to its new position.
2868
+ array_splice($templates, $settings->index, 0, $template);
2869
+
2870
+ // Save the templates array.
2871
+ self::save_templates($templates);
2872
+ }
2873
 
2874
  /**
2875
+ * Delete a core template.
2876
+ *
2877
+ * @since 1.0
2878
+ * @param int $index The index of the template to delete.
2879
+ * @return void
2880
+ */
2881
+ static public function delete_template($index)
2882
+ {
2883
+ // Get the templates array.
2884
+ $templates = self::get_templates();
2885
+
2886
+ // Remove the template.
2887
+ array_splice($templates, $index, 1);
2888
 
2889
+ // Save the templates array.
2890
+ self::save_templates($templates);
2891
+ }
 
2892
 
2893
  /**
2894
+ * Apply a core template.
2895
+ *
2896
+ * @since 1.0
2897
+ * @param int $index The index of the template to apply.
2898
+ * @param bool $append Whether to append the new template or replacing the existing layout.
2899
+ * @return void
2900
+ */
2901
+ static public function apply_template($index = 0, $append = false)
2902
+ {
2903
+ $post_data = self::get_post_data();
2904
+ $index = isset($post_data['index']) ? $post_data['index'] : $index;
2905
+ $append = isset($post_data['append']) ? $post_data['append'] : $append;
2906
+ $template = self::get_template($index);
2907
+ $row_position = self::next_node_position('row');
2908
+
2909
+ // Delete existing nodes?
2910
+ if(!$append) {
2911
+ self::delete_layout_data('draft');
2912
+ }
2913
+
2914
+ // Only move forward if we have template nodes.
2915
+ if(isset($template->nodes)) {
2916
+
2917
+ // Get new ids for the template nodes.
2918
+ $template_data = self::generate_new_node_ids($template->nodes);
2919
 
2920
+ // Get the existing layout data.
2921
+ $layout_data = self::get_layout_data();
2922
 
2923
+ // Reposition rows?
2924
+ if($append) {
 
 
2925
 
2926
+ foreach($template_data as $node_id => $node) {
 
2927
 
2928
+ if($node->type == 'row') {
2929
+ $template_data[$node_id]->position += $row_position;
2930
+ }
2931
+ }
2932
+ }
2933
+
2934
+ // Merge the data.
2935
+ $data = array_merge($layout_data, $template_data);
2936
+
2937
+ // Update the layout data.
2938
+ self::update_layout_data($data);
2939
+ }
2940
+
2941
+ // Delete old asset cache.
2942
+ self::delete_all_asset_cache();
2943
+ }
2944
+
2945
+ /**
2946
+ * Returns data for a core template.
2947
+ *
2948
+ * @since 1.0
2949
+ * @param int $index The index of the template.
2950
+ * @return object
2951
+ */
2952
+ static public function get_template($index)
2953
+ {
2954
+ $templates = self::get_templates();
2955
 
2956
+ return $templates[$index];
2957
+ }
2958
 
2959
+ /**
2960
+ * Returns data for all core templates.
2961
+ *
2962
+ * @since 1.0
2963
+ * @return array
2964
+ */
2965
+ static public function get_templates()
2966
+ {
2967
+ $templates = unserialize(file_get_contents(FL_BUILDER_DIR . 'data/templates.dat'));
2968
 
2969
+ return is_array($templates) ? $templates : array();
2970
+ }
2971
 
2972
+ /**
2973
+ * Save all core template data.
2974
+ *
2975
+ * @since 1.0
2976
+ * @param array $templates
2977
+ * @return void
2978
+ */
2979
+ static public function save_templates($templates = array())
2980
+ {
2981
+ // Update the indexes for proper positioning.
2982
+ $i = 0;
2983
+ $updated = array();
2984
+
2985
+ foreach($templates as $template) {
2986
+ $template->index = $i;
2987
+ $updated[$i] = $template;
2988
+ $i++;
2989
+ }
2990
 
2991
+ // Save the templates array.
2992
+ file_put_contents(FL_BUILDER_DIR . 'data/templates.dat', serialize($updated));
2993
+ }
 
 
2994
 
2995
+ /**
2996
+ * Returns the custom branding string.
2997
+ *
2998
+ * @since 1.3.1
2999
+ * @return string
3000
+ */
3001
+ static public function get_branding()
3002
+ {
3003
+ $key = '_fl_builder_branding';
3004
+ $default = __('Page Builder', 'fl-builder');
3005
 
3006
+ // Get the value.
3007
+ if(is_network_admin() || class_exists('FLBuilderMultisiteSettings')) {
3008
+ $value = get_site_option($key);
3009
+ }
3010
+ else {
3011
+ $value = get_option($key);
3012
+ }
3013
 
3014
+ // Return the value.
3015
+ if(!$value) {
3016
+ return $default;
3017
+ }
3018
+ else {
3019
+ return stripcslashes($value);
3020
+ }
3021
+ }
3022
 
3023
  /**
3024
+ * Returns the custom branding icon URL.
3025
+ *
3026
+ * @since 1.3.7
3027
+ * @return string
3028
+ */
3029
+ static public function get_branding_icon()
3030
+ {
3031
+ $key = '_fl_builder_branding_icon';
3032
+ $default = FL_BUILDER_URL . 'img/beaver.png';
3033
+
3034
+ // Get the value.
3035
+ if(is_network_admin() || class_exists('FLBuilderMultisiteSettings')) {
3036
+ $value = get_site_option($key);
3037
+ }
3038
+ else {
3039
+ $value = get_option($key);
3040
+ }
3041
 
3042
+ // Return the value.
3043
+ if($value === false) {
3044
+ return $default;
3045
+ }
3046
+ else {
3047
+ return $value;
3048
+ }
3049
+ }
3050
 
3051
+ /**
3052
+ * Returns an array of slugs for all enabled icon sets.
3053
+ *
3054
+ * @since 1.4.6
3055
+ * @return array
3056
+ */
3057
+ static public function get_enabled_icons()
3058
+ {
3059
+ $key = '_fl_builder_enabled_icons';
3060
+ $default = array( 'font-awesome', 'foundation-icons', 'dashicons' );
3061
 
3062
+ // Get the value.
3063
+ if(is_network_admin()) {
3064
+ $value = get_site_option($key);
3065
+ }
3066
+ else if(class_exists('FLBuilderMultisiteSettings')) {
3067
+ $value = get_option($key);
3068
+ $value = !$value ? get_site_option($key) : $value;
3069
+ }
3070
+ else {
3071
+ $value = get_option($key);
3072
+ }
3073
 
3074
+ // Return the value.
3075
+ if(!$value) {
3076
+ return $default;
3077
+ }
3078
+ else {
3079
+ return $value;
3080
+ }
3081
+ }
3082
 
3083
  /**
3084
+ * Returns the capability necessary for a user to access all
3085
+ * editing features in the builder interface.
3086
+ *
3087
+ * @since 1.3.9
3088
+ * @return string
3089
+ */
3090
+ static public function get_editing_capability()
3091
+ {
3092
+ $key = '_fl_builder_editing_capability';
3093
+ $default = 'edit_posts';
3094
 
3095
+ // Get the value.
3096
+ if(is_network_admin()) {
3097
+ $value = get_site_option($key);
3098
+ }
3099
+ else if(class_exists('FLBuilderMultisiteSettings')) {
3100
+ $value = get_option($key);
3101
+ $value = !$value ? get_site_option($key) : $value;
3102
+ }
3103
+ else {
3104
+ $value = get_option($key);
3105
+ }
3106
+
3107
+ // Return the value.
3108
+ if(!$value) {
3109
+ return $default;
3110
+ }
3111
+ else {
3112
+ return $value;
3113
+ }
3114
+ }
3115
+
3116
+ /**
3117
+ * Returns the default settings for the builder's help button.
3118
+ *
3119
+ * @since 1.4.9
3120
+ * @return array
3121
+ */
3122
+ static public function get_help_button_defaults()
3123
+ {
3124
+ $defaults = array(
3125
+ 'enabled' => true,
3126
+ 'tour' => true,
3127
+ 'video' => true,
3128
+ 'video_embed' => '<iframe src="https://player.vimeo.com/video/124230072?autoplay=1" width="420" height="315" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>',
3129
+ 'knowledge_base' => true,
3130
+ 'knowledge_base_url' => 'https://www.wpbeaverbuilder.com/knowledge-base/?utm_source=external&utm_medium=builder&utm_campaign=docs-button',
3131
+ 'forums' => true,
3132
+ 'forums_url' => 'https://www.wpbeaverbuilder.com/support/?utm_source=external&utm_medium=builder&utm_campaign=forums-button',
3133
+ );
3134
+
3135
+ return $defaults;
3136
+ }
3137
 
3138
+ /**
3139
+ * Returns the settings for the builder's help button.
3140
+ *
3141
+ * @since 1.4.9
3142
+ * @return array
3143
+ */
3144
+ static public function get_help_button_settings()
3145
+ {
3146
+ $key = '_fl_builder_help_button';
3147
+ $defaults = self::get_help_button_defaults();
3148
 
3149
+ // Get the value.
3150
+ if ( is_network_admin() || class_exists( 'FLBuilderMultisiteSettings' ) ) {
3151
+ $value = get_site_option( $key );
3152
+ }
3153
+ else {
3154
+ $value = get_option( $key );
3155
+ }
3156
 
3157
+ // Return the value.
3158
+ if ( false === $value ) {
3159
+ return $defaults;
3160
+ }
3161
+ else {
3162
+ return $value;
3163
+ }
3164
+ }
3165
 
3166
  /**
3167
+ * Returns an array of account data for all integrated services.
3168
+ *
3169
+ * @since 1.5.4
3170
+ * @return array
3171
+ */
3172
+ static public function get_services()
3173
+ {
3174
+ return get_option( '_fl_builder_services', array() );
3175
+ }
3176
 
3177
+ /**
3178
+ * Updates the account data for an integrated service.
3179
+ *
3180
+ * @since 1.5.4
3181
+ * @param string $service The service id.
3182
+ * @param string $account The account name.
3183
+ * @param array $data The account data.
3184
+ * @return void
3185
+ */
3186
+ static public function update_services( $service, $account, $data )
3187
+ {
3188
+ $services = self::get_services();
3189
+ $account = sanitize_text_field( $account );
3190
+
3191
+ if ( ! isset( $services[ $service ] ) ) {
3192
+ $services[ $service ] = array();
3193
+ }
3194
+
3195
+ $services[ $service ][ $account ] = $data;
3196
+
3197
+ update_option( '_fl_builder_services', $services );
3198
+ }
3199
 
3200
+ /**
3201
+ * Deletes an account for an integrated service.
3202
+ *
3203
+ * @since 1.5.4
3204
+ * @param string $service The service id.
3205
+ * @param string $account The account name.
3206
+ * @return void
3207
+ */
3208
+ static public function delete_service_account( $service, $account )
3209
+ {
3210
+ $services = self::get_services();
3211
+
3212
+ if ( isset( $services[ $service ][ $account ] ) ) {
3213
+ unset( $services[ $service ][ $account ] );
3214
+ }
3215
+ if ( 0 === count( $services[ $service ] ) ) {
3216
+ unset( $services[ $service ] );
3217
+ }
3218
+
3219
+ update_option( '_fl_builder_services', $services );
3220
+ }
3221
 
3222
  /**
3223
+ * Returns the plugin basename for Beaver Builder.
3224
+ *
3225
+ * @since 1.0
3226
+ * @return string
3227
+ */
3228
+ static public function plugin_basename()
3229
+ {
3230
+ return plugin_basename( FL_BUILDER_DIR . 'fl-builder.php' );
3231
+ }
3232
 
3233
+ /**
3234
+ * Deletes almost all database data and asset cache for the builder.
3235
+ * We don't delete _fl_builder_enabled, _fl_builder_data and _fl_builder_draft
3236
+ * so layouts can be recovered should the plugin be installed again.
3237
+ *
3238
+ * @since 1.0
3239
+ * @return void
3240
+ */
3241
+ static public function uninstall_database()
3242
+ {
3243
+ if(current_user_can('delete_plugins')) {
3244
+
3245
+ // Delete builder options.
3246
+ delete_option('_fl_builder_settings');
3247
+ delete_option('_fl_builder_enabled_modules');
3248
+ delete_option('_fl_builder_enabled_templates');
3249
+ delete_option('_fl_builder_post_types');
3250
+ delete_option('_fl_builder_enabled_icons');
3251
+ delete_option('_fl_builder_branding');
3252
+ delete_option('_fl_builder_editing_capability');
3253
+ delete_option('_fl_builder_help_button');
3254
+
3255
+ // Delete builder user meta.
3256
+ delete_metadata('user', 0, '_fl_builder_launched', 1, true);
3257
+
3258
+ // Delete uploaded files and folders.
3259
+ $upload_dir = self::get_upload_dir();
3260
+ $filesystem = FLBuilderUtils::get_filesystem();
3261
+ $filesystem->rmdir( $upload_dir['path'], true );
3262
+
3263
+ // Deactivate and delete the plugin.
3264
+ deactivate_plugins(array(self::plugin_basename()), false, is_network_admin());
3265
+ delete_plugins(array(self::plugin_basename()));
3266
+
3267
+ // Redirect to the plugins page.
3268
+ wp_redirect(admin_url('plugins.php?deleted=true&plugin_status=all&paged=1&s='));
3269
+
3270
+ exit;
3271
+ }
3272
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3273
  }
classes/class-fl-builder-module.php CHANGED
@@ -3,235 +3,255 @@
3
  /**
4
  * Base class that gets extended by all module classes.
5
  *
6
- * @class FLBuilderModule
7
  */
8
  class FLBuilderModule {
9
-
10
- /**
11
- * A unique ID for the module.
12
- *
13
- * @property $node
14
- * @type string
15
- */
16
- public $node;
17
-
18
- /**
19
- * A unique ID for the module's parent.
20
- *
21
- * @property $parent
22
- * @type number
23
- */
24
- public $parent;
25
-
26
- /**
27
- * The sort order for this module.
28
- *
29
- * @property $position
30
- * @type number
31
- */
32
- public $position;
33
-
34
- /**
35
- * A display name for the module.
36
- *
37
- * @property $name
38
- * @type string
39
- */
40
- public $name;
41
-
42
- /**
43
- * A description to display for the module.
44
- *
45
- * @property $description
46
- * @type string
47
- */
48
- public $description;
49
-
50
- /**
51
- * The category this module belongs to.
52
- *
53
- * @property $category
54
- * @type string
55
- */
56
- public $category;
57
-
58
- /**
59
- * Must be the module's folder name.
60
- *
61
- * @property $slug
62
- * @type string
63
- */
64
- public $slug;
65
-
66
- /**
67
- * The module's directory path.
68
- *
69
- * @property $dir
70
- * @type string
71
- */
72
- public $dir;
73
-
74
- /**
75
- * The module's directory url.
76
- *
77
- * @property $url
78
- * @type string
79
- */
80
- public $url;
81
-
82
- /**
83
- * An array of form settings.
84
- *
85
- * @property $form
86
- * @type array
87
- */
88
- public $form = array();
89
-
90
- /**
91
- * Whether this module is enabled on the
92
- * frontend or not.
93
- *
94
- * @property $enabled
95
- * @type boolean
96
- */
97
- public $enabled = true;
98
-
99
- /**
100
- * Whether this module's content should
101
- * be exported to the WP editor or not.
102
- *
103
- * @property $editor_export
104
- * @type boolean
105
- */
106
- public $editor_export = true;
107
-
108
- /**
109
- * The module settings object.
110
- *
111
- * @property $settings
112
- * @type object
113
- */
114
- public $settings;
115
-
116
- /**
117
- * Additional CSS to enqueue.
118
- *
119
- * @property $css
120
- * @type array
121
- */
122
- public $css = array();
123
-
124
- /**
125
- * Additional JS to enqueue.
126
- *
127
- * @property $js
128
- * @type array
129
- */
130
- public $js = array();
131
 
132
- /**
133
- * @method __construct
134
- */
135
- public function __construct($params)
136
- {
137
- $class_info = new ReflectionClass($this);
138
- $class_path = $class_info->getFileName();
139
- $dir_path = dirname($class_path);
140
- $this->name = $params['name'];
141
- $this->description = $params['description'];
142
- $this->category = $params['category'];
143
- $this->slug = basename($class_path, '.php');
144
- $this->enabled = isset($params['enabled']) ? $params['enabled'] : true;
145
- $this->editor_export = isset($params['editor_export']) ? $params['editor_export'] : true;
146
-
147
- // We need to normalize the paths here since path comparisons
148
- // break on Windows because they use backslashes.
149
- $dir_path = str_replace( '\\', '/', $dir_path );
150
- $stylesheet_directory = str_replace( '\\', '/', get_stylesheet_directory() );
151
- $stylesheet_directory_uri = str_replace( '\\', '/', get_stylesheet_directory_uri() );
152
- $template_directory = str_replace( '\\', '/', get_template_directory() );
153
- $template_directory_uri = str_replace( '\\', '/', get_template_directory_uri() );
154
-
155
- // Find the right paths.
156
- if(is_child_theme() && stristr($dir_path, $stylesheet_directory)) {
157
- $this->url = str_replace($stylesheet_directory, $stylesheet_directory_uri, $dir_path) . '/';
158
- $this->dir = $dir_path . '/';
159
- }
160
- else if(stristr($dir_path, $template_directory)) {
161
- $this->url = str_replace($template_directory, $template_directory_uri, $dir_path) . '/';
162
- $this->dir = $dir_path . '/';
163
- }
164
- else {
165
- $this->url = isset($params['url']) ? $params['url'] : FL_BUILDER_URL . 'modules/' . $this->slug . '/';
166
- $this->dir = isset($params['dir']) ? $params['dir'] : FL_BUILDER_DIR . 'modules/' . $this->slug . '/';
167
- }
168
- }
 
 
169
 
170
- /**
171
- * Used to enqueue additional frontend styles. Do not enqueue
172
- * frontend.css or frontend.responsive.css as those will be
173
- * enqueued automatically.
174
- *
175
- * @method add_css
176
- */
177
- public function add_css($handle, $src = null, $deps = null, $ver = null, $media = null)
178
- {
179
- $this->css[$handle] = array($src, $deps, $ver, $media);
180
- }
 
 
 
 
 
 
 
181
 
182
- /**
183
- * Used to enqueue additional frontend scripts. Do not enqueue
184
- * frontend.js as that will be enqueued automatically.
185
- *
186
- * @method add_js
187
- */
188
- public function add_js($handle, $src = null, $deps = null, $ver = null, $in_footer = null)
189
- {
190
- $this->js[$handle] = array($src, $deps, $ver, $in_footer);
191
- }
 
 
 
 
 
 
 
192
 
193
- /**
194
- * Enqueues the needed styles for any icon fields
195
- * in this module.
196
- *
197
- * @method enqueue_icon_styles
198
- */
199
- public function enqueue_icon_styles()
200
- {
201
- FLBuilderIcons::enqueue_styles_for_module( $this );
202
- }
 
203
 
204
- /**
205
- * Should be overridden by child classes to enqueue
206
- * additional css/js using the add_css and add_js methods.
207
- *
208
- * @method enqueue_scripts
209
- */
210
- public function enqueue_scripts()
211
- {
 
212
 
213
- }
214
 
215
- /**
216
- * Should be overridden by child classes to
217
- * work with settings data before it is saved.
218
- *
219
- * @method update
220
- * @param $settings {object}
221
- */
222
- public function update($settings)
223
- {
224
- return $settings;
225
- }
 
226
 
227
- /**
228
- * Should be overridden by child classes to
229
- * work with a module before it is deleted.
230
- *
231
- * @method delete
232
- */
233
- public function delete()
234
- {
 
235
 
236
- }
237
  }
3
  /**
4
  * Base class that gets extended by all module classes.
5
  *
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
+ *
103
+ * @since 1.0
104
+ * @var boolean $editor_export
105
+ */
106
+ public $editor_export = true;
107
+
108
+ /**
109
+ * The module settings object.
110
+ *
111
+ * @since 1.0
112
+ * @var object $settings
113
+ */
114
+ public $settings;
115
+
116
+ /**
117
+ * Additional CSS to enqueue.
118
+ *
119
+ * @since 1.0
120
+ * @var array $css
121
+ */
122
+ public $css = array();
123
+
124
+ /**
125
+ * Additional JS to enqueue.
126
+ *
127
+ * @since 1.0
128
+ * @var array $js
129
+ */
130
+ public $js = array();
131
 
132
+ /**
133
+ * Module constructor.
134
+ *
135
+ * @since 1.0
136
+ */
137
+ public function __construct($params)
138
+ {
139
+ $class_info = new ReflectionClass($this);
140
+ $class_path = $class_info->getFileName();
141
+ $dir_path = dirname($class_path);
142
+ $this->name = $params['name'];
143
+ $this->description = $params['description'];
144
+ $this->category = $params['category'];
145
+ $this->slug = basename($class_path, '.php');
146
+ $this->enabled = isset($params['enabled']) ? $params['enabled'] : true;
147
+ $this->editor_export = isset($params['editor_export']) ? $params['editor_export'] : true;
148
+
149
+ // We need to normalize the paths here since path comparisons
150
+ // break on Windows because they use backslashes.
151
+ $dir_path = str_replace( '\\', '/', $dir_path );
152
+ $stylesheet_directory = str_replace( '\\', '/', get_stylesheet_directory() );
153
+ $stylesheet_directory_uri = str_replace( '\\', '/', get_stylesheet_directory_uri() );
154
+ $template_directory = str_replace( '\\', '/', get_template_directory() );
155
+ $template_directory_uri = str_replace( '\\', '/', get_template_directory_uri() );
156
+
157
+ // Find the right paths.
158
+ if(is_child_theme() && stristr($dir_path, $stylesheet_directory)) {
159
+ $this->url = str_replace($stylesheet_directory, $stylesheet_directory_uri, $dir_path) . '/';
160
+ $this->dir = $dir_path . '/';
161
+ }
162
+ else if(stristr($dir_path, $template_directory)) {
163
+ $this->url = str_replace($template_directory, $template_directory_uri, $dir_path) . '/';
164
+ $this->dir = $dir_path . '/';
165
+ }
166
+ else {
167
+ $this->url = isset($params['url']) ? $params['url'] : FL_BUILDER_URL . 'modules/' . $this->slug . '/';
168
+ $this->dir = isset($params['dir']) ? $params['dir'] : FL_BUILDER_DIR . 'modules/' . $this->slug . '/';
169
+ }
170
+ }
171
 
172
+ /**
173
+ * Used to enqueue additional frontend styles. Do not enqueue
174
+ * frontend.css or frontend.responsive.css as those will be
175
+ * enqueued automatically. Params are the same as those used in
176
+ * WordPress' wp_enqueue_style function.
177
+ *
178
+ * @since 1.0
179
+ * @param string $handle
180
+ * @param string $src
181
+ * @param array $deps
182
+ * @param string $ver
183
+ * @param string $media
184
+ * @return void
185
+ */
186
+ public function add_css($handle, $src = null, $deps = null, $ver = null, $media = null)
187
+ {
188
+ $this->css[$handle] = array($src, $deps, $ver, $media);
189
+ }
190
 
191
+ /**
192
+ * Used to enqueue additional frontend scripts. Do not enqueue
193
+ * frontend.js as that will be enqueued automatically. Params
194
+ * are the same as those used in WordPress' wp_enqueue_script function.
195
+ *
196
+ * @since 1.0
197
+ * @param string $handle
198
+ * @param string $src
199
+ * @param array $deps
200
+ * @param string $ver
201
+ * @param bool $in_footer
202
+ * @return void
203
+ */
204
+ public function add_js($handle, $src = null, $deps = null, $ver = null, $in_footer = null)
205
+ {
206
+ $this->js[$handle] = array($src, $deps, $ver, $in_footer);
207
+ }
208
 
209
+ /**
210
+ * Enqueues the needed styles for any icon fields
211
+ * in this module.
212
+ *
213
+ * @since 1.4.6
214
+ * @return void
215
+ */
216
+ public function enqueue_icon_styles()
217
+ {
218
+ FLBuilderIcons::enqueue_styles_for_module( $this );
219
+ }
220
 
221
+ /**
222
+ * Should be overridden by subclasses to enqueue
223
+ * additional css/js using the add_css and add_js methods.
224
+ *
225
+ * @since 1.0
226
+ * @return void
227
+ */
228
+ public function enqueue_scripts()
229
+ {
230
 
231
+ }
232
 
233
+ /**
234
+ * Should be overridden by subclasses to
235
+ * work with settings data before it is saved.
236
+ *
237
+ * @since 1.0
238
+ * @param object A settings object that is going to be saved.
239
+ * @return object
240
+ */
241
+ public function update($settings)
242
+ {
243
+ return $settings;
244
+ }
245
 
246
+ /**
247
+ * Should be overridden by subclasses to
248
+ * work with a module before it is deleted.
249
+ *
250
+ * @since 1.0
251
+ * @return void
252
+ */
253
+ public function delete()
254
+ {
255
 
256
+ }
257
  }
classes/class-fl-builder-photo.php CHANGED
@@ -3,79 +3,96 @@
3
  /**
4
  * Helper class for working with photos.
5
  *
6
- * @class FLBuilderPhoto
7
  */
8
-
9
  final class FLBuilderPhoto {
10
 
11
- /**
12
- * @method sizes
13
- */
14
- static public function sizes()
15
- {
16
- global $_wp_additional_image_sizes;
 
 
 
 
17
 
18
- $sizes = array();
19
 
20
- foreach(get_intermediate_image_sizes() as $size) {
21
 
22
- $sizes[$size] = array(0, 0);
23
 
24
- if(in_array($size, array('thumbnail', 'medium', 'large'))) {
25
- $sizes[$size][0] = get_option($size . '_size_w');
26
- $sizes[$size][1] = get_option($size . '_size_h');
27
- }
28
- else if(isset($_wp_additional_image_sizes) && isset($_wp_additional_image_sizes[$size])) {
29
- $sizes[$size] = array(
30
- $_wp_additional_image_sizes[$size]['width'],
31
- $_wp_additional_image_sizes[$size]['height']
32
- );
33
- }
34
- }
35
 
36
- return $sizes;
37
- }
38
 
39
- /**
40
- * @method get_attachment_data
41
- */
42
- static public function get_attachment_data($id)
43
- {
44
- $data = wp_prepare_attachment_for_js($id);
 
 
 
 
 
45
 
46
- if(gettype($data) == 'array') {
47
- return json_decode(json_encode($data));
48
- }
49
 
50
- return $data;
51
- }
52
 
53
- /**
54
- * @method get_thumb
55
- */
56
- static public function get_thumb($photo)
57
- {
58
- if ( empty( $photo ) ) {
59
- echo FL_BUILDER_URL . 'img/spacer.png';
60
- }
61
- else if ( ! isset( $photo->sizes ) ) {
62
- echo $photo->url;
63
- }
64
- else if ( ! empty( $photo->sizes->thumbnail ) ) {
65
- echo $photo->sizes->thumbnail->url;
66
- }
67
- else {
68
- echo $photo->sizes->full->url;
69
- }
70
- }
 
 
 
 
71
 
72
- /**
73
- * @method get_src_options
74
- */
75
- static public function get_src_options($selected, $photo)
76
- {
77
- if ( ! isset( $photo->sizes ) ) {
78
- echo '<option value="' . $photo->url . '" selected="selected">' . _x( 'Full Size', 'Image size.', 'fl-builder' ) . '</option>';
 
 
 
 
 
79
  }
80
  else {
81
 
@@ -86,14 +103,14 @@ final class FLBuilderPhoto {
86
  'thumbnail' => _x( 'Thumbnail', 'Image size.', 'fl-builder' )
87
  );
88
 
89
- foreach($photo->sizes as $key => $val) {
90
 
91
- if(!isset($titles[$key])) {
92
- $titles[$key] = ucwords(str_replace(array('_', '-'), ' ', $key));
93
- }
94
 
95
- echo '<option value="' . $val->url . '" ' . selected($selected, $val->url) . '>' . $titles[$key] . ' - ' . $val->width . ' x ' . $val->height . '</option>';
96
- }
97
  }
98
- }
99
  }
3
  /**
4
  * Helper class for working with photos.
5
  *
6
+ * @since 1.0
7
  */
 
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
+ $sizes[$size] = array(0, 0);
26
 
27
+ if(in_array($size, array('thumbnail', 'medium', 'large'))) {
28
+ $sizes[$size][0] = get_option($size . '_size_w');
29
+ $sizes[$size][1] = get_option($size . '_size_h');
30
+ }
31
+ else if(isset($_wp_additional_image_sizes) && isset($_wp_additional_image_sizes[$size])) {
32
+ $sizes[$size] = array(
33
+ $_wp_additional_image_sizes[$size]['width'],
34
+ $_wp_additional_image_sizes[$size]['height']
35
+ );
36
+ }
37
+ }
38
 
39
+ return $sizes;
40
+ }
41
 
42
+ /**
43
+ * Returns an object with data for an attachment using
44
+ * wp_prepare_attachment_for_js based on the provided id.
45
+ *
46
+ * @since 1.0
47
+ * @param string $id The attachment id.
48
+ * @return object
49
+ */
50
+ static public function get_attachment_data($id)
51
+ {
52
+ $data = wp_prepare_attachment_for_js($id);
53
 
54
+ if(gettype($data) == 'array') {
55
+ return json_decode(json_encode($data));
56
+ }
57
 
58
+ return $data;
59
+ }
60
 
61
+ /**
62
+ * Renders the thumb URL for a photo object.
63
+ *
64
+ * @since 1.0
65
+ * @param object $photo An object with photo data.
66
+ * @return void
67
+ */
68
+ static public function get_thumb($photo)
69
+ {
70
+ if ( empty( $photo ) ) {
71
+ echo FL_BUILDER_URL . 'img/spacer.png';
72
+ }
73
+ else if ( ! isset( $photo->sizes ) ) {
74
+ echo $photo->url;
75
+ }
76
+ else if ( ! empty( $photo->sizes->thumbnail ) ) {
77
+ echo $photo->sizes->thumbnail->url;
78
+ }
79
+ else {
80
+ echo $photo->sizes->full->url;
81
+ }
82
+ }
83
 
84
+ /**
85
+ * Renders the options for a photo select field.
86
+ *
87
+ * @since 1.0
88
+ * @param string $selected The selected URL.
89
+ * @param object $photo An object with photo data.
90
+ * @return void
91
+ */
92
+ static public function get_src_options($selected, $photo)
93
+ {
94
+ if ( ! isset( $photo->sizes ) ) {
95
+ echo '<option value="' . $photo->url . '" selected="selected">' . _x( 'Full Size', 'Image size.', 'fl-builder' ) . '</option>';
96
  }
97
  else {
98
 
103
  'thumbnail' => _x( 'Thumbnail', 'Image size.', 'fl-builder' )
104
  );
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
+ echo '<option value="' . $val->url . '" ' . selected($selected, $val->url) . '>' . $titles[$key] . ' - ' . $val->width . ' x ' . $val->height . '</option>';
113
+ }
114
  }
115
+ }
116
  }
classes/class-fl-builder-service-aweber.php CHANGED
@@ -11,15 +11,15 @@ final class FLBuilderServiceAWeber extends FLBuilderService {
11
  * The ID for this service.
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,22 +28,22 @@ 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
  }
@@ -53,85 +53,85 @@ final class FLBuilderServiceAWeber extends FLBuilderService {
53
  *
54
  * @since 1.5.4
55
  * @param array $fields {
56
- * @type string $auth_code A valid authorization code.
57
  * }
58
  * @return array{
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
 
113
  /**
114
- * Renders the markup for the connection settings.
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',
126
- 'type' => 'text',
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
  /**
@@ -141,29 +141,29 @@ final class FLBuilderServiceAWeber extends FLBuilderService {
141
  * @param string $account The name of the saved account.
142
  * @param object $settings Saved module settings.
143
  * @return array {
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 {
158
- $account = $api->getAccount( $account_data['access_token'], $account_data['access_secret'] );
159
- $lists = $account->loadFromUrl( '/accounts/' . $account->id . '/lists' );
160
- $response['html'] = $this->render_list_field( $lists, $settings );
161
- }
162
- catch ( AWeberException $e ) {
163
- $response['error'] = $e->getMessage();
164
- }
165
-
166
- return $response;
167
  }
168
 
169
  /**
@@ -173,55 +173,55 @@ final class FLBuilderServiceAWeber extends FLBuilderService {
173
  * @param array $lists List data from the API.
174
  * @param object $settings Saved module settings.
175
  * @return string The markup for the list field.
176
- * @access private
177
- */
178
- private function render_list_field( $lists, $settings )
179
- {
180
- ob_start();
181
-
182
- $options = array( '' => __( 'Choose...', 'fl-builder' ) );
183
-
184
- foreach ( $lists->data['entries'] as $list ) {
185
- $options[ $list['id'] ] = $list['name'];
186
- }
187
-
188
- FLBuilder::render_settings_field( 'list_id', array(
189
- 'row_class' => 'fl-builder-service-field-row',
190
- 'class' => 'fl-builder-service-list-select',
191
- 'type' => 'select',
192
- 'label' => __( 'List', 'fl-builder' ),
193
- 'options' => $options,
194
- 'preview' => array(
195
- 'type' => 'none'
196
- )
197
  ), $settings);
198
-
199
- return ob_get_clean();
200
  }
201
 
202
- /**
203
  * Subscribe an email address to AWeber.
204
  *
205
- * @since 1.5.4
206
- * @param object $settings A module settings object.
207
- * @param string $email The email to subscribe.
208
- * @param string $name Optional. The full name of the person subscribing.
209
- * @return array {
210
- * @type bool|string $error The error message or false if no error.
211
  * }
212
- */
213
- public function subscribe( $settings, $email, $name = false )
214
- {
215
- $account_data = $this->get_account_data( $settings->service_account );
216
- $response = array( 'error' => false );
217
-
218
- if ( ! $account_data ) {
219
- $response['error'] = __( 'There was an error subscribing to AWeber. The account is no longer connected.', 'fl-builder' );
220
- }
221
- else {
222
-
223
- $api = $this->get_api( $account_data['auth_code'] );
224
- $data = array(
225
  'ws.op' => 'create',
226
  'email' => $email
227
  );
@@ -230,26 +230,26 @@ final class FLBuilderServiceAWeber extends FLBuilderService {
230
  $data['name'] = $name;
231
  }
232
 
233
- try {
234
- $account = $api->getAccount( $account_data['access_token'], $account_data['access_secret'] );
235
- $url = '/accounts/' . $account->id . '/lists/' . $settings->list_id . '/subscribers';
236
- $result = $api->adapter->request( 'POST', $url, $data, array( 'return' => 'headers' ) );
237
 
238
- if ( is_array( $result ) && isset( $result['Status-Code'] ) && 201 == $result['Status-Code'] ) {
239
- return $response;
240
- }
241
- else {
242
- $response['error'] = __( 'There was an error connecting to AWeber. Please try again.', 'fl-builder' );
243
- }
244
- }
245
- catch ( AWeberAPIException $e ) {
246
- $response['error'] = sprintf(
247
- __( 'There was an error subscribing to AWeber. %s', 'fl-builder' ),
248
- $e->getMessage()
249
- );
250
- }
251
- }
252
-
253
- return $response;
254
  }
255
  }
11
  * The ID for this service.
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
+ {
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
  }
53
  *
54
  * @since 1.5.4
55
  * @param array $fields {
56
+ * @type string $auth_code A valid authorization code.
57
  * }
58
  * @return array{
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
 
113
  /**
114
+ * Renders the markup for the connection settings.
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',
126
+ 'type' => 'text',
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
  /**
141
  * @param string $account The name of the saved account.
142
  * @param object $settings Saved module settings.
143
  * @return array {
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 {
158
+ $account = $api->getAccount( $account_data['access_token'], $account_data['access_secret'] );
159
+ $lists = $account->loadFromUrl( '/accounts/' . $account->id . '/lists' );
160
+ $response['html'] = $this->render_list_field( $lists, $settings );
161
+ }
162
+ catch ( AWeberException $e ) {
163
+ $response['error'] = $e->getMessage();
164
+ }
165
+
166
+ return $response;
167
  }
168
 
169
  /**
173
  * @param array $lists List data from the API.
174
  * @param object $settings Saved module settings.
175
  * @return string The markup for the list field.
176
+ * @access private
177
+ */
178
+ private function render_list_field( $lists, $settings )
179
+ {
180
+ ob_start();
181
+
182
+ $options = array( '' => __( 'Choose...', 'fl-builder' ) );
183
+
184
+ foreach ( $lists->data['entries'] as $list ) {
185
+ $options[ $list['id'] ] = $list['name'];
186
+ }
187
+
188
+ FLBuilder::render_settings_field( 'list_id', array(
189
+ 'row_class' => 'fl-builder-service-field-row',
190
+ 'class' => 'fl-builder-service-list-select',
191
+ 'type' => 'select',
192
+ 'label' => _x( 'List', 'An email list from a third party provider.', 'fl-builder' ),
193
+ 'options' => $options,
194
+ 'preview' => array(
195
+ 'type' => 'none'
196
+ )
197
  ), $settings);
198
+
199
+ return ob_get_clean();
200
  }
201
 
202
+ /**
203
  * Subscribe an email address to AWeber.
204
  *
205
+ * @since 1.5.4
206
+ * @param object $settings A module settings object.
207
+ * @param string $email The email to subscribe.
208
+ * @param string $name Optional. The full name of the person subscribing.
209
+ * @return array {
210
+ * @type bool|string $error The error message or false if no error.
211
  * }
212
+ */
213
+ public function subscribe( $settings, $email, $name = false )
214
+ {
215
+ $account_data = $this->get_account_data( $settings->service_account );
216
+ $response = array( 'error' => false );
217
+
218
+ if ( ! $account_data ) {
219
+ $response['error'] = __( 'There was an error subscribing to AWeber. The account is no longer connected.', 'fl-builder' );
220
+ }
221
+ else {
222
+
223
+ $api = $this->get_api( $account_data['auth_code'] );
224
+ $data = array(
225
  'ws.op' => 'create',
226
  'email' => $email
227
  );
230
  $data['name'] = $name;
231
  }
232
 
233
+ try {
234
+ $account = $api->getAccount( $account_data['access_token'], $account_data['access_secret'] );
235
+ $url = '/accounts/' . $account->id . '/lists/' . $settings->list_id . '/subscribers';
236
+ $result = $api->adapter->request( 'POST', $url, $data, array( 'return' => 'headers' ) );
237
 
238
+ if ( is_array( $result ) && isset( $result['Status-Code'] ) && 201 == $result['Status-Code'] ) {
239
+ return $response;
240
+ }
241
+ else {
242
+ $response['error'] = __( 'There was an error connecting to AWeber. Please try again.', 'fl-builder' );
243
+ }
244
+ }
245
+ catch ( AWeberAPIException $e ) {
246
+ $response['error'] = sprintf(
247
+ __( 'There was an error subscribing to AWeber. %s', 'fl-builder' ),
248
+ $e->getMessage()
249
+ );
250
+ }
251
+ }
252
+
253
+ return $response;
254
  }
255
  }
classes/class-fl-builder-service-campaign-monitor.php CHANGED
@@ -11,8 +11,8 @@ final class FLBuilderServiceCampaignMonitor extends FLBuilderService {
11
  * The ID for this service.
12
  *
13
  * @since 1.5.4
14
- * @var string $id
15
- */
16
  public $id = 'campaign-monitor';
17
 
18
  /**
@@ -20,10 +20,10 @@ 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';
29
  require_once FL_BUILDER_DIR . 'includes/vendor/campaign-monitor/csrest_lists.php';
@@ -36,63 +36,63 @@ final class FLBuilderServiceCampaignMonitor extends FLBuilderService {
36
  *
37
  * @since 1.5.4
38
  * @param array $fields {
39
- * @type string $api_key A valid API key.
40
  * }
41
  * @return array{
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
 
74
  /**
75
- * Renders the markup for the connection settings.
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',
87
- 'type' => 'text',
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
  /**
@@ -102,34 +102,34 @@ final class FLBuilderServiceCampaignMonitor extends FLBuilderService {
102
  * @param string $account The name of the saved account.
103
  * @param object $settings Saved module settings.
104
  * @return array {
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
  /**
@@ -139,30 +139,30 @@ final class FLBuilderServiceCampaignMonitor extends FLBuilderService {
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',
157
- 'type' => 'select',
158
- 'label' => __( 'Client', 'fl-builder' ),
159
- 'options' => $options,
160
- 'preview' => array(
161
- 'type' => 'none'
162
- )
163
  ), $settings);
164
-
165
- return ob_get_clean();
166
  }
167
 
168
  /**
@@ -172,88 +172,88 @@ final class FLBuilderServiceCampaignMonitor extends FLBuilderService {
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',
208
- 'type' => 'select',
209
- 'label' => __( 'List', '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
223
- * @param object $settings A module settings object.
224
- * @param string $email The email to subscribe.
225
- * @param string $name Optional. The full name of the person subscribing.
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
  }
11
  * The ID for this service.
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
+ {
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';
29
  require_once FL_BUILDER_DIR . 'includes/vendor/campaign-monitor/csrest_lists.php';
36
  *
37
  * @since 1.5.4
38
  * @param array $fields {
39
+ * @type string $api_key A valid API key.
40
  * }
41
  * @return array{
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
 
74
  /**
75
+ * Renders the markup for the connection settings.
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',
87
+ 'type' => 'text',
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
  /**
102
  * @param string $account The name of the saved account.
103
  * @param object $settings Saved module settings.
104
  * @return array {
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
  /**
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',
157
+ 'type' => 'select',
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
  /**
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',
208
+ 'type' => 'select',
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
223
+ * @param object $settings A module settings object.
224
+ * @param string $email The email to subscribe.
225
+ * @param string $name Optional. The full name of the person subscribing.
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
  }
classes/class-fl-builder-service-constant-contact.php CHANGED
@@ -11,16 +11,16 @@ final class FLBuilderServiceConstantContact extends FLBuilderService {
11
  * The ID for this service.
12
  *
13
  * @since 1.5.4
14
- * @var string $id
15
- */
16
  public $id = 'constant-contact';
17
 
18
  /**
19
  * The api url for this service.
20
  *
21
  * @since 1.5.4
22
- * @var string $api_url
23
- */
24
  public $api_url = 'https://api.constantcontact.com/v2/';
25
 
26
  /**
@@ -28,83 +28,83 @@ final class FLBuilderServiceConstantContact extends FLBuilderService {
28
  *
29
  * @since 1.5.4
30
  * @param array $fields {
31
- * @type string $api_key A valid API key.
32
- * @type string $access_token A valid access token.
33
  * }
34
  * @return array{
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
 
74
  /**
75
- * Renders the markup for the connection settings.
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',
87
- 'type' => 'text',
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',
98
- 'type' => 'text',
99
- 'label' => __( 'Access Token', 'fl-builder' ),
100
- 'help' => __( 'Your Constant Contact access token.', 'fl-builder' ),
101
- 'description' => sprintf( __( 'You must register a <a%s>Developer Account</a> with Constant Contact to obtain an API key and access token. Please see <a%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();
108
  }
109
 
110
  /**
@@ -114,30 +114,30 @@ final class FLBuilderServiceConstantContact extends FLBuilderService {
114
  * @param string $account The name of the saved account.
115
  * @param object $settings Saved module settings.
116
  * @return array {
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
  /**
@@ -147,140 +147,140 @@ final class FLBuilderServiceConstantContact extends FLBuilderService {
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',
165
- 'type' => 'select',
166
- 'label' => __( 'List', '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
180
- * @param object $settings A module settings object.
181
- * @param string $email The email to subscribe.
182
- * @param string $name Optional. The full name of the person subscribing.
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;
231
- $new_list->id = $list_id;
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';
239
- $args['headers']['Content-Length'] = strlen( $args['body'] );
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;
254
- $data['email_addresses'][0]['status'] = 'ACTIVE';
255
- $data['email_addresses'][0]['confirm_status'] = 'CONFIRMED';
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
- }
267
- if ( isset( $names[1] ) ) {
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
  }
11
  * The ID for this service.
12
  *
13
  * @since 1.5.4
14
+ * @var string $id
15
+ */
16
  public $id = 'constant-contact';
17
 
18
  /**
19
  * The api url for this service.
20
  *
21
  * @since 1.5.4
22
+ * @var string $api_url
23
+ */
24
  public $api_url = 'https://api.constantcontact.com/v2/';
25
 
26
  /**
28
  *
29
  * @since 1.5.4
30
  * @param array $fields {
31
+ * @type string $api_key A valid API key.
32
+ * @type string $access_token A valid access token.
33
  * }
34
  * @return array{
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
 
74
  /**
75
+ * Renders the markup for the connection settings.
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',
87
+ 'type' => 'text',
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',
98
+ 'type' => 'text',
99
+ 'label' => __( 'Access Token', 'fl-builder' ),
100
+ 'help' => __( 'Your Constant Contact access token.', 'fl-builder' ),
101
+ 'description' => sprintf( __( 'You must register a <a%s>Developer Account</a> with Constant Contact to obtain an API key and access token. Please see <a%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();
108
  }
109
 
110
  /**
114
  * @param string $account The name of the saved account.
115
  * @param object $settings Saved module settings.
116
  * @return array {
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
  /**
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',
165
+ 'type' => 'select',
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
180
+ * @param object $settings A module settings object.
181
+ * @param string $email The email to subscribe.
182
+ * @param string $name Optional. The full name of the person subscribing.
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;
231
+ $new_list->id = $list_id;
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';
239
+ $args['headers']['Content-Length'] = strlen( $args['body'] );
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;
254
+ $data['email_addresses'][0]['status'] = 'ACTIVE';
255
+ $data['email_addresses'][0]['confirm_status'] = 'CONFIRMED';
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
+ }
267
+ if ( isset( $names[1] ) ) {
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
  }
classes/class-fl-builder-service-getresponse.php CHANGED
@@ -11,15 +11,15 @@ final class FLBuilderServiceGetResponse extends FLBuilderService {
11
  * The ID for this service.
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,13 +28,13 @@ 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
 
@@ -48,63 +48,63 @@ final class FLBuilderServiceGetResponse extends FLBuilderService {
48
  *
49
  * @since 1.5.4
50
  * @param array $fields {
51
- * @type string $api_key A valid API key.
52
  * }
53
  * @return array{
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
 
86
  /**
87
- * Renders the markup for the connection settings.
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',
99
- 'type' => 'text',
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
  /**
@@ -114,28 +114,28 @@ final class FLBuilderServiceGetResponse extends FLBuilderService {
114
  * @param string $account The name of the saved account.
115
  * @param object $settings Saved module settings.
116
  * @return array {
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
  /**
@@ -145,66 +145,66 @@ final class FLBuilderServiceGetResponse extends FLBuilderService {
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',
163
- 'type' => 'select',
164
- 'label' => __( 'List', '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
178
- * @param object $settings A module settings object.
179
- * @param string $email The email to subscribe.
180
- * @param string $name Optional. The full name of the person subscribing.
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
- $result = $api->addContact( $settings->list_id, $name, $email );
199
- }
200
- catch ( Exception $e ) {
201
- $response['error'] = sprintf(
202
- __( 'There was an error subscribing to GetResponse. %s', 'fl-builder' ),
203
- $e->getMessage()
204
- );
205
- }
206
- }
207
-
208
- return $response;
209
  }
210
  }
11
  * The ID for this service.
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
+ {
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
 
48
  *
49
  * @since 1.5.4
50
  * @param array $fields {
51
+ * @type string $api_key A valid API key.
52
  * }
53
  * @return array{
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
 
86
  /**
87
+ * Renders the markup for the connection settings.
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',
99
+ 'type' => 'text',
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
  /**
114
  * @param string $account The name of the saved account.
115
  * @param object $settings Saved module settings.
116
  * @return array {
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
  /**
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',
163
+ 'type' => 'select',
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
178
+ * @param object $settings A module settings object.
179
+ * @param string $email The email to subscribe.
180
+ * @param string $name Optional. The full name of the person subscribing.
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
+ $result = $api->addContact( $settings->list_id, $name, $email );
199
+ }
200
+ catch ( Exception $e ) {
201
+ $response['error'] = sprintf(
202
+ __( 'There was an error subscribing to GetResponse. %s', 'fl-builder' ),
203
+ $e->getMessage()
204
+ );
205
+ }
206
+ }
207
+
208
+ return $response;
209
  }
210
  }
classes/class-fl-builder-service-icontact.php CHANGED
@@ -11,15 +11,15 @@ final class FLBuilderServiceIContact extends FLBuilderService {
11
  * The ID for this service.
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
  /**
@@ -27,24 +27,24 @@ final class FLBuilderServiceIContact extends FLBuilderService {
27
  *
28
  * @since 1.5.4
29
  * @param array $data {
30
- * @type string $username A valid username.
31
- * @type string $app_id A valid app ID.
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
  }
@@ -54,105 +54,105 @@ final class FLBuilderServiceIContact extends FLBuilderService {
54
  *
55
  * @since 1.5.4
56
  * @param array $fields {
57
- * @type string $username A valid username.
58
- * @type string $app_id A valid app ID.
59
- * @type string $app_password A valid app password.
60
  * }
61
  * @return array{
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
 
111
  /**
112
- * Renders the markup for the connection settings.
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',
124
- 'type' => 'text',
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',
135
- 'type' => 'text',
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',
146
- 'type' => 'text',
147
- 'label' => __( 'App Password', 'fl-builder' ),
148
- 'help' => __( 'Your iContact app password.', 'fl-builder' ),
149
- 'description' => sprintf( __( 'You must <a%s>create an app</a> in iContact to obtain an app ID and password. Please see <a%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();
156
  }
157
 
158
  /**
@@ -162,33 +162,33 @@ final class FLBuilderServiceIContact extends FLBuilderService {
162
  * @param string $account The name of the saved account.
163
  * @param object $settings Saved module settings.
164
  * @return array {
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
  /**
@@ -198,89 +198,89 @@ final class FLBuilderServiceIContact extends FLBuilderService {
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',
216
- 'type' => 'select',
217
- 'label' => __( 'List', '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
231
- * @param object $settings A module settings object.
232
- * @param string $email The email to subscribe.
233
- * @param string $name Optional. The full name of the person subscribing.
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
  }
11
  * The ID for this service.
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
  /**
27
  *
28
  * @since 1.5.4
29
  * @param array $data {
30
+ * @type string $username A valid username.
31
+ * @type string $app_id A valid app ID.
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
  }
54
  *
55
  * @since 1.5.4
56
  * @param array $fields {
57
+ * @type string $username A valid username.
58
+ * @type string $app_id A valid app ID.
59
+ * @type string $app_password A valid app password.
60
  * }
61
  * @return array{
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
 
111
  /**
112
+ * Renders the markup for the connection settings.
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',
124
+ 'type' => 'text',
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',
135
+ 'type' => 'text',
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',
146
+ 'type' => 'text',
147
+ 'label' => __( 'App Password', 'fl-builder' ),
148
+ 'help' => __( 'Your iContact app password.', 'fl-builder' ),
149
+ 'description' => sprintf( __( 'You must <a%s>create an app</a> in iContact to obtain an app ID and password. Please see <a%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();
156
  }
157
 
158
  /**
162
  * @param string $account The name of the saved account.
163
  * @param object $settings Saved module settings.
164
  * @return array {
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
  /**
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',
216
+ 'type' => 'select',
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
231
+ * @param object $settings A module settings object.
232
+ * @param string $email The email to subscribe.
233
+ * @param string $name Optional. The full name of the person subscribing.
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
  }
classes/class-fl-builder-service-madmimi.php CHANGED
@@ -11,15 +11,15 @@ final class FLBuilderServiceMadMimi extends FLBuilderService {
11
  * The ID for this service.
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,13 +29,13 @@ 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
 
@@ -49,83 +49,83 @@ final class FLBuilderServiceMadMimi extends FLBuilderService {
49
  *
50
  * @since 1.5.2
51
  * @param array $fields {
52
- * @type string $api_email A valid email address.
53
- * @type string $api_key A valid API key.
54
  * }
55
  * @return array{
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
 
96
  /**
97
- * Renders the markup for the connection settings.
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',
109
- 'type' => 'text',
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',
120
- 'type' => 'text',
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
  /**
@@ -135,31 +135,31 @@ final class FLBuilderServiceMadMimi extends FLBuilderService {
135
  * @param string $account The name of the saved account.
136
  * @param object $settings Saved module settings.
137
  * @return array {
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
  /**
@@ -169,56 +169,56 @@ final class FLBuilderServiceMadMimi extends FLBuilderService {
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',
187
- 'type' => 'select',
188
- 'label' => __( 'List', '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
202
- * @param object $settings A module settings object.
203
- * @param string $email The email to subscribe.
204
- * @param string $name Optional. The full name of the person subscribing.
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
 
@@ -227,22 +227,22 @@ final class FLBuilderServiceMadMimi extends FLBuilderService {
227
  $names = explode( ' ', $name );
228
 
229
  if ( isset( $names[0] ) ) {
230
- $data['firstName'] = $names[0];
231
- }
232
- if ( isset( $names[1] ) ) {
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
  }
11
  * The ID for this service.
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
+ {
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
 
49
  *
50
  * @since 1.5.2
51
  * @param array $fields {
52
+ * @type string $api_email A valid email address.
53
+ * @type string $api_key A valid API key.
54
  * }
55
  * @return array{
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
 
96
  /**
97
+ * Renders the markup for the connection settings.
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',
109
+ 'type' => 'text',
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',
120
+ 'type' => 'text',
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
  /**
135
  * @param string $account The name of the saved account.
136
  * @param object $settings Saved module settings.
137
  * @return array {
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
  /**
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',
187
+ 'type' => 'select',
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
202
+ * @param object $settings A module settings object.
203
+ * @param string $email The email to subscribe.
204
+ * @param string $name Optional. The full name of the person subscribing.
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
 
227
  $names = explode( ' ', $name );
228
 
229
  if ( isset( $names[0] ) ) {
230
+ $data['firstName'] = $names[0];
231
+ }
232
+ if ( isset( $names[1] ) ) {
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
  }
classes/class-fl-builder-service-mailchimp.php CHANGED
@@ -11,15 +11,15 @@ final class FLBuilderServiceMailChimp extends FLBuilderService {
11
  * The ID for this service.
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,13 +28,13 @@ 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
 
@@ -48,63 +48,63 @@ final class FLBuilderServiceMailChimp extends FLBuilderService {
48
  *
49
  * @since 1.5.4
50
  * @param array $fields {
51
- * @type string $api_key A valid API key.
52
  * }
53
  * @return array{
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
 
86
  /**
87
- * Renders the markup for the connection settings.
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',
99
- 'type' => 'text',
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
  /**
@@ -114,28 +114,28 @@ final class FLBuilderServiceMailChimp extends FLBuilderService {
114
  * @param string $account The name of the saved account.
115
  * @param object $settings Saved module settings.
116
  * @return array {
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
- $response = array(
126
- 'error' => false,
127
- 'html' => ''
128
- );
129
-
130
- try {
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
- return $response;
139
  }
140
 
141
  /**
@@ -145,83 +145,85 @@ final class FLBuilderServiceMailChimp extends FLBuilderService {
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['data'] as $list ) {
157
- $options[ $list['id'] ] = $list['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',
163
- 'type' => 'select',
164
- 'label' => __( 'List', '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 MailChimp.
176
  *
177
- * @since 1.5.4
178
- * @param object $settings A module settings object.
179
- * @param string $email The email to subscribe.
180
- * @param string $name Optional. The full name of the person subscribing.
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 = false )
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 MailChimp. The account is no longer connected.', 'fl-builder' );
192
- }
193
- else {
194
-
195
- $api = $this->get_api( $account_data['api_key'] );
196
- $email = array( 'email' => $email );
197
- $data = array();
 
 
198
 
199
  if ( $name ) {
200
 
201
  $names = explode( ' ', $name );
202
 
203
  if ( isset( $names[0] ) ) {
204
- $data['FNAME'] = $names[0];
205
- }
206
- if ( isset( $names[1] ) ) {
207
- $data['LNAME'] = $names[1];
208
- }
209
  }
210
 
211
  try {
212
- $api->lists->subscribe( $settings->list_id, $email, $data, 'html', true, true, false, true );
213
- }
214
- catch( Mailchimp_List_AlreadySubscribed $e ) {
215
- return $response;
216
- }
217
- catch ( Mailchimp_Error $e ) {
218
- $response['error'] = sprintf(
219
- __( 'There was an error subscribing to MailChimp. %s', 'fl-builder' ),
220
- $e->getMessage()
221
- );
222
- }
223
- }
224
-
225
- return $response;
226
  }
227
  }
11
  * The ID for this service.
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
+ {
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
 
48
  *
49
  * @since 1.5.4
50
  * @param array $fields {
51
+ * @type string $api_key A valid API key.
52
  * }
53
  * @return array{
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
 
86
  /**
87
+ * Renders the markup for the connection settings.
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',
99
+ 'type' => 'text',
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
  /**
114
  * @param string $account The name of the saved account.
115
  * @param object $settings Saved module settings.
116
  * @return array {
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
+ $response = array(
126
+ 'error' => false,
127
+ 'html' => ''
128
+ );
129
+
130
+ try {
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
+ return $response;
139
  }
140
 
141
  /**
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['data'] as $list ) {
157
+ $options[ $list['id'] ] = $list['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',
163
+ 'type' => 'select',
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 MailChimp.
176
  *
177
+ * @since 1.5.4
178
+ * @param object $settings A module settings object.
179
+ * @param string $email The email to subscribe.
180
+ * @param string $name Optional. The full name of the person subscribing.
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 = false )
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 MailChimp. The account is no longer connected.', 'fl-builder' );
192
+ }
193
+ else {
194
+
195
+ $api = $this->get_api( $account_data['api_key'] );
196
+ $double = apply_filters( 'fl_builder_mailchimp_double_option', true );
197
+ $welcome = apply_filters( 'fl_builder_mailchimp_welcome', true );
198
+ $email = array( 'email' => $email );
199
+ $data = array();
200
 
201
  if ( $name ) {
202
 
203
  $names = explode( ' ', $name );
204
 
205
  if ( isset( $names[0] ) ) {
206
+ $data['FNAME'] = $names[0];
207
+ }
208
+ if ( isset( $names[1] ) ) {
209
+ $data['LNAME'] = $names[1];
210
+ }
211
  }
212
 
213
  try {
214
+ $api->lists->subscribe( $settings->list_id, $email, $data, 'html', (bool) $double, true, false, (bool) $welcome );
215
+ }
216
+ catch( Mailchimp_List_AlreadySubscribed $e ) {
217
+ return $response;
218
+ }
219
+ catch ( Mailchimp_Error $e ) {
220
+ $response['error'] = sprintf(
221
+ __( 'There was an error subscribing to MailChimp. %s', 'fl-builder' ),
222
+ $e->getMessage()
223
+ );
224
+ }
225
+ }
226
+
227
+ return $response;
228
  }
229
  }
classes/class-fl-builder-service-mailpoet.php CHANGED
@@ -11,8 +11,8 @@ final class FLBuilderServiceMailPoet extends FLBuilderService {
11
  * The ID for this service.
12
  *
13
  * @since 1.5.4
14
- * @var string $id
15
- */
16
  public $id = 'mailpoet';
17
 
18
  /**
@@ -21,29 +21,29 @@ final class FLBuilderServiceMailPoet extends FLBuilderService {
21
  * @since 1.5.4
22
  * @param array $fields
23
  * @return array{
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
 
38
  /**
39
- * Renders the markup for the connection settings.
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
  /**
@@ -53,27 +53,27 @@ final class FLBuilderServiceMailPoet extends FLBuilderService {
53
  * @param string $account The name of the saved account.
54
  * @param object $settings Saved module settings.
55
  * @return array {
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
-
67
- try {
68
- $list_model = WYSIJA::get( 'list', 'model' );
69
- $lists = $list_model->get( array( 'name', 'list_id' ), array( 'is_enabled' => 1 ) );
70
- $response['html'] = self::render_list_field( $lists, $settings );
71
- }
72
- catch ( Exception $e ) {
73
- $response['error'] = __( 'There was an error retrieveing your lists.', 'fl-builder' );
74
- }
75
-
76
- return $response;
77
  }
78
 
79
  /**
@@ -83,47 +83,47 @@ final class FLBuilderServiceMailPoet extends FLBuilderService {
83
  * @param array $lists List data from the API.
84
  * @param object $settings Saved module settings.
85
  * @return string The markup for the list field.
86
- * @access private
87
- */
88
- private function render_list_field( $lists, $settings )
89
- {
90
- ob_start();
91
-
92
- $options = array( '' => __( 'Choose...', 'fl-builder' ) );
93
-
94
- foreach ( $lists as $list ) {
95
- $options[ $list['list_id'] ] = $list['name'];
96
- }
97
-
98
- FLBuilder::render_settings_field( 'list_id', array(
99
- 'row_class' => 'fl-builder-service-field-row',
100
- 'class' => 'fl-builder-service-list-select',
101
- 'type' => 'select',
102
- 'label' => __( 'List', 'fl-builder' ),
103
- 'options' => $options,
104
- 'preview' => array(
105
- 'type' => 'none'
106
- )
107
  ), $settings);
108
-
109
- return ob_get_clean();
110
  }
111
 
112
- /**
113
  * Subscribe an email address to MailPoet.
114
  *
115
- * @since 1.5.4
116
- * @param object $settings A module settings object.
117
- * @param string $email The email to subscribe.
118
- * @param string $name Optional. The full name of the person subscribing.
119
- * @return array {
120
- * @type bool|string $error The error message or false if no error.
121
  * }
122
- */
123
- public function subscribe( $settings, $email, $name = false )
124
- {
125
- $response = array( 'error' => false );
126
- $user = array( 'email' => $email );
127
 
128
  if ( ! class_exists( 'WYSIJA' ) ) {
129
  $response['error'] = __( 'There was an error subscribing. MailPoet is not installed.', 'fl-builder' );
@@ -137,19 +137,19 @@ final class FLBuilderServiceMailPoet extends FLBuilderService {
137
  $names = explode( ' ', $name );
138
 
139
  if ( isset( $names[0] ) ) {
140
- $user['firstname'] = $names[0];
141
- }
142
- if ( isset( $names[1] ) ) {
143
- $user['lastname'] = $names[1];
144
- }
145
  }
146
 
147
- $helper->addSubscriber( array(
148
- 'user' => $user,
149
- 'user_list' => array( 'list_ids' => array( $settings->list_id ) ),
150
- ));
151
  }
152
-
153
- return $response;
154
  }
155
  }
11
  * The ID for this service.
12
  *
13
  * @since 1.5.4
14
+ * @var string $id
15
+ */
16
  public $id = 'mailpoet';
17
 
18
  /**
21
  * @since 1.5.4
22
  * @param array $fields
23
  * @return array{
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
 
38
  /**
39
+ * Renders the markup for the connection settings.
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
  /**
53
  * @param string $account The name of the saved account.
54
  * @param object $settings Saved module settings.
55
  * @return array {
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
+
67
+ try {
68
+ $list_model = WYSIJA::get( 'list', 'model' );
69
+ $lists = $list_model->get( array( 'name', 'list_id' ), array( 'is_enabled' => 1 ) );
70
+ $response['html'] = self::render_list_field( $lists, $settings );
71
+ }
72
+ catch ( Exception $e ) {
73
+ $response['error'] = __( 'There was an error retrieveing your lists.', 'fl-builder' );
74
+ }
75
+
76
+ return $response;
77
  }
78
 
79
  /**
83
  * @param array $lists List data from the API.
84
  * @param object $settings Saved module settings.
85
  * @return string The markup for the list field.
86
+ * @access private
87
+ */
88
+ private function render_list_field( $lists, $settings )
89
+ {
90
+ ob_start();
91
+
92
+ $options = array( '' => __( 'Choose...', 'fl-builder' ) );
93
+
94
+ foreach ( $lists as $list ) {
95
+ $options[ $list['list_id'] ] = $list['name'];
96
+ }
97
+
98
+ FLBuilder::render_settings_field( 'list_id', array(
99
+ 'row_class' => 'fl-builder-service-field-row',
100
+ 'class' => 'fl-builder-service-list-select',
101
+ 'type' => 'select',
102
+ 'label' => _x( 'List', 'An email list from a third party provider.', 'fl-builder' ),
103
+ 'options' => $options,
104
+ 'preview' => array(
105
+ 'type' => 'none'
106
+ )
107
  ), $settings);
108
+
109
+ return ob_get_clean();
110
  }
111
 
112
+ /**
113
  * Subscribe an email address to MailPoet.
114
  *
115
+ * @since 1.5.4
116
+ * @param object $settings A module settings object.
117
+ * @param string $email The email to subscribe.
118
+ * @param string $name Optional. The full name of the person subscribing.
119
+ * @return array {
120
+ * @type bool|string $error The error message or false if no error.
121
  * }
122
+ */
123
+ public function subscribe( $settings, $email, $name = false )
124
+ {
125
+ $response = array( 'error' => false );
126
+ $user = array( 'email' => $email );
127
 
128
  if ( ! class_exists( 'WYSIJA' ) ) {
129
  $response['error'] = __( 'There was an error subscribing. MailPoet is not installed.', 'fl-builder' );
137
  $names = explode( ' ', $name );
138
 
139
  if ( isset( $names[0] ) ) {
140
+ $user['firstname'] = $names[0];
141
+ }
142
+ if ( isset( $names[1] ) ) {
143
+ $user['lastname'] = $names[1];
144
+ }
145
  }
146
 
147
+ $helper->addSubscriber( array(
148
+ 'user' => $user,
149
+ 'user_list' => array( 'list_ids' => array( $settings->list_id ) ),
150
+ ));
151
  }
152
+
153
+ return $response;
154
  }
155
  }
classes/class-fl-builder-service-sendinblue.php ADDED
@@ -0,0 +1,229 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Helper class for the SendinBlue API.
5
+ *
6
+ * @since 1.5.6
7
+ */
8
+ final class FLBuilderServiceSendinBlue extends FLBuilderService {
9
+
10
+ /**
11
+ * The ID for this service.
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
+ /**
26
+ * Get an instance of the API.
27
+ *
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
+ *
49
+ * @since 1.5.6
50
+ * @param array $fields {
51
+ * @type string $access_key A valid access key.
52
+ * }
53
+ * @return array{
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.' );
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
+
89
+ /**
90
+ * Renders the markup for the connection settings.
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',
102
+ 'type' => 'text',
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.
118
+ * @param object $settings Saved module settings.
119
+ * @return array {
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.' );
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
+
145
+ return $response;
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',
170
+ 'type' => 'select',
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
185
+ * @param object $settings A module settings object.
186
+ * @param string $email The email to subscribe.
187
+ * @param string $name Optional. The full name of the person subscribing.
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
+ }
212
+ if ( isset( $names[1] ) ) {
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.' );
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
+ }
classes/class-fl-builder-service.php CHANGED
@@ -11,8 +11,8 @@ abstract class FLBuilderService {
11
  * The ID for this service such as aweber or mailchimp.
12
  *
13
  * @since 1.5.4
14
- * @var string $id
15
- */
16
  public $id = '';
17
 
18
  /**
@@ -21,19 +21,19 @@ abstract class FLBuilderService {
21
  * @since 1.5.4
22
  * @param array $fields
23
  * @return array{
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
  /**
31
- * Renders the markup for the connection settings.
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.
@@ -42,27 +42,27 @@ abstract class FLBuilderService {
42
  * @param string $account The name of the saved account.
43
  * @param object $settings Saved module settings.
44
  * @return array {
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
  /**
52
  * Get the saved data for a specific account.
53
  *
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
  }
11
  * The ID for this service such as aweber or mailchimp.
12
  *
13
  * @since 1.5.4
14
+ * @var string $id
15
+ */
16
  public $id = '';
17
 
18
  /**
21
  * @since 1.5.4
22
  * @param array $fields
23
  * @return array{
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
  /**
31
+ * Renders the markup for the connection settings.
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.
42
  * @param string $account The name of the saved account.
43
  * @param object $settings Saved module settings.
44
  * @return array {
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
  /**
52
  * Get the saved data for a specific account.
53
  *
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
  }
classes/class-fl-builder-services.php CHANGED
@@ -11,49 +11,49 @@ final class FLBuilderServices {
11
  * Data for working with each supported third party service.
12
  *
13
  * @since 1.5.4
14
- * @var array $services_data
15
- * @access private
16
- */
17
  static private $services_data = array(
18
- 'aweber' => array(
19
- 'type' => 'autoresponder',
20
- 'name' => 'AWeber',
21
- 'class' => 'FLBuilderServiceAWeber'
22
  ),
23
- 'campaign-monitor' => array(
24
- 'type' => 'autoresponder',
25
- 'name' => 'Campaign Monitor',
26
- 'class' => 'FLBuilderServiceCampaignMonitor'
27
  ),
28
- 'constant-contact' => array(
29
- 'type' => 'autoresponder',
30
- 'name' => 'Constant Contact',
31
- 'class' => 'FLBuilderServiceConstantContact'
32
  ),
33
- 'getresponse' => array(
34
- 'type' => 'autoresponder',
35
- 'name' => 'GetResponse',
36
- 'class' => 'FLBuilderServiceGetResponse'
37
  ),
38
- 'icontact' => array(
39
- 'type' => 'autoresponder',
40
- 'name' => 'iContact',
41
- 'class' => 'FLBuilderServiceIContact'
42
  ),
43
- 'madmimi' => array(
44
- 'type' => 'autoresponder',
45
- 'name' => 'Mad Mimi',
46
- 'class' => 'FLBuilderServiceMadMimi'
47
  ),
48
- 'mailchimp' => array(
49
- 'type' => 'autoresponder',
50
- 'name' => 'MailChimp',
51
- 'class' => 'FLBuilderServiceMailChimp'
52
  ),
53
- 'mailpoet' => array(
54
- 'type' => 'autoresponder',
55
- 'name' => 'MailPoet',
56
- 'class' => 'FLBuilderServiceMailPoet'
57
  )
58
  );
59
 
@@ -61,13 +61,13 @@ final class FLBuilderServices {
61
  * Get an array of services data of a certain type such as "autoresponder".
62
  * If no type is specified, all services will be returned.
63
  *
64
- * @since 1.5.4
65
- * @param string $type The type of service data to return.
66
- * @return array An array of services and related data.
67
- */
68
- static public function get_services_data( $type = null )
69
- {
70
- $services = array();
71
 
72
  // Return all services.
73
  if ( ! $type ) {
@@ -89,26 +89,26 @@ final class FLBuilderServices {
89
  /**
90
  * Get an instance of a service helper class.
91
  *
92
- * @since 1.5.4
93
- * @param string $type The type of service.
94
- * @return object
95
- */
96
- static public function get_service_instance( $service )
97
- {
98
- $services = self::get_services_data();
99
- $data = $services[ $service ];
100
-
101
- // Make sure the base class is loaded.
102
- if ( ! class_exists( 'FLBuilderService' ) ) {
103
- require_once FL_BUILDER_DIR . 'classes/class-fl-builder-service.php';
104
- }
105
-
106
- // Make sure the service class is loaded.
107
- if ( ! class_exists( $data['class'] ) ) {
108
- require_once FL_BUILDER_DIR . 'classes/class-fl-builder-service-' . $service . '.php';
109
- }
110
-
111
- return new $data['class']();
112
  }
113
 
114
  /**
@@ -118,61 +118,61 @@ final class FLBuilderServices {
118
  *
119
  * @since 1.5.4
120
  * @return string The JSON encoded response.
121
- */
122
- static public function connect_service()
123
- {
124
- $saved_services = FLBuilderModel::get_services();
125
- $post_data = FLBuilderModel::get_post_data();
126
- $response = array(
127
- 'error' => false,
128
- 'html' => ''
129
- );
130
-
131
- // Validate the service data.
132
- if ( ! isset( $post_data['service'] ) || empty( $post_data['service'] ) ) {
133
- $response['error'] = _x( 'Error: Missing service type.', 'Third party service such as MailChimp.', 'fl-builder' );
134
- }
135
- else if ( ! isset( $post_data['fields'] ) || 0 === count( $post_data['fields'] ) ) {
136
- $response['error'] = _x( 'Error: Missing service data.', 'Connection data such as an API key.', 'fl-builder' );
137
- }
138
- else if ( ! isset( $post_data['fields']['service_account'] ) || empty( $post_data['fields']['service_account'] ) ) {
139
- $response['error'] = _x( 'Error: Missing account name.', 'Account name for a third party service such as MailChimp.', 'fl-builder' );
140
- }
141
-
142
- // Get the service data.
143
- $service = $post_data['service'];
144
  $service_account = $post_data['fields']['service_account'];
145
-
146
- // Does this account already exist?
147
- if ( isset( $saved_services[ $service ][ $service_account ] ) ) {
148
- $response['error'] = _x( 'Error: An account with that name already exists.', 'Account name for a third party service such as MailChimp.', 'fl-builder' );
149
- }
150
-
151
- // Try to connect to the service.
152
- if ( ! $response['error'] ) {
153
-
154
- $instance = self::get_service_instance( $service );
155
- $connection = $instance->connect( $post_data['fields'] );
156
-
157
- if ( $connection['error'] ) {
158
- $response['error'] = $connection['error'];
159
- }
160
- else {
161
-
162
- FLBuilderModel::update_services(
163
- $service,
164
- $service_account,
165
- $connection['data']
166
- );
167
-
168
- $response['html'] = self::render_account_settings( $service, $service_account );
169
- }
170
- }
171
-
172
- // Return the response.
173
- echo json_encode( $response );
174
-
175
- die();
176
  }
177
 
178
  /**
@@ -182,67 +182,67 @@ final class FLBuilderServices {
182
  *
183
  * @since 1.5.4
184
  * @return string The JSON encoded response.
185
- */
186
- static public function render_settings()
187
- {
188
- $post_data = FLBuilderModel::get_post_data();
189
- $saved_services = FLBuilderModel::get_services();
190
- $module = FLBuilderModel::get_module( $post_data['node_id'] );
191
- $settings = $module->settings;
192
- $service = $post_data['service'];
193
- $response = array(
194
- 'error' => false,
195
- 'html' => ''
196
- );
197
-
198
- // Render the settings to connect a new account.
199
- if ( isset( $post_data['add_new'] ) || ! isset( $saved_services[ $service ] ) ) {
200
- $response['html'] = self::render_connect_settings( $service );
201
- }
202
- // Render the settings to select a connected account.
203
- else {
204
- $account = isset( $settings->service_account ) ? $settings->service_account : '';
205
- $response['html'] = self::render_account_settings( $service, $account );
206
- }
207
-
208
- // Return the response.
209
- echo json_encode( $response );
210
-
211
- die();
212
- }
213
 
214
  /**
215
  * Render the settings to connect to a new account.
216
  *
217
  * @since 1.5.4
218
  * @return string The settings markup.
219
- */
220
- static public function render_connect_settings( $service )
221
- {
222
- ob_start();
223
-
224
- FLBuilder::render_settings_field( 'service_account', array(
225
- 'row_class' => 'fl-builder-service-connect-row',
226
- 'class' => 'fl-builder-service-connect-input',
227
- 'type' => 'text',
228
- 'label' => __( 'Account Name', 'fl-builder' ),
229
- 'help' => __( 'Used to identify this connection within the accounts list and can be anything you like.', 'fl-builder' ),
230
- 'preview' => array(
231
- 'type' => 'none'
232
- )
233
  ));
234
 
235
  $instance = self::get_service_instance( $service );
236
  echo $instance->render_connect_settings();
237
-
238
- FLBuilder::render_settings_field( 'service_connect_button', array(
239
- 'row_class' => 'fl-builder-service-connect-row',
240
- 'class' => 'fl-builder-service-connect-button',
241
- 'type' => 'button',
242
- 'label' => __( 'Connect', 'fl-builder' )
243
  ));
244
-
245
- return ob_get_clean();
246
  }
247
 
248
  /**
@@ -252,49 +252,49 @@ final class FLBuilderServices {
252
  * @param string $service The service id such as "mailchimp".
253
  * @param string $active The name of the active account, if any.
254
  * @return string The account settings markup.
255
- */
256
- static public function render_account_settings( $service, $active = '' )
257
- {
258
- ob_start();
259
-
260
- $saved_services = FLBuilderModel::get_services();
261
- $settings = new stdClass();
262
- $settings->service_account = $active;
263
- $options = array( '' => __( 'Choose...', 'fl-builder' ) );
264
-
265
- // Build the account select options.
266
- foreach ( $saved_services[ $service ] as $account => $data ) {
267
- $options[ $account ] = $account;
268
- }
269
-
270
- $options['add_new_account'] = __( 'Add Account...', 'fl-builder' );
271
-
272
- // Render the account select.
273
- FLBuilder::render_settings_field( 'service_account', array(
274
- 'row_class' => 'fl-builder-service-account-row',
275
- 'class' => 'fl-builder-service-account-select',
276
- 'type' => 'select',
277
- 'label' => __( 'Account', 'fl-builder' ),
278
- 'options' => $options,
279
- 'preview' => array(
280
- 'type' => 'none'
281
- )
282
  ), $settings);
283
 
284
  // Render additional service fields if we have a saved account.
285
  if ( ! empty( $active ) && isset( $saved_services[ $service ][ $active ] ) ) {
286
 
287
- $post_data = FLBuilderModel::get_post_data();
288
- $module = FLBuilderModel::get_module( $post_data['node_id'] );
289
- $instance = self::get_service_instance( $service );
290
- $response = $instance->render_fields( $active, $module->settings );
291
 
292
  if ( ! $response['error'] ) {
293
  echo $response['html'];
294
  }
295
  }
296
-
297
- return ob_get_clean();
298
  }
299
 
300
  /**
@@ -304,17 +304,17 @@ final class FLBuilderServices {
304
  *
305
  * @since 1.5.4
306
  * @return string The JSON encoded response.
307
- */
308
- static public function render_fields()
309
- {
310
- $post_data = FLBuilderModel::get_post_data();
311
- $module = FLBuilderModel::get_module( $post_data['node_id'] );
312
- $instance = self::get_service_instance( $post_data['service'] );
313
- $response = $instance->render_fields( $post_data['account'], $module->settings );
314
-
315
- echo json_encode( $response );
316
-
317
- die();
318
  }
319
 
320
  /**
@@ -324,15 +324,15 @@ final class FLBuilderServices {
324
  *
325
  * @since 1.5.4
326
  * @return void
327
- */
328
- static public function delete_account()
329
- {
330
- $post_data = FLBuilderModel::get_post_data();
331
-
332
- if ( ! isset( $post_data['service'] ) || ! isset( $post_data['account'] ) ) {
333
- return;
334
- }
335
-
336
- FLBuilderModel::delete_service_account( $post_data['service'], $post_data['account'] );
337
  }
338
  }
11
  * Data for working with each supported third party service.
12
  *
13
  * @since 1.5.4
14
+ * @access private
15
+ * @var array $services_data
16
+ */
17
  static private $services_data = array(
18
+ 'aweber' => array(
19
+ 'type' => 'autoresponder',
20
+ 'name' => 'AWeber',
21
+ 'class' => 'FLBuilderServiceAWeber'
22
  ),
23
+ 'campaign-monitor' => array(
24
+ 'type' => 'autoresponder',
25
+ 'name' => 'Campaign Monitor',
26
+ 'class' => 'FLBuilderServiceCampaignMonitor'
27
  ),
28
+ 'constant-contact' => array(
29
+ 'type' => 'autoresponder',
30
+ 'name' => 'Constant Contact',
31
+ 'class' => 'FLBuilderServiceConstantContact'
32
  ),
33
+ 'getresponse' => array(
34
+ 'type' => 'autoresponder',
35
+ 'name' => 'GetResponse',
36
+ 'class' => 'FLBuilderServiceGetResponse'
37
  ),
38
+ 'icontact' => array(
39
+ 'type' => 'autoresponder',
40
+ 'name' => 'iContact',
41
+ 'class' => 'FLBuilderServiceIContact'
42
  ),
43
+ 'madmimi' => array(
44
+ 'type' => 'autoresponder',
45
+ 'name' => 'Mad Mimi',
46
+ 'class' => 'FLBuilderServiceMadMimi'
47
  ),
48
+ 'mailchimp' => array(
49
+ 'type' => 'autoresponder',
50
+ 'name' => 'MailChimp',
51
+ 'class' => 'FLBuilderServiceMailChimp'
52
  ),
53
+ 'sendinblue' => array(
54
+ 'type' => 'autoresponder',
55
+ 'name' => 'SendinBlue',
56
+ 'class' => 'FLBuilderServiceSendinBlue'
57
  )
58
  );
59
 
61
  * Get an array of services data of a certain type such as "autoresponder".
62
  * If no type is specified, all services will be returned.
63
  *
64
+ * @since 1.5.4
65
+ * @param string $type The type of service data to return.
66
+ * @return array An array of services and related data.
67
+ */
68
+ static public function get_services_data( $type = null )
69
+ {
70
+ $services = array();
71
 
72
  // Return all services.
73
  if ( ! $type ) {
89
  /**
90
  * Get an instance of a service helper class.
91
  *
92
+ * @since 1.5.4
93
+ * @param string $type The type of service.
94
+ * @return object
95
+ */
96
+ static public function get_service_instance( $service )
97
+ {
98
+ $services = self::get_services_data();
99
+ $data = $services[ $service ];
100
+
101
+ // Make sure the base class is loaded.
102
+ if ( ! class_exists( 'FLBuilderService' ) ) {
103
+ require_once FL_BUILDER_DIR . 'classes/class-fl-builder-service.php';
104
+ }
105
+
106
+ // Make sure the service class is loaded.
107
+ if ( ! class_exists( $data['class'] ) ) {
108
+ require_once FL_BUILDER_DIR . 'classes/class-fl-builder-service-' . $service . '.php';
109
+ }
110
+
111
+ return new $data['class']();
112
  }
113
 
114
  /**
118
  *
119
  * @since 1.5.4
120
  * @return string The JSON encoded response.
121
+ */
122
+ static public function connect_service()
123
+ {
124
+ $saved_services = FLBuilderModel::get_services();
125
+ $post_data = FLBuilderModel::get_post_data();
126
+ $response = array(
127
+ 'error' => false,
128
+ 'html' => ''
129
+ );
130
+
131
+ // Validate the service data.
132
+ if ( ! isset( $post_data['service'] ) || empty( $post_data['service'] ) ) {
133
+ $response['error'] = _x( 'Error: Missing service type.', 'Third party service such as MailChimp.', 'fl-builder' );
134
+ }
135
+ else if ( ! isset( $post_data['fields'] ) || 0 === count( $post_data['fields'] ) ) {
136
+ $response['error'] = _x( 'Error: Missing service data.', 'Connection data such as an API key.', 'fl-builder' );
137
+ }
138
+ else if ( ! isset( $post_data['fields']['service_account'] ) || empty( $post_data['fields']['service_account'] ) ) {
139
+ $response['error'] = _x( 'Error: Missing account name.', 'Account name for a third party service such as MailChimp.', 'fl-builder' );
140
+ }
141
+
142
+ // Get the service data.
143
+ $service = $post_data['service'];
144
  $service_account = $post_data['fields']['service_account'];
145
+
146
+ // Does this account already exist?
147
+ if ( isset( $saved_services[ $service ][ $service_account ] ) ) {
148
+ $response['error'] = _x( 'Error: An account with that name already exists.', 'Account name for a third party service such as MailChimp.', 'fl-builder' );
149
+ }
150
+
151
+ // Try to connect to the service.
152
+ if ( ! $response['error'] ) {
153
+
154
+ $instance = self::get_service_instance( $service );
155
+ $connection = $instance->connect( $post_data['fields'] );
156
+
157
+ if ( $connection['error'] ) {
158
+ $response['error'] = $connection['error'];
159
+ }
160
+ else {
161
+
162
+ FLBuilderModel::update_services(
163
+ $service,
164
+ $service_account,
165
+ $connection['data']
166
+ );
167
+
168
+ $response['html'] = self::render_account_settings( $service, $service_account );
169
+ }
170
+ }
171
+
172
+ // Return the response.
173
+ echo json_encode( $response );
174
+
175
+ die();
176
  }
177
 
178
  /**
182
  *
183
  * @since 1.5.4
184
  * @return string The JSON encoded response.
185
+ */
186
+ static public function render_settings()
187
+ {
188
+ $post_data = FLBuilderModel::get_post_data();
189
+ $saved_services = FLBuilderModel::get_services();
190
+ $module = FLBuilderModel::get_module( $post_data['node_id'] );
191
+ $settings = $module->settings;
192
+ $service = $post_data['service'];
193
+ $response = array(
194
+ 'error' => false,
195
+ 'html' => ''
196
+ );
197
+
198
+ // Render the settings to connect a new account.
199
+ if ( isset( $post_data['add_new'] ) || ! isset( $saved_services[ $service ] ) ) {
200
+ $response['html'] = self::render_connect_settings( $service );
201
+ }
202
+ // Render the settings to select a connected account.
203
+ else {
204
+ $account = isset( $settings->service_account ) ? $settings->service_account : '';
205
+ $response['html'] = self::render_account_settings( $service, $account );
206
+ }
207
+
208
+ // Return the response.
209
+ echo json_encode( $response );
210
+
211
+ die();
212
+ }
213
 
214
  /**
215
  * Render the settings to connect to a new account.
216
  *
217
  * @since 1.5.4
218
  * @return string The settings markup.
219
+ */
220
+ static public function render_connect_settings( $service )
221
+ {
222
+ ob_start();
223
+
224
+ FLBuilder::render_settings_field( 'service_account', array(
225
+ 'row_class' => 'fl-builder-service-connect-row',
226
+ 'class' => 'fl-builder-service-connect-input',
227
+ 'type' => 'text',
228
+ 'label' => __( 'Account Name', 'fl-builder' ),
229
+ 'help' => __( 'Used to identify this connection within the accounts list and can be anything you like.', 'fl-builder' ),
230
+ 'preview' => array(
231
+ 'type' => 'none'
232
+ )
233
  ));
234
 
235
  $instance = self::get_service_instance( $service );
236
  echo $instance->render_connect_settings();
237
+
238
+ FLBuilder::render_settings_field( 'service_connect_button', array(
239
+ 'row_class' => 'fl-builder-service-connect-row',
240
+ 'class' => 'fl-builder-service-connect-button',
241
+ 'type' => 'button',
242
+ 'label' => __( 'Connect', 'fl-builder' )
243
  ));
244
+
245
+ return ob_get_clean();
246
  }
247
 
248
  /**
252
  * @param string $service The service id such as "mailchimp".
253
  * @param string $active The name of the active account, if any.
254
  * @return string The account settings markup.
255
+ */
256
+ static public function render_account_settings( $service, $active = '' )
257
+ {
258
+ ob_start();
259
+
260
+ $saved_services = FLBuilderModel::get_services();
261
+ $settings = new stdClass();
262
+ $settings->service_account = $active;
263
+ $options = array( '' => __( 'Choose...', 'fl-builder' ) );
264
+
265
+ // Build the account select options.
266
+ foreach ( $saved_services[ $service ] as $account => $data ) {
267
+ $options[ $account ] = $account;
268
+ }
269
+
270
+ $options['add_new_account'] = __( 'Add Account...', 'fl-builder' );
271
+
272
+ // Render the account select.
273
+ FLBuilder::render_settings_field( 'service_account', array(
274
+ 'row_class' => 'fl-builder-service-account-row',
275
+ 'class' => 'fl-builder-service-account-select',
276
+ 'type' => 'select',
277
+ 'label' => __( 'Account', 'fl-builder' ),
278
+ 'options' => $options,
279
+ 'preview' => array(
280
+ 'type' => 'none'
281
+ )
282
  ), $settings);
283
 
284
  // Render additional service fields if we have a saved account.
285
  if ( ! empty( $active ) && isset( $saved_services[ $service ][ $active ] ) ) {
286
 
287
+ $post_data = FLBuilderModel::get_post_data();
288
+ $module = FLBuilderModel::get_module( $post_data['node_id'] );
289
+ $instance = self::get_service_instance( $service );
290
+ $response = $instance->render_fields( $active, $module->settings );
291
 
292
  if ( ! $response['error'] ) {
293
  echo $response['html'];
294
  }
295
  }
296
+
297
+ return ob_get_clean();
298
  }
299
 
300
  /**
304
  *
305
  * @since 1.5.4
306
  * @return string The JSON encoded response.
307
+ */
308
+ static public function render_fields()
309
+ {
310
+ $post_data = FLBuilderModel::get_post_data();
311
+ $module = FLBuilderModel::get_module( $post_data['node_id'] );
312
+ $instance = self::get_service_instance( $post_data['service'] );
313
+ $response = $instance->render_fields( $post_data['account'], $module->settings );
314
+
315
+ echo json_encode( $response );
316
+
317
+ die();
318
  }
319
 
320
  /**
324
  *
325
  * @since 1.5.4
326
  * @return void
327
+ */
328
+ static public function delete_account()
329
+ {
330
+ $post_data = FLBuilderModel::get_post_data();
331
+
332
+ if ( ! isset( $post_data['service'] ) || ! isset( $post_data['account'] ) ) {
333
+ return;
334
+ }
335
+
336
+ FLBuilderModel::delete_service_account( $post_data['service'], $post_data['account'] );
337
  }
338
  }
classes/class-fl-builder-update.php CHANGED
@@ -1,367 +1,401 @@
1
  <?php
2
 
3
  /**
4
- * @class FLBuilderUpdate
 
 
5
  */
6
  final class FLBuilderUpdate {
7
 
8
- /**
9
- * @method init
10
- */
11
- static public function init()
12
- {
13
- // Make sure the user is logged in.
14
- if ( ! is_user_logged_in() ) {
15
- return;
16
- }
17
-
18
- // Don't update for dev copies.
19
- if ( FL_BUILDER_VERSION == '{FL_BUILDER_VERSION}' ) {
20
- return;
21
- }
22
-
23
- // Get the saved version.
24
- $saved_version = get_site_option( '_fl_builder_version' );
25
-
26
- // No saved version number. This must be a fresh install.
27
- if ( ! $saved_version ) {
28
- update_site_option( '_fl_builder_version', FL_BUILDER_VERSION );
29
- return;
30
- }
31
- // Only run updates if the version numbers don't match.
32
- else if ( ! version_compare( $saved_version, FL_BUILDER_VERSION, '=' ) ) {
33
-
34
- if ( is_multisite() ) {
35
- self::run_multisite( $saved_version );
36
- }
37
- else {
38
- self::run( $saved_version );
39
- }
40
-
41
- update_site_option( '_fl_builder_version', FL_BUILDER_VERSION );
42
- }
43
- }
44
-
45
- /**
46
- * @method run
47
- * @private
48
- */
49
- static private function run( $saved_version )
50
- {
51
- // Update to 1.2.8 or greater.
52
- if ( version_compare( $saved_version, '1.2.8', '<' ) ) {
53
- self::v_1_2_8();
54
- }
55
-
56
- // Update to 1.4.6 or greater.
57
- if ( version_compare( $saved_version, '1.4.6', '<' ) ) {
58
- self::v_1_4_6();
59
- }
60
-
61
- // Clear all asset cache.
62
- FLBuilderModel::delete_all_asset_cache();
63
- }
64
 
65
- /**
66
- * @method run_multisite
67
- * @private
68
- */
69
- static private function run_multisite( $saved_version )
70
- {
71
- global $blog_id;
72
- global $wpdb;
73
-
74
- // Save the original blog id.
75
- $original_blog_id = $blog_id;
76
-
77
- // Get all blog ids.
78
- $blog_ids = $wpdb->get_col( "SELECT blog_id FROM $wpdb->blogs" );
79
-
80
- // Loop through the blog ids and run the update.
81
- foreach ( $blog_ids as $id ) {
82
- switch_to_blog( $id );
83
- self::run( $saved_version );
84
- }
85
-
86
- // Revert to the original blog.
87
- switch_to_blog( $original_blog_id );
88
- }
89
 
90
- /**
91
- * Check for the fl_builder_nodes table that existed before 1.2.8.
92
- *
93
- * @method pre_1_2_8_table_exists
94
- * @private
95
- */
96
- static private function pre_1_2_8_table_exists()
97
- {
98
- global $wpdb;
99
-
100
- $table = $wpdb->prefix . 'fl_builder_nodes';
101
- $results = $wpdb->get_results("SHOW TABLES LIKE '{$table}'");
102
-
103
- return count($results) > 0;
104
- }
 
 
 
 
 
 
 
 
 
 
 
 
105
 
106
- /**
107
- * Check to see if the fl_builder_nodes table that existed before 1.2.8
108
- * is empty or not.
109
- *
110
- * @method pre_1_2_8_table_is_empty
111
- * @private
112
- */
113
- static private function pre_1_2_8_table_is_empty()
114
- {
115
- global $wpdb;
116
-
117
- if(self::pre_1_2_8_table_exists()) {
118
-
119
- $table = $wpdb->prefix . 'fl_builder_nodes';
120
- $nodes = $wpdb->get_results("SELECT * FROM {$table}");
121
-
122
- return count($nodes) === 0;
123
- }
124
-
125
- return true;
126
- }
127
 
128
- /**
129
- * @method pre_1_2_8_backup
130
- * @private
131
- */
132
- static private function pre_1_2_8_backup()
133
- {
134
- global $wpdb;
135
-
136
- if(self::pre_1_2_8_table_exists()) {
137
-
138
- $cache_dir = FLBuilderModel::get_cache_dir();
139
- $table = $wpdb->prefix . 'fl_builder_nodes';
 
 
 
 
 
 
 
 
 
 
140
 
141
- // Get the data to backup.
142
- $nodes = $wpdb->get_results("SELECT * FROM {$table}");
143
- $meta = $wpdb->get_results("SELECT * FROM {$wpdb->postmeta} WHERE meta_key = '_fl_builder_layout'");
144
-
145
- // Build the export object.
146
- $data = new StdClass();
147
- $data->version = FL_BUILDER_VERSION;
148
- $data->nodes = $nodes;
149
- $data->meta = $meta;
150
-
151
- // Save the backup.
152
- file_put_contents($cache_dir['path'] . 'backup.dat', serialize($data));
153
- }
154
- }
 
155
 
156
- /**
157
- * @method pre_1_2_8_restore
158
- * @private
159
- */
160
- static private function pre_1_2_8_restore()
161
- {
162
- global $wpdb;
163
-
164
- if(!self::pre_1_2_8_table_exists() || self::pre_1_2_8_table_is_empty()) {
165
-
166
- $cache_dir = FLBuilderModel::get_cache_dir();
167
- $backup_path = $cache_dir['path'] . 'backup.dat';
168
-
169
- // Install the database.
170
- FLBuilderModel::install_database();
171
-
172
- // Check for the backup file.
173
- if(file_exists($backup_path)) {
174
-
175
- // Get the backup data.
176
- $backup = unserialize(file_get_contents($backup_path));
177
-
178
- // Check for the correct backup data.
179
- if(!isset($backup->nodes) || !isset($backup->meta)) {
180
- return;
181
- }
182
-
183
- // Restore the nodes.
184
- foreach($backup->nodes as $node) {
185
-
186
- $wpdb->insert("{$wpdb->prefix}fl_builder_nodes",
187
- array(
188
- 'node' => $node->node,
189
- 'type' => $node->type,
190
- 'layout' => $node->layout,
191
- 'parent' => $node->parent,
192
- 'position' => $node->position,
193
- 'settings' => $node->settings,
194
- 'status' => $node->status
195
- ),
196
- array('%s', '%s', '%s', '%s', '%d', '%s', '%s')
197
- );
198
- }
199
-
200
- // Restore the meta.
201
- foreach($backup->meta as $meta) {
202
- update_post_meta($meta->post_id, '_fl_builder_layout', $meta->meta_value);
203
- }
204
- }
205
- }
206
- }
207
 
208
- /**
209
- * Update to version 1.2.8 or later.
210
- *
211
- * @method v_1_2_8
212
- * @private
213
- */
214
- static private function v_1_2_8()
215
- {
216
- global $wpdb;
217
-
218
- if(self::pre_1_2_8_table_exists()) {
219
-
220
- $table = $wpdb->prefix . 'fl_builder_nodes';
221
- $metas = $wpdb->get_results("SELECT * FROM {$wpdb->postmeta} WHERE meta_key = '_fl_builder_layout'");
222
- $cache_dir = FLBuilderModel::get_cache_dir();
223
-
224
- // Loop through the layout ids for each post.
225
- foreach($metas as $meta) {
226
-
227
- // Get the old layout nodes from the database.
228
- $published = $wpdb->get_results("SELECT * FROM {$table} WHERE layout = '{$meta->meta_value}' AND status = 'published'");
229
- $draft = $wpdb->get_results("SELECT * FROM {$table} WHERE layout = '{$meta->meta_value}' AND status = 'draft'");
230
-
231
- // Convert the old nodes to new ones.
232
- $published = self::v_1_2_8_convert_nodes($published);
233
- $draft = self::v_1_2_8_convert_nodes($draft);
234
-
235
- // Add the new layout post meta.
236
- update_post_meta($meta->post_id, '_fl_builder_data', $published);
237
- update_post_meta($meta->post_id, '_fl_builder_draft', $draft);
238
- }
239
-
240
- // Backup the old builder table.
241
- self::pre_1_2_8_backup();
242
-
243
- // Drop the old builder table.
244
- if(file_exists($cache_dir['path'] . 'backup.dat')) {
245
- $wpdb->query("DROP TABLE {$wpdb->prefix}fl_builder_nodes");
246
- }
247
-
248
- // Delete old post meta.
249
- delete_post_meta_by_key('_fl_builder_layout');
250
- delete_post_meta_by_key('_fl_builder_layout_export');
251
- delete_post_meta_by_key('_fl_builder_css');
252
- delete_post_meta_by_key('_fl_builder_css-draft');
253
- delete_post_meta_by_key('_fl_builder_js');
254
- delete_post_meta_by_key('_fl_builder_js-draft');
255
-
256
- // Convert global settings.
257
- self::v_1_2_8_convert_global_settings();
258
-
259
- // Delete all asset cache.
260
- $css = glob( $cache_dir['path'] . '*.css' );
261
- $js = glob( $cache_dir['path'] . '*.js' );
262
-
263
- if ( is_array( $css ) ) {
264
- array_map( 'unlink', $css );
265
- }
266
- if ( is_array( $js ) ) {
267
- array_map( 'unlink', $js );
268
- }
269
- }
270
- }
271
 
272
- /**
273
- * @method v_1_2_8_convert_global_settings
274
- * @private
275
- */
276
- static private function v_1_2_8_convert_global_settings()
277
- {
278
- $settings = get_option('_fl_builder_settings');
279
-
280
- if($settings && is_string($settings)) {
281
- update_option('_fl_builder_settings', json_decode($settings));
282
- }
283
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
284
 
285
- /**
286
- * @method v_1_2_8_convert_nodes
287
- * @private
288
- */
289
- static private function v_1_2_8_convert_nodes($nodes)
290
- {
291
- $new_nodes = array();
292
-
293
- foreach($nodes as $node) {
294
-
295
- unset($node->id);
296
- unset($node->layout);
297
- unset($node->status);
298
-
299
- if($node->type == 'row') {
300
- $node->parent = null;
301
- }
302
-
303
- $node->settings = self::v_1_2_8_json_decode_settings($node->settings);
304
- $new_nodes[$node->node] = $node;
305
- }
306
-
307
- return $new_nodes;
308
- }
309
 
310
- /**
311
- * @method v_1_2_8_json_decode_settings
312
- * @private
313
- */
314
- static private function v_1_2_8_json_decode_settings($settings)
315
- {
316
- if(!$settings || empty($settings)) {
317
- return null;
318
- }
319
-
320
- $settings = json_decode($settings);
321
-
322
- foreach($settings as $key => $val) {
323
-
324
- if(is_string($val)) {
325
-
326
- $decoded = json_decode($val);
327
-
328
- if(is_object($decoded) || is_array($decoded)) {
329
-
330
- $settings->{$key} = $decoded;
331
- }
332
- }
333
- else if(is_array($val)) {
334
-
335
- foreach($val as $sub_key => $sub_val) {
336
-
337
- if(is_string($sub_val)) {
338
-
339
- $decoded = json_decode($sub_val);
340
-
341
- if(is_object($decoded) || is_array($decoded)) {
342
-
343
- $settings->{$key}[$sub_key] = $decoded;
344
- }
345
- }
346
- }
347
- }
348
- }
349
-
350
- return $settings;
351
- }
352
 
353
- /**
354
- * Update to version 1.4.6 or later.
355
- *
356
- * @method v_1_4_6
357
- * @private
358
- */
359
- static private function v_1_4_6()
360
- {
361
- // Remove the old fl-builder uploads folder.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
362
  $filesystem = FLBuilderUtils::get_filesystem();
363
  $upload_dir = wp_upload_dir();
364
- $path = trailingslashit( $upload_dir['basedir'] ) . 'fl-builder';
365
 
366
  if ( file_exists( $path ) ) {
367
  $filesystem->rmdir( $path, true );
1
  <?php
2
 
3
  /**
4
+ * Helper class for builder updates.
5
+ *
6
+ * @since 1.2.8
7
  */
8
  final class FLBuilderUpdate {
9
 
10
+ /**
11
+ * Checks to see if an update should be run. If it should,
12
+ * the appropriate update method is run and the version
13
+ * number is updated in the database.
14
+ *
15
+ * @since 1.2.8
16
+ * @return void
17
+ */
18
+ static public function init()
19
+ {
20
+ // Make sure the user is logged in.
21
+ if ( ! is_user_logged_in() ) {
22
+ return;
23
+ }
24
+
25
+ // Don't update for dev copies.
26
+ if ( FL_BUILDER_VERSION == '{FL_BUILDER_VERSION}' ) {
27
+ return;
28
+ }
29
+
30
+ // Get the saved version.
31
+ $saved_version = get_site_option( '_fl_builder_version' );
32
+
33
+ // No saved version number. This must be a fresh install.
34
+ if ( ! $saved_version ) {
35
+ update_site_option( '_fl_builder_version', FL_BUILDER_VERSION );
36
+ return;
37
+ }
38
+ // Only run updates if the version numbers don't match.
39
+ else if ( ! version_compare( $saved_version, FL_BUILDER_VERSION, '=' ) ) {
40
+
41
+ if ( is_multisite() ) {
42
+ self::run_multisite( $saved_version );
43
+ }
44
+ else {
45
+ self::run( $saved_version );
46
+ }
47
+
48
+ update_site_option( '_fl_builder_version', FL_BUILDER_VERSION );
49
+ }
50
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
 
52
+ /**
53
+ * Runs the update for a specific version.
54
+ *
55
+ * @since 1.2.8
56
+ * @access private
57
+ * @return void
58
+ */
59
+ static private function run( $saved_version )
60
+ {
61
+ // Update to 1.2.8 or greater.
62
+ if ( version_compare( $saved_version, '1.2.8', '<' ) ) {
63
+ self::v_1_2_8();
64
+ }
65
+
66
+ // Update to 1.4.6 or greater.
67
+ if ( version_compare( $saved_version, '1.4.6', '<' ) ) {
68
+ self::v_1_4_6();
69
+ }
70
+
71
+ // Clear all asset cache.
72
+ FLBuilderModel::delete_all_asset_cache();
73
+ }
 
 
74
 
75
+ /**
76
+ * Runs the update for all sites on a network install.
77
+ *
78
+ * @since 1.2.8
79
+ * @access private
80
+ * @return void
81
+ */
82
+ static private function run_multisite( $saved_version )
83
+ {
84
+ global $blog_id;
85
+ global $wpdb;
86
+
87
+ // Save the original blog id.
88
+ $original_blog_id = $blog_id;
89
+
90
+ // Get all blog ids.
91
+ $blog_ids = $wpdb->get_col( "SELECT blog_id FROM $wpdb->blogs" );
92
+
93
+ // Loop through the blog ids and run the update.
94
+ foreach ( $blog_ids as $id ) {
95
+ switch_to_blog( $id );
96
+ self::run( $saved_version );
97
+ }
98
+
99
+ // Revert to the original blog.
100
+ switch_to_blog( $original_blog_id );
101
+ }
102
 
103
+ /**
104
+ * Check for the fl_builder_nodes table that existed before 1.2.8.
105
+ *
106
+ * @since 1.2.8
107
+ * @access private
108
+ * @return bool
109
+ */
110
+ static private function pre_1_2_8_table_exists()
111
+ {
112
+ global $wpdb;
113
+
114
+ $table = $wpdb->prefix . 'fl_builder_nodes';
115
+ $results = $wpdb->get_results("SHOW TABLES LIKE '{$table}'");
116
+
117
+ return count($results) > 0;
118
+ }
 
 
 
 
 
119
 
120
+ /**
121
+ * Check to see if the fl_builder_nodes table that existed before 1.2.8
122
+ * is empty or not.
123
+ *
124
+ * @since 1.2.8
125
+ * @access private
126
+ * @return bool
127
+ */
128
+ static private function pre_1_2_8_table_is_empty()
129
+ {
130
+ global $wpdb;
131
+
132
+ if(self::pre_1_2_8_table_exists()) {
133
+
134
+ $table = $wpdb->prefix . 'fl_builder_nodes';
135
+ $nodes = $wpdb->get_results("SELECT * FROM {$table}");
136
+
137
+ return count($nodes) === 0;
138
+ }
139
+
140
+ return true;
141
+ }
142
 
143
+ /**
144
+ * Saves a backup of the pre 1.2.8 database table.
145
+ *
146
+ * @since 1.2.8
147
+ * @access private
148
+ * @return void
149
+ */
150
+ static private function pre_1_2_8_backup()
151
+ {
152
+ global $wpdb;
153
+
154
+ if(self::pre_1_2_8_table_exists()) {
155
+
156
+ $cache_dir = FLBuilderModel::get_cache_dir();
157
+ $table = $wpdb->prefix . 'fl_builder_nodes';
158
 
159
+ // Get the data to backup.
160
+ $nodes = $wpdb->get_results("SELECT * FROM {$table}");
161
+ $meta = $wpdb->get_results("SELECT * FROM {$wpdb->postmeta} WHERE meta_key = '_fl_builder_layout'");
162
+
163
+ // Build the export object.
164
+ $data = new StdClass();
165
+ $data->version = FL_BUILDER_VERSION;
166
+ $data->nodes = $nodes;
167
+ $data->meta = $meta;
168
+
169
+ // Save the backup.
170
+ file_put_contents($cache_dir['path'] . 'backup.dat', serialize($data));
171
+ }
172
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
173
 
174
+ /**
175
+ * Restores a site to pre 1.2.8.
176
+ *
177
+ * @since 1.2.8
178
+ * @access private
179
+ * @return void
180
+ */
181
+ static private function pre_1_2_8_restore()
182
+ {
183
+ global $wpdb;
184
+
185
+ if(!self::pre_1_2_8_table_exists() || self::pre_1_2_8_table_is_empty()) {
186
+
187
+ $cache_dir = FLBuilderModel::get_cache_dir();
188
+ $backup_path = $cache_dir['path'] . 'backup.dat';
189
+
190
+ // Install the database.
191
+ FLBuilderModel::install_database();
192
+
193
+ // Check for the backup file.
194
+ if(file_exists($backup_path)) {
195
+
196
+ // Get the backup data.
197
+ $backup = unserialize(file_get_contents($backup_path));
198
+
199
+ // Check for the correct backup data.
200
+ if(!isset($backup->nodes) || !isset($backup->meta)) {
201
+ return;
202
+ }
203
+
204
+ // Restore the nodes.
205
+ foreach($backup->nodes as $node) {
206
+
207
+ $wpdb->insert("{$wpdb->prefix}fl_builder_nodes",
208
+ array(
209
+ 'node' => $node->node,
210
+ 'type' => $node->type,
211
+ 'layout' => $node->layout,
212
+ 'parent' => $node->parent,
213
+ 'position' => $node->position,
214
+ 'settings' => $node->settings,
215
+ 'status' => $node->status
216
+ ),
217
+ array('%s', '%s', '%s', '%s', '%d', '%s', '%s')
218
+ );
219
+ }
220
+
221
+ // Restore the meta.
222
+ foreach($backup->meta as $meta) {
223
+ update_post_meta($meta->post_id, '_fl_builder_layout', $meta->meta_value);
224
+ }
225
+ }
226
+ }
227
+ }
 
 
 
 
 
 
 
 
 
228
 
229
+ /**
230
+ * Update to version 1.2.8 or later.
231
+ *
232
+ * @since 1.2.8
233
+ * @access private
234
+ * @return void
235
+ */
236
+ static private function v_1_2_8()
237
+ {
238
+ global $wpdb;
239
+
240
+ if(self::pre_1_2_8_table_exists()) {
241
+
242
+ $table = $wpdb->prefix . 'fl_builder_nodes';
243
+ $metas = $wpdb->get_results("SELECT * FROM {$wpdb->postmeta} WHERE meta_key = '_fl_builder_layout'");
244
+ $cache_dir = FLBuilderModel::get_cache_dir();
245
+
246
+ // Loop through the layout ids for each post.
247
+ foreach($metas as $meta) {
248
+
249
+ // Get the old layout nodes from the database.
250
+ $published = $wpdb->get_results("SELECT * FROM {$table} WHERE layout = '{$meta->meta_value}' AND status = 'published'");
251
+ $draft = $wpdb->get_results("SELECT * FROM {$table} WHERE layout = '{$meta->meta_value}' AND status = 'draft'");
252
+
253
+ // Convert the old nodes to new ones.
254
+ $published = self::v_1_2_8_convert_nodes($published);
255
+ $draft = self::v_1_2_8_convert_nodes($draft);
256
+
257
+ // Add the new layout post meta.
258
+ update_post_meta($meta->post_id, '_fl_builder_data', $published);
259
+ update_post_meta($meta->post_id, '_fl_builder_draft', $draft);
260
+ }
261
+
262
+ // Backup the old builder table.
263
+ self::pre_1_2_8_backup();
264
+
265
+ // Drop the old builder table.
266
+ if(file_exists($cache_dir['path'] . 'backup.dat')) {
267
+ $wpdb->query("DROP TABLE {$wpdb->prefix}fl_builder_nodes");
268
+ }
269
+
270
+ // Delete old post meta.
271
+ delete_post_meta_by_key('_fl_builder_layout');
272
+ delete_post_meta_by_key('_fl_builder_layout_export');
273
+ delete_post_meta_by_key('_fl_builder_css');
274
+ delete_post_meta_by_key('_fl_builder_css-draft');
275
+ delete_post_meta_by_key('_fl_builder_js');
276
+ delete_post_meta_by_key('_fl_builder_js-draft');
277
+
278
+ // Convert global settings.
279
+ self::v_1_2_8_convert_global_settings();
280
+
281
+ // Delete all asset cache.
282
+ $css = glob( $cache_dir['path'] . '*.css' );
283
+ $js = glob( $cache_dir['path'] . '*.js' );
284
+
285
+ if ( is_array( $css ) ) {
286
+ array_map( 'unlink', $css );
287
+ }
288
+ if ( is_array( $js ) ) {
289
+ array_map( 'unlink', $js );
290
+ }
291
+ }
292
+ }
293
 
294
+ /**
295
+ * Convert the global settings for 1.2.8 or later.
296
+ *
297
+ * @since 1.2.8
298
+ * @access private
299
+ * @return void
300
+ */
301
+ static private function v_1_2_8_convert_global_settings()
302
+ {
303
+ $settings = get_option('_fl_builder_settings');
304
+
305
+ if($settings && is_string($settings)) {
306
+ update_option('_fl_builder_settings', json_decode($settings));
307
+ }
308
+ }
 
 
 
 
 
 
 
 
 
309
 
310
+ /**
311
+ * Convert the nodes for 1.2.8 or earlier.
312
+ *
313
+ * @since 1.2.8
314
+ * @access private
315
+ * @param array $nodes An array of node data.
316
+ * @return array
317
+ */
318
+ static private function v_1_2_8_convert_nodes($nodes)
319
+ {
320
+ $new_nodes = array();
321
+
322
+ foreach($nodes as $node) {
323
+
324
+ unset($node->id);
325
+ unset($node->layout);
326
+ unset($node->status);
327
+
328
+ if($node->type == 'row') {
329
+ $node->parent = null;
330
+ }
331
+
332
+ $node->settings = self::v_1_2_8_json_decode_settings($node->settings);
333
+ $new_nodes[$node->node] = $node;
334
+ }
335
+
336
+ return $new_nodes;
337
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
338
 
339
+ /**
340
+ * Convert a JSON encoded settings string for 1.2.8 or earlier.
341
+ *
342
+ * @since 1.2.8
343
+ * @access private
344
+ * @param object $settings The settings object.
345
+ * @return object
346
+ */
347
+ static private function v_1_2_8_json_decode_settings($settings)
348
+ {
349
+ if(!$settings || empty($settings)) {
350
+ return null;
351
+ }
352
+
353
+ $settings = json_decode($settings);
354
+
355
+ foreach($settings as $key => $val) {
356
+
357
+ if(is_string($val)) {
358
+
359
+ $decoded = json_decode($val);
360
+
361
+ if(is_object($decoded) || is_array($decoded)) {
362
+
363
+ $settings->{$key} = $decoded;
364
+ }
365
+ }
366
+ else if(is_array($val)) {
367
+
368
+ foreach($val as $sub_key => $sub_val) {
369
+
370
+ if(is_string($sub_val)) {
371
+
372
+ $decoded = json_decode($sub_val);
373
+
374
+ if(is_object($decoded) || is_array($decoded)) {
375
+
376
+ $settings->{$key}[$sub_key] = $decoded;
377
+ }
378
+ }
379
+ }
380
+ }
381
+ }
382
+
383
+ return $settings;
384
+ }
385
+
386
+ /**
387
+ * Update to version 1.4.6 or later.
388
+ *
389
+ * @since 1.4.6
390
+ * @access private
391
+ * @return void
392
+ */
393
+ static private function v_1_4_6()
394
+ {
395
+ // Remove the old fl-builder uploads folder.
396
  $filesystem = FLBuilderUtils::get_filesystem();
397
  $upload_dir = wp_upload_dir();
398
+ $path = trailingslashit( $upload_dir['basedir'] ) . 'fl-builder';
399
 
400
  if ( file_exists( $path ) ) {
401
  $filesystem->rmdir( $path, true );
classes/class-fl-builder-utils.php CHANGED
@@ -3,21 +3,22 @@
3
  /**
4
  * Misc helper methods.
5
  *
6
- * @class FLBuilderUtils
7
  */
8
 
9
  final class FLBuilderUtils {
10
 
11
- /**
12
  * Get an instance of WP_Filesystem_Direct.
13
  *
14
- * @method get_filesystem
15
- */
16
- static public function get_filesystem()
17
- {
18
- global $wp_filesystem;
 
19
 
20
- require_once ABSPATH .'/wp-admin/includes/file.php';
21
 
22
  add_filter('filesystem_method', 'FLBuilderUtils::filesystem_method');
23
 
@@ -26,36 +27,91 @@ final class FLBuilderUtils {
26
  remove_filter('filesystem_method', 'FLBuilderUtils::filesystem_method');
27
 
28
  return $wp_filesystem;
29
- }
30
 
31
- /**
32
- * @method filesystem_method
33
- */
34
- static public function filesystem_method()
35
- {
36
- return 'direct';
37
- }
 
 
 
38
 
39
- /**
40
  * Return a snippet without punctuation at the end.
41
  *
42
- * @method snippetwop
43
- */
44
- static public function snippetwop($text, $length = 64, $tail = "...")
45
- {
46
- $text = trim($text);
47
- $txtl = strlen($text);
48
-
49
- if($txtl > $length) {
50
- for($i=1;$text[$length-$i]!=" ";$i++) {
51
- if($i == $length) {
52
- return substr($text,0,$length) . $tail;
53
- }
54
- }
55
- for(;$text[$length-$i]=="," || $text[$length-$i]=="." || $text[$length-$i]==" ";$i++) {;}
56
- $text = substr($text,0,$length-$i+1) . $tail;
57
- }
58
-
59
- return $text;
60
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
  }
3
  /**
4
  * Misc helper methods.
5
  *
6
+ * @since 1.0
7
  */
8
 
9
  final class FLBuilderUtils {
10
 
11
+ /**
12
  * Get an instance of WP_Filesystem_Direct.
13
  *
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
 
27
  remove_filter('filesystem_method', 'FLBuilderUtils::filesystem_method');
28
 
29
  return $wp_filesystem;
30
+ }
31
 
32
+ /**
33
+ * Sets the filesystem method to direct.
34
+ *
35
+ * @since 1.4.6
36
+ * @return string
37
+ */
38
+ static public function filesystem_method()
39
+ {
40
+ return 'direct';
41
+ }
42
 
43
+ /**
44
  * Return a snippet without punctuation at the end.
45
  *
46
+ * @since 1.2.3
47
+ * @param string $text The text to truncate.
48
+ * @param int $length The number of characters to return.
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 = strlen($text);
56
+
57
+ if($txtl > $length) {
58
+ for($i=1;$text[$length-$i]!=" ";$i++) {
59
+ if($i == $length) {
60
+ return substr($text,0,$length) . $tail;
61
+ }
62
+ }
63
+ for(;$text[$length-$i]=="," || $text[$length-$i]=="." || $text[$length-$i]==" ";$i++) {;}
64
+ $text = substr($text,0,$length-$i+1) . $tail;
65
+ }
66
+
67
+ return $text;
68
+ }
69
+
70
+ /**
71
+ * JSON decode multidimensional array values or object properties.
72
+ *
73
+ * @since 1.5.6
74
+ * @param mixed $data The data to decode.
75
+ * @return mixed The decoded data.
76
+ */
77
+ static public function json_decode_deep( $data )
78
+ {
79
+ // First check if we have a string and try to decode that.
80
+ if ( is_string( $data ) ) {
81
+ $data = json_decode( $data );
82
+ }
83
+
84
+ // Decode object properies or array values.
85
+ if ( is_object( $data ) || is_array( $data ) ) {
86
+
87
+ foreach ( $data as $key => $val ) {
88
+
89
+ $new_val = null;
90
+
91
+ if ( is_string( $val ) ) {
92
+
93
+ $decoded = json_decode( $val );
94
+
95
+ if ( is_object( $decoded ) || is_array( $decoded ) ) {
96
+ $new_val = $decoded;
97
+ }
98
+ }
99
+ else if ( is_object( $val ) || is_array( $val ) ) {
100
+ $new_val = self::json_decode_deep( $val );
101
+ }
102
+
103
+ if ( $new_val ) {
104
+
105
+ if ( is_object( $data ) ) {
106
+ $data->{$key} = $new_val;
107
+ }
108
+ else if ( is_array( $data ) ) {
109
+ $data[ $key ] = $new_val;
110
+ }
111
+ }
112
+ }
113
+ }
114
+
115
+ return $data;
116
+ }
117
  }
classes/class-fl-builder.php CHANGED
@@ -3,7 +3,7 @@
3
  /**
4
  * Main builder class.
5
  *
6
- * @class FLBuilder
7
  */
8
  final class FLBuilder {
9
 
@@ -13,7 +13,8 @@ final class FLBuilder {
13
  * Load the translation file for current language. Checks the default WordPress
14
  * languages folder first and then the languages folder inside the plugin.
15
  *
16
- * @method load_plugin_textdomain
 
17
  */
18
  static public function load_plugin_textdomain()
19
  {
@@ -38,873 +39,1004 @@ final class FLBuilder {
38
  }
39
 
40
  /**
41
- * Custom ajax handeling since wp_ajax only works in the
42
- * admin and we need everything to work on the frontend.
 
 
 
 
43
  *
44
- * @method ajax
45
- */
46
- static public function ajax()
47
- {
48
- // Only run for logged in users.
49
- if(is_user_logged_in()) {
50
-
51
- // Get builder post data.
52
- $post_data = FLBuilderModel::get_post_data();
53
-
54
- // Get the action.
55
- if(!empty($_REQUEST['fl_action'])) {
56
- $action = $_REQUEST['fl_action'];
57
- }
58
- else if(!empty($post_data['fl_action'])) {
59
- $action = $post_data['fl_action'];
60
- }
61
- else {
62
- return;
63
- }
64
-
65
- // Run the action.
66
- define('DOING_AJAX', true);
67
- do_action('fl_ajax_' . $action);
68
- die('0');
69
- }
70
- }
 
71
 
72
  /**
73
- * @method init
74
- */
75
- static public function init()
76
- {
77
- // Enable editing if the builder is active.
78
- if(FLBuilderModel::is_builder_active()) {
79
-
80
- // Tell W3TC not to minify while the builder is active.
81
- define( 'DONOTMINIFY', true );
82
-
83
- // Remove 3rd party editor buttons.
84
- remove_all_actions('media_buttons', 999999);
85
- remove_all_actions('media_buttons_context', 999999);
86
-
87
- // Get the post.
88
- require_once ABSPATH . 'wp-admin/includes/post.php';
89
- $post_id = FLBuilderModel::get_post_id();
90
-
91
- // Check to see if the post is locked.
92
- if(wp_check_post_lock($post_id) !== false) {
93
- header('Location: ' . admin_url('/post.php?post=' . $post_id . '&action=edit'));
94
- }
95
- else {
96
- FLBuilderModel::enable_editing();
97
- }
98
- }
99
- }
 
 
 
100
 
101
  /**
102
- * @method register_module
103
- */
104
- static public function register_module($class, $form)
105
- {
106
- FLBuilderModel::register_module($class, $form);
107
- }
 
 
 
 
 
108
 
109
  /**
110
- * @method register_settings_form
111
- */
112
- static public function register_settings_form($id, $form)
113
- {
114
- FLBuilderModel::register_settings_form($id, $form);
115
- }
 
 
 
 
 
116
 
117
  /**
118
- * @method no_cache_headers
119
- */
120
- static public function no_cache_headers()
121
- {
122
- if(isset($_GET['fl_builder'])) {
123
- header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
124
- header('Cache-Control: no-store, no-cache, must-revalidate');
125
- header('Cache-Control: post-check=0, pre-check=0', false);
126
- header('Pragma: no-cache');
127
- header('Expires: Sat, 26 Jul 1997 05:00:00 GMT');
128
- }
129
- }
 
 
 
130
 
131
  /**
132
- * @method default_editor
133
- */
 
 
 
 
134
  static public function default_editor($type)
135
  {
136
- return FLBuilderModel::is_builder_active() ? 'tinymce' : $type;
137
  }
138
 
139
  /**
140
- * @method add_editor_css
141
- */
 
 
 
 
142
  static public function add_editor_css($mce_css)
143
  {
144
- if(FLBuilderModel::is_builder_active()) {
145
 
146
- if(!empty($mce_css)) {
147
- $mce_css .= ',';
148
- }
149
 
150
- $mce_css .= FL_BUILDER_URL . 'css/editor.css';
151
- }
152
 
153
- return $mce_css;
154
  }
155
 
156
  /**
157
- * @method editor_buttons_2
158
- */
 
 
 
 
159
  static public function editor_buttons_2($buttons)
160
  {
161
- if(FLBuilderModel::is_builder_active()) {
162
 
163
- array_shift($buttons);
164
- array_unshift($buttons, 'fontsizeselect');
165
- array_unshift($buttons, 'formatselect');
166
 
167
- if(($key = array_search('wp_help', $buttons)) !== false) {
168
- unset($buttons[$key]);
169
- }
170
- }
171
 
172
- return $buttons;
173
  }
174
 
175
  /**
176
- * @method editor_external_plugins
177
- */
 
 
 
 
 
178
  static public function editor_external_plugins($plugins)
179
  {
180
- if(FLBuilderModel::is_builder_active()) {
181
-
182
- $allowed = array(
183
- 'anchor',
184
- 'code',
185
- 'insertdatetime',
186
- 'nonbreaking',
187
- 'print',
188
- 'searchreplace',
189
- 'table',
190
- 'visualblocks',
191
- 'visualchars',
192
- 'emoticons',
193
- 'advlist',
194
- 'wptadv',
195
- );
196
-
197
- foreach($plugins as $key => $val) {
198
- if(!in_array($key, $allowed)) {
199
- unset($plugins[$key]);
200
- }
201
- }
202
- }
203
-
204
- return $plugins;
205
  }
206
 
207
  /**
208
- * @method include_jquery
209
- */
 
 
 
 
210
  static public function include_jquery()
211
  {
212
- if(FLBuilderModel::is_builder_enabled()) {
213
- include FL_BUILDER_DIR . 'includes/jquery.php';
214
- }
215
  }
216
 
217
  /**
218
- * @method layout_styles_scripts
219
- */
 
 
 
 
220
  static public function layout_styles_scripts()
221
  {
222
- global $wp_query;
223
- global $post;
224
 
225
  $original_post = $post;
226
- $ver = FL_BUILDER_VERSION;
227
- $css_url = FL_BUILDER_URL . 'css/';
228
- $js_url = FL_BUILDER_URL . 'js/';
229
-
230
- // Register additional CSS
231
- wp_register_style('font-awesome', $css_url . 'font-awesome.min.css', array(), $ver);
232
- wp_register_style('foundation-icons', $css_url . 'foundation-icons.css', array(), $ver);
233
- wp_register_style('fl-slideshow', $css_url . 'fl-slideshow.css', array(), $ver);
234
- wp_register_style('jquery-bxslider', $css_url . 'jquery.bxslider.css', array(), $ver);
235
- wp_register_style('jquery-magnificpopup', $css_url . 'jquery.magnificpopup.css', array(), $ver);
236
-
237
- // Register additional JS
238
- wp_register_script('fl-slideshow', $js_url . 'fl-slideshow.js', array('yui3'), $ver, true);
239
- wp_register_script('fl-gallery-grid', $js_url . 'fl-gallery-grid.js', array('jquery'), $ver, true);
240
- wp_register_script('jquery-bxslider', $js_url . 'jquery.bxslider.min.js', array('jquery-easing', 'jquery-fitvids'), $ver, true);
241
- wp_register_script('jquery-easing', $js_url . 'jquery.easing.1.3.js', array('jquery'), '1.3', true);
242
- wp_register_script('jquery-fitvids', $js_url . 'jquery.fitvids.js', array('jquery'), $ver, true);
243
- wp_register_script('jquery-infinitescroll', $js_url . 'jquery.infinitescroll.js', array('jquery'), $ver, true);
244
- wp_register_script('jquery-magnificpopup', $js_url . 'jquery.magnificpopup.min.js', array('jquery'), $ver, true);
245
- wp_register_script('jquery-mosaicflow', $js_url . 'jquery.mosaicflow.min.js', array('jquery'), $ver, true);
246
- wp_register_script('jquery-waypoints', $js_url . 'jquery.waypoints.min.js', array('jquery'), $ver, true);
247
- wp_register_script('jquery-wookmark', $js_url . 'jquery.wookmark.min.js', array('jquery'), $ver, true);
248
-
249
- // YUI 3 (Needed for the slideshow)
250
- if(FLBuilderModel::is_ssl()) {
251
- wp_register_script('yui3', 'https://yui-s.yahooapis.com/3.5.1/build/yui/yui-min.js', array(), '3.5.1', false);
252
- }
253
- else {
254
- wp_register_script('yui3', 'http://yui.yahooapis.com/3.5.1/build/yui/yui-min.js', array(), '3.5.1', false);
255
- }
256
-
257
- // Enqueue assets for posts in the main query.
258
- if ( isset( $wp_query->posts ) ) {
259
- foreach ( $wp_query->posts as $post ) {
260
- self::enqueue_layout_styles_scripts( $post->ID );
261
- }
262
- }
263
-
264
- // Enqueue assets for posts via the fl_builder_global_posts filter.
265
- $post_ids = FLBuilderModel::get_global_posts();
266
-
267
- if(count($post_ids) > 0) {
268
-
269
- $posts = get_posts(array('post__in' => $post_ids, 'post_type' => 'any'));
270
-
271
- foreach($posts as $post) {
272
- self::enqueue_layout_styles_scripts($post->ID);
273
- }
274
- }
275
-
276
- // Reset the global post variable.
277
- $post = $original_post;
278
  }
279
 
280
  /**
281
- * @method enqueue_layout_styles_scripts
282
- */
 
 
 
 
283
  static public function enqueue_layout_styles_scripts($post_id)
284
  {
285
- if(FLBuilderModel::is_builder_enabled()) {
286
-
287
- $rows = FLBuilderModel::get_nodes('row');
288
- $modules = FLBuilderModel::get_all_modules();
289
- $asset_info = FLBuilderModel::get_asset_info();
290
- $asset_ver = FLBuilderModel::get_asset_version();
291
-
292
- // Enqueue required row CSS and JS
293
- foreach($rows as $row) {
294
- if($row->settings->bg_type == 'slideshow') {
295
- wp_enqueue_script('yui3');
296
- wp_enqueue_script('fl-slideshow');
297
- wp_enqueue_style('fl-slideshow');
298
- }
299
- }
300
-
301
- // Enqueue required module CSS and JS
302
- foreach($modules as $module) {
303
-
304
- $module->enqueue_icon_styles();
305
- $module->enqueue_scripts();
306
-
307
- foreach($module->css as $handle => $props) {
308
- wp_enqueue_style($handle, $props[0], $props[1], $props[2], $props[3]);
309
- }
310
- foreach($module->js as $handle => $props) {
311
- wp_enqueue_script($handle, $props[0], $props[1], $props[2], $props[3]);
312
- }
313
- if(!empty($module->settings->animation)) {
314
- wp_enqueue_script('jquery-waypoints');
315
- }
316
- }
317
-
318
- // Enqueue main CSS
319
- if(!file_exists($asset_info['css'])) {
320
- FLBuilder::render_css();
321
- }
322
-
323
- wp_enqueue_style('fl-builder-layout-' . $post_id, $asset_info['css_url'], array(), $asset_ver);
324
-
325
- // Enqueue main JS
326
- if(!file_exists($asset_info['js'])) {
327
- FLBuilder::render_js();
328
- }
329
-
330
- wp_enqueue_script('fl-builder-layout-' . $post_id, $asset_info['js_url'], array(), $asset_ver, true);
331
- }
332
  }
333
 
334
  /**
335
- * @method styles_scripts
336
- */
 
 
 
337
  static public function styles_scripts()
338
  {
339
- if(FLBuilderModel::is_builder_active()) {
340
-
341
- $ver = FL_BUILDER_VERSION;
342
- $css_url = FL_BUILDER_URL . 'css/';
343
- $js_url = FL_BUILDER_URL . 'js/';
344
-
345
- /* We have a custom version of sortable that fixes a bug. */
346
- wp_deregister_script('jquery-ui-sortable');
347
-
348
- /* Frontend builder styles */
349
- wp_enqueue_style('dashicons');
350
- wp_enqueue_style('font-awesome');
351
- wp_enqueue_style('foundation-icons');
352
- wp_enqueue_style('jquery-nanoscroller', $css_url . 'jquery.nanoscroller.css', array(), $ver);
353
- wp_enqueue_style('jquery-autosuggest', $css_url . 'jquery.autoSuggest.min.css', array(), $ver);
354
- wp_enqueue_style('jquery-tiptip', $css_url . 'jquery.tiptip.css', array(), $ver);
355
- wp_enqueue_style('bootstrap-tour', $css_url . 'bootstrap-tour-standalone.min.css', array(), $ver);
356
- wp_enqueue_style('fl-color-picker', $css_url . 'colorpicker.css', array(), $ver);
357
- wp_enqueue_style('fl-lightbox', $css_url . 'fl-lightbox.css', array(), $ver);
358
- wp_enqueue_style('fl-icon-selector', $css_url . 'fl-icon-selector.css', array(), $ver);
359
- wp_enqueue_style('fl-builder', $css_url . 'fl-builder.css', array(), $ver);
360
-
361
- /* Custom Icons */
362
- FLBuilderIcons::enqueue_all_custom_icons_styles();
363
-
364
- /* RTL Support */
365
- if(is_rtl()) {
366
- wp_enqueue_style('fl-builder-rtl', $css_url . 'fl-builder-rtl.css', array(), $ver);
367
- }
368
-
369
- /* Frontend builder scripts */
370
- wp_enqueue_media();
371
- wp_enqueue_script('heartbeat');
372
- wp_enqueue_script('wpdialogs');
373
- wp_enqueue_script('wpdialogs-popup');
374
- wp_enqueue_script('wplink');
375
- wp_enqueue_script('editor');
376
- wp_enqueue_script('quicktags');
377
- wp_enqueue_script('json2');
378
- wp_enqueue_script('jquery-ui-droppable');
379
- wp_enqueue_script('jquery-ui-draggable');
380
- wp_enqueue_script('jquery-ui-sortable', $js_url . 'jquery.ui.sortable.js', array('jquery-ui-core', 'jquery-ui-widget', 'jquery-ui-mouse'), $ver, true);
381
- wp_enqueue_script('jquery-nanoscroller', $js_url . 'jquery.nanoscroller.min.js', array(), $ver, true);
382
- wp_enqueue_script('jquery-autosuggest', $js_url . 'jquery.autoSuggest.min.js', array(), $ver, true);
383
- wp_enqueue_script('jquery-tiptip', $js_url . 'jquery.tiptip.min.js', array(), $ver, true);
384
- wp_enqueue_script('jquery-simulate', $js_url . 'jquery.simulate.js', array(), $ver, true);
385
- wp_enqueue_script('jquery-validate', $js_url . 'jquery.validate.min.js', array(), $ver, true);
386
- wp_enqueue_script('bootstrap-tour', $js_url . 'bootstrap-tour-standalone.min.js', array(), $ver, true);
387
  wp_enqueue_script('ace', $js_url . 'ace/ace.js', array(), $ver, true);
388
- wp_enqueue_script('fl-color-picker', $js_url . 'colorpicker.js', array(), $ver, true);
389
- wp_enqueue_script('fl-lightbox', $js_url . 'fl-lightbox.js', array(), $ver, true);
390
- wp_enqueue_script('fl-icon-selector', $js_url . 'fl-icon-selector.js', array(), $ver, true);
391
- wp_enqueue_script('fl-stylesheet', $js_url . 'fl-stylesheet.js', array(), $ver, true);
392
- wp_enqueue_script('fl-builder', $js_url . 'fl-builder.js', array(), $ver, true);
393
- wp_enqueue_script('fl-builder-preview', $js_url . 'fl-builder-preview.js', array(), $ver, true);
394
- wp_enqueue_script('fl-builder-services', $js_url . 'fl-builder-services.js', array(), $ver, true);
395
- wp_enqueue_script('fl-builder-tour', $js_url . 'fl-builder-tour.js', array(), $ver, true);
396
-
397
- /* Core template settings */
398
- if(file_exists(FL_BUILDER_DIR . 'js/fl-template-settings.js')) {
399
- wp_enqueue_script('fl-template-settings', FL_BUILDER_URL . 'js/fl-template-settings.js', array(), $ver, true);
400
- }
401
-
402
- /* Additional module styles and scripts */
403
- foreach(FLBuilderModel::$modules as $module) {
404
-
405
- $module->enqueue_scripts();
406
-
407
- foreach($module->css as $handle => $props) {
408
- wp_enqueue_style($handle, $props[0], $props[1], $props[2], $props[3]);
409
- }
410
- foreach($module->js as $handle => $props) {
411
- wp_enqueue_script($handle, $props[0], $props[1], $props[2], $props[3]);
412
- }
413
- }
414
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
415
  }
416
 
417
- /**
418
- * @method body_class
419
- */
420
- static public function body_class($classes)
421
- {
422
- if(FLBuilderModel::is_builder_enabled()) {
423
- $classes[] = 'fl-builder';
424
- }
425
- if(FLBuilderModel::is_builder_active() && !current_user_can(FLBuilderModel::get_editing_capability())) {
426
- $classes[] = 'fl-builder-simple';
427
- }
428
-
429
- return $classes;
430
- }
431
-
432
- /**
433
- * @method admin_bar_menu
434
- */
435
- static public function admin_bar_menu($wp_admin_bar)
436
- {
437
- global $wp_the_query;
438
-
439
- if ( FLBuilderModel::is_post_editable() ) {
440
-
441
- $wp_admin_bar->add_node( array(
442
- 'id' => 'fl-builder-frontend-edit-link',
443
- '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(),
444
- 'href' => FLBuilderModel::get_edit_url( $wp_the_query->post->ID )
445
- ));
446
- }
447
- }
448
-
449
- /**
450
- * @method render_ui
451
- */
452
- static public function render_ui()
453
- {
454
- global $wp_the_query;
455
-
456
- if ( FLBuilderModel::is_builder_active() ) {
457
-
458
- $post_id = $wp_the_query->post->ID;
459
- $categories = FLBuilderModel::get_categorized_modules();
460
- $enabled_templates = FLBuilderModel::get_enabled_templates();
461
- $help_button = FLBuilderModel::get_help_button_settings();
462
-
463
- include FL_BUILDER_DIR . 'includes/ui.php';
464
- include FL_BUILDER_DIR . 'includes/js-config.php';
465
- }
466
- }
467
-
468
- /**
469
- * Renders a preview of the layout to be
470
- * passed back to the builder via AJAX.
471
- *
472
- * @method render_preview
473
- */
474
- static public function render_preview($return = false)
475
- {
476
- self::render_css();
477
- self::render_js();
478
-
479
- if($return) {
480
- return self::render_layout(true);
481
- }
482
- else {
483
- self::render_layout();
484
- }
485
- }
486
-
487
- /**
488
- * Renders the layout to be passed back to
489
- * the builder via AJAX for an update.
490
- *
491
- * @method render_layout
492
- */
493
- static public function render_layout($return = false)
494
- {
495
- global $wp_scripts;
496
- global $wp_styles;
497
-
498
- // Deregister scripts and styles so we can capture those
499
- // registered by content functions such as shortcodes.
500
- if(isset($wp_scripts)) {
501
- $wp_scripts->queue = array();
502
- }
503
- if(isset($wp_styles)) {
504
- $wp_styles->queue = array();
505
- }
506
-
507
- // Enqueue jQuery again so it's not added by any
508
- // third party shortcodes or plugins.
509
- wp_enqueue_script('jquery');
510
-
511
- // Render the layout.
512
- ob_start();
513
- self::render_rows();
514
- $html = ob_get_clean();
515
-
516
- // Process shortcodes.
517
- ob_start();
518
- echo do_shortcode($html);
519
- $html = ob_get_clean();
520
-
521
- // Print scripts and styles registered by content
522
- // functions such as shortcodes.
523
- ob_start();
524
-
525
- if(isset($wp_scripts)) {
526
- $wp_scripts->done[] = 'jquery';
527
- wp_print_scripts($wp_scripts->queue);
528
- }
529
- if(isset($wp_styles)) {
530
- wp_print_styles($wp_styles->queue);
531
- }
532
-
533
- $html = ob_get_clean() . $html;
534
-
535
- // Get the asset info.
536
- $asset_info = FLBuilderModel::get_asset_info();
537
- $asset_ver = FLBuilderModel::get_asset_version();
538
-
539
- // Build the response.
540
- $response = array(
541
- 'html' => $html,
542
- 'css' => $asset_info['css_url'] . '?ver=' . $asset_ver,
543
- 'js' => $asset_info['js_url'] . '?ver=' . $asset_ver
544
- );
545
-
546
- // Return or echo the response.
547
- if($return) {
548
- return $response;
549
- }
550
- else {
551
- echo json_encode($response);
552
- die();
553
- }
554
- }
555
-
556
- /**
557
- * @method render_content
558
- */
559
- static public function render_content($content)
560
- {
561
- global $post;
562
-
563
- $post_id = FLBuilderModel::get_post_id();
564
- $enabled = FLBuilderModel::is_builder_enabled();
565
- $ajax = defined('DOING_AJAX');
566
- $global_posts = FLBuilderModel::get_global_posts();
567
- $is_global = in_array($post->ID, $global_posts);
568
- $in_loop = in_the_loop();
569
-
570
- if($enabled && !$ajax && ($is_global || $in_loop)) {
571
-
572
- // Remove the builder's render_content filter in case apply_filters
573
- // is called again by a widget, module or shortcode.
574
- remove_filter('the_content', 'FLBuilder::render_content');
575
-
576
- // Render the content.
577
- ob_start();
578
- echo '<div class="fl-builder-content fl-builder-content-' . $post_id . '" data-post-id="' . $post_id . '">';
579
- self::render_rows();
580
- echo '</div>';
581
- $content = do_shortcode(ob_get_clean());
582
-
583
- // Reapply the builder's render_content filter.
584
- add_filter('the_content', 'FLBuilder::render_content');
585
- }
586
-
587
- return $content;
588
- }
589
-
590
- /**
591
- * @method render_editor_content
592
- */
593
- static public function render_editor_content()
594
- {
595
- $rows = FLBuilderModel::get_nodes('row');
596
-
597
- ob_start();
598
-
599
- // Render the modules.
600
- foreach($rows as $row) {
601
-
602
- $groups = FLBuilderModel::get_nodes('column-group', $row->node);
603
-
604
- foreach($groups as $group) {
605
-
606
- $cols = FLBuilderModel::get_nodes('column', $group->node);
607
-
608
- foreach($cols as $col) {
609
-
610
- $modules = FLBuilderModel::get_modules($col->node);
611
-
612
- foreach($modules as $module) {
613
-
614
- if($module->editor_export) {
615
-
616
- // Don't crop photos to ensure media library photos are rendered.
617
- if($module->settings->type == 'photo') {
618
- $module->settings->crop = false;
619
- }
620
-
621
- FLBuilder::render_module_html($module->settings->type, $module->settings, $module);
622
- }
623
- }
624
- }
625
- }
626
- }
627
-
628
- // Get the content.
629
- $content = ob_get_clean();
630
 
631
- // Remove unnecessary tags.
632
- $content = preg_replace('/<\/?div[^>]*\>/i', '', $content);
633
- $content = preg_replace('/<\/?span[^>]*\>/i', '', $content);
634
- $content = preg_replace('#<script(.*?)>(.*?)</script>#is', '', $content);
635
- $content = preg_replace('/<i [^>]*><\\/i[^>]*>/', '', $content);
636
- $content = preg_replace('/ class=".*?"/', '', $content);
637
 
638
- // Remove empty lines.
639
- $content = preg_replace('/(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+/', "\n", $content);
640
-
641
- return $content;
642
- }
 
 
643
 
644
  /**
645
- * @method render_settings
646
- */
647
- static public function render_settings($form = array(), $settings, $return = false)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
648
  {
649
- $defaults = array(
650
- 'class' => '',
651
- 'attrs' => '',
652
- 'title' => '',
653
- 'tabs' => array()
654
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
655
 
656
- $form = array_merge($defaults, $form);
657
 
658
- ob_start();
659
- include FL_BUILDER_DIR . 'includes/settings.php';
660
- $html = ob_get_clean();
661
 
662
- if(defined('DOING_AJAX') && !$return) {
663
- echo $html;
664
- die();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
665
  }
666
  else {
667
- return $html;
668
  }
669
  }
670
 
671
  /**
672
- * @method render_settings_field
673
- */
 
 
 
 
 
 
674
  static public function render_settings_field($name, $field, $settings = null)
675
  {
676
- $i = null;
677
- $is_multiple = isset($field['multiple']) && $field['multiple'] === true;
678
- $supports_multiple = $field['type'] != 'editor' && $field['type'] != 'photo' && $field['type'] != 'service';
679
- $settings = ! $settings ? new stdClass() : $settings;
680
- $value = isset($settings->$name) ? $settings->$name : '';
681
- $preview = isset($field['preview']) ? json_encode($field['preview']) : json_encode(array('type' => 'refresh'));
682
  $row_class = isset($field['row_class']) ? ' ' . $field['row_class'] : '';
683
 
684
- if($is_multiple && $supports_multiple) {
685
-
686
- $values = $value;
687
- $arr_name = $name;
688
- $name .= '[]';
689
-
690
- echo '<tbody class="fl-field fl-builder-field-multiples" data-type="form" data-preview=\'' . $preview . '\'>';
691
-
692
- for($i = 0; $i < count($values); $i++) {
693
- $value = $values[$i];
694
- echo '<tr class="fl-builder-field-multiple" data-field="'. $arr_name .'">';
695
- include FL_BUILDER_DIR . 'includes/field.php';
696
- echo '<td class="fl-builder-field-actions">';
697
- echo '<i class="fl-builder-field-move fa fa-arrows"></i>';
698
- echo '<i class="fl-builder-field-copy fa fa-copy"></i>';
699
- echo '<i class="fl-builder-field-delete fa fa-times"></i>';
700
- echo '</td>';
701
- echo '</tr>';
702
- }
703
-
704
- echo '<tr>';
705
-
706
- if(empty($field['label'])) {
707
- echo '<td colspan="2">';
708
- }
709
- else {
710
- echo '<td>&nbsp;</td><td>';
711
- }
712
-
713
- 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>';
714
- echo '</td>';
715
- echo '</tr>';
716
- echo '</tbody>';
717
- }
718
- else {
719
- echo '<tr id="fl-field-'. $name .'" class="fl-field' . $row_class . '" data-type="' . $field['type'] . '" data-preview=\'' . $preview . '\'>';
720
- include FL_BUILDER_DIR . 'includes/field.php';
721
- echo '</tr>';
722
- }
723
  }
724
 
725
  /**
726
- * @method render_settings_form
727
- */
 
 
 
 
 
 
728
  static public function render_settings_form($type = null, $settings = null)
729
  {
730
- $post_data = FLBuilderModel::get_post_data();
731
- $type = isset($post_data['type']) ? $post_data['type'] : $type;
732
- $settings = isset($post_data['settings']) ? $post_data['settings'] : $settings;
733
- $form = FLBuilderModel::get_settings_form( $type );
734
-
735
- if(isset($settings) && !empty($settings)) {
736
- $defaults = FLBuilderModel::get_settings_form_defaults( $type );
737
- $settings = (object)array_merge((array)$defaults, (array)$settings);
738
- }
739
- else {
740
- $settings = FLBuilderModel::get_settings_form_defaults( $type );
741
- }
742
-
743
- self::render_settings(array(
744
- 'title' => $form['title'],
745
- 'tabs' => $form['tabs']
746
- ), $settings);
747
  }
748
 
749
  /**
750
- * @method render_global_settings
751
- */
 
 
 
752
  static public function render_global_settings()
753
  {
754
- $settings = FLBuilderModel::get_global_settings();
755
- $form = FLBuilderModel::$settings_forms['global'];
756
-
757
- self::render_settings(array(
758
- 'class' => 'fl-builder-global-settings',
759
- 'title' => $form['title'],
760
- 'tabs' => $form['tabs']
761
- ), $settings);
762
  }
763
 
764
- /**
765
- * @method register_templates_post_type
766
- */
767
- static public function register_templates_post_type()
768
- {
769
- if(FL_BUILDER_LITE === true) {
770
- return;
771
- }
772
-
773
- register_post_type('fl-builder-template', array(
774
- 'public' => false,
775
- 'labels' => array(
776
- 'name' => _x( 'Layout Templates', 'Custom post type label.', 'fl-builder' ),
777
- 'singular_name' => _x( 'Layout Template', 'Custom post type label.', 'fl-builder' ),
778
- 'menu_name' => _x( 'Layout Templates', 'Custom post type label.', 'fl-builder' ),
779
- 'name_admin_bar' => _x( 'Layout Template', 'Custom post type label.', 'fl-builder' ),
780
- 'add_new' => _x( 'Add New', 'Custom post type label.', 'fl-builder' ),
781
- 'add_new_item' => _x( 'Add New Layout Template', 'Custom post type label.', 'fl-builder' ),
782
- 'new_item' => _x( 'New Layout Template', 'Custom post type label.', 'fl-builder' ),
783
- 'edit_item' => _x( 'Edit Layout Template', 'Custom post type label.', 'fl-builder' ),
784
- 'view_item' => _x( 'View Layout Template', 'Custom post type label.', 'fl-builder' ),
785
- 'all_items' => _x( 'All Layout Templates', 'Custom post type label.', 'fl-builder' ),
786
- 'search_items' => _x( 'Search Layout Templates', 'Custom post type label.', 'fl-builder' ),
787
- 'parent_item_colon' => _x( 'Parent Layout Templates:', 'Custom post type label.', 'fl-builder' ),
788
- 'not_found' => _x( 'No layout templates found.', 'Custom post type label.', 'fl-builder' ),
789
- 'not_found_in_trash' => _x( 'No layout templates found in Trash.', 'Custom post type label.', 'fl-builder' )
790
- ),
791
- 'supports' => array(
792
- 'title'
793
- ),
794
- 'publicly_queryable' => true
795
- ));
796
- }
797
-
798
- /**
799
- * @method render_template_selector
800
- */
801
- static public function render_template_selector()
802
- {
803
- if(file_exists(FL_BUILDER_DIR . 'includes/template-selector.php')) {
804
-
805
- $enabled_templates = FLBuilderModel::get_enabled_templates();
806
- $user_templates = FLBuilderModel::get_user_templates();
807
- $templates = FLBuilderModel::get_templates();
808
- $num_rows = FLBuilderModel::count_nodes('row');
809
-
810
- include FL_BUILDER_DIR . 'includes/template-selector.php';
811
-
812
- if(defined('DOING_AJAX')) {
813
- die();
814
- }
815
- }
816
- }
817
-
818
- /**
819
- * @method render_user_template_settings
820
- */
821
- static public function render_user_template_settings()
822
- {
823
- $defaults = FLBuilderModel::get_settings_form_defaults( 'user_template' );
824
- $form = FLBuilderModel::get_settings_form( 'user_template' );
825
-
826
- FLBuilder::render_settings(array(
827
- 'class' => 'fl-builder-user-template-settings',
828
- 'title' => $form['title'],
829
- 'tabs' => $form['tabs']
830
- ), $defaults);
831
- }
832
 
833
  /**
834
- * @method render_template
835
- */
836
- static public function render_template($template)
837
- {
838
- global $post;
 
 
 
839
 
840
- if($post && $post->post_type == 'fl-builder-template') {
 
 
 
841
 
842
- $page = locate_template(array('page.php'));
843
 
844
- if(!empty($page)) {
845
- return $page;
846
- }
847
- }
 
848
 
849
- return $template;
850
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
851
 
852
  /**
853
- * @method render_icon_selector
854
- */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
855
  static public function render_icon_selector()
856
  {
857
- $icon_sets = FLBuilderIcons::get_sets();
858
 
859
- include FL_BUILDER_DIR . 'includes/icon-selector.php';
860
 
861
- if(defined('DOING_AJAX')) {
862
- die();
863
  }
864
  }
865
 
866
- /**
867
- * @method render_rows
868
- */
869
- static public function render_rows()
870
- {
871
- $rows = FLBuilderModel::get_nodes('row');
 
 
 
872
 
873
- foreach($rows as $row) {
874
- self::render_row($row);
875
- }
876
- }
877
 
878
  /**
879
- * @method render_row
880
- */
 
 
 
 
881
  static public function render_row($row)
882
  {
883
- $groups = FLBuilderModel::get_nodes('column-group', $row->node);
884
 
885
  include FL_BUILDER_DIR . 'includes/row.php';
886
  }
887
 
888
  /**
889
- * @method render_new_row
890
- */
 
 
 
 
 
891
  static public function render_new_row($cols = '1-col', $position = false)
892
  {
893
- $post_data = FLBuilderModel::get_post_data();
894
- $cols = isset($post_data['cols']) ? $post_data['cols'] : $cols;
895
- $position = isset($post_data['position']) ? (int)$post_data['position'] : $position;
896
- $row = FLBuilderModel::add_row($cols, $position);
897
 
898
- self::render_row($row);
899
 
900
  if(defined('DOING_AJAX')) {
901
- die();
902
  }
903
  }
904
 
905
  /**
906
- * @method render_row_attributes
907
- */
 
 
 
 
908
  static public function render_row_attributes( $row )
909
  {
910
  $custom_class = apply_filters( 'fl_builder_row_custom_class', $row->settings->class, $row );
@@ -916,110 +1048,138 @@ final class FLBuilder {
916
  }
917
 
918
  // Class
919
- echo ' class="fl-row';
920
- echo ' fl-row-' . $row->settings->width . '-width';
921
- echo ' fl-row-bg-' . $row->settings->bg_type;
922
-
923
- if ( in_array( $row->settings->bg_type, $overlay_bgs ) && ! empty( $row->settings->bg_overlay_color ) ) {
924
- echo ' fl-row-bg-overlay';
925
- }
926
- if ( ! empty( $row->settings->responsive_display ) ) {
927
- echo ' fl-visible-' . $row->settings->responsive_display;
928
- }
929
- if ( ! empty( $custom_class ) ) {
930
- echo ' ' . trim( esc_attr( $custom_class ) );
931
- }
932
-
933
- echo ' fl-node-' . $row->node;
934
- echo '"';
935
 
936
  // Data
937
- echo ' data-node="' . $row->node . '"';
938
 
939
- if ( $row->settings->bg_type == 'parallax' && ! empty( $row->settings->bg_parallax_image_src ) ) {
940
- echo ' data-parallax-speed="' . $row->settings->bg_parallax_speed . '"';
941
- echo ' data-parallax-image="' . $row->settings->bg_parallax_image_src . '"';
942
- }
943
  }
944
 
945
  /**
946
- * @method render_row_bg
947
- */
 
 
 
 
948
  static public function render_row_bg($row)
949
  {
950
- if($row->settings->bg_type == 'video') {
951
 
952
- $vid_data = FLBuilderModel::get_row_bg_data($row);
953
 
954
- if($vid_data) {
955
- include FL_BUILDER_DIR . 'includes/row-video.php';
956
- }
957
- }
958
- else if($row->settings->bg_type == 'slideshow') {
959
- echo '<div class="fl-bg-slideshow"></div>';
960
- }
961
  }
962
 
963
  /**
964
- * @method render_row_content_class
965
- */
 
 
 
 
966
  static public function render_row_content_class($row)
967
  {
968
- echo 'fl-row-content';
969
- echo ' fl-row-' . $row->settings->content_width . '-width';
970
- echo ' fl-node-content';
971
  }
972
 
973
  /**
974
- * @method render_row_settings
975
- */
 
 
 
 
976
  static public function render_row_settings($node_id = null)
977
  {
978
- $post_data = FLBuilderModel::get_post_data();
979
- $node_id = isset($post_data['node_id']) ? $post_data['node_id'] : $node_id;
980
- $node = FLBuilderModel::get_node($node_id);
981
- $settings = $node->settings;
982
- $form = FLBuilderModel::$settings_forms['row'];
983
-
984
- self::render_settings(array(
985
- 'class' => 'fl-builder-row-settings',
986
- 'attrs' => 'data-node="'. $node->node .'"',
987
- 'title' => $form['title'],
988
- 'tabs' => $form['tabs']
989
- ), $settings);
990
  }
991
 
992
  /**
993
- * @method render_column_group
994
- */
 
 
 
 
995
  static public function render_column_group($group)
996
  {
997
- $cols = FLBuilderModel::get_nodes('column', $group->node);
998
 
999
- include FL_BUILDER_DIR . 'includes/column-group.php';
1000
  }
1001
 
1002
  /**
1003
- * @method render_new_column_group
1004
- */
 
 
 
 
 
 
1005
  static public function render_new_column_group($node_id = null, $cols = '1-col', $position = false)
1006
  {
1007
- $post_data = FLBuilderModel::get_post_data();
1008
- $node_id = isset($post_data['node_id']) ? $post_data['node_id'] : $node_id;
1009
- $cols = isset($post_data['cols']) ? $post_data['cols'] : $cols;
1010
- $position = isset($post_data['position']) ? (int)$post_data['position'] : $position;
1011
- $group = FLBuilderModel::add_col_group($node_id, $cols, $position);
1012
 
1013
- self::render_column_group($group);
1014
 
1015
  if(defined('DOING_AJAX')) {
1016
- die();
1017
  }
1018
  }
1019
 
1020
  /**
1021
- * @method render_column_group_attributes
1022
- */
 
 
 
 
 
 
1023
  static public function render_column_group_attributes( $group )
1024
  {
1025
  echo ' class="fl-col-group fl-node-' . $group->node . '"';
@@ -1027,27 +1187,35 @@ final class FLBuilder {
1027
  }
1028
 
1029
  /**
1030
- * @method render_column_settings
1031
- */
 
 
 
 
1032
  static public function render_column_settings($node_id = null)
1033
  {
1034
- $post_data = FLBuilderModel::get_post_data();
1035
- $node_id = isset($post_data['node_id']) ? $post_data['node_id'] : $node_id;
1036
- $node = FLBuilderModel::get_node($node_id);
1037
- $settings = $node->settings;
1038
- $form = FLBuilderModel::$settings_forms['col'];
1039
-
1040
- self::render_settings(array(
1041
- 'class' => 'fl-builder-col-settings',
1042
- 'attrs' => 'data-node="'. $node->node .'"',
1043
- 'title' => $form['title'],
1044
- 'tabs' => $form['tabs']
1045
- ), $settings);
1046
  }
1047
 
1048
  /**
1049
- * @method render_column_attributes
1050
- */
 
 
 
 
1051
  static public function render_column_attributes( $col )
1052
  {
1053
  $custom_class = apply_filters( 'fl_builder_column_custom_class', $col->settings->class, $col );
@@ -1058,133 +1226,163 @@ final class FLBuilder {
1058
  }
1059
 
1060
  // Class
1061
- echo ' class="fl-col';
1062
-
1063
- if ( $col->settings->size <= 50 ) {
1064
- echo ' fl-col-small';
1065
- }
1066
- if ( ! empty( $col->settings->responsive_display ) ) {
1067
- echo ' fl-visible-' . $col->settings->responsive_display;
1068
- }
1069
- if ( ! empty( $custom_class ) ) {
1070
- echo ' ' . trim( esc_attr( $custom_class ) );
1071
- }
1072
-
1073
- echo ' fl-node-' . $col->node;
1074
- echo '"';
1075
-
1076
- // Width
1077
- echo ' style="width: ' . $col->settings->size . '%;"';
1078
-
1079
- // Data
1080
- echo ' data-node="' . $col->node . '"';
1081
  }
1082
 
1083
- /**
1084
- * @method render_modules
1085
- */
1086
- static public function render_modules($parent_id)
1087
- {
1088
- $modules = FLBuilderModel::get_modules($parent_id);
 
 
 
 
1089
 
1090
- foreach($modules as $module) {
1091
- $settings = $module->settings;
1092
- include FL_BUILDER_DIR . 'includes/module.php';
1093
- }
1094
- }
1095
 
1096
  /**
1097
- * @method render_new_module_settings
1098
- */
 
 
 
 
 
 
 
1099
  static public function render_new_module_settings($parent_id = null, $type = null, $position = false)
1100
  {
1101
- $post_data = FLBuilderModel::get_post_data();
1102
- $parent_id = isset($post_data['parent_id']) ? $post_data['parent_id'] : $parent_id;
1103
- $type = isset($post_data['type']) ? $post_data['type'] : $type;
1104
- $position = isset($post_data['position']) ? (int)$post_data['position'] : $position;
1105
- $module = FLBuilderModel::add_default_module($parent_id, $type, $position);
1106
-
1107
- // Force the global parent id.
1108
- FLBuilderModel::update_post_data('parent_id', $module->parent);
1109
-
1110
- // Get the settings html.
1111
- ob_start();
1112
- self::render_module_settings($module->node, $module->type, $module->parent, true);
1113
- $settings = ob_get_clean();
1114
-
1115
- // Build the response.
1116
- $response = array(
1117
- 'layout' => self::render_preview(true),
1118
- 'settings' => $settings
1119
- );
1120
-
1121
- // Echo or return the response.
1122
- if(defined('DOING_AJAX')) {
1123
- echo json_encode($response);
1124
- die();
1125
- }
1126
- else {
1127
- return $response;
1128
- }
1129
  }
1130
 
1131
  /**
1132
- * @method render_module_settings
1133
- */
 
 
 
 
 
 
 
1134
  static public function render_module_settings($node_id = null, $type = null, $parent_id = null, $return = false)
1135
  {
1136
- $post_data = FLBuilderModel::get_post_data();
1137
- $node_id = isset($post_data['node_id']) ? $post_data['node_id'] : $node_id;
1138
- $type = isset($post_data['type']) ? $post_data['type'] : $type;
1139
- $parent_id = isset($post_data['parent_id']) ? $post_data['parent_id'] : $parent_id;
1140
-
1141
- if($node_id) {
1142
- $module = FLBuilderModel::get_module($node_id);
1143
- $settings = $module->settings;
1144
- }
1145
- else {
1146
- $module = FLBuilderModel::$modules[$type];
1147
- $settings = FLBuilderModel::get_module_defaults($type);
1148
- }
1149
-
1150
- if(file_exists($module->dir .'css/settings.css')) {
1151
- echo '<link class="fl-builder-settings-css" rel="stylesheet" href="'. $module->url .'css/settings.css" />';
1152
- }
1153
- if(file_exists($module->dir .'js/settings.js')) {
1154
- echo '<script class="fl-builder-settings-js" src="'. $module->url .'js/settings.js"></script>';
1155
- }
1156
-
1157
- echo self::render_settings(array(
1158
- 'class' => 'fl-builder-module-settings fl-builder-'. $type .'-settings',
1159
- 'attrs' => 'data-node="'. $node_id .'" data-parent="'. $parent_id .'" data-type="'. $type .'"',
1160
- 'title' => sprintf( _x( '%s Settings', '%s stands for module name.', 'fl-builder' ), $module->name ),
1161
- 'tabs' => $module->form
1162
- ), $settings, $return);
1163
  }
1164
 
1165
- /**
1166
- * @method render_module_html
1167
- */
1168
- static public function render_module_html($type, $settings, $module = null)
1169
- {
1170
- // Settings
1171
- $defaults = FLBuilderModel::get_module_defaults($type);
1172
- $settings = (object)array_merge((array)$defaults, (array)$settings);
 
 
 
 
 
 
 
 
1173
 
1174
- // Module
1175
- $class = get_class(FLBuilderModel::$modules[$type]);
1176
- $module = new $class();
1177
- $module->settings = $settings;
1178
 
1179
- // Shorthand reference to the module's id.
1180
- $id = $module->node;
1181
 
1182
- include $module->dir .'includes/frontend.php';
1183
- }
1184
 
1185
  /**
1186
- * @method render_module_attributes
1187
- */
 
 
 
 
1188
  static public function render_module_attributes( $module )
1189
  {
1190
  $custom_class = apply_filters( 'fl_builder_module_custom_class', $module->settings->class, $module );
@@ -1196,506 +1394,553 @@ final class FLBuilder {
1196
 
1197
  // Class
1198
  echo ' class="fl-module';
1199
- echo ' fl-module-' . $module->settings->type;
1200
-
1201
- if ( ! empty( $module->settings->responsive_display ) ) {
1202
- echo ' fl-visible-' . $module->settings->responsive_display;
1203
- }
1204
- if ( ! empty( $module->settings->animation ) ) {
1205
- echo ' fl-animation fl-' . $module->settings->animation;
1206
- }
1207
- if ( ! empty( $custom_class ) ) {
1208
- echo ' ' . trim( esc_attr( $custom_class ) );
1209
- }
1210
-
1211
- echo ' fl-node-' . $module->node;
1212
- echo '"';
1213
 
1214
  // Data
1215
- echo ' data-node="' . $module->node . '" ';
1216
- echo ' data-animation-delay="' . $module->settings->animation_delay . '" ';
1217
-
1218
- if ( FLBuilderModel::is_builder_active() ) {
1219
- echo ' data-parent="' . $module->parent . '" ';
1220
- echo ' data-type="' . $module->settings->type . '" ';
1221
- echo ' data-name="' . $module->name . '" ';
1222
- }
1223
  }
1224
 
1225
- /**
1226
- * @method render_module_css
1227
- */
1228
- static public function render_module_css($type, $id, $settings)
1229
- {
1230
- // Settings
1231
- $global_settings = FLBuilderModel::get_global_settings();
1232
- $defaults = FLBuilderModel::get_module_defaults($type);
1233
- $settings = (object)array_merge((array)$defaults, (array)$settings);
 
 
 
 
 
 
1234
 
1235
- // Module
1236
- $class = get_class(FLBuilderModel::$modules[$type]);
1237
- $module = new $class();
1238
- $module->settings = $settings;
1239
 
1240
- include $module->dir .'includes/frontend.css.php';
1241
- }
1242
 
1243
  /**
1244
- * @method render_css
1245
- */
 
 
 
1246
  static public function render_css()
1247
  {
1248
- // Delete the old file.
1249
- FLBuilderModel::delete_asset_cache('css');
1250
-
1251
- // Get info on the new file.
1252
- $rows = FLBuilderModel::get_nodes('row');
1253
- $cols = FLBuilderModel::get_nodes('column');
1254
- $modules = FLBuilderModel::get_all_modules();
1255
- $global_settings = FLBuilderModel::get_global_settings();
1256
- $asset_info = FLBuilderModel::get_asset_info();
1257
- $post_id = FLBuilderModel::get_post_id();
1258
- $post = get_post($post_id);
1259
- $compiled = array();
1260
-
1261
- // Global css
1262
- $css = file_get_contents(FL_BUILDER_DIR . '/css/fl-builder-layout.css');
1263
-
1264
- // Responsive css
1265
- if($global_settings->responsive_enabled) {
1266
-
1267
- $css .= '@media (max-width: '. $global_settings->medium_breakpoint .'px) { ';
1268
- $css .= file_get_contents(FL_BUILDER_DIR . '/css/fl-builder-layout-medium.css');
1269
- $css .= ' }';
1270
- $css .= '@media (max-width: '. $global_settings->responsive_breakpoint .'px) { ';
1271
- $css .= file_get_contents(FL_BUILDER_DIR . '/css/fl-builder-layout-responsive.css');
1272
-
1273
- if ( ! isset( $global_settings->auto_spacing ) || $global_settings->auto_spacing ) {
1274
- $css .= file_get_contents(FL_BUILDER_DIR . '/css/fl-builder-layout-auto-spacing.css');
1275
- }
1276
-
1277
- $css .= ' }';
1278
- }
1279
-
1280
- // Global row margins
1281
- $css .= '.fl-row-content-wrap { margin: '. $global_settings->row_margins .'px; }';
1282
-
1283
- // Global row padding
1284
- $css .= '.fl-row-content-wrap { padding: '. $global_settings->row_padding .'px; }';
1285
-
1286
- // Global row width
1287
- $css .= '.fl-row-fixed-width { max-width: '. $global_settings->row_width .'px; }';
1288
-
1289
- // Global row content width
1290
- $css .= '.fl-row-content-wrap.fl-row-fixed-width .fl-row-content { max-width: '. $global_settings->row_width .'px; }';
1291
-
1292
- // Row instances
1293
- foreach($rows as $row) {
1294
-
1295
- // Instance row css
1296
- ob_start();
1297
- include FL_BUILDER_DIR . 'includes/row-css.php';
1298
- $css .= ob_get_clean();
1299
-
1300
- // Instance row margins
1301
- $css .= self::render_row_margins($row);
1302
-
1303
- // Instance row padding
1304
- $css .= self::render_row_padding($row);
1305
-
1306
- // Instance row bg positions
1307
- $css .= self::render_row_bg_positions($row);
1308
-
1309
- if ( ! isset( $global_settings->auto_spacing ) || $global_settings->auto_spacing ) {
1310
- $css .= self::render_responsive_row_bg_positions($row);
1311
- }
1312
- }
1313
-
1314
- // Column instances
1315
- foreach($cols as $col) {
1316
-
1317
- // Instance column css
1318
- ob_start();
1319
- include FL_BUILDER_DIR . 'includes/column-css.php';
1320
- $css .= ob_get_clean();
1321
-
1322
- // Instance column margins
1323
- $css .= self::render_column_margins($col);
1324
-
1325
- // Instance column padding
1326
- $css .= self::render_column_padding($col);
1327
- }
1328
-
1329
- // Global module margins
1330
- $css .= '.fl-module-content { margin: '. $global_settings->module_margins .'px; }';
1331
-
1332
- // Modules
1333
- foreach($modules as $module) {
1334
-
1335
- // Global module css
1336
- $file = $module->dir . 'css/frontend.css';
1337
- $file_responsive = $module->dir . 'css/frontend.responsive.css';
1338
-
1339
- // Only include global module css that hasn't been included yet.
1340
- if(!in_array($module->settings->type, $compiled)) {
1341
-
1342
- // Add to the compiled array so we don't include it again.
1343
- $compiled[] = $module->settings->type;
1344
-
1345
- // Get the standard module css.
1346
- if(file_exists($file)) {
1347
- $css .= file_get_contents($file);
1348
- }
1349
-
1350
- // Get the responsive module css.
1351
- if($global_settings->responsive_enabled && file_exists($file_responsive)) {
1352
- $css .= '@media (max-width: '. $global_settings->responsive_breakpoint .'px) { ';
1353
- $css .= file_get_contents($file_responsive);
1354
- $css .= ' }';
1355
- }
1356
- }
1357
-
1358
- // Instance module css
1359
- $file = $module->dir . 'includes/frontend.css.php';
1360
- $settings = $module->settings;
1361
- $id = $module->node;
1362
-
1363
- if(file_exists($file)) {
1364
- ob_start();
1365
- include $file;
1366
- $css .= ob_get_clean();
1367
- }
1368
-
1369
- // Instance module margins
1370
- $css .= self::render_module_margins($module);
1371
-
1372
- if ( ! isset( $global_settings->auto_spacing ) || $global_settings->auto_spacing ) {
1373
- $css .= self::render_responsive_module_margins($module);
1374
- }
1375
- }
1376
-
1377
- // Default page heading
1378
- if($post && !$global_settings->show_default_heading && ($post->post_type == 'page' || $post->post_type == 'fl-builder-template')) {
1379
- $css .= $global_settings->default_heading_selector . ' { display:none; }';
1380
- }
1381
-
1382
- // Save the css
1383
- if(!empty($css)) {
1384
- $css = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $css);
1385
- $css = str_replace(array("\r\n", "\r", "\n", "\t", ' ', ' ', ' '), '', $css);
1386
- file_put_contents($asset_info['css'], $css);
1387
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1388
  }
1389
 
1390
  /**
1391
- * @method render_row_margins
1392
- */
1393
- static public function render_row_margins($row)
1394
- {
1395
- $settings = $row->settings;
1396
- $margins = '';
1397
- $css = '';
1398
-
1399
- if($settings->margin_top != '') {
1400
- $margins .= 'margin-top:' . $settings->margin_top . 'px;';
1401
- }
1402
- if($settings->margin_bottom != '') {
1403
- $margins .= 'margin-bottom:' . $settings->margin_bottom . 'px;';
1404
- }
1405
- if($settings->margin_left != '') {
1406
- $margins .= 'margin-left:' . $settings->margin_left . 'px;';
1407
- }
1408
- if($settings->margin_right != '') {
1409
- $margins .= 'margin-right:' . $settings->margin_right . 'px;';
1410
- }
1411
- if($margins != '') {
1412
- $css .= '.fl-node-' . $row->node . ' .fl-row-content-wrap {' . $margins . '}';
1413
- }
1414
-
1415
- return $css;
1416
- }
 
 
 
 
1417
 
1418
  /**
1419
- * @method render_row_padding
1420
- */
1421
- static public function render_row_padding($row)
1422
- {
1423
- $settings = $row->settings;
1424
- $padding = '';
1425
- $css = '';
1426
-
1427
- if($settings->padding_top != '') {
1428
- $padding .= 'padding-top:' . $settings->padding_top . 'px;';
1429
- }
1430
- if($settings->padding_bottom != '') {
1431
- $padding .= 'padding-bottom:' . $settings->padding_bottom . 'px;';
1432
- }
1433
- if($settings->padding_left != '') {
1434
- $padding .= 'padding-left:' . $settings->padding_left . 'px;';
1435
- }
1436
- if($settings->padding_right != '') {
1437
- $padding .= 'padding-right:' . $settings->padding_right . 'px;';
1438
- }
1439
- if($padding != '') {
1440
- $css = '.fl-node-' . $row->node . ' .fl-row-content-wrap {' . $padding . '}';
1441
- }
1442
-
1443
- return $css;
1444
- }
 
 
 
 
 
1445
 
1446
  /**
1447
- * @method render_row_bg_positions
1448
- */
1449
- static public function render_row_bg_positions($row)
1450
- {
1451
- $settings = $row->settings;
1452
- $positions = '';
1453
- $css = '';
1454
-
1455
- if($settings->margin_top != '' || $settings->border_top != '') {
1456
- $positions .= 'top:' . ($settings->margin_top + $settings->border_top) . 'px;';
1457
- }
1458
- if($settings->margin_bottom != ''|| $settings->border_bottom != '') {
1459
- $positions .= 'bottom:' . ($settings->margin_bottom + $settings->border_bottom) . 'px;';
1460
- }
1461
- if($settings->margin_left != ''|| $settings->border_left != '') {
1462
- $positions .= 'left:' . ($settings->margin_left + $settings->border_left) . 'px;';
1463
- }
1464
- if($settings->margin_right != ''|| $settings->border_right != '') {
1465
- $positions .= 'right:' . ($settings->margin_right + $settings->border_right) . 'px;';
1466
- }
1467
- if($positions != '') {
1468
- $css .= '.fl-node-' . $row->node . ' .fl-bg-video {' . $positions . '}';
1469
- $css .= '.fl-node-' . $row->node . ' .fl-bg-slideshow {' . $positions . '}';
1470
- }
1471
-
1472
- return $css;
1473
- }
 
1474
 
1475
  /**
1476
- * @method render_responsive_row_bg_positions
1477
- */
1478
- static public function render_responsive_row_bg_positions($row)
1479
- {
1480
- $global_settings = FLBuilderModel::get_global_settings();
1481
- $settings = $row->settings;
1482
- $positions = '';
1483
- $css = '';
1484
-
1485
- if($settings->border_top != '') {
1486
- $positions .= 'top:' . $settings->border_top . 'px;';
1487
- }
1488
- if($settings->border_bottom != '') {
1489
- $positions .= 'bottom:' . $settings->border_bottom . 'px;';
1490
- }
1491
- if($positions != '') {
1492
- $css .= '@media (max-width: '. $global_settings->responsive_breakpoint .'px) { ';
1493
- $css .= '.fl-node-' . $row->node . ' .fl-bg-video {' . $positions . '}';
1494
- $css .= '.fl-node-' . $row->node . ' .fl-bg-slideshow {' . $positions . '}';
1495
- $css .= ' }';
1496
- }
1497
-
1498
- return $css;
1499
- }
 
 
 
 
 
 
1500
 
1501
  /**
1502
- * @method render_column_margins
1503
- */
1504
- static public function render_column_margins($col)
1505
- {
1506
- $settings = $col->settings;
1507
- $margins = '';
1508
- $css = '';
1509
-
1510
- if($settings->margin_top != '') {
1511
- $margins .= 'margin-top:' . $settings->margin_top . 'px;';
1512
- }
1513
- if($settings->margin_bottom != '') {
1514
- $margins .= 'margin-bottom:' . $settings->margin_bottom . 'px;';
1515
- }
1516
- if($settings->margin_left != '') {
1517
- $margins .= 'margin-left:' . $settings->margin_left . 'px;';
1518
- }
1519
- if($settings->margin_right != '') {
1520
- $margins .= 'margin-right:' . $settings->margin_right . 'px;';
1521
- }
1522
- if($margins != '') {
1523
- $css .= '.fl-node-' . $col->node . ' .fl-col-content {' . $margins . '}';
1524
- }
1525
-
1526
- return $css;
1527
- }
 
 
 
 
1528
 
1529
  /**
1530
- * @method render_column_padding
1531
- */
1532
- static public function render_column_padding($col)
1533
- {
1534
- $settings = $col->settings;
1535
- $padding = '';
1536
- $css = '';
1537
-
1538
- if($settings->padding_top != '') {
1539
- $padding .= 'padding-top:' . $settings->padding_top . 'px;';
1540
- }
1541
- if($settings->padding_bottom != '') {
1542
- $padding .= 'padding-bottom:' . $settings->padding_bottom . 'px;';
1543
- }
1544
- if($settings->padding_left != '') {
1545
- $padding .= 'padding-left:' . $settings->padding_left . 'px;';
1546
- }
1547
- if($settings->padding_right != '') {
1548
- $padding .= 'padding-right:' . $settings->padding_right . 'px;';
1549
- }
1550
- if($padding != '') {
1551
- $css = '.fl-node-' . $col->node . ' .fl-col-content {' . $padding . '}';
1552
- }
1553
-
1554
- return $css;
1555
- }
 
 
 
 
1556
 
1557
  /**
1558
- * @method render_module_margins
1559
- */
1560
- static public function render_module_margins($module)
1561
- {
1562
- $settings = $module->settings;
1563
- $margins = '';
1564
- $css = '';
1565
-
1566
- if($settings->margin_top != '') {
1567
- $margins .= 'margin-top:' . $settings->margin_top . 'px;';
1568
- }
1569
- if($settings->margin_bottom != '') {
1570
- $margins .= 'margin-bottom:' . $settings->margin_bottom . 'px;';
1571
- }
1572
- if($settings->margin_left != '') {
1573
- $margins .= 'margin-left:' . $settings->margin_left . 'px;';
1574
- }
1575
- if($settings->margin_right != '') {
1576
- $margins .= 'margin-right:' . $settings->margin_right . 'px;';
1577
- }
1578
- if($margins != '') {
1579
- $css = '.fl-node-' . $module->node . ' .fl-module-content {' . $margins . '}';
1580
- }
1581
-
1582
- return $css;
1583
- }
 
 
 
 
 
 
 
 
1584
 
1585
  /**
1586
- * @method render_responsive_module_margins
1587
- */
1588
- static public function render_responsive_module_margins($module)
1589
- {
1590
- $global_settings = FLBuilderModel::get_global_settings();
1591
- $default = $global_settings->module_margins;
1592
- $settings = $module->settings;
1593
- $margins = '';
1594
- $css = '';
1595
-
1596
- if($settings->margin_top != '' && ($settings->margin_top > $default || $settings->margin_top < 0)) {
1597
- $margins .= 'margin-top:' . $default . 'px;';
1598
- }
1599
- if($settings->margin_bottom != '' && ($settings->margin_bottom > $default || $settings->margin_bottom < 0)) {
1600
- $margins .= 'margin-bottom:' . $default . 'px;';
1601
- }
1602
- if($settings->margin_left != '' && ($settings->margin_left > $default || $settings->margin_left < 0)) {
1603
- $margins .= 'margin-left:' . $default . 'px;';
1604
- }
1605
- if($settings->margin_right != '' && ($settings->margin_right > $default || $settings->margin_right < 0)) {
1606
- $margins .= 'margin-right:' . $default . 'px;';
1607
- }
1608
- if($margins != '') {
1609
- $css .= '@media (max-width: '. $global_settings->responsive_breakpoint .'px) { ';
1610
- $css .= '.fl-node-' . $module->node . ' .fl-module-content {' . $margins . '}';
1611
- $css .= ' }';
1612
- }
1613
-
1614
- return $css;
1615
- }
1616
-
1617
- /**
1618
- * @method render_js
1619
- */
1620
- static public function render_js()
1621
- {
1622
- // Delete the old file.
1623
- FLBuilderModel::delete_asset_cache('js');
1624
-
1625
- // Get info on the new file.
1626
- $global_settings = FLBuilderModel::get_global_settings();
1627
- $rows = FLBuilderModel::get_nodes('row');
1628
- $modules = FLBuilderModel::get_all_modules();
1629
- $asset_info = FLBuilderModel::get_asset_info();
1630
- $compiled = array();
1631
- $js = '';
1632
-
1633
- // Main JS
1634
- $js .= file_get_contents(FL_BUILDER_DIR . 'js/fl-builder-layout.js');
1635
-
1636
- // Instance Row JS
1637
- foreach($rows as $row) {
1638
-
1639
- $settings = $row->settings;
1640
- $id = $row->node;
1641
-
1642
- ob_start();
1643
- include FL_BUILDER_DIR . 'includes/row-js.php';
1644
- $js .= ob_get_clean();
1645
- }
1646
-
1647
- // Modules
1648
- foreach($modules as $module) {
1649
-
1650
- // Global module JS
1651
- $file = $module->dir . 'js/frontend.js';
1652
-
1653
- if(file_exists($file) && !in_array($module->settings->type, $compiled)) {
1654
- $js .= "\n" . file_get_contents($file);
1655
- $compiled[] = $module->settings->type;
1656
- }
1657
-
1658
- // Instance module JS
1659
- $file = $module->dir . 'includes/frontend.js.php';
1660
- $settings = $module->settings;
1661
- $id = $module->node;
1662
-
1663
- if(file_exists($file)) {
1664
- ob_start();
1665
- include $file;
1666
- $js .= ob_get_clean();
1667
- }
1668
- }
1669
-
1670
- // Add the AJAX url global.
1671
- $js .= "var wpAjaxUrl = '" . admin_url('admin-ajax.php') . "';";
1672
-
1673
- // Add the builder url global.
1674
- $js .= "var flBuilderUrl = '" . FL_BUILDER_URL . "';";
1675
-
1676
- // Call the FLBuilder._renderLayoutComplete method if we're currently editing.
1677
- if(stristr($asset_info['js'], '-draft.js') || stristr($asset_info['js'], '-preview.js')) {
1678
- $js .= "; if(typeof FLBuilder !== 'undefined' && typeof FLBuilder._renderLayoutComplete !== 'undefined') FLBuilder._renderLayoutComplete();";
1679
- }
1680
-
1681
- // Include FLJSMin
1682
- if(!class_exists('FLJSMin')) {
1683
- include FL_BUILDER_DIR . 'classes/class-fl-jsmin.php';
1684
- }
1685
-
1686
- // Save the js
1687
- if(!empty($js)) {
1688
- file_put_contents($asset_info['js'], FLJSMin::minify($js));
1689
- }
1690
- }
1691
 
1692
  /**
1693
- * @method log
1694
- */
1695
- static public function log($data)
1696
- {
1697
- ob_start();
1698
- print_r($data);
1699
- error_log(ob_get_clean());
1700
- }
 
 
 
1701
  }
3
  /**
4
  * Main builder class.
5
  *
6
+ * @since 1.0
7
  */
8
  final class FLBuilder {
9
 
13
  * Load the translation file for current language. Checks the default WordPress
14
  * languages folder first and then the languages folder inside the plugin.
15
  *
16
+ * @since 1.4.4
17
+ * @return string|bool The translation file path or false if none is found.
18
  */
19
  static public function load_plugin_textdomain()
20
  {
39
  }
40
 
41
  /**
42
+ * Front-end AJAX handler for the builder interface. We use this
43
+ * instead of wp_ajax because that only works in the admin and
44
+ * certain things like some shortcodes won't render there. AJAX
45
+ * requests handled through this method only run for logged in users
46
+ * for extra security. Developers creating custom modules that need
47
+ * AJAX should use wp_ajax instead.
48
  *
49
+ * @since 1.0
50
+ * @return void
51
+ */
52
+ static public function ajax()
53
+ {
54
+ // Only run for logged in users.
55
+ if(is_user_logged_in()) {
56
+
57
+ // Get builder post data.
58
+ $post_data = FLBuilderModel::get_post_data();
59
+
60
+ // Get the action.
61
+ if(!empty($_REQUEST['fl_action'])) {
62
+ $action = $_REQUEST['fl_action'];
63
+ }
64
+ else if(!empty($post_data['fl_action'])) {
65
+ $action = $post_data['fl_action'];
66
+ }
67
+ else {
68
+ return;
69
+ }
70
+
71
+ // Run the action.
72
+ define('DOING_AJAX', true);
73
+ do_action('fl_ajax_' . $action);
74
+ die('0');
75
+ }
76
+ }
77
 
78
  /**
79
+ * Initializes the builder interface.
80
+ *
81
+ * @since 1.0
82
+ * @return void
83
+ */
84
+ static public function init()
85
+ {
86
+ // Enable editing if the builder is active.
87
+ if(FLBuilderModel::is_builder_active()) {
88
+
89
+ // Tell W3TC not to minify while the builder is active.
90
+ define( 'DONOTMINIFY', true );
91
+
92
+ // Remove 3rd party editor buttons.
93
+ remove_all_actions('media_buttons', 999999);
94
+ remove_all_actions('media_buttons_context', 999999);
95
+
96
+ // Get the post.
97
+ require_once ABSPATH . 'wp-admin/includes/post.php';
98
+ $post_id = FLBuilderModel::get_post_id();
99
+
100
+ // Check to see if the post is locked.
101
+ if(wp_check_post_lock($post_id) !== false) {
102
+ header('Location: ' . admin_url('/post.php?post=' . $post_id . '&action=edit'));
103
+ }
104
+ else {
105
+ FLBuilderModel::enable_editing();
106
+ }
107
+ }
108
+ }
109
 
110
  /**
111
+ * Alias method for registering a module with the builder.
112
+ *
113
+ * @since 1.0
114
+ * @param string $class The module's PHP class name.
115
+ * @param array $form The module's settings form data.
116
+ * @return void
117
+ */
118
+ static public function register_module($class, $form)
119
+ {
120
+ FLBuilderModel::register_module($class, $form);
121
+ }
122
 
123
  /**
124
+ * Alias method for registering a settings form with the builder.
125
+ *
126
+ * @since 1.0
127
+ * @param string $id The form's ID.
128
+ * @param array $form The form data.
129
+ * @return void
130
+ */
131
+ static public function register_settings_form($id, $form)
132
+ {
133
+ FLBuilderModel::register_settings_form($id, $form);
134
+ }
135
 
136
  /**
137
+ * Send no cache headers when the builder interface is active.
138
+ *
139
+ * @since 1.0
140
+ * @return void
141
+ */
142
+ static public function no_cache_headers()
143
+ {
144
+ if(isset($_GET['fl_builder'])) {
145
+ header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
146
+ header('Cache-Control: no-store, no-cache, must-revalidate');
147
+ header('Cache-Control: post-check=0, pre-check=0', false);
148
+ header('Pragma: no-cache');
149
+ header('Expires: Sat, 26 Jul 1997 05:00:00 GMT');
150
+ }
151
+ }
152
 
153
  /**
154
+ * Set the default text editor to tinymce when the builder is active.
155
+ *
156
+ * @since 1.0
157
+ * @param string $type The current default editor type.
158
+ * @return string
159
+ */
160
  static public function default_editor($type)
161
  {
162
+ return FLBuilderModel::is_builder_active() ? 'tinymce' : $type;
163
  }
164
 
165
  /**
166
+ * Add custom CSS for the builder to the text editor.
167
+ *
168
+ * @since 1.0
169
+ * @param string $mce_css
170
+ * @return string
171
+ */
172
  static public function add_editor_css($mce_css)
173
  {
174
+ if(FLBuilderModel::is_builder_active()) {
175
 
176
+ if(!empty($mce_css)) {
177
+ $mce_css .= ',';
178
+ }
179
 
180
+ $mce_css .= FL_BUILDER_URL . 'css/editor.css';
181
+ }
182
 
183
+ return $mce_css;
184
  }
185
 
186
  /**
187
+ * Add additional buttons to the text editor.
188
+ *
189
+ * @since 1.0
190
+ * @param array $buttons The current buttons array.
191
+ * @return array
192
+ */
193
  static public function editor_buttons_2($buttons)
194
  {
195
+ if(FLBuilderModel::is_builder_active()) {
196
 
197
+ array_shift($buttons);
198
+ array_unshift($buttons, 'fontsizeselect');
199
+ array_unshift($buttons, 'formatselect');
200
 
201
+ if(($key = array_search('wp_help', $buttons)) !== false) {
202
+ unset($buttons[$key]);
203
+ }
204
+ }
205
 
206
+ return $buttons;
207
  }
208
 
209
  /**
210
+ * Only allows certain text editor plugins to avoid conflicts
211
+ * with third party plugins.
212
+ *
213
+ * @since 1.0
214
+ * @param array $plugins The current editor plugins.
215
+ * @return array
216
+ */
217
  static public function editor_external_plugins($plugins)
218
  {
219
+ if(FLBuilderModel::is_builder_active()) {
220
+
221
+ $allowed = array(
222
+ 'anchor',
223
+ 'code',
224
+ 'insertdatetime',
225
+ 'nonbreaking',
226
+ 'print',
227
+ 'searchreplace',
228
+ 'table',
229
+ 'visualblocks',
230
+ 'visualchars',
231
+ 'emoticons',
232
+ 'advlist',
233
+ 'wptadv',
234
+ );
235
+
236
+ foreach($plugins as $key => $val) {
237
+ if(!in_array($key, $allowed)) {
238
+ unset($plugins[$key]);
239
+ }
240
+ }
241
+ }
242
+
243
+ return $plugins;
244
  }
245
 
246
  /**
247
+ * Include a jQuery fallback script when the builder is
248
+ * enabled for a page.
249
+ *
250
+ * @since 1.0
251
+ * @return void
252
+ */
253
  static public function include_jquery()
254
  {
255
+ if(FLBuilderModel::is_builder_enabled()) {
256
+ include FL_BUILDER_DIR . 'includes/jquery.php';
257
+ }
258
  }
259
 
260
  /**
261
+ * Register and enqueue the styles and scripts for all builder
262
+ * layouts in the main WordPress query.
263
+ *
264
+ * @since 1.0
265
+ * @return void
266
+ */
267
  static public function layout_styles_scripts()
268
  {
269
+ global $wp_query;
270
+ global $post;
271
 
272
  $original_post = $post;
273
+ $ver = FL_BUILDER_VERSION;
274
+ $css_url = FL_BUILDER_URL . 'css/';
275
+ $js_url = FL_BUILDER_URL . 'js/';
276
+
277
+ // Register additional CSS
278
+ wp_register_style('font-awesome', $css_url . 'font-awesome.min.css', array(), $ver);
279
+ wp_register_style('foundation-icons', $css_url . 'foundation-icons.css', array(), $ver);
280
+ wp_register_style('fl-slideshow', $css_url . 'fl-slideshow.css', array(), $ver);
281
+ wp_register_style('jquery-bxslider', $css_url . 'jquery.bxslider.css', array(), $ver);
282
+ wp_register_style('jquery-magnificpopup', $css_url . 'jquery.magnificpopup.css', array(), $ver);
283
+
284
+ // Register additional JS
285
+ wp_register_script('fl-slideshow', $js_url . 'fl-slideshow.js', array('yui3'), $ver, true);
286
+ wp_register_script('fl-gallery-grid', $js_url . 'fl-gallery-grid.js', array('jquery'), $ver, true);
287
+ wp_register_script('jquery-bxslider', $js_url . 'jquery.bxslider.min.js', array('jquery-easing', 'jquery-fitvids'), $ver, true);
288
+ wp_register_script('jquery-easing', $js_url . 'jquery.easing.1.3.js', array('jquery'), '1.3', true);
289
+ wp_register_script('jquery-fitvids', $js_url . 'jquery.fitvids.js', array('jquery'), $ver, true);
290
+ wp_register_script('jquery-infinitescroll', $js_url . 'jquery.infinitescroll.js', array('jquery'), $ver, true);
291
+ wp_register_script('jquery-magnificpopup', $js_url . 'jquery.magnificpopup.min.js', array('jquery'), $ver, true);
292
+ wp_register_script('jquery-mosaicflow', $js_url . 'jquery.mosaicflow.min.js', array('jquery'), $ver, true);
293
+ wp_register_script('jquery-waypoints', $js_url . 'jquery.waypoints.min.js', array('jquery'), $ver, true);
294
+ wp_register_script('jquery-wookmark', $js_url . 'jquery.wookmark.min.js', array('jquery'), $ver, true);
295
+
296
+ // YUI 3 (Needed for the slideshow)
297
+ if(FLBuilderModel::is_ssl()) {
298
+ wp_register_script('yui3', 'https://yui-s.yahooapis.com/3.5.1/build/yui/yui-min.js', array(), '3.5.1', false);
299
+ }
300
+ else {
301
+ wp_register_script('yui3', 'http://yui.yahooapis.com/3.5.1/build/yui/yui-min.js', array(), '3.5.1', false);
302
+ }
303
+
304
+ // Enqueue assets for posts in the main query.
305
+ if ( isset( $wp_query->posts ) ) {
306
+ foreach ( $wp_query->posts as $post ) {
307
+ self::enqueue_layout_styles_scripts( $post->ID );
308
+ }
309
+ }
310
+
311
+ // Enqueue assets for posts via the fl_builder_global_posts filter.
312
+ $post_ids = FLBuilderModel::get_global_posts();
313
+
314
+ if(count($post_ids) > 0) {
315
+
316
+ $posts = get_posts(array('post__in' => $post_ids, 'post_type' => 'any'));
317
+
318
+ foreach($posts as $post) {
319
+ self::enqueue_layout_styles_scripts($post->ID);
320
+ }
321
+ }
322
+
323
+ // Reset the global post variable.
324
+ $post = $original_post;
325
  }
326
 
327
  /**
328
+ * Enqueue the styles and scripts for a single layout.
329
+ *
330
+ * @since 1.0
331
+ * @param int $post_id The post ID for this layout.
332
+ * @return void
333
+ */
334
  static public function enqueue_layout_styles_scripts($post_id)
335
  {
336
+ if(FLBuilderModel::is_builder_enabled()) {
337
+
338
+ $rows = FLBuilderModel::get_nodes('row');
339
+ $modules = FLBuilderModel::get_all_modules();
340
+ $asset_info = FLBuilderModel::get_asset_info();
341
+ $asset_ver = FLBuilderModel::get_asset_version();
342
+
343
+ // Enqueue required row CSS and JS
344
+ foreach($rows as $row) {
345
+ if($row->settings->bg_type == 'slideshow') {
346
+ wp_enqueue_script('yui3');
347
+ wp_enqueue_script('fl-slideshow');
348
+ wp_enqueue_style('fl-slideshow');
349
+ }
350
+ }
351
+
352
+ // Enqueue required module CSS and JS
353
+ foreach($modules as $module) {
354
+
355
+ $module->enqueue_icon_styles();
356
+ $module->enqueue_scripts();
357
+
358
+ foreach($module->css as $handle => $props) {
359
+ wp_enqueue_style($handle, $props[0], $props[1], $props[2], $props[3]);
360
+ }
361
+ foreach($module->js as $handle => $props) {
362
+ wp_enqueue_script($handle, $props[0], $props[1], $props[2], $props[3]);
363
+ }
364
+ if(!empty($module->settings->animation)) {
365
+ wp_enqueue_script('jquery-waypoints');
366
+ }
367
+ }
368
+
369
+ // Enqueue main CSS
370
+ if(!file_exists($asset_info['css'])) {
371
+ FLBuilder::render_css();
372
+ }
373
+
374
+ wp_enqueue_style('fl-builder-layout-' . $post_id, $asset_info['css_url'], array(), $asset_ver);
375
+
376
+ // Enqueue main JS
377
+ if(!file_exists($asset_info['js'])) {
378
+ FLBuilder::render_js();
379
+ }
380
+
381
+ wp_enqueue_script('fl-builder-layout-' . $post_id, $asset_info['js_url'], array(), $asset_ver, true);
382
+ }
383
  }
384
 
385
  /**
386
+ * Enqueue the styles and scripts for the builder interface.
387
+ *
388
+ * @since 1.0
389
+ * @return void
390
+ */
391
  static public function styles_scripts()
392
  {
393
+ if(FLBuilderModel::is_builder_active()) {
394
+
395
+ $ver = FL_BUILDER_VERSION;
396
+ $css_url = FL_BUILDER_URL . 'css/';
397
+ $js_url = FL_BUILDER_URL . 'js/';
398
+
399
+ /* We have a custom version of sortable that fixes a bug. */
400
+ wp_deregister_script('jquery-ui-sortable');
401
+
402
+ /* Frontend builder styles */
403
+ wp_enqueue_style('dashicons');
404
+ wp_enqueue_style('font-awesome');
405
+ wp_enqueue_style('foundation-icons');
406
+ wp_enqueue_style('jquery-nanoscroller', $css_url . 'jquery.nanoscroller.css', array(), $ver);
407
+ wp_enqueue_style('jquery-autosuggest', $css_url . 'jquery.autoSuggest.min.css', array(), $ver);
408
+ wp_enqueue_style('jquery-tiptip', $css_url . 'jquery.tiptip.css', array(), $ver);
409
+ wp_enqueue_style('bootstrap-tour', $css_url . 'bootstrap-tour-standalone.min.css', array(), $ver);
410
+ wp_enqueue_style('fl-color-picker', $css_url . 'colorpicker.css', array(), $ver);
411
+ wp_enqueue_style('fl-lightbox', $css_url . 'fl-lightbox.css', array(), $ver);
412
+ wp_enqueue_style('fl-icon-selector', $css_url . 'fl-icon-selector.css', array(), $ver);
413
+ wp_enqueue_style('fl-builder', $css_url . 'fl-builder.css', array(), $ver);
414
+
415
+ /* Custom Icons */
416
+ FLBuilderIcons::enqueue_all_custom_icons_styles();
417
+
418
+ /* RTL Support */
419
+ if(is_rtl()) {
420
+ wp_enqueue_style('fl-builder-rtl', $css_url . 'fl-builder-rtl.css', array(), $ver);
421
+ }
422
+
423
+ /* Frontend builder scripts */
424
+ wp_enqueue_media();
425
+ wp_enqueue_script('heartbeat');
426
+ wp_enqueue_script('wpdialogs');
427
+ wp_enqueue_script('wpdialogs-popup');
428
+ wp_enqueue_script('wplink');
429
+ wp_enqueue_script('editor');
430
+ wp_enqueue_script('quicktags');
431
+ wp_enqueue_script('json2');
432
+ wp_enqueue_script('jquery-ui-droppable');
433
+ wp_enqueue_script('jquery-ui-draggable');
434
+ wp_enqueue_script('jquery-ui-sortable', $js_url . 'jquery.ui.sortable.js', array('jquery-ui-core', 'jquery-ui-widget', 'jquery-ui-mouse'), $ver, true);
435
+ wp_enqueue_script('jquery-nanoscroller', $js_url . 'jquery.nanoscroller.min.js', array(), $ver, true);
436
+ wp_enqueue_script('jquery-autosuggest', $js_url . 'jquery.autoSuggest.min.js', array(), $ver, true);
437
+ wp_enqueue_script('jquery-tiptip', $js_url . 'jquery.tiptip.min.js', array(), $ver, true);
438
+ wp_enqueue_script('jquery-simulate', $js_url . 'jquery.simulate.js', array(), $ver, true);
439
+ wp_enqueue_script('jquery-validate', $js_url . 'jquery.validate.min.js', array(), $ver, true);
440
+ wp_enqueue_script('bootstrap-tour', $js_url . 'bootstrap-tour-standalone.min.js', array(), $ver, true);
441
  wp_enqueue_script('ace', $js_url . 'ace/ace.js', array(), $ver, true);
442
+ wp_enqueue_script('fl-color-picker', $js_url . 'colorpicker.js', array(), $ver, true);
443
+ wp_enqueue_script('fl-lightbox', $js_url . 'fl-lightbox.js', array(), $ver, true);
444
+ wp_enqueue_script('fl-icon-selector', $js_url . 'fl-icon-selector.js', array(), $ver, true);
445
+ wp_enqueue_script('fl-stylesheet', $js_url . 'fl-stylesheet.js', array(), $ver, true);
446
+ wp_enqueue_script('fl-builder', $js_url . 'fl-builder.js', array(), $ver, true);
447
+ wp_enqueue_script('fl-builder-preview', $js_url . 'fl-builder-preview.js', array(), $ver, true);
448
+ wp_enqueue_script('fl-builder-services', $js_url . 'fl-builder-services.js', array(), $ver, true);
449
+ wp_enqueue_script('fl-builder-tour', $js_url . 'fl-builder-tour.js', array(), $ver, true);
450
+
451
+ /* Core template settings */
452
+ if(file_exists(FL_BUILDER_DIR . 'js/fl-builder-template-settings.js')) {
453
+ wp_enqueue_script('fl-builder-template-settings', FL_BUILDER_URL . 'js/fl-builder-template-settings.js', array(), $ver, true);
454
+ }
455
+
456
+ /* Additional module styles and scripts */
457
+ foreach(FLBuilderModel::$modules as $module) {
458
+
459
+ $module->enqueue_scripts();
460
+
461
+ foreach($module->css as $handle => $props) {
462
+ wp_enqueue_style($handle, $props[0], $props[1], $props[2], $props[3]);
463
+ }
464
+ foreach($module->js as $handle => $props) {
465
+ wp_enqueue_script($handle, $props[0], $props[1], $props[2], $props[3]);
466
+ }
467
+ }
468
+ }
469
+ }
470
+
471
+ /**
472
+ * Adds builder classes to the body class.
473
+ *
474
+ * @since 1.0
475
+ * @param array $classes An array of existing classes.
476
+ * @return array
477
+ */
478
+ static public function body_class($classes)
479
+ {
480
+ if(FLBuilderModel::is_builder_enabled()) {
481
+ $classes[] = 'fl-builder';
482
+ }
483
+ if(FLBuilderModel::is_builder_active() && !current_user_can(FLBuilderModel::get_editing_capability())) {
484
+ $classes[] = 'fl-builder-simple';
485
+ }
486
+
487
+ return $classes;
488
  }
489
 
490
+ /**
491
+ * Adds the page builder button to the WordPress admin bar.
492
+ *
493
+ * @since 1.0
494
+ * @param object $wp_admin_bar An instance of the WordPress admin bar.
495
+ * @return void
496
+ */
497
+ static public function admin_bar_menu($wp_admin_bar)
498
+ {
499
+ global $wp_the_query;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
500
 
501
+ if ( FLBuilderModel::is_post_editable() ) {
 
 
 
 
 
502
 
503
+ $wp_admin_bar->add_node( array(
504
+ 'id' => 'fl-builder-frontend-edit-link',
505
+ '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(),
506
+ 'href' => FLBuilderModel::get_edit_url( $wp_the_query->post->ID )
507
+ ));
508
+ }
509
+ }
510
 
511
  /**
512
+ * Renders the markup for the builder interface.
513
+ *
514
+ * @since 1.0
515
+ * @return void
516
+ */
517
+ static public function render_ui()
518
+ {
519
+ global $wp_the_query;
520
+
521
+ if ( FLBuilderModel::is_builder_active() ) {
522
+
523
+ $post_id = $wp_the_query->post->ID;
524
+ $categories = FLBuilderModel::get_categorized_modules();
525
+ $enabled_templates = FLBuilderModel::get_enabled_templates();
526
+ $help_button = FLBuilderModel::get_help_button_settings();
527
+
528
+ include FL_BUILDER_DIR . 'includes/ui.php';
529
+ include FL_BUILDER_DIR . 'includes/js-config.php';
530
+ }
531
+ }
532
+
533
+ /**
534
+ * Renders a preview of the layout to be
535
+ * passed back to the builder via AJAX.
536
+ *
537
+ * @since 1.0
538
+ * @param bool $return Whether to return the layout or output it.
539
+ * @return array|void The layout data or nothing.
540
+ */
541
+ static public function render_preview($return = false)
542
+ {
543
+ self::render_css();
544
+ self::render_js();
545
+
546
+ if($return) {
547
+ return self::render_layout(true);
548
+ }
549
+ else {
550
+ self::render_layout();
551
+ }
552
+ }
553
+
554
+ /**
555
+ * Renders the layout to be passed back to
556
+ * the builder via AJAX for an update.
557
+ *
558
+ * @since 1.0
559
+ * @param bool $return Whether to return the layout or output it.
560
+ * @return array|void The layout data or nothing.
561
+ */
562
+ static public function render_layout($return = false)
563
+ {
564
+ global $wp_scripts;
565
+ global $wp_styles;
566
+
567
+ // Deregister scripts and styles so we can capture those
568
+ // registered by content functions such as shortcodes.
569
+ if(isset($wp_scripts)) {
570
+ $wp_scripts->queue = array();
571
+ }
572
+ if(isset($wp_styles)) {
573
+ $wp_styles->queue = array();
574
+ }
575
+
576
+ // Enqueue jQuery again so it's not added by any
577
+ // third party shortcodes or plugins.
578
+ wp_enqueue_script('jquery');
579
+
580
+ // Render the layout.
581
+ ob_start();
582
+ self::render_rows();
583
+ $html = ob_get_clean();
584
+
585
+ // Process shortcodes.
586
+ ob_start();
587
+ echo do_shortcode($html);
588
+ $html = ob_get_clean();
589
+
590
+ // Print scripts and styles registered by content
591
+ // functions such as shortcodes.
592
+ ob_start();
593
+
594
+ if(isset($wp_scripts)) {
595
+ $wp_scripts->done[] = 'jquery';
596
+ wp_print_scripts($wp_scripts->queue);
597
+ }
598
+ if(isset($wp_styles)) {
599
+ wp_print_styles($wp_styles->queue);
600
+ }
601
+
602
+ $html = ob_get_clean() . $html;
603
+
604
+ // Get the asset info.
605
+ $asset_info = FLBuilderModel::get_asset_info();
606
+ $asset_ver = FLBuilderModel::get_asset_version();
607
+
608
+ // Build the response.
609
+ $response = array(
610
+ 'html' => $html,
611
+ 'css' => $asset_info['css_url'] . '?ver=' . $asset_ver,
612
+ 'js' => $asset_info['js_url'] . '?ver=' . $asset_ver
613
+ );
614
+
615
+ // Return or echo the response.
616
+ if($return) {
617
+ return $response;
618
+ }
619
+ else {
620
+ echo json_encode($response);
621
+ die();
622
+ }
623
+ }
624
+
625
+ /**
626
+ * Renders the content for a builder layout while in the loop.
627
+ *
628
+ * @since 1.0
629
+ * @param string $content The existing content.
630
+ * @return string
631
+ */
632
+ static public function render_content($content)
633
  {
634
+ global $post;
635
+
636
+ $post_id = FLBuilderModel::get_post_id();
637
+ $enabled = FLBuilderModel::is_builder_enabled();
638
+ $ajax = defined('DOING_AJAX');
639
+ $global_posts = FLBuilderModel::get_global_posts();
640
+ $is_global = in_array($post->ID, $global_posts);
641
+ $in_loop = in_the_loop();
642
+
643
+ if($enabled && !$ajax && ($is_global || $in_loop)) {
644
+
645
+ // Remove the builder's render_content filter in case apply_filters
646
+ // is called again by a widget, module or shortcode.
647
+ remove_filter('the_content', 'FLBuilder::render_content');
648
+
649
+ // Render the content.
650
+ ob_start();
651
+ echo '<div class="fl-builder-content fl-builder-content-' . $post_id . '" data-post-id="' . $post_id . '">';
652
+ self::render_rows();
653
+ echo '</div>';
654
+ $content = do_shortcode(ob_get_clean());
655
+
656
+ // Reapply the builder's render_content filter.
657
+ add_filter('the_content', 'FLBuilder::render_content');
658
+ }
659
+
660
+ return $content;
661
+ }
662
+
663
+ /**
664
+ * Renders the stripped down content for a layout
665
+ * that is saved to the WordPress editor.
666
+ *
667
+ * @since 1.0
668
+ * @param string $content The existing content.
669
+ * @return string
670
+ */
671
+ static public function render_editor_content()
672
+ {
673
+ $rows = FLBuilderModel::get_nodes('row');
674
+
675
+ ob_start();
676
+
677
+ // Render the modules.
678
+ foreach($rows as $row) {
679
+
680
+ $groups = FLBuilderModel::get_nodes('column-group', $row->node);
681
+
682
+ foreach($groups as $group) {
683
 
684
+ $cols = FLBuilderModel::get_nodes('column', $group->node);
685
 
686
+ foreach($cols as $col) {
 
 
687
 
688
+ $modules = FLBuilderModel::get_modules($col->node);
689
+
690
+ foreach($modules as $module) {
691
+
692
+ if($module->editor_export) {
693
+
694
+ // Don't crop photos to ensure media library photos are rendered.
695
+ if($module->settings->type == 'photo') {
696
+ $module->settings->crop = false;
697
+ }
698
+
699
+ FLBuilder::render_module_html($module->settings->type, $module->settings, $module);
700
+ }
701
+ }
702
+ }
703
+ }
704
+ }
705
+
706
+ // Get the content.
707
+ $content = ob_get_clean();
708
+
709
+ // Remove unnecessary tags.
710
+ $content = preg_replace('/<\/?div[^>]*\>/i', '', $content);
711
+ $content = preg_replace('/<\/?span[^>]*\>/i', '', $content);
712
+ $content = preg_replace('#<script(.*?)>(.*?)</script>#is', '', $content);
713
+ $content = preg_replace('/<i [^>]*><\\/i[^>]*>/', '', $content);
714
+ $content = preg_replace('/ class=".*?"/', '', $content);
715
+
716
+ // Remove empty lines.
717
+ $content = preg_replace('/(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+/', "\n", $content);
718
+
719
+ return $content;
720
+ }
721
+
722
+ /**
723
+ * Renders a settings form. The form is either returned
724
+ * or output for an AJAX request.
725
+ *
726
+ * @since 1.0
727
+ * @param array $form The form data.
728
+ * @param object $settings The settings data.
729
+ * @param bool $return Whether to return the form or output it.
730
+ * @return string|void The form markup or nothing.
731
+ */
732
+ static public function render_settings($form = array(), $settings, $return = false)
733
+ {
734
+ $defaults = array(
735
+ 'class' => '',
736
+ 'attrs' => '',
737
+ 'title' => '',
738
+ 'tabs' => array()
739
+ );
740
+
741
+ $form = array_merge($defaults, $form);
742
+
743
+ ob_start();
744
+ include FL_BUILDER_DIR . 'includes/settings.php';
745
+ $html = ob_get_clean();
746
+
747
+ if(defined('DOING_AJAX') && !$return) {
748
+ echo $html;
749
+ die();
750
  }
751
  else {
752
+ return $html;
753
  }
754
  }
755
 
756
  /**
757
+ * Renders a settings form field.
758
+ *
759
+ * @since 1.0
760
+ * @param string $name The field name.
761
+ * @param array $field An array of setup data for the field.
762
+ * @param object $settings Form settings data object.
763
+ * @return void
764
+ */
765
  static public function render_settings_field($name, $field, $settings = null)
766
  {
767
+ $i = null;
768
+ $is_multiple = isset($field['multiple']) && $field['multiple'] === true;
769
+ $supports_multiple = $field['type'] != 'editor' && $field['type'] != 'photo' && $field['type'] != 'service';
770
+ $settings = ! $settings ? new stdClass() : $settings;
771
+ $value = isset($settings->$name) ? $settings->$name : '';
772
+ $preview = isset($field['preview']) ? json_encode($field['preview']) : json_encode(array('type' => 'refresh'));
773
  $row_class = isset($field['row_class']) ? ' ' . $field['row_class'] : '';
774
 
775
+ if($is_multiple && $supports_multiple) {
776
+
777
+ $values = $value;
778
+ $arr_name = $name;
779
+ $name .= '[]';
780
+
781
+ echo '<tbody class="fl-field fl-builder-field-multiples" data-type="form" data-preview=\'' . $preview . '\'>';
782
+
783
+ for($i = 0; $i < count($values); $i++) {
784
+ $value = $values[$i];
785
+ echo '<tr class="fl-builder-field-multiple" data-field="'. $arr_name .'">';
786
+ include FL_BUILDER_DIR . 'includes/field.php';
787
+ echo '<td class="fl-builder-field-actions">';
788
+ echo '<i class="fl-builder-field-move fa fa-arrows"></i>';
789
+ echo '<i class="fl-builder-field-copy fa fa-copy"></i>';
790
+ echo '<i class="fl-builder-field-delete fa fa-times"></i>';
791
+ echo '</td>';
792
+ echo '</tr>';
793
+ }
794
+
795
+ echo '<tr>';
796
+
797
+ if(empty($field['label'])) {
798
+ echo '<td colspan="2">';
799
+ }
800
+ else {
801
+ echo '<td>&nbsp;</td><td>';
802
+ }
803
+
804
+ 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>';
805
+ echo '</td>';
806
+ echo '</tr>';
807
+ echo '</tbody>';
808
+ }
809
+ else {
810
+ echo '<tr id="fl-field-'. $name .'" class="fl-field' . $row_class . '" data-type="' . $field['type'] . '" data-preview=\'' . $preview . '\'>';
811
+ include FL_BUILDER_DIR . 'includes/field.php';
812
+ echo '</tr>';
813
+ }
814
  }
815
 
816
  /**
817
+ * Renders a settings form for an AJAX request. The form
818
+ * markup will be output to the page.
819
+ *
820
+ * @since 1.0
821
+ * @param string $type The type of form to render.
822
+ * @param object $settings The settings data.
823
+ * @return void
824
+ */
825
  static public function render_settings_form($type = null, $settings = null)
826
  {
827
+ $post_data = FLBuilderModel::get_post_data();
828
+ $type = isset($post_data['type']) ? $post_data['type'] : $type;
829
+ $settings = isset($post_data['settings']) ? $post_data['settings'] : $settings;
830
+ $form = FLBuilderModel::get_settings_form( $type );
831
+
832
+ if(isset($settings) && !empty($settings)) {
833
+ $defaults = FLBuilderModel::get_settings_form_defaults( $type );
834
+ $settings = (object)array_merge((array)$defaults, (array)$settings);
835
+ }
836
+ else {
837
+ $settings = FLBuilderModel::get_settings_form_defaults( $type );
838
+ }
839
+
840
+ self::render_settings(array(
841
+ 'title' => $form['title'],
842
+ 'tabs' => $form['tabs']
843
+ ), $settings);
844
  }
845
 
846
  /**
847
+ * Renders the markup for the global settings form.
848
+ *
849
+ * @since 1.0
850
+ * @return void
851
+ */
852
  static public function render_global_settings()
853
  {
854
+ $settings = FLBuilderModel::get_global_settings();
855
+ $form = FLBuilderModel::$settings_forms['global'];
856
+
857
+ self::render_settings(array(
858
+ 'class' => 'fl-builder-global-settings',
859
+ 'title' => $form['title'],
860
+ 'tabs' => $form['tabs']
861
+ ), $settings);
862
  }
863
 
864
+ /**
865
+ * Registers the custom post type for builder templates.
866
+ *
867
+ * @since 1.1.3
868
+ * @return void
869
+ */
870
+ static public function register_templates_post_type()
871
+ {
872
+ if(FL_BUILDER_LITE === true) {
873
+ return;
874
+ }
875
+
876
+ register_post_type('fl-builder-template', array(
877
+ 'public' => false,
878
+ 'labels' => array(
879
+ 'name' => _x( 'Layout Templates', 'Custom post type label.', 'fl-builder' ),
880
+ 'singular_name' => _x( 'Layout Template', 'Custom post type label.', 'fl-builder' ),
881
+ 'menu_name' => _x( 'Layout Templates', 'Custom post type label.', 'fl-builder' ),
882
+ 'name_admin_bar' => _x( 'Layout Template', 'Custom post type label.', 'fl-builder' ),
883
+ 'add_new' => _x( 'Add New', 'Custom post type label.', 'fl-builder' ),
884
+ 'add_new_item' => _x( 'Add New Layout Template', 'Custom post type label.', 'fl-builder' ),
885
+ 'new_item' => _x( 'New Layout Template', 'Custom post type label.', 'fl-builder' ),
886
+ 'edit_item' => _x( 'Edit Layout Template', 'Custom post type label.', 'fl-builder' ),
887
+ 'view_item' => _x( 'View Layout Template', 'Custom post type label.', 'fl-builder' ),
888
+ 'all_items' => _x( 'All Layout Templates', 'Custom post type label.', 'fl-builder' ),
889
+ 'search_items' => _x( 'Search Layout Templates', 'Custom post type label.', 'fl-builder' ),
890
+ 'parent_item_colon' => _x( 'Parent Layout Templates:', 'Custom post type label.', 'fl-builder' ),
891
+ 'not_found' => _x( 'No layout templates found.', 'Custom post type label.', 'fl-builder' ),
892
+ 'not_found_in_trash' => _x( 'No layout templates found in Trash.', 'Custom post type label.', 'fl-builder' )
893
+ ),
894
+ 'supports' => array(
895
+ 'title'
896
+ ),
897
+ 'publicly_queryable' => true
898
+ ));
899
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
900
 
901
  /**
902
+ * Renders the markup for the template selector.
903
+ *
904
+ * @since 1.0
905
+ * @return void
906
+ */
907
+ static public function render_template_selector()
908
+ {
909
+ if(file_exists(FL_BUILDER_DIR . 'includes/template-selector.php')) {
910
 
911
+ $enabled_templates = FLBuilderModel::get_enabled_templates();
912
+ $user_templates = FLBuilderModel::get_user_templates();
913
+ $templates = FLBuilderModel::get_templates();
914
+ $num_rows = FLBuilderModel::count_nodes('row');
915
 
916
+ include FL_BUILDER_DIR . 'includes/template-selector.php';
917
 
918
+ if(defined('DOING_AJAX')) {
919
+ die();
920
+ }
921
+ }
922
+ }
923
 
924
+ /**
925
+ * Renders the settings form for saving a user defined template.
926
+ *
927
+ * @since 1.0
928
+ * @return void
929
+ */
930
+ static public function render_user_template_settings()
931
+ {
932
+ $defaults = FLBuilderModel::get_settings_form_defaults( 'user_template' );
933
+ $form = FLBuilderModel::get_settings_form( 'user_template' );
934
+
935
+ FLBuilder::render_settings(array(
936
+ 'class' => 'fl-builder-user-template-settings',
937
+ 'title' => $form['title'],
938
+ 'tabs' => $form['tabs']
939
+ ), $defaults);
940
+ }
941
 
942
  /**
943
+ * Trys to load page.php for editing a builder template.
944
+ *
945
+ * @since 1.0
946
+ * @param string $template The current template to be loaded.
947
+ * @return string
948
+ */
949
+ static public function render_template($template)
950
+ {
951
+ global $post;
952
+
953
+ if($post && $post->post_type == 'fl-builder-template') {
954
+
955
+ $page = locate_template(array('page.php'));
956
+
957
+ if(!empty($page)) {
958
+ return $page;
959
+ }
960
+ }
961
+
962
+ return $template;
963
+ }
964
+
965
+ /**
966
+ * Renders the markup for the icon selector.
967
+ *
968
+ * @since 1.0
969
+ * @return void
970
+ */
971
  static public function render_icon_selector()
972
  {
973
+ $icon_sets = FLBuilderIcons::get_sets();
974
 
975
+ include FL_BUILDER_DIR . 'includes/icon-selector.php';
976
 
977
+ if(defined('DOING_AJAX')) {
978
+ die();
979
  }
980
  }
981
 
982
+ /**
983
+ * Renders the markup for all of the rows in a layout.
984
+ *
985
+ * @since 1.0
986
+ * @return void
987
+ */
988
+ static public function render_rows()
989
+ {
990
+ $rows = FLBuilderModel::get_nodes('row');
991
 
992
+ foreach($rows as $row) {
993
+ self::render_row($row);
994
+ }
995
+ }
996
 
997
  /**
998
+ * Renders the markup for a single row.
999
+ *
1000
+ * @since 1.0
1001
+ * @param object $row The row to render.
1002
+ * @return void
1003
+ */
1004
  static public function render_row($row)
1005
  {
1006
+ $groups = FLBuilderModel::get_nodes('column-group', $row->node);
1007
 
1008
  include FL_BUILDER_DIR . 'includes/row.php';
1009
  }
1010
 
1011
  /**
1012
+ * Adds a new row to the current layout and renders it.
1013
+ *
1014
+ * @since 1.0
1015
+ * @param string $cols The type of column layout to use.
1016
+ * @param int $position The position of the new row in the layout.
1017
+ * @return void
1018
+ */
1019
  static public function render_new_row($cols = '1-col', $position = false)
1020
  {
1021
+ $post_data = FLBuilderModel::get_post_data();
1022
+ $cols = isset($post_data['cols']) ? $post_data['cols'] : $cols;
1023
+ $position = isset($post_data['position']) ? (int)$post_data['position'] : $position;
1024
+ $row = FLBuilderModel::add_row($cols, $position);
1025
 
1026
+ self::render_row($row);
1027
 
1028
  if(defined('DOING_AJAX')) {
1029
+ die();
1030
  }
1031
  }
1032
 
1033
  /**
1034
+ * Renders the HTML attributes for a single row.
1035
+ *
1036
+ * @since 1.0
1037
+ * @param object $row A row node object.
1038
+ * @return void
1039
+ */
1040
  static public function render_row_attributes( $row )
1041
  {
1042
  $custom_class = apply_filters( 'fl_builder_row_custom_class', $row->settings->class, $row );
1048
  }
1049
 
1050
  // Class
1051
+ echo ' class="fl-row';
1052
+ echo ' fl-row-' . $row->settings->width . '-width';
1053
+ echo ' fl-row-bg-' . $row->settings->bg_type;
1054
+
1055
+ if ( in_array( $row->settings->bg_type, $overlay_bgs ) && ! empty( $row->settings->bg_overlay_color ) ) {
1056
+ echo ' fl-row-bg-overlay';
1057
+ }
1058
+ if ( ! empty( $row->settings->responsive_display ) ) {
1059
+ echo ' fl-visible-' . $row->settings->responsive_display;
1060
+ }
1061
+ if ( ! empty( $custom_class ) ) {
1062
+ echo ' ' . trim( esc_attr( $custom_class ) );
1063
+ }
1064
+
1065
+ echo ' fl-node-' . $row->node;
1066
+ echo '"';
1067
 
1068
  // Data
1069
+ echo ' data-node="' . $row->node . '"';
1070
 
1071
+ if ( $row->settings->bg_type == 'parallax' && ! empty( $row->settings->bg_parallax_image_src ) ) {
1072
+ echo ' data-parallax-speed="' . $row->settings->bg_parallax_speed . '"';
1073
+ echo ' data-parallax-image="' . $row->settings->bg_parallax_image_src . '"';
1074
+ }
1075
  }
1076
 
1077
  /**
1078
+ * Renders the markup for a row's background.
1079
+ *
1080
+ * @since 1.0
1081
+ * @param object $row A row node object.
1082
+ * @return void
1083
+ */
1084
  static public function render_row_bg($row)
1085
  {
1086
+ if($row->settings->bg_type == 'video') {
1087
 
1088
+ $vid_data = FLBuilderModel::get_row_bg_data($row);
1089
 
1090
+ if($vid_data) {
1091
+ include FL_BUILDER_DIR . 'includes/row-video.php';
1092
+ }
1093
+ }
1094
+ else if($row->settings->bg_type == 'slideshow') {
1095
+ echo '<div class="fl-bg-slideshow"></div>';
1096
+ }
1097
  }
1098
 
1099
  /**
1100
+ * Renders the HTML class for a row's content wrapper.
1101
+ *
1102
+ * @since 1.0
1103
+ * @param object $row A row node object.
1104
+ * @return void
1105
+ */
1106
  static public function render_row_content_class($row)
1107
  {
1108
+ echo 'fl-row-content';
1109
+ echo ' fl-row-' . $row->settings->content_width . '-width';
1110
+ echo ' fl-node-content';
1111
  }
1112
 
1113
  /**
1114
+ * Renders the settings lightbox for a row.
1115
+ *
1116
+ * @since 1.0
1117
+ * @param string $node_id A row node ID.
1118
+ * @return void
1119
+ */
1120
  static public function render_row_settings($node_id = null)
1121
  {
1122
+ $post_data = FLBuilderModel::get_post_data();
1123
+ $node_id = isset($post_data['node_id']) ? $post_data['node_id'] : $node_id;
1124
+ $node = FLBuilderModel::get_node($node_id);
1125
+ $settings = $node->settings;
1126
+ $form = FLBuilderModel::$settings_forms['row'];
1127
+
1128
+ self::render_settings(array(
1129
+ 'class' => 'fl-builder-row-settings',
1130
+ 'attrs' => 'data-node="'. $node->node .'"',
1131
+ 'title' => $form['title'],
1132
+ 'tabs' => $form['tabs']
1133
+ ), $settings);
1134
  }
1135
 
1136
  /**
1137
+ * Renders the markup for a column group.
1138
+ *
1139
+ * @since 1.0
1140
+ * @param object $group A column group node object.
1141
+ * @return void
1142
+ */
1143
  static public function render_column_group($group)
1144
  {
1145
+ $cols = FLBuilderModel::get_nodes('column', $group->node);
1146
 
1147
+ include FL_BUILDER_DIR . 'includes/column-group.php';
1148
  }
1149
 
1150
  /**
1151
+ * Adds a new column group and renders it.
1152
+ *
1153
+ * @since 1.0
1154
+ * @param string $node_id The node ID of a row to add the new group to.
1155
+ * @param string $cols The type of column layout to use.
1156
+ * @param int $position The position of the new column group in the row.
1157
+ * @return void
1158
+ */
1159
  static public function render_new_column_group($node_id = null, $cols = '1-col', $position = false)
1160
  {
1161
+ $post_data = FLBuilderModel::get_post_data();
1162
+ $node_id = isset($post_data['node_id']) ? $post_data['node_id'] : $node_id;
1163
+ $cols = isset($post_data['cols']) ? $post_data['cols'] : $cols;
1164
+ $position = isset($post_data['position']) ? (int)$post_data['position'] : $position;
1165
+ $group = FLBuilderModel::add_col_group($node_id, $cols, $position);
1166
 
1167
+ self::render_column_group($group);
1168
 
1169
  if(defined('DOING_AJAX')) {
1170
+ die();
1171
  }
1172
  }
1173
 
1174
  /**
1175
+ * Adds a new column group and renders it.
1176
+ *
1177
+ * @since 1.0
1178
+ * @param string $node_id The node ID of a row to add the new group to.
1179
+ * @param string $cols The type of column layout to use.
1180
+ * @param int $position The position of the new column group in the row.
1181
+ * @return void
1182
+ */
1183
  static public function render_column_group_attributes( $group )
1184
  {
1185
  echo ' class="fl-col-group fl-node-' . $group->node . '"';
1187
  }
1188
 
1189
  /**
1190
+ * Renders the markup for the column settings lightbox.
1191
+ *
1192
+ * @since 1.0
1193
+ * @param string $node_id A column node ID.
1194
+ * @return void
1195
+ */
1196
  static public function render_column_settings($node_id = null)
1197
  {
1198
+ $post_data = FLBuilderModel::get_post_data();
1199
+ $node_id = isset($post_data['node_id']) ? $post_data['node_id'] : $node_id;
1200
+ $node = FLBuilderModel::get_node($node_id);
1201
+ $settings = $node->settings;
1202
+ $form = FLBuilderModel::$settings_forms['col'];
1203
+
1204
+ self::render_settings(array(
1205
+ 'class' => 'fl-builder-col-settings',
1206
+ 'attrs' => 'data-node="'. $node->node .'"',
1207
+ 'title' => $form['title'],
1208
+ 'tabs' => $form['tabs']
1209
+ ), $settings);
1210
  }
1211
 
1212
  /**
1213
+ * Renders the HTML attributes for a single column.
1214
+ *
1215
+ * @since 1.0
1216
+ * @param object $col A column node object.
1217
+ * @return void
1218
+ */
1219
  static public function render_column_attributes( $col )
1220
  {
1221
  $custom_class = apply_filters( 'fl_builder_column_custom_class', $col->settings->class, $col );
1226
  }
1227
 
1228
  // Class
1229
+ echo ' class="fl-col';
1230
+
1231
+ if ( $col->settings->size <= 50 ) {
1232
+ echo ' fl-col-small';
1233
+ }
1234
+ if ( ! empty( $col->settings->responsive_display ) ) {
1235
+ echo ' fl-visible-' . $col->settings->responsive_display;
1236
+ }
1237
+ if ( ! empty( $custom_class ) ) {
1238
+ echo ' ' . trim( esc_attr( $custom_class ) );
1239
+ }
1240
+
1241
+ echo ' fl-node-' . $col->node;
1242
+ echo '"';
1243
+
1244
+ // Width
1245
+ echo ' style="width: ' . $col->settings->size . '%;"';
1246
+
1247
+ // Data
1248
+ echo ' data-node="' . $col->node . '"';
1249
  }
1250
 
1251
+ /**
1252
+ * Renders the markup for all modules in a column.
1253
+ *
1254
+ * @since 1.0
1255
+ * @param string $parent_id A column node ID.
1256
+ * @return void
1257
+ */
1258
+ static public function render_modules($parent_id)
1259
+ {
1260
+ $modules = FLBuilderModel::get_modules($parent_id);
1261
 
1262
+ foreach($modules as $module) {
1263
+ $settings = $module->settings;
1264
+ include FL_BUILDER_DIR . 'includes/module.php';
1265
+ }
1266
+ }
1267
 
1268
  /**
1269
+ * Renders the settings lightbox for when a new module
1270
+ * is added to a layout.
1271
+ *
1272
+ * @since 1.0
1273
+ * @param string $parent_id A column node ID.
1274
+ * @param string $type The type of module.
1275
+ * @param int $position The new module position.
1276
+ * @return array|void An array of layout data or nothing if called via AJAX.
1277
+ */
1278
  static public function render_new_module_settings($parent_id = null, $type = null, $position = false)
1279
  {
1280
+ $post_data = FLBuilderModel::get_post_data();
1281
+ $parent_id = isset($post_data['parent_id']) ? $post_data['parent_id'] : $parent_id;
1282
+ $type = isset($post_data['type']) ? $post_data['type'] : $type;
1283
+ $position = isset($post_data['position']) ? (int)$post_data['position'] : $position;
1284
+ $module = FLBuilderModel::add_default_module($parent_id, $type, $position);
1285
+
1286
+ // Force the global parent id.
1287
+ FLBuilderModel::update_post_data('parent_id', $module->parent);
1288
+
1289
+ // Get the settings html.
1290
+ ob_start();
1291
+ self::render_module_settings($module->node, $module->type, $module->parent, true);
1292
+ $settings = ob_get_clean();
1293
+
1294
+ // Build the response.
1295
+ $response = array(
1296
+ 'layout' => self::render_preview(true),
1297
+ 'settings' => $settings
1298
+ );
1299
+
1300
+ // Echo or return the response.
1301
+ if(defined('DOING_AJAX')) {
1302
+ echo json_encode($response);
1303
+ die();
1304
+ }
1305
+ else {
1306
+ return $response;
1307
+ }
1308
  }
1309
 
1310
  /**
1311
+ * Renders the settings lightbox for a module.
1312
+ *
1313
+ * @since 1.0
1314
+ * @param string $node_id The module node ID.
1315
+ * @param string $type The type of module.
1316
+ * @param string $parent_id The parent column node ID.
1317
+ * @param bool $return Whether to return the layout data or echo it.
1318
+ * @return void
1319
+ */
1320
  static public function render_module_settings($node_id = null, $type = null, $parent_id = null, $return = false)
1321
  {
1322
+ $post_data = FLBuilderModel::get_post_data();
1323
+ $node_id = isset($post_data['node_id']) ? $post_data['node_id'] : $node_id;
1324
+ $type = isset($post_data['type']) ? $post_data['type'] : $type;
1325
+ $parent_id = isset($post_data['parent_id']) ? $post_data['parent_id'] : $parent_id;
1326
+
1327
+ if($node_id) {
1328
+ $module = FLBuilderModel::get_module($node_id);
1329
+ $settings = $module->settings;
1330
+ }
1331
+ else {
1332
+ $module = FLBuilderModel::$modules[$type];
1333
+ $settings = FLBuilderModel::get_module_defaults($type);
1334
+ }
1335
+
1336
+ if(file_exists($module->dir .'css/settings.css')) {
1337
+ echo '<link class="fl-builder-settings-css" rel="stylesheet" href="'. $module->url .'css/settings.css" />';
1338
+ }
1339
+ if(file_exists($module->dir .'js/settings.js')) {
1340
+ echo '<script class="fl-builder-settings-js" src="'. $module->url .'js/settings.js"></script>';
1341
+ }
1342
+
1343
+ echo self::render_settings(array(
1344
+ 'class' => 'fl-builder-module-settings fl-builder-'. $type .'-settings',
1345
+ 'attrs' => 'data-node="'. $node_id .'" data-parent="'. $parent_id .'" data-type="'. $type .'"',
1346
+ 'title' => sprintf( _x( '%s Settings', '%s stands for module name.', 'fl-builder' ), $module->name ),
1347
+ 'tabs' => $module->form
1348
+ ), $settings, $return);
1349
  }
1350
 
1351
+ /**
1352
+ * Renders the markup for a single module. This can be used to render
1353
+ * the markup of a module within another module by passing the type
1354
+ * and settings params and leaving the module param null.
1355
+ *
1356
+ * @since 1.0
1357
+ * @param string $type The type of module.
1358
+ * @param object $settings A module settings object.
1359
+ * @param object $module Optional. An existing module object to use.
1360
+ * @return void
1361
+ */
1362
+ static public function render_module_html($type, $settings, $module = null)
1363
+ {
1364
+ // Settings
1365
+ $defaults = FLBuilderModel::get_module_defaults($type);
1366
+ $settings = (object)array_merge((array)$defaults, (array)$settings);
1367
 
1368
+ // Module
1369
+ $class = get_class(FLBuilderModel::$modules[$type]);
1370
+ $module = new $class();
1371
+ $module->settings = $settings;
1372
 
1373
+ // Shorthand reference to the module's id.
1374
+ $id = $module->node;
1375
 
1376
+ include $module->dir .'includes/frontend.php';
1377
+ }
1378
 
1379
  /**
1380
+ * Renders the HTML attributes for a single module.
1381
+ *
1382
+ * @since 1.0
1383
+ * @param object $module A module node object.
1384
+ * @return void
1385
+ */
1386
  static public function render_module_attributes( $module )
1387
  {
1388
  $custom_class = apply_filters( 'fl_builder_module_custom_class', $module->settings->class, $module );
1394
 
1395
  // Class
1396
  echo ' class="fl-module';
1397
+ echo ' fl-module-' . $module->settings->type;
1398
+
1399
+ if ( ! empty( $module->settings->responsive_display ) ) {
1400
+ echo ' fl-visible-' . $module->settings->responsive_display;
1401
+ }
1402
+ if ( ! empty( $module->settings->animation ) ) {
1403
+ echo ' fl-animation fl-' . $module->settings->animation;
1404
+ }
1405
+ if ( ! empty( $custom_class ) ) {
1406
+ echo ' ' . trim( esc_attr( $custom_class ) );
1407
+ }
1408
+
1409
+ echo ' fl-node-' . $module->node;
1410
+ echo '"';
1411
 
1412
  // Data
1413
+ echo ' data-node="' . $module->node . '" ';
1414
+ echo ' data-animation-delay="' . $module->settings->animation_delay . '" ';
1415
+
1416
+ if ( FLBuilderModel::is_builder_active() ) {
1417
+ echo ' data-parent="' . $module->parent . '" ';
1418
+ echo ' data-type="' . $module->settings->type . '" ';
1419
+ echo ' data-name="' . $module->name . '" ';
1420
+ }
1421
  }
1422
 
1423
+ /**
1424
+ * Renders the CSS for a single module.
1425
+ *
1426
+ * @since 1.0
1427
+ * @param string $type The type of module.
1428
+ * @param object $id A module node ID.
1429
+ * @param object $settings A module settings object.
1430
+ * @return void
1431
+ */
1432
+ static public function render_module_css($type, $id, $settings)
1433
+ {
1434
+ // Settings
1435
+ $global_settings = FLBuilderModel::get_global_settings();
1436
+ $defaults = FLBuilderModel::get_module_defaults($type);
1437
+ $settings = (object)array_merge((array)$defaults, (array)$settings);
1438
 
1439
+ // Module
1440
+ $class = get_class(FLBuilderModel::$modules[$type]);
1441
+ $module = new $class();
1442
+ $module->settings = $settings;
1443
 
1444
+ include $module->dir .'includes/frontend.css.php';
1445
+ }
1446
 
1447
  /**
1448
+ * Renders and caches the CSS for a builder layout.
1449
+ *
1450
+ * @since 1.0
1451
+ * @return void
1452
+ */
1453
  static public function render_css()
1454
  {
1455
+ // Delete the old file.
1456
+ FLBuilderModel::delete_asset_cache('css');
1457
+
1458
+ // Get info on the new file.
1459
+ $rows = FLBuilderModel::get_nodes('row');
1460
+ $cols = FLBuilderModel::get_nodes('column');
1461
+ $modules = FLBuilderModel::get_all_modules();
1462
+ $global_settings = FLBuilderModel::get_global_settings();
1463
+ $asset_info = FLBuilderModel::get_asset_info();
1464
+ $post_id = FLBuilderModel::get_post_id();
1465
+ $post = get_post($post_id);
1466
+ $compiled = array();
1467
+
1468
+ // Global css
1469
+ $css = file_get_contents(FL_BUILDER_DIR . '/css/fl-builder-layout.css');
1470
+
1471
+ // Responsive css
1472
+ if($global_settings->responsive_enabled) {
1473
+
1474
+ $css .= '@media (max-width: '. $global_settings->medium_breakpoint .'px) { ';
1475
+ $css .= file_get_contents(FL_BUILDER_DIR . '/css/fl-builder-layout-medium.css');
1476
+ $css .= ' }';
1477
+ $css .= '@media (max-width: '. $global_settings->responsive_breakpoint .'px) { ';
1478
+ $css .= file_get_contents(FL_BUILDER_DIR . '/css/fl-builder-layout-responsive.css');
1479
+
1480
+ if ( ! isset( $global_settings->auto_spacing ) || $global_settings->auto_spacing ) {
1481
+ $css .= file_get_contents(FL_BUILDER_DIR . '/css/fl-builder-layout-auto-spacing.css');
1482
+ }
1483
+
1484
+ $css .= ' }';
1485
+ }
1486
+
1487
+ // Global row margins
1488
+ $css .= '.fl-row-content-wrap { margin: '. $global_settings->row_margins .'px; }';
1489
+
1490
+ // Global row padding
1491
+ $css .= '.fl-row-content-wrap { padding: '. $global_settings->row_padding .'px; }';
1492
+
1493
+ // Global row width
1494
+ $css .= '.fl-row-fixed-width { max-width: '. $global_settings->row_width .'px; }';
1495
+
1496
+ // Global row content width
1497
+ $css .= '.fl-row-content-wrap.fl-row-fixed-width .fl-row-content { max-width: '. $global_settings->row_width .'px; }';
1498
+
1499
+ // Row instances
1500
+ foreach($rows as $row) {
1501
+
1502
+ // Instance row css
1503
+ ob_start();
1504
+ include FL_BUILDER_DIR . 'includes/row-css.php';
1505
+ $css .= ob_get_clean();
1506
+
1507
+ // Instance row margins
1508
+ $css .= self::render_row_margins($row);
1509
+
1510
+ // Instance row padding
1511
+ $css .= self::render_row_padding($row);
1512
+
1513
+ // Instance row bg positions
1514
+ $css .= self::render_row_bg_positions($row);
1515
+
1516
+ if ( ! isset( $global_settings->auto_spacing ) || $global_settings->auto_spacing ) {
1517
+ $css .= self::render_responsive_row_bg_positions($row);
1518
+ }
1519
+ }
1520
+
1521
+ // Column instances
1522
+ foreach($cols as $col) {
1523
+
1524
+ // Instance column css
1525
+ ob_start();
1526
+ include FL_BUILDER_DIR . 'includes/column-css.php';
1527
+ $css .= ob_get_clean();
1528
+
1529
+ // Instance column margins
1530
+ $css .= self::render_column_margins($col);
1531
+
1532
+ // Instance column padding
1533
+ $css .= self::render_column_padding($col);
1534
+ }
1535
+
1536
+ // Global module margins
1537
+ $css .= '.fl-module-content { margin: '. $global_settings->module_margins .'px; }';
1538
+
1539
+ // Modules
1540
+ foreach($modules as $module) {
1541
+
1542
+ // Global module css
1543
+ $file = $module->dir . 'css/frontend.css';
1544
+ $file_responsive = $module->dir . 'css/frontend.responsive.css';
1545
+
1546
+ // Only include global module css that hasn't been included yet.
1547
+ if(!in_array($module->settings->type, $compiled)) {
1548
+
1549
+ // Add to the compiled array so we don't include it again.
1550
+ $compiled[] = $module->settings->type;
1551
+
1552
+ // Get the standard module css.
1553
+ if(file_exists($file)) {
1554
+ $css .= file_get_contents($file);
1555
+ }
1556
+
1557
+ // Get the responsive module css.
1558
+ if($global_settings->responsive_enabled && file_exists($file_responsive)) {
1559
+ $css .= '@media (max-width: '. $global_settings->responsive_breakpoint .'px) { ';
1560
+ $css .= file_get_contents($file_responsive);
1561
+ $css .= ' }';
1562
+ }
1563
+ }
1564
+
1565
+ // Instance module css
1566
+ $file = $module->dir . 'includes/frontend.css.php';
1567
+ $settings = $module->settings;
1568
+ $id = $module->node;
1569
+
1570
+ if(file_exists($file)) {
1571
+ ob_start();
1572
+ include $file;
1573
+ $css .= ob_get_clean();
1574
+ }
1575
+
1576
+ // Instance module margins
1577
+ $css .= self::render_module_margins($module);
1578
+
1579
+ if ( ! isset( $global_settings->auto_spacing ) || $global_settings->auto_spacing ) {
1580
+ $css .= self::render_responsive_module_margins($module);
1581
+ }
1582
+ }
1583
+
1584
+ // Default page heading
1585
+ if($post && !$global_settings->show_default_heading && ($post->post_type == 'page' || $post->post_type == 'fl-builder-template')) {
1586
+ $css .= $global_settings->default_heading_selector . ' { display:none; }';
1587
+ }
1588
+
1589
+ // Save the css
1590
+ if(!empty($css)) {
1591
+ $css = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $css);
1592
+ $css = str_replace(array("\r\n", "\r", "\n", "\t", ' ', ' ', ' '), '', $css);
1593
+ file_put_contents($asset_info['css'], $css);
1594
+ }
1595
+ }
1596
+
1597
+ /**
1598
+ * Renders the CSS margins for a row.
1599
+ *
1600
+ * @since 1.0
1601
+ * @param object $row A row node object.
1602
+ * @return string The row CSS margins string.
1603
+ */
1604
+ static public function render_row_margins($row)
1605
+ {
1606
+ $settings = $row->settings;
1607
+ $margins = '';
1608
+ $css = '';
1609
+
1610
+ if($settings->margin_top != '') {
1611
+ $margins .= 'margin-top:' . $settings->margin_top . 'px;';
1612
+ }
1613
+ if($settings->margin_bottom != '') {
1614
+ $margins .= 'margin-bottom:' . $settings->margin_bottom . 'px;';
1615
+ }
1616
+ if($settings->margin_left != '') {
1617
+ $margins .= 'margin-left:' . $settings->margin_left . 'px;';
1618
+ }
1619
+ if($settings->margin_right != '') {
1620
+ $margins .= 'margin-right:' . $settings->margin_right . 'px;';
1621
+ }
1622
+ if($margins != '') {
1623
+ $css .= '.fl-node-' . $row->node . ' .fl-row-content-wrap {' . $margins . '}';
1624
+ }
1625
+
1626
+ return $css;
1627
  }
1628
 
1629
  /**
1630
+ * Renders the CSS padding for a row.
1631
+ *
1632
+ * @since 1.0
1633
+ * @param object $row A row node object.
1634
+ * @return string The row CSS padding string.
1635
+ */
1636
+ static public function render_row_padding($row)
1637
+ {
1638
+ $settings = $row->settings;
1639
+ $padding = '';
1640
+ $css = '';
1641
+
1642
+ if($settings->padding_top != '') {
1643
+ $padding .= 'padding-top:' . $settings->padding_top . 'px;';
1644
+ }
1645
+ if($settings->padding_bottom != '') {
1646
+ $padding .= 'padding-bottom:' . $settings->padding_bottom . 'px;';
1647
+ }
1648
+ if($settings->padding_left != '') {
1649
+ $padding .= 'padding-left:' . $settings->padding_left . 'px;';
1650
+ }
1651
+ if($settings->padding_right != '') {
1652
+ $padding .= 'padding-right:' . $settings->padding_right . 'px;';
1653
+ }
1654
+ if($padding != '') {
1655
+ $css = '.fl-node-' . $row->node . ' .fl-row-content-wrap {' . $padding . '}';
1656
+ }
1657
+
1658
+ return $css;
1659
+ }
1660
 
1661
  /**
1662
+ * Renders the CSS positions for a row's backgrounds.
1663
+ *
1664
+ * @since 1.0
1665
+ * @param object $row A row node object.
1666
+ * @return string The row CSS positions string.
1667
+ */
1668
+ static public function render_row_bg_positions($row)
1669
+ {
1670
+ $settings = $row->settings;
1671
+ $positions = '';
1672
+ $css = '';
1673
+
1674
+ if($settings->margin_top != '' || $settings->border_top != '') {
1675
+ $positions .= 'top:' . ($settings->margin_top + $settings->border_top) . 'px;';
1676
+ }
1677
+ if($settings->margin_bottom != ''|| $settings->border_bottom != '') {
1678
+ $positions .= 'bottom:' . ($settings->margin_bottom + $settings->border_bottom) . 'px;';
1679
+ }
1680
+ if($settings->margin_left != ''|| $settings->border_left != '') {
1681
+ $positions .= 'left:' . ($settings->margin_left + $settings->border_left) . 'px;';
1682
+ }
1683
+ if($settings->margin_right != ''|| $settings->border_right != '') {
1684
+ $positions .= 'right:' . ($settings->margin_right + $settings->border_right) . 'px;';
1685
+ }
1686
+ if($positions != '') {
1687
+ $css .= '.fl-node-' . $row->node . ' .fl-bg-video {' . $positions . '}';
1688
+ $css .= '.fl-node-' . $row->node . ' .fl-bg-slideshow {' . $positions . '}';
1689
+ }
1690
+
1691
+ return $css;
1692
+ }
1693
 
1694
  /**
1695
+ * Renders the responsive CSS positions for a row's backgrounds.
1696
+ *
1697
+ * @since 1.0
1698
+ * @param object $row A row node object.
1699
+ * @return string The row CSS positions string.
1700
+ */
1701
+ static public function render_responsive_row_bg_positions($row)
1702
+ {
1703
+ $global_settings = FLBuilderModel::get_global_settings();
1704
+ $settings = $row->settings;
1705
+ $positions = '';
1706
+ $css = '';
1707
+
1708
+ if($settings->border_top != '') {
1709
+ $positions .= 'top:' . $settings->border_top . 'px;';
1710
+ }
1711
+ if($settings->border_bottom != '') {
1712
+ $positions .= 'bottom:' . $settings->border_bottom . 'px;';
1713
+ }
1714
+ if($positions != '') {
1715
+ $css .= '@media (max-width: '. $global_settings->responsive_breakpoint .'px) { ';
1716
+ $css .= '.fl-node-' . $row->node . ' .fl-bg-video {' . $positions . '}';
1717
+ $css .= '.fl-node-' . $row->node . ' .fl-bg-slideshow {' . $positions . '}';
1718
+ $css .= ' }';
1719
+ }
1720
+
1721
+ return $css;
1722
+ }
1723
 
1724
  /**
1725
+ * Renders the CSS margins for a column.
1726
+ *
1727
+ * @since 1.0
1728
+ * @param object $col A column node object.
1729
+ * @return string The column CSS margins string.
1730
+ */
1731
+ static public function render_column_margins($col)
1732
+ {
1733
+ $settings = $col->settings;
1734
+ $margins = '';
1735
+ $css = '';
1736
+
1737
+ if($settings->margin_top != '') {
1738
+ $margins .= 'margin-top:' . $settings->margin_top . 'px;';
1739
+ }
1740
+ if($settings->margin_bottom != '') {
1741
+ $margins .= 'margin-bottom:' . $settings->margin_bottom . 'px;';
1742
+ }
1743
+ if($settings->margin_left != '') {
1744
+ $margins .= 'margin-left:' . $settings->margin_left . 'px;';
1745
+ }
1746
+ if($settings->margin_right != '') {
1747
+ $margins .= 'margin-right:' . $settings->margin_right . 'px;';
1748
+ }
1749
+ if($margins != '') {
1750
+ $css .= '.fl-node-' . $col->node . ' .fl-col-content {' . $margins . '}';
1751
+ }
1752
+
1753
+ return $css;
1754
+ }
1755
 
1756
  /**
1757
+ * Renders the CSS padding for a column.
1758
+ *
1759
+ * @since 1.0
1760
+ * @param object $col A column node object.
1761
+ * @return string The column CSS padding string.
1762
+ */
1763
+ static public function render_column_padding($col)
1764
+ {
1765
+ $settings = $col->settings;
1766
+ $padding = '';
1767
+ $css = '';
1768
+
1769
+ if($settings->padding_top != '') {
1770
+ $padding .= 'padding-top:' . $settings->padding_top . 'px;';
1771
+ }
1772
+ if($settings->padding_bottom != '') {
1773
+ $padding .= 'padding-bottom:' . $settings->padding_bottom . 'px;';
1774
+ }
1775
+ if($settings->padding_left != '') {
1776
+ $padding .= 'padding-left:' . $settings->padding_left . 'px;';
1777
+ }
1778
+ if($settings->padding_right != '') {
1779
+ $padding .= 'padding-right:' . $settings->padding_right . 'px;';
1780
+ }
1781
+ if($padding != '') {
1782
+ $css = '.fl-node-' . $col->node . ' .fl-col-content {' . $padding . '}';
1783
+ }
1784
+
1785
+ return $css;
1786
+ }
1787
 
1788
  /**
1789
+ * Renders the CSS margins for a module.
1790
+ *
1791
+ * @since 1.0
1792
+ * @param object $module A module node object.
1793
+ * @return string The module CSS margins string.
1794
+ */
1795
+ static public function render_module_margins($module)
1796
+ {
1797
+ $settings = $module->settings;
1798
+ $margins = '';
1799
+ $css = '';
1800
+
1801
+ if($settings->margin_top != '') {
1802
+ $margins .= 'margin-top:' . $settings->margin_top . 'px;';
1803
+ }
1804
+ if($settings->margin_bottom != '') {
1805
+ $margins .= 'margin-bottom:' . $settings->margin_bottom . 'px;';
1806
+ }
1807
+ if($settings->margin_left != '') {
1808
+ $margins .= 'margin-left:' . $settings->margin_left . 'px;';
1809
+ }
1810
+ if($settings->margin_right != '') {
1811
+ $margins .= 'margin-right:' . $settings->margin_right . 'px;';
1812
+ }
1813
+ if($margins != '') {
1814
+ $css = '.fl-node-' . $module->node . ' .fl-module-content {' . $margins . '}';
1815
+ }
1816
+
1817
+ return $css;
1818
+ }
1819
 
1820
  /**
1821
+ * Renders the responsive CSS margins for a module.
1822
+ *
1823
+ * @since 1.0
1824
+ * @param object $module A module node object.
1825
+ * @return string The module CSS margins string.
1826
+ */
1827
+ static public function render_responsive_module_margins($module)
1828
+ {
1829
+ $global_settings = FLBuilderModel::get_global_settings();
1830
+ $default = $global_settings->module_margins;
1831
+ $settings = $module->settings;
1832
+ $margins = '';
1833
+ $css = '';
1834
+
1835
+ if($settings->margin_top != '' && ($settings->margin_top > $default || $settings->margin_top < 0)) {
1836
+ $margins .= 'margin-top:' . $default . 'px;';
1837
+ }
1838
+ if($settings->margin_bottom != '' && ($settings->margin_bottom > $default || $settings->margin_bottom < 0)) {
1839
+ $margins .= 'margin-bottom:' . $default . 'px;';
1840
+ }
1841
+ if($settings->margin_left != '' && ($settings->margin_left > $default || $settings->margin_left < 0)) {
1842
+ $margins .= 'margin-left:' . $default . 'px;';
1843
+ }
1844
+ if($settings->margin_right != '' && ($settings->margin_right > $default || $settings->margin_right < 0)) {
1845
+ $margins .= 'margin-right:' . $default . 'px;';
1846
+ }
1847
+ if($margins != '') {
1848
+ $css .= '@media (max-width: '. $global_settings->responsive_breakpoint .'px) { ';
1849
+ $css .= '.fl-node-' . $module->node . ' .fl-module-content {' . $margins . '}';
1850
+ $css .= ' }';
1851
+ }
1852
+
1853
+ return $css;
1854
+ }
1855
 
1856
  /**
1857
+ * Renders and caches the JavaScript for a builder layout.
1858
+ *
1859
+ * @since 1.0
1860
+ * @return void
1861
+ */
1862
+ static public function render_js()
1863
+ {
1864
+ // Delete the old file.
1865
+ FLBuilderModel::delete_asset_cache('js');
1866
+
1867
+ // Get info on the new file.
1868
+ $global_settings = FLBuilderModel::get_global_settings();
1869
+ $rows = FLBuilderModel::get_nodes('row');
1870
+ $modules = FLBuilderModel::get_all_modules();
1871
+ $asset_info = FLBuilderModel::get_asset_info();
1872
+ $compiled = array();
1873
+ $js = '';
1874
+
1875
+ // Main JS
1876
+ $js .= file_get_contents(FL_BUILDER_DIR . 'js/fl-builder-layout.js');
1877
+
1878
+ // Instance Row JS
1879
+ foreach($rows as $row) {
1880
+
1881
+ $settings = $row->settings;
1882
+ $id = $row->node;
1883
+
1884
+ ob_start();
1885
+ include FL_BUILDER_DIR . 'includes/row-js.php';
1886
+ $js .= ob_get_clean();
1887
+ }
1888
+
1889
+ // Modules
1890
+ foreach($modules as $module) {
1891
+
1892
+ // Global module JS
1893
+ $file = $module->dir . 'js/frontend.js';
1894
+
1895
+ if(file_exists($file) && !in_array($module->settings->type, $compiled)) {
1896
+ $js .= "\n" . file_get_contents($file);
1897
+ $compiled[] = $module->settings->type;
1898
+ }
1899
+
1900
+ // Instance module JS
1901
+ $file = $module->dir . 'includes/frontend.js.php';
1902
+ $settings = $module->settings;
1903
+ $id = $module->node;
1904
+
1905
+ if(file_exists($file)) {
1906
+ ob_start();
1907
+ include $file;
1908
+ $js .= ob_get_clean();
1909
+ }
1910
+ }
1911
+
1912
+ // Add the AJAX url global.
1913
+ $js .= "var wpAjaxUrl = '" . admin_url('admin-ajax.php') . "';";
1914
+
1915
+ // Add the builder url global.
1916
+ $js .= "var flBuilderUrl = '" . FL_BUILDER_URL . "';";
1917
+
1918
+ // Call the FLBuilder._renderLayoutComplete method if we're currently editing.
1919
+ if(stristr($asset_info['js'], '-draft.js') || stristr($asset_info['js'], '-preview.js')) {
1920
+ $js .= "; if(typeof FLBuilder !== 'undefined' && typeof FLBuilder._renderLayoutComplete !== 'undefined') FLBuilder._renderLayoutComplete();";
1921
+ }
1922
+
1923
+ // Include FLJSMin
1924
+ if(!class_exists('FLJSMin')) {
1925
+ include FL_BUILDER_DIR . 'classes/class-fl-jsmin.php';
1926
+ }
1927
+
1928
+ // Save the js
1929
+ if(!empty($js)) {
1930
+ file_put_contents($asset_info['js'], FLJSMin::minify($js));
1931
+ }
1932
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1933
 
1934
  /**
1935
+ * Custom error logging function that handles objects and arrays.
1936
+ *
1937
+ * @since 1.0
1938
+ * @return void
1939
+ */
1940
+ static public function log($data)
1941
+ {
1942
+ ob_start();
1943
+ print_r($data);
1944
+ error_log(ob_get_clean());
1945
+ }
1946
  }
classes/class-fl-jsmin.php CHANGED
@@ -48,244 +48,244 @@
48
  */
49
 
50
  class FLJSMin {
51
- const ORD_LF = 10;
52
- const ORD_SPACE = 32;
53
-
54
- protected $a = '';
55
- protected $b = '';
56
- protected $input = '';
57
- protected $inputIndex = 0;
58
- protected $inputLength = 0;
59
- protected $lookAhead = null;
60
- protected $output = '';
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
- }
103
- }
104
- }
105
-
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 '.
126
- 'literal.');
127
- }
128
-
129
- $this->output .= $this->a;
130
- }
131
-
132
- $this->b = $this->next();
133
- }
134
- }
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
- }
197
- else {
198
- $this->action(2);
199
- }
200
- }
201
- break;
202
-
203
- default:
204
- switch ($this->b) {
205
- case ' ':
206
- if ($this->isAlphaNum($this->a)) {
207
- $this->action(1);
208
- break;
209
- }
210
-
211
- $this->action(3);
212
- break;
213
-
214
- case "\n":
215
- switch ($this->a) {
216
- case '}':
217
- case ']':
218
- case ')':
219
- case '+':
220
- case '-':
221
- case '"':
222
- case "'":
223
- $this->action(1);
224
- break;
225
-
226
- default:
227
- if ($this->isAlphaNum($this->a)) {
228
- $this->action(1);
229
- }
230
- else {
231
- $this->action(3);
232
- }
233
- }
234
- break;
235
-
236
- default:
237
- $this->action(1);
238
- break;
239
- }
240
- }
241
- }
242
-
243
- return $this->output;
244
- }
245
-
246
- protected function next() {
247
- $c = $this->get();
248
-
249
- if ($c === '/') {
250
- switch($this->peek()) {
251
- case '/':
252
- for (;;) {
253
- $c = $this->get();
254
-
255
- if (ord($c) <= self::ORD_LF) {
256
- return $c;
257
- }
258
- }
259
-
260
- case '*':
261
- $this->get();
262
-
263
- for (;;) {
264
- switch($this->get()) {
265
- case '*':
266
- if ($this->peek() === '/') {
267
- $this->get();
268
- return ' ';
269
- }
270
- break;
271
-
272
- case null:
273
- throw new FLJSMinException('Unterminated comment.');
274
- }
275
- }
276
-
277
- default:
278
- return $c;
279
- }
280
- }
281
-
282
- return $c;
283
- }
284
-
285
- protected function peek() {
286
- $this->lookAhead = $this->get();
287
- return $this->lookAhead;
288
- }
289
  }
290
 
291
  // -- Exceptions ---------------------------------------------------------------
48
  */
49
 
50
  class FLJSMin {
51
+ const ORD_LF = 10;
52
+ const ORD_SPACE = 32;
53
+
54
+ protected $a = '';
55
+ protected $b = '';
56
+ protected $input = '';
57
+ protected $inputIndex = 0;
58
+ protected $inputLength = 0;
59
+ protected $lookAhead = null;
60
+ protected $output = '';
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
+ }
103
+ }
104
+ }
105
+
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 '.
126
+ 'literal.');
127
+ }
128
+
129
+ $this->output .= $this->a;
130
+ }
131
+
132
+ $this->b = $this->next();
133
+ }
134
+ }
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
+ }
197
+ else {
198
+ $this->action(2);
199
+ }
200
+ }
201
+ break;
202
+
203
+ default:
204
+ switch ($this->b) {
205
+ case ' ':
206
+ if ($this->isAlphaNum($this->a)) {
207
+ $this->action(1);
208
+ break;
209
+ }
210
+
211
+ $this->action(3);
212
+ break;
213
+
214
+ case "\n":
215
+ switch ($this->a) {
216
+ case '}':
217
+ case ']':
218
+ case ')':
219
+ case '+':
220
+ case '-':
221
+ case '"':
222
+ case "'":
223
+ $this->action(1);
224
+ break;
225
+
226
+ default:
227
+ if ($this->isAlphaNum($this->a)) {
228
+ $this->action(1);
229
+ }
230
+ else {
231
+ $this->action(3);
232
+ }
233
+ }
234
+ break;
235
+
236
+ default:
237
+ $this->action(1);
238
+ break;
239
+ }
240
+ }
241
+ }
242
+
243
+ return $this->output;
244
+ }
245
+
246
+ protected function next() {
247
+ $c = $this->get();
248
+
249
+ if ($c === '/') {
250
+ switch($this->peek()) {
251
+ case '/':
252
+ for (;;) {
253
+ $c = $this->get();
254
+
255
+ if (ord($c) <= self::ORD_LF) {
256
+ return $c;
257
+ }
258
+ }
259
+
260
+ case '*':
261
+ $this->get();
262
+
263
+ for (;;) {
264
+ switch($this->get()) {
265
+ case '*':
266
+ if ($this->peek() === '/') {
267
+ $this->get();
268
+ return ' ';
269
+ }
270
+ break;
271
+
272
+ case null:
273
+ throw new FLJSMinException('Unterminated comment.');
274
+ }
275
+ }
276
+
277
+ default:
278
+ return $c;
279
+ }
280
+ }
281
+
282
+ return $c;
283
+ }
284
+
285
+ protected function peek() {
286
+ $this->lookAhead = $this->get();
287
+ return $this->lookAhead;
288
+ }
289
  }
290
 
291
  // -- Exceptions ---------------------------------------------------------------
css/colorpicker.css CHANGED
@@ -83,12 +83,12 @@
83
  padding: 0;
84
  height: 11px;
85
  -moz-box-sizing: content-box;
86
- -webkit-box-sizing: content-box;
87
- -ms-box-sizing: content-box;
88
- box-sizing: content-box;
89
  }
90
  .colorpicker input:focus {
91
- border-color: transparent;
92
  }
93
  .colorpicker_hex {
94
  position: absolute;
83
  padding: 0;
84
  height: 11px;
85
  -moz-box-sizing: content-box;
86
+ -webkit-box-sizing: content-box;
87
+ -ms-box-sizing: content-box;
88
+ box-sizing: content-box;
89
  }
90
  .colorpicker input:focus {
91
+ border-color: transparent;
92
  }
93
  .colorpicker_hex {
94
  position: absolute;
css/editor.css CHANGED
@@ -1,3 +1,3 @@
1
  * {
2
- line-height: 1.3em;
3
  }
1
  * {
2
+ line-height: 1.3em;
3
  }
css/fl-builder-admin-posts-legacy.css CHANGED
@@ -6,29 +6,29 @@
6
  ------------------------------------------------------ */
7
 
8
  .fl-pre-wp-3-8 .fl-builder-admin-tabs a {
9
- text-shadow: #fff 0 1px 0;
10
- background: -moz-linear-gradient(top, rgba(245,245,245,0.65) 0%, rgba(255,255,255,0) 100%); /* FF3.6+ */
11
- background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(245,245,245,0.65)), color-stop(100%,rgba(255,255,255,0))); /* Chrome,Safari4+ */
12
- background: -webkit-linear-gradient(top, rgba(245,245,245,0.65) 0%,rgba(255,255,255,0) 100%); /* Chrome10+,Safari5.1+ */
13
- background: -o-linear-gradient(top, rgba(245,245,245,0.65) 0%,rgba(255,255,255,0) 100%); /* Opera 11.10+ */
14
- background: -ms-linear-gradient(top, rgba(245,245,245,0.65) 0%,rgba(255,255,255,0) 100%); /* IE10+ */
15
- background: linear-gradient(to bottom, rgba(245,245,245,0.65) 0%,rgba(255,255,255,0) 100%); /* W3C */
16
- filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#a6f5f5f5', endColorstr='#00ffffff',GradientType=0 ); /* IE6-9 */
17
  }
18
  .fl-pre-wp-3-8 .fl-builder-admin-tabs a:hover,
19
  .fl-pre-wp-3-8 .fl-builder-admin-tabs a.fl-active {
20
- border-color: #ccc #ccc #fff;
21
  }
22
  .fl-pre-wp-3-8 .fl-builder-admin-tabs a:hover {
23
- color: #d54e21;
24
  }
25
  .fl-pre-wp-3-8 .fl-builder-admin-tabs a.fl-active {
26
- color: #464646;
27
  }
28
 
29
  /* Loading
30
  ------------------------------------------------------ */
31
 
32
  .fl-builder-loading {
33
- background: rgba(255,255,255,0.8) url(../img/ajax-loader.gif) center center no-repeat;
34
  }
6
  ------------------------------------------------------ */
7
 
8
  .fl-pre-wp-3-8 .fl-builder-admin-tabs a {
9
+ text-shadow: #fff 0 1px 0;
10
+ background: -moz-linear-gradient(top, rgba(245,245,245,0.65) 0%, rgba(255,255,255,0) 100%); /* FF3.6+ */
11
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(245,245,245,0.65)), color-stop(100%,rgba(255,255,255,0))); /* Chrome,Safari4+ */
12
+ background: -webkit-linear-gradient(top, rgba(245,245,245,0.65) 0%,rgba(255,255,255,0) 100%); /* Chrome10+,Safari5.1+ */
13
+ background: -o-linear-gradient(top, rgba(245,245,245,0.65) 0%,rgba(255,255,255,0) 100%); /* Opera 11.10+ */
14
+ background: -ms-linear-gradient(top, rgba(245,245,245,0.65) 0%,rgba(255,255,255,0) 100%); /* IE10+ */
15
+ background: linear-gradient(to bottom, rgba(245,245,245,0.65) 0%,rgba(255,255,255,0) 100%); /* W3C */
16
+ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#a6f5f5f5', endColorstr='#00ffffff',GradientType=0 ); /* IE6-9 */
17
  }
18
  .fl-pre-wp-3-8 .fl-builder-admin-tabs a:hover,
19
  .fl-pre-wp-3-8 .fl-builder-admin-tabs a.fl-active {
20
+ border-color: #ccc #ccc #fff;
21
  }
22
  .fl-pre-wp-3-8 .fl-builder-admin-tabs a:hover {
23
+ color: #d54e21;
24
  }
25
  .fl-pre-wp-3-8 .fl-builder-admin-tabs a.fl-active {
26
+ color: #464646;
27
  }
28
 
29
  /* Loading
30
  ------------------------------------------------------ */
31
 
32
  .fl-builder-loading {
33
+ background: rgba(255,255,255,0.8) url(../img/ajax-loader.gif) center center no-repeat;
34
  }
css/fl-builder-admin-posts.css CHANGED
@@ -2,101 +2,101 @@
2
  ------------------------------------------------------ */
3
 
4
  .fl-builder-admin {
5
- position: relative;
6
  }
7
 
8
  /* Enabled/Disabled States
9
  ------------------------------------------------------ */
10
 
11
  .fl-builder-enabled .fl-builder-admin-tabs {
12
- border: none;
13
- margin: 10px 0 0;
14
  }
15
  .fl-builder-admin-ui {
16
- display: none;
17
  }
18
  .fl-builder-enabled .fl-builder-admin-ui {
19
- display: block;
20
  }
21
  .fl-builder-enabled #postdivrich {
22
- display: none;
23
  }
24
 
25
  /* Tabs
26
  ------------------------------------------------------ */
27
 
28
  .fl-builder-admin-tabs {
29
- border-bottom: 1px solid #ccc;
30
- margin: 10px 0;
31
  }
32
  .fl-builder-admin-tabs a {
33
- border-color: #dfdfdf #dfdfdf #f0f0f0;
34
- border-style: solid;
35
- border-width: 1px 1px 0;
36
- color: #aaa;
37
- font-size: 12px;
38
- font-weight: bold;
39
- line-height: 16px;
40
- display: inline-block;
41
- padding: 8px 14px;
42
- text-decoration: none;
43
- margin: 0 4px -1px 0;
44
- border-top-left-radius: 3px;
45
- border-top-right-radius: 3px;
46
- -moz-border-top-left-radius: 3px;
47
- -moz-border-top-right-radius: 3px;
48
- -webkit-border-top-left-radius: 3px;
49
- -webkit-border-top-right-radius: 3px;
50
  }
51
  .fl-builder-admin-tabs a:hover,
52
  .fl-builder-admin-tabs a.fl-active {
53
- border-color: #ccc #ccc #f0f0f0;
54
  }
55
  .fl-builder-admin-tabs a:hover {
56
- color: #333;
57
  }
58
  .fl-builder-admin-tabs a.fl-active {
59
- border-width: 1px;
60
- color: #464646;
61
  }
62
 
63
  /* UI
64
  ------------------------------------------------------ */
65
 
66
  .fl-builder-admin-ui {
67
- border: 1px solid #ccc;
68
- border-top-right-radius: 3px;
69
- border-bottom-right-radius: 3px;
70
- border-bottom-left-radius: 3px;
71
- -moz-border-top-right-radius: 3px;
72
- -moz-border-bottom-right-radius: 3px;
73
- -moz-border-bottom-left-radius: 3px;
74
- -webkit-border-top-right-radius: 3px;
75
- -webkit-border-bottom-right-radius: 3px;
76
- -webkit-border-bottom-left-radius: 3px;
77
- margin-bottom: 20px;
78
- padding: 50px;
79
- text-align: center;
80
  }
81
  .fl-builder-admin-ui h3 {
82
- font-family: Helvetica, sans-serif !important;
83
- font-size: 18px !important;
84
- font-weight: 300 !important;
85
- margin: 0 0 30px 0 !important;
86
- padding: 0 !important;
87
  }
88
 
89
  /* Loading
90
  ------------------------------------------------------ */
91
 
92
  .fl-builder-loading {
93
- background: rgba(240,240,240,0.8) url(../img/ajax-loader.gif) center center no-repeat;
94
- bottom: 0;
95
- display: none;
96
- left: 0;
97
- position: absolute;
98
- right: 0;
99
- text-align: center;
100
- top: 0;
101
- z-index: 1;
102
  }
2
  ------------------------------------------------------ */
3
 
4
  .fl-builder-admin {
5
+ position: relative;
6
  }
7
 
8
  /* Enabled/Disabled States
9
  ------------------------------------------------------ */
10
 
11
  .fl-builder-enabled .fl-builder-admin-tabs {
12
+ border: none;
13
+ margin: 10px 0 0;
14
  }
15
  .fl-builder-admin-ui {
16
+ display: none;
17
  }
18
  .fl-builder-enabled .fl-builder-admin-ui {
19
+ display: block;
20
  }
21
  .fl-builder-enabled #postdivrich {
22
+ display: none;
23
  }
24
 
25
  /* Tabs
26
  ------------------------------------------------------ */
27
 
28
  .fl-builder-admin-tabs {
29
+ border-bottom: 1px solid #ccc;
30
+ margin: 10px 0;
31
  }
32
  .fl-builder-admin-tabs a {
33
+ border-color: #dfdfdf #dfdfdf #f0f0f0;
34
+ border-style: solid;
35
+ border-width: 1px 1px 0;
36
+ color: #aaa;
37
+ font-size: 12px;
38
+ font-weight: bold;
39
+ line-height: 16px;
40
+ display: inline-block;
41
+ padding: 8px 14px;
42
+ text-decoration: none;
43
+ margin: 0 4px -1px 0;
44
+ border-top-left-radius: 3px;
45
+ border-top-right-radius: 3px;
46
+ -moz-border-top-left-radius: 3px;
47
+ -moz-border-top-right-radius: 3px;
48
+ -webkit-border-top-left-radius: 3px;
49
+ -webkit-border-top-right-radius: 3px;
50
  }
51
  .fl-builder-admin-tabs a:hover,
52
  .fl-builder-admin-tabs a.fl-active {
53
+ border-color: #ccc #ccc #f0f0f0;
54
  }
55
  .fl-builder-admin-tabs a:hover {
56
+ color: #333;
57
  }
58
  .fl-builder-admin-tabs a.fl-active {
59
+ border-width: 1px;
60
+ color: #464646;
61
  }
62
 
63
  /* UI
64
  ------------------------------------------------------ */
65
 
66
  .fl-builder-admin-ui {
67
+ border: 1px solid #ccc;
68
+ border-top-right-radius: 3px;
69
+ border-bottom-right-radius: 3px;
70
+ border-bottom-left-radius: 3px;
71
+ -moz-border-top-right-radius: 3px;
72
+ -moz-border-bottom-right-radius: 3px;
73
+ -moz-border-bottom-left-radius: 3px;
74
+ -webkit-border-top-right-radius: 3px;
75
+ -webkit-border-bottom-right-radius: 3px;
76
+ -webkit-border-bottom-left-radius: 3px;
77
+ margin-bottom: 20px;
78
+ padding: 50px;
79
+ text-align: center;
80
  }
81
  .fl-builder-admin-ui h3 {
82
+ font-family: Helvetica, sans-serif !important;
83
+ font-size: 18px !important;
84
+ font-weight: 300 !important;
85
+ margin: 0 0 30px 0 !important;
86
+ padding: 0 !important;
87
  }
88
 
89
  /* Loading
90
  ------------------------------------------------------ */
91
 
92
  .fl-builder-loading {
93
+ background: rgba(240,240,240,0.8) url(../img/ajax-loader.gif) center center no-repeat;
94
+ bottom: 0;
95
+ display: none;
96
+ left: 0;
97
+ position: absolute;
98
+ right: 0;
99
+ text-align: center;
100
+ top: 0;
101
+ z-index: 1;
102
  }
css/fl-builder-admin-settings.css CHANGED
@@ -2,46 +2,46 @@
2
  ----------------------------------------------------------- */
3
 
4
  .fl-settings-heading img {
5
- height: 40px;
6
- margin-right: 5px;
7
- vertical-align: middle;
8
  }
9
  .fl-settings-heading span {
10
- vertical-align: middle;
11
  }
12
 
13
  /* Nav
14
  ----------------------------------------------------------- */
15
 
16
  .fl-settings-nav {
17
- float: left;
18
- margin: 15px 2% 0 0;
19
- width: 19%;
20
  }
21
  .fl-settings-nav ul {
22
- background: #fff;
23
- border: 1px solid #e5e5e5;
24
- -webkit-box-shadow: 0 1px 1px rgba(0,0,0,.04);
25
- box-shadow: 0 1px 1px rgba(0,0,0,.04);
26
  }
27
  .fl-settings-nav ul li {
28
- display: block;
29
- margin: 0;
30
  }
31
  .fl-settings-nav ul li a {
32
- border-bottom: 1px solid #eee;
33
- display: block;
34
- padding: 10px;
35
  }
36
  .fl-settings-nav ul li a:hover,
37
  .fl-settings-nav ul li a.fl-active {
38
- background: #f5f5f5;
39
  }
40
  .fl-settings-nav ul li:last-child a {
41
- border-bottom: none;
42
  }
43
  .fl-settings-nav a {
44
- text-decoration: none;
45
  }
46
  .fl-settings-nav .fl-settings-save {
47
  padding: 0 2px;
@@ -54,9 +54,9 @@
54
  ----------------------------------------------------------- */
55
 
56
  .fl-settings-content {
57
- float: left;
58
- margin-top: 15px;
59
- width: 78%;
60
  }
61
  .fl-settings-form-content h4 {
62
  font-size: 14px;
@@ -66,31 +66,31 @@
66
  ----------------------------------------------------------- */
67
 
68
  .fl-settings-form {
69
- display: none;
70
- max-width: 450px;
71
  }
72
  .fl-settings-form-header {
73
- margin-bottom: 20px !important;
74
  }
75
  .fl-settings-form .form-table {
76
- margin: 12px 0;
77
  }
78
  .fl-settings-form th {
79
- font-weight: bold;
80
- vertical-align: middle;
81
  }
82
  .fl-settings-form th,
83
  .fl-settings-form td {
84
- font-size: 13px;
85
- font-weight: normal;
86
- padding: 12px;
87
  }
88
  .fl-settings-form-content {
89
- display: none;
90
  }
91
  .fl-settings-network-admin .fl-settings-form-content,
92
  .fl-settings-single-install .fl-settings-form-content {
93
- display: block;
94
  }
95
 
96
  /* Icons
@@ -115,26 +115,26 @@
115
 
116
  @media (max-width: 900px) {
117
 
118
- /* Nav
119
- ----------------------------------------------------------- */
120
-
121
- .fl-settings-nav {
122
- float: none;
123
- margin: 15px 0 0 0;
124
- width: 100%;
125
- }
126
-
127
- /* Content
128
- ----------------------------------------------------------- */
129
-
130
- .fl-settings-content {
131
- float: none;
132
- margin-top: 15px;
133
- width: 100%;
134
- }
135
  .fl-settings-content .fl-settings-save {
136
  float: none;
137
- width: 100%;
138
  }
139
  .fl-settings-content .fl-settings-save .button-primary {
140
  width: 100%;
@@ -145,12 +145,12 @@
145
  ----------------------------------------------------------- */
146
 
147
  @media (max-width: 782px) {
148
-
149
- /* Settings Forms
150
- ----------------------------------------------------------- */
151
-
152
- .fl-settings-form th,
153
- .fl-settings-form td {
154
- padding: 5px 17px;
155
- }
156
  }
2
  ----------------------------------------------------------- */
3
 
4
  .fl-settings-heading img {
5
+ height: 40px;
6
+ margin-right: 5px;
7
+ vertical-align: middle;
8
  }
9
  .fl-settings-heading span {
10
+ vertical-align: middle;
11
  }
12
 
13
  /* Nav
14
  ----------------------------------------------------------- */
15
 
16
  .fl-settings-nav {
17
+ float: left;
18
+ margin: 15px 2% 0 0;
19
+ width: 19%;
20
  }
21
  .fl-settings-nav ul {
22
+ background: #fff;
23
+ border: 1px solid #e5e5e5;
24
+ -webkit-box-shadow: 0 1px 1px rgba(0,0,0,.04);
25
+ box-shadow: 0 1px 1px rgba(0,0,0,.04);
26
  }
27
  .fl-settings-nav ul li {
28
+ display: block;
29
+ margin: 0;
30
  }
31
  .fl-settings-nav ul li a {
32
+ border-bottom: 1px solid #eee;
33
+ display: block;
34
+ padding: 10px;
35
  }
36
  .fl-settings-nav ul li a:hover,
37
  .fl-settings-nav ul li a.fl-active {
38
+ background: #f5f5f5;
39
  }
40
  .fl-settings-nav ul li:last-child a {
41
+ border-bottom: none;
42
  }
43
  .fl-settings-nav a {
44
+ text-decoration: none;
45
  }
46
  .fl-settings-nav .fl-settings-save {
47
  padding: 0 2px;
54
  ----------------------------------------------------------- */
55
 
56
  .fl-settings-content {
57
+ float: left;
58
+ margin-top: 15px;
59
+ width: 78%;
60
  }
61
  .fl-settings-form-content h4 {
62
  font-size: 14px;
66
  ----------------------------------------------------------- */
67
 
68
  .fl-settings-form {
69
+ display: none;
70
+ max-width: 450px;
71
  }
72
  .fl-settings-form-header {
73
+ margin-bottom: 20px !important;
74
  }
75
  .fl-settings-form .form-table {
76
+ margin: 12px 0;
77
  }
78
  .fl-settings-form th {
79
+ font-weight: bold;
80
+ vertical-align: middle;
81
  }
82
  .fl-settings-form th,
83
  .fl-settings-form td {
84
+ font-size: 13px;
85
+ font-weight: normal;
86
+ padding: 12px;
87
  }
88
  .fl-settings-form-content {
89
+ display: none;
90
  }
91
  .fl-settings-network-admin .fl-settings-form-content,
92
  .fl-settings-single-install .fl-settings-form-content {
93
+ display: block;
94
  }
95
 
96
  /* Icons
115
 
116
  @media (max-width: 900px) {
117
 
118
+ /* Nav
119
+ ----------------------------------------------------------- */
120
+
121
+ .fl-settings-nav {
122
+ float: none;
123
+ margin: 15px 0 0 0;
124
+ width: 100%;
125
+ }
126
+
127
+ /* Content
128
+ ----------------------------------------------------------- */
129
+
130
+ .fl-settings-content {
131
+ float: none;
132
+ margin-top: 15px;
133
+ width: 100%;
134
+ }
135
  .fl-settings-content .fl-settings-save {
136
  float: none;
137
+ width: 100%;
138
  }
139
  .fl-settings-content .fl-settings-save .button-primary {
140
  width: 100%;
145
  ----------------------------------------------------------- */
146
 
147
  @media (max-width: 782px) {
148
+
149
+ /* Settings Forms
150
+ ----------------------------------------------------------- */
151
+
152
+ .fl-settings-form th,
153
+ .fl-settings-form td {
154
+ padding: 5px 17px;
155
+ }
156
  }
css/fl-builder-layout-auto-spacing.css CHANGED
@@ -2,25 +2,25 @@
2
  ------------------------------------------------------ */
3
 
4
  .fl-row-content-wrap {
5
- border-left: none !important;
6
- border-right: none !important;
7
- margin: 0 !important;
8
- padding-left: 0 !important;
9
- padding-right: 0 !important;
10
  }
11
  .fl-row .fl-bg-video,
12
  .fl-row .fl-bg-slideshow {
13
- left: 0 !important;
14
- right: 0 !important;
15
  }
16
 
17
  /* Columns
18
  ------------------------------------------------------ */
19
 
20
  .fl-col-content {
21
- border-left: none !important;
22
- border-right: none !important;
23
- margin: 0 !important;
24
- padding-left: 0 !important;
25
- padding-right: 0 !important;
26
  }
2
  ------------------------------------------------------ */
3
 
4
  .fl-row-content-wrap {
5
+ border-left: none !important;
6
+ border-right: none !important;
7
+ margin: 0 !important;
8
+ padding-left: 0 !important;
9
+ padding-right: 0 !important;
10
  }
11
  .fl-row .fl-bg-video,
12
  .fl-row .fl-bg-slideshow {
13
+ left: 0 !important;
14
+ right: 0 !important;
15
  }
16
 
17
  /* Columns
18
  ------------------------------------------------------ */
19
 
20
  .fl-col-content {
21
+ border-left: none !important;
22
+ border-right: none !important;
23
+ margin: 0 !important;
24
+ padding-left: 0 !important;
25
+ padding-right: 0 !important;
26
  }
css/fl-builder-layout-medium.css CHANGED
@@ -3,10 +3,10 @@
3
 
4
  .fl-visible-desktop,
5
  .fl-visible-mobile {
6
- display: none;
7
  }
8
  .fl-visible-desktop-medium,
9
  .fl-visible-medium,
10
  .fl-visible-medium-mobile {
11
- display: block;
12
  }
3
 
4
  .fl-visible-desktop,
5
  .fl-visible-mobile {
6
+ display: none;
7
  }
8
  .fl-visible-desktop-medium,
9
  .fl-visible-medium,
10
  .fl-visible-medium-mobile {
11
+ display: block;
12
  }
css/fl-builder-layout-responsive.css CHANGED
@@ -4,34 +4,34 @@
4
  .fl-visible-desktop,
5
  .fl-visible-desktop-medium,
6
  .fl-visible-medium {
7
- display: none;
8
  }
9
  .fl-visible-medium-mobile,
10
  .fl-visible-mobile {
11
- display: block;
12
  }
13
 
14
  /* Rows
15
  ------------------------------------------------------ */
16
 
17
  .fl-row-content-wrap {
18
- background-attachment: scroll !important;
19
  }
20
  .fl-row-bg-parallax .fl-row-content-wrap {
21
- background-attachment: scroll !important;
22
- background-position: center center !important;
23
  }
24
 
25
  /* Columns
26
  ------------------------------------------------------ */
27
 
28
  .fl-col {
29
- clear: both;
30
- float: none;
31
- margin-left: auto;
32
- margin-right: auto;
33
- width: auto !important;
34
  }
35
  .fl-col-small {
36
- max-width: 400px;
37
  }
4
  .fl-visible-desktop,
5
  .fl-visible-desktop-medium,
6
  .fl-visible-medium {
7
+ display: none;
8
  }
9
  .fl-visible-medium-mobile,
10
  .fl-visible-mobile {
11
+ display: block;
12
  }
13
 
14
  /* Rows
15
  ------------------------------------------------------ */
16
 
17
  .fl-row-content-wrap {
18
+ background-attachment: scroll !important;
19
  }
20
  .fl-row-bg-parallax .fl-row-content-wrap {
21
+ background-attachment: scroll !important;
22
+ background-position: center center !important;
23
  }
24
 
25
  /* Columns
26
  ------------------------------------------------------ */
27
 
28
  .fl-col {
29
+ clear: both;
30
+ float: none;
31
+ margin-left: auto;
32
+ margin-right: auto;
33
+ width: auto !important;
34
  }
35
  .fl-col-small {
36
+ max-width: 400px;
37
  }
css/fl-builder-layout.css CHANGED
@@ -4,9 +4,9 @@
4
  .fl-builder-content *,
5
  .fl-builder-content *:before,
6
  .fl-builder-content *:after {
7
- -webkit-box-sizing: border-box;
8
- -moz-box-sizing: border-box;
9
- box-sizing: border-box;
10
  }
11
  .fl-row:before,
12
  .fl-row:after,
@@ -20,8 +20,8 @@
20
  .fl-module:after,
21
  .fl-module-content:before,
22
  .fl-module-content:after {
23
- display: table;
24
- content: " ";
25
  }
26
  .fl-row:after,
27
  .fl-row-content:after,
@@ -29,7 +29,7 @@
29
  .fl-col:after,
30
  .fl-module:after,
31
  .fl-module-content:after {
32
- clear: both;
33
  }
34
  .fl-row,
35
  .fl-row-content,
@@ -37,19 +37,19 @@
37
  .fl-col,
38
  .fl-module,
39
  .fl-module-content {
40
- zoom:1;
41
  }
42
  .fl-row,
43
  .fl-row-content {
44
- margin-left: auto;
45
- margin-right: auto;
46
  }
47
  .fl-col {
48
- float: left;
49
- min-height: 1px;
50
  }
51
  .fl-clear {
52
- clear: both;
53
  }
54
 
55
  /* Utilities
@@ -57,14 +57,14 @@
57
 
58
  .fl-clearfix:before,
59
  .fl-clearfix:after {
60
- display: table;
61
- content: " ";
62
  }
63
  .fl-clearfix:after {
64
- clear: both;
65
  }
66
  .fl-clearfix {
67
- zoom:1;
68
  }
69
 
70
  /* Responsive Utilities
@@ -73,7 +73,7 @@
73
  .fl-visible-medium,
74
  .fl-visible-medium-mobile,
75
  .fl-visible-mobile {
76
- display: none;
77
  }
78
 
79
  /* Rows
@@ -82,81 +82,81 @@
82
  /* Video Bg */
83
  .fl-row-bg-video,
84
  .fl-row-bg-video .fl-row-content {
85
- position: relative;
86
  }
87
  .fl-row-bg-video .fl-bg-video {
88
- bottom: 0;
89
- left: 0;
90
- overflow: hidden;
91
- position: absolute;
92
- right: 0;
93
- top: 0;
94
  }
95
  .fl-row-bg-video .fl-bg-video video {
96
- bottom: 0;
97
- left: 0px;
98
- position: absolute;
99
- right: 0;
100
- top: 0px;
101
  }
102
  .fl-bg-video-fallback {
103
- background-position: 50% 50%;
104
- background-repeat: no-repeat;
105
- background-size: cover;
106
- bottom: 0px;
107
- left: 0px;
108
- position: absolute;
109
- right: 0px;
110
- top: 0px;
111
  }
112
 
113
  /* Slideshow Bg */
114
  .fl-row-bg-slideshow,
115
  .fl-row-bg-slideshow .fl-row-content {
116
- position: relative;
117
  }
118
  .fl-row .fl-bg-slideshow {
119
- bottom: 0;
120
- left: 0;
121
- overflow: hidden;
122
- position: absolute;
123
- right: 0;
124
- top: 0;
125
- z-index: 0;
126
  }
127
  .fl-builder-edit .fl-row .fl-bg-slideshow * {
128
- bottom: 0;
129
- height: auto !important;
130
- left: 0;
131
- position: absolute !important;
132
- right: 0;
133
- top: 0;
134
  }
135
 
136
  /* Bg Overlay */
137
  .fl-row-bg-overlay .fl-row-content-wrap {
138
- position: relative;
139
  }
140
  .fl-row-bg-overlay .fl-row-content-wrap:after {
141
- content: '';
142
- display: block;
143
- position: absolute;
144
- top: 0;
145
- right: 0;
146
- bottom: 0;
147
- left: 0;
148
- z-index: 0;
149
  }
150
  .fl-row-bg-overlay .fl-row-content {
151
- position: relative;
152
- z-index: 1;
153
  }
154
 
155
  /* Modules
156
  ------------------------------------------------------ */
157
 
158
  .fl-module img {
159
- max-width: 100%;
160
  }
161
 
162
  /* Buttons
@@ -170,175 +170,175 @@
170
  -moz-border-radius: 4px;
171
  -webkit-border-radius: 4px;
172
  color: #333;
173
- display: inline-block;
174
- font-size: 16px;
175
- font-weight: normal;
176
- line-height: 18px;
177
  padding: 12px 24px;
178
- text-decoration: none;
179
- text-shadow: none;
180
  }
181
  .fl-builder-content a.fl-button *,
182
  .fl-builder-content a.fl-button:visited * {
183
  color: #333;
184
  }
185
  .fl-builder-content .fl-button:hover {
186
- text-decoration: none;
187
  }
188
  .fl-builder-content .fl-button:active {
189
- position: relative;
190
- top: 1px;
191
  }
192
  .fl-builder-content .fl-button-width-full .fl-button {
193
- display: block;
194
- text-align: center;
195
  }
196
  .fl-builder-content .fl-button-width-custom .fl-button {
197
- display: inline-block;
198
- text-align: center;
199
- max-width: 100%;
200
  }
201
  .fl-builder-content .fl-button-left {
202
- text-align: left;
203
  }
204
  .fl-builder-content .fl-button-center {
205
- text-align: center;
206
  }
207
  .fl-builder-content .fl-button-right {
208
- text-align: right;
209
  }
210
  .fl-builder-content .fl-button i {
211
- font-size: 1.3em;
212
- height: auto;
213
- margin-right:8px;
214
- vertical-align: middle;
215
- width: auto;
216
  }
217
  .fl-builder-content .fl-button-has-icon .fl-button-text {
218
- vertical-align: middle;
219
  }
220
 
221
  /* Icons
222
  ------------------------------------------------------ */
223
 
224
  .fl-icon-wrap {
225
- display: inline-block;
226
  }
227
  .fl-icon {
228
- display: table-cell;
229
- vertical-align: middle;
230
  }
231
  .fl-icon a {
232
- text-decoration: none;
233
  }
234
  .fl-icon i {
235
- float: left;
236
  }
237
  .fl-icon i:before {
238
- border: none !important;
239
  }
240
  .fl-icon-text {
241
- display: table-cell;
242
- text-align: left;
243
- padding-left: 15px;
244
- vertical-align: middle;
245
  }
246
  .fl-icon-text *:last-child {
247
- margin: 0 !important;
248
- padding: 0 !important;
249
  }
250
  .fl-icon-text a {
251
- text-decoration: none;
252
  }
253
 
254
  /* Photos
255
  ------------------------------------------------------ */
256
 
257
  .fl-photo {
258
- position: relative;
259
  }
260
  .fl-photo-align-left {
261
- text-align: left;
262
  }
263
  .fl-photo-align-center {
264
- text-align: center;
265
  }
266
  .fl-photo-align-right {
267
- text-align: right;
268
  }
269
  .fl-photo-content {
270
- line-height: 0;
271
  }
272
  .fl-photo-content img {
273
  display: inline;
274
- height: auto !important;
275
- max-width: 100%;
276
- width: auto !important;
277
  }
278
  .fl-photo-crop-circle img {
279
- -webkit-border-radius: 100%;
280
- -moz-border-radius: 100%;
281
- border-radius: 100%;
282
  }
283
  .fl-photo-caption {
284
- font-size: 13px;
285
- line-height: 18px;
286
  overflow: hidden;
287
  text-overflow: ellipsis;
288
  white-space: nowrap;
289
  }
290
  .fl-photo-caption-below {
291
- padding-bottom: 20px;
292
- padding-top: 10px;
293
  }
294
  .fl-photo-caption-hover {
295
- background: rgba(0,0,0,0.7);
296
- bottom: 0;
297
- color: #fff;
298
- left: 0;
299
- opacity: 0;
300
- filter: alpha(opacity = 0);
301
- padding: 10px 15px;
302
- position: absolute;
303
- right: 0;
304
  -webkit-transition:opacity 0.3s ease-in;
305
  -moz-transition:opacity 0.3s ease-in;
306
  transition:opacity 0.3s ease-in;
307
  }
308
  .fl-photo:hover .fl-photo-caption-hover {
309
- opacity: 100;
310
- filter: alpha(opacity = 100);
311
  }
312
 
313
  /* Pagination
314
  ------------------------------------------------------ */
315
 
316
  .fl-builder-pagination {
317
- padding: 40px 0;
318
  }
319
  .fl-builder-pagination ul.page-numbers {
320
- list-style: none;
321
- margin: 0;
322
- padding: 0;
323
- text-align: center;
324
  }
325
  .fl-builder-pagination li {
326
- display: inline-block;
327
- list-style: none;
328
- margin: 0;
329
- padding: 0;
330
  }
331
  .fl-builder-pagination li a.page-numbers,
332
  .fl-builder-pagination li span.page-numbers {
333
- border: 1px solid #e6e6e6;
334
- display: inline-block;
335
- padding: 5px 10px;
336
- margin: 0 0 5px;
337
  }
338
  .fl-builder-pagination li a.page-numbers:hover,
339
  .fl-builder-pagination li span.current {
340
- background: #f5f5f5;
341
- text-decoration: none;
342
  }
343
 
344
  /* Slideshows
@@ -346,65 +346,65 @@
346
 
347
  .fl-slideshow,
348
  .fl-slideshow * {
349
- -webkit-box-sizing: content-box;
350
- -moz-box-sizing: content-box;
351
- box-sizing: content-box;
352
 
353
  }
354
  .fl-slideshow .fl-slideshow-image img {
355
- max-width: none !important;
356
  }
357
  .fl-slideshow-social {
358
- line-height: 0 !important;
359
  }
360
  .fl-slideshow-social * {
361
- margin: 0 !important;
362
  }
363
 
364
  /* Sliders
365
  ------------------------------------------------------ */
366
 
367
  .fl-builder-content .bx-wrapper .bx-viewport {
368
- background: transparent;
369
- border: none;
370
- box-shadow: none;
371
- -moz-box-shadow: none;
372
- -webkit-box-shadow: none;
373
- left: 0;
374
  }
375
 
376
  /* Lightbox
377
  ------------------------------------------------------ */
378
 
379
  .mfp-wrap button {
380
- background: transparent !important;
381
- box-shadow: none !important;
382
- -moz-box-shadow: none !important;
383
- -webkit-box-shadow: none !important;
384
  }
385
  .mfp-wrap button.mfp-arrow:active,
386
  .mfp-wrap button.mfp-arrow:hover,
387
  .mfp-wrap button.mfp-arrow:focus {
388
- background: transparent !important;
389
- border: none !important;
390
- outline: none;
391
- position: absolute;
392
- top: 50%;
393
  }
394
  .mfp-wrap .mfp-close:active,
395
  .mfp-wrap .mfp-close:hover,
396
  .mfp-wrap .mfp-close:focus {
397
- background: transparent !important;
398
- border: none !important;
399
- outline: none;
400
- position: absolute;
401
- top: 0;
402
  }
403
  img.mfp-img {
404
- padding: 0;
405
  }
406
  .mfp-counter {
407
- display: none;
408
  }
409
 
410
  /* Form Fields
@@ -432,12 +432,12 @@ img.mfp-img {
432
  ------------------------------------------------------ */
433
 
434
  .fl-animation {
435
- opacity: 0;
436
  }
437
  .fl-builder-touch .fl-animation,
438
  .fl-builder-edit .fl-animation,
439
  .fl-animated {
440
- opacity: 1;
441
  }
442
 
443
  /* Fade In */
@@ -448,15 +448,15 @@ img.mfp-img {
448
  }
449
  @keyframes fl-fade-in {
450
  0% { opacity: 0; }
451
- 100% { opacity: 1; }
452
  }
453
  @-webkit-keyframes fl-fade-in {
454
  0% { opacity: 0; }
455
- 100% { opacity: 1; }
456
  }
457
  @-moz-keyframes fl-fade-in {
458
  0% { opacity: 0; }
459
- 100% { opacity: 1; }
460
  }
461
 
462
  /* Slide Left */
@@ -466,15 +466,15 @@ img.mfp-img {
466
  -moz-animation: fl-slide-left 1s ease-out;
467
  }
468
  @keyframes fl-slide-left {
469
- 0% { opacity: 0; transform: translateX(10%); }
470
  100% { opacity: 1; transform: translateX(0%); }
471
  }
472
  @-webkit-keyframes fl-slide-left {
473
- 0% { opacity: 0; -webkit-transform: translateX(10%); }
474
  100% { opacity: 1; -webkit-transform: translateX(0%); }
475
  }
476
  @-moz-keyframes fl-slide-left {
477
- 0% { opacity: 0; -moz-transform: translateX(10%); }
478
  100% { opacity: 1; -moz-transform: translateX(0%); }
479
  }
480
 
@@ -485,15 +485,15 @@ img.mfp-img {
485
  -moz-animation: fl-slide-right 1s ease-out;
486
  }
487
  @keyframes fl-slide-right {
488
- 0% { opacity: 0; transform: translateX(-10%); }
489
  100% { opacity: 1; transform: translateX(0%); }
490
  }
491
  @-webkit-keyframes fl-slide-right {
492
- 0% { opacity: 0; -webkit-transform: translateX(-10%); }
493
  100% { opacity: 1; -webkit-transform: translateX(0%); }
494
  }
495
  @-moz-keyframes fl-slide-right {
496
- 0% { opacity: 0; -moz-transform: translateX(-10%); }
497
  100% { opacity: 1; -moz-transform: translateX(0%); }
498
  }
499
 
@@ -504,15 +504,15 @@ img.mfp-img {
504
  -moz-animation: fl-slide-up 1s ease-out;
505
  }
506
  @keyframes fl-slide-up {
507
- 0% { opacity: 0; transform: translateY(10%); }
508
  100% { opacity: 1; transform: translateY(0%); }
509
  }
510
  @-webkit-keyframes fl-slide-up {
511
- 0% { opacity: 0; -webkit-transform: translateY(10%); }
512
  100% { opacity: 1; -webkit-transform: translateY(0%); }
513
  }
514
  @-moz-keyframes fl-slide-up {
515
- 0% { opacity: 0; -moz-transform: translateY(10%); }
516
  100% { opacity: 1; -moz-transform: translateY(0%); }
517
  }
518
 
@@ -523,14 +523,14 @@ img.mfp-img {
523
  -moz-animation: fl-slide-down 1s ease-out;
524
  }
525
  @keyframes fl-slide-down {
526
- 0% { opacity: 0; transform: translateY(-10%); }
527
  100% { opacity: 1; transform: translateY(0%); }
528
  }
529
  @-webkit-keyframes fl-slide-down {
530
- 0% { opacity: 0; -webkit-transform: translateY(-10%); }
531
  100% { opacity: 1; -webkit-transform: translateY(0%); }
532
  }
533
  @-moz-keyframes fl-slide-down {
534
- 0% { opacity: 0; -moz-transform: translateY(-10%); }
535
  100% { opacity: 1; -moz-transform: translateY(0%); }
536
  }
4
  .fl-builder-content *,
5
  .fl-builder-content *:before,
6
  .fl-builder-content *:after {
7
+ -webkit-box-sizing: border-box;
8
+ -moz-box-sizing: border-box;
9
+ box-sizing: border-box;
10
  }
11
  .fl-row:before,
12
  .fl-row:after,
20
  .fl-module:after,
21
  .fl-module-content:before,
22
  .fl-module-content:after {
23
+ display: table;
24
+ content: " ";
25
  }
26
  .fl-row:after,
27
  .fl-row-content:after,
29
  .fl-col:after,
30
  .fl-module:after,
31
  .fl-module-content:after {
32
+ clear: both;
33
  }
34
  .fl-row,
35
  .fl-row-content,
37
  .fl-col,
38
  .fl-module,
39
  .fl-module-content {
40
+ zoom:1;
41
  }
42
  .fl-row,
43
  .fl-row-content {
44
+ margin-left: auto;
45
+ margin-right: auto;
46
  }
47
  .fl-col {
48
+ float: left;
49
+ min-height: 1px;
50
  }
51
  .fl-clear {
52
+ clear: both;
53
  }
54
 
55
  /* Utilities
57
 
58
  .fl-clearfix:before,
59
  .fl-clearfix:after {
60
+ display: table;
61
+ content: " ";
62
  }
63
  .fl-clearfix:after {
64
+ clear: both;
65
  }
66
  .fl-clearfix {
67
+ zoom:1;
68
  }
69
 
70
  /* Responsive Utilities
73
  .fl-visible-medium,
74
  .fl-visible-medium-mobile,
75
  .fl-visible-mobile {
76
+ display: none;
77
  }
78
 
79
  /* Rows
82
  /* Video Bg */
83
  .fl-row-bg-video,
84
  .fl-row-bg-video .fl-row-content {
85
+ position: relative;
86
  }
87
  .fl-row-bg-video .fl-bg-video {
88
+ bottom: 0;
89
+ left: 0;
90
+ overflow: hidden;
91
+ position: absolute;
92
+ right: 0;
93
+ top: 0;
94
  }
95
  .fl-row-bg-video .fl-bg-video video {
96
+ bottom: 0;
97
+ left: 0px;
98
+ position: absolute;
99
+ right: 0;
100
+ top: 0px;
101
  }
102
  .fl-bg-video-fallback {
103
+ background-position: 50% 50%;
104
+ background-repeat: no-repeat;
105
+ background-size: cover;
106
+ bottom: 0px;
107
+ left: 0px;
108
+ position: absolute;
109
+ right: 0px;
110
+ top: 0px;
111
  }
112
 
113
  /* Slideshow Bg */
114
  .fl-row-bg-slideshow,
115
  .fl-row-bg-slideshow .fl-row-content {
116
+ position: relative;
117
  }
118
  .fl-row .fl-bg-slideshow {
119
+ bottom: 0;
120
+ left: 0;
121
+ overflow: hidden;
122
+ position: absolute;
123
+ right: 0;
124
+ top: 0;
125
+ z-index: 0;
126
  }
127
  .fl-builder-edit .fl-row .fl-bg-slideshow * {
128
+ bottom: 0;
129
+ height: auto !important;
130
+ left: 0;
131
+ position: absolute !important;
132
+ right: 0;
133
+ top: 0;
134
  }
135
 
136
  /* Bg Overlay */
137
  .fl-row-bg-overlay .fl-row-content-wrap {
138
+ position: relative;
139
  }
140
  .fl-row-bg-overlay .fl-row-content-wrap:after {
141
+ content: '';
142
+ display: block;
143
+ position: absolute;
144
+ top: 0;
145
+ right: 0;
146
+ bottom: 0;
147
+ left: 0;
148
+ z-index: 0;
149
  }
150
  .fl-row-bg-overlay .fl-row-content {
151
+ position: relative;
152
+ z-index: 1;
153
  }
154
 
155
  /* Modules
156
  ------------------------------------------------------ */
157
 
158
  .fl-module img {
159
+ max-width: 100%;
160
  }
161
 
162
  /* Buttons
170
  -moz-border-radius: 4px;
171
  -webkit-border-radius: 4px;
172
  color: #333;
173
+ display: inline-block;
174
+ font-size: 16px;
175
+ font-weight: normal;
176
+ line-height: 18px;
177
  padding: 12px 24px;
178
+ text-decoration: none;
179
+ text-shadow: none;
180
  }
181
  .fl-builder-content a.fl-button *,
182
  .fl-builder-content a.fl-button:visited * {
183
  color: #333;
184
  }
185
  .fl-builder-content .fl-button:hover {
186
+ text-decoration: none;
187
  }
188
  .fl-builder-content .fl-button:active {
189
+ position: relative;
190
+ top: 1px;
191
  }
192
  .fl-builder-content .fl-button-width-full .fl-button {
193
+ display: block;
194
+ text-align: center;
195
  }
196
  .fl-builder-content .fl-button-width-custom .fl-button {
197
+ display: inline-block;
198
+ text-align: center;
199
+ max-width: 100%;
200
  }
201
  .fl-builder-content .fl-button-left {
202
+ text-align: left;
203
  }
204
  .fl-builder-content .fl-button-center {
205
+ text-align: center;
206
  }
207
  .fl-builder-content .fl-button-right {
208
+ text-align: right;
209
  }
210
  .fl-builder-content .fl-button i {
211
+ font-size: 1.3em;
212
+ height: auto;
213
+ margin-right:8px;
214
+ vertical-align: middle;
215
+ width: auto;
216
  }
217
  .fl-builder-content .fl-button-has-icon .fl-button-text {
218
+ vertical-align: middle;
219
  }
220
 
221
  /* Icons
222
  ------------------------------------------------------ */
223
 
224
  .fl-icon-wrap {
225
+ display: inline-block;
226
  }
227
  .fl-icon {
228
+ display: table-cell;
229
+ vertical-align: middle;
230
  }
231
  .fl-icon a {
232
+ text-decoration: none;
233
  }
234
  .fl-icon i {
235
+ float: left;
236
  }
237
  .fl-icon i:before {
238
+ border: none !important;
239
  }
240
  .fl-icon-text {
241
+ display: table-cell;
242
+ text-align: left;
243
+ padding-left: 15px;
244
+ vertical-align: middle;
245
  }
246
  .fl-icon-text *:last-child {
247
+ margin: 0 !important;
248
+ padding: 0 !important;
249
  }
250
  .fl-icon-text a {
251
+ text-decoration: none;
252
  }
253
 
254
  /* Photos
255
  ------------------------------------------------------ */
256
 
257
  .fl-photo {
258
+ position: relative;
259
  }
260
  .fl-photo-align-left {
261
+ text-align: left;
262
  }
263
  .fl-photo-align-center {
264
+ text-align: center;
265
  }
266
  .fl-photo-align-right {
267
+ text-align: right;
268
  }
269
  .fl-photo-content {
270
+ line-height: 0;
271
  }
272
  .fl-photo-content img {
273
  display: inline;
274
+ height: auto !important;
275
+ max-width: 100%;
276
+ width: auto !important;
277
  }
278
  .fl-photo-crop-circle img {
279
+ -webkit-border-radius: 100%;
280
+ -moz-border-radius: 100%;
281
+ border-radius: 100%;
282
  }
283
  .fl-photo-caption {
284
+ font-size: 13px;
285
+ line-height: 18px;
286
  overflow: hidden;
287
  text-overflow: ellipsis;
288
  white-space: nowrap;
289
  }
290
  .fl-photo-caption-below {
291
+ padding-bottom: 20px;
292
+ padding-top: 10px;
293
  }
294
  .fl-photo-caption-hover {
295
+ background: rgba(0,0,0,0.7);
296
+ bottom: 0;
297
+ color: #fff;
298
+ left: 0;
299
+ opacity: 0;
300
+ filter: alpha(opacity = 0);
301
+ padding: 10px 15px;
302
+ position: absolute;
303
+ right: 0;
304
  -webkit-transition:opacity 0.3s ease-in;
305
  -moz-transition:opacity 0.3s ease-in;
306
  transition:opacity 0.3s ease-in;
307
  }
308
  .fl-photo:hover .fl-photo-caption-hover {
309
+ opacity: 100;
310
+ filter: alpha(opacity = 100);
311
  }
312
 
313
  /* Pagination
314
  ------------------------------------------------------ */
315
 
316
  .fl-builder-pagination {
317
+ padding: 40px 0;
318
  }
319
  .fl-builder-pagination ul.page-numbers {
320
+ list-style: none;
321
+ margin: 0;
322
+ padding: 0;
323
+ text-align: center;
324
  }
325
  .fl-builder-pagination li {
326
+ display: inline-block;
327
+ list-style: none;
328
+ margin: 0;
329
+ padding: 0;
330
  }
331
  .fl-builder-pagination li a.page-numbers,
332
  .fl-builder-pagination li span.page-numbers {
333
+ border: 1px solid #e6e6e6;
334
+ display: inline-block;
335
+ padding: 5px 10px;
336
+ margin: 0 0 5px;
337
  }
338
  .fl-builder-pagination li a.page-numbers:hover,
339
  .fl-builder-pagination li span.current {
340
+ background: #f5f5f5;
341
+ text-decoration: none;
342
  }
343
 
344
  /* Slideshows
346
 
347
  .fl-slideshow,
348
  .fl-slideshow * {
349
+ -webkit-box-sizing: content-box;
350
+ -moz-box-sizing: content-box;
351
+ box-sizing: content-box;
352
 
353
  }
354
  .fl-slideshow .fl-slideshow-image img {
355
+ max-width: none !important;
356
  }
357
  .fl-slideshow-social {
358
+ line-height: 0 !important;
359
  }
360
  .fl-slideshow-social * {
361
+ margin: 0 !important;
362
  }
363
 
364
  /* Sliders
365
  ------------------------------------------------------ */
366
 
367
  .fl-builder-content .bx-wrapper .bx-viewport {
368
+ background: transparent;
369
+ border: none;
370
+ box-shadow: none;
371
+ -moz-box-shadow: none;
372
+ -webkit-box-shadow: none;
373
+ left: 0;
374
  }
375
 
376
  /* Lightbox
377
  ------------------------------------------------------ */
378
 
379
  .mfp-wrap button {
380
+ background: transparent !important;
381
+ box-shadow: none !important;
382
+ -moz-box-shadow: none !important;
383
+ -webkit-box-shadow: none !important;
384
  }
385
  .mfp-wrap button.mfp-arrow:active,
386
  .mfp-wrap button.mfp-arrow:hover,
387
  .mfp-wrap button.mfp-arrow:focus {
388
+ background: transparent !important;
389
+ border: none !important;
390
+ outline: none;
391
+ position: absolute;
392
+ top: 50%;
393
  }
394
  .mfp-wrap .mfp-close:active,
395
  .mfp-wrap .mfp-close:hover,
396
  .mfp-wrap .mfp-close:focus {
397
+ background: transparent !important;
398
+ border: none !important;
399
+ outline: none;
400
+ position: absolute;
401
+ top: 0;
402
  }
403
  img.mfp-img {
404
+ padding: 0;
405
  }
406
  .mfp-counter {
407
+ display: none;
408
  }
409
 
410
  /* Form Fields
432
  ------------------------------------------------------ */
433
 
434
  .fl-animation {
435
+ opacity: 0;
436
  }
437
  .fl-builder-touch .fl-animation,
438
  .fl-builder-edit .fl-animation,
439
  .fl-animated {
440
+ opacity: 1;
441
  }
442
 
443
  /* Fade In */
448
  }
449
  @keyframes fl-fade-in {
450
  0% { opacity: 0; }
451
+ 100% { opacity: 1; }
452
  }
453
  @-webkit-keyframes fl-fade-in {
454
  0% { opacity: 0; }
455
+ 100% { opacity: 1; }
456
  }
457
  @-moz-keyframes fl-fade-in {
458
  0% { opacity: 0; }
459
+ 100% { opacity: 1; }
460
  }
461
 
462
  /* Slide Left */
466
  -moz-animation: fl-slide-left 1s ease-out;
467
  }
468
  @keyframes fl-slide-left {
469
+ 0% { opacity: 0; transform: translateX(10%); }
470
  100% { opacity: 1; transform: translateX(0%); }
471
  }
472
  @-webkit-keyframes fl-slide-left {
473
+ 0% { opacity: 0; -webkit-transform: translateX(10%); }
474
  100% { opacity: 1; -webkit-transform: translateX(0%); }
475
  }
476
  @-moz-keyframes fl-slide-left {
477
+ 0% { opacity: 0; -moz-transform: translateX(10%); }
478
  100% { opacity: 1; -moz-transform: translateX(0%); }
479
  }
480
 
485
  -moz-animation: fl-slide-right 1s ease-out;
486
  }
487
  @keyframes fl-slide-right {
488
+ 0% { opacity: 0; transform: translateX(-10%); }
489
  100% { opacity: 1; transform: translateX(0%); }
490
  }
491
  @-webkit-keyframes fl-slide-right {
492
+ 0% { opacity: 0; -webkit-transform: translateX(-10%); }
493
  100% { opacity: 1; -webkit-transform: translateX(0%); }
494
  }
495
  @-moz-keyframes fl-slide-right {
496
+ 0% { opacity: 0; -moz-transform: translateX(-10%); }
497
  100% { opacity: 1; -moz-transform: translateX(0%); }
498
  }
499
 
504
  -moz-animation: fl-slide-up 1s ease-out;
505
  }
506
  @keyframes fl-slide-up {
507
+ 0% { opacity: 0; transform: translateY(10%); }
508
  100% { opacity: 1; transform: translateY(0%); }
509
  }
510
  @-webkit-keyframes fl-slide-up {
511
+ 0% { opacity: 0; -webkit-transform: translateY(10%); }
512
  100% { opacity: 1; -webkit-transform: translateY(0%); }
513
  }
514
  @-moz-keyframes fl-slide-up {
515
+ 0% { opacity: 0; -moz-transform: translateY(10%); }
516
  100% { opacity: 1; -moz-transform: translateY(0%); }
517
  }
518
 
523
  -moz-animation: fl-slide-down 1s ease-out;
524
  }
525
  @keyframes fl-slide-down {
526
+ 0% { opacity: 0; transform: translateY(-10%); }
527
  100% { opacity: 1; transform: translateY(0%); }
528
  }
529
  @-webkit-keyframes fl-slide-down {
530
+ 0% { opacity: 0; -webkit-transform: translateY(-10%); }
531
  100% { opacity: 1; -webkit-transform: translateY(0%); }
532
  }
533
  @-moz-keyframes fl-slide-down {
534
+ 0% { opacity: 0; -moz-transform: translateY(-10%); }
535
  100% { opacity: 1; -moz-transform: translateY(0%); }
536
  }
css/fl-builder-rtl.css CHANGED
@@ -4,58 +4,58 @@
4
  .fl-builder-bar,
5
  .fl-builder-panel,
6
  .fl-lightbox {
7
- direction: rtl;
8
- unicode-bidi: embed;
9
  }
10
 
11
  /* Panel
12
  ------------------------------------------------------ */
13
 
14
  .fl-builder-blocks-section > span i {
15
- float: left;
16
  }
17
 
18
  /* Template Selector
19
  ------------------------------------------------------ */
20
 
21
  .fl-user-template-actions {
22
- left: 0;
23
- right: auto;
24
  }
25
 
26
  /* Settings Forms
27
  ------------------------------------------------------ */
28
 
29
  .fl-lightbox-header .fl-builder-preview-loader {
30
- left: 15px;
31
- right: auto;
32
  }
33
  .fl-form-table th {
34
- text-align: right !important;
35
  }
36
 
37
  /* Icon Fields
38
  ------------------------------------------------------ */
39
 
40
  .fl-icon-field .fl-icon-preview i {
41
- margin: 10px 2px 9px 10px;
42
  }
43
 
44
  /* Icon Selector
45
  ------------------------------------------------------ */
46
 
47
  .fl-icons-filter {
48
- left: 10px;
49
- right: auto;
50
  }
51
  .fl-icons-section h2 {
52
- text-align: right;
53
  }
54
 
55
  /* Tooltips
56
  ------------------------------------------------------ */
57
 
58
  .fl-help-tooltip-text {
59
- left: auto;
60
- right: 23px;
61
  }
4
  .fl-builder-bar,
5
  .fl-builder-panel,
6
  .fl-lightbox {
7
+ direction: rtl;
8
+ unicode-bidi: embed;
9
  }
10
 
11
  /* Panel
12
  ------------------------------------------------------ */
13
 
14
  .fl-builder-blocks-section > span i {
15
+ float: left;
16
  }
17
 
18
  /* Template Selector
19
  ------------------------------------------------------ */
20
 
21
  .fl-user-template-actions {
22
+ left: 0;
23
+ right: auto;
24
  }
25
 
26
  /* Settings Forms
27
  ------------------------------------------------------ */
28
 
29
  .fl-lightbox-header .fl-builder-preview-loader {
30
+ left: 15px;
31
+ right: auto;
32
  }
33
  .fl-form-table th {
34
+ text-align: right !important;
35
  }
36
 
37
  /* Icon Fields
38
  ------------------------------------------------------ */
39
 
40
  .fl-icon-field .fl-icon-preview i {
41
+ margin: 10px 2px 9px 10px;
42
  }
43
 
44
  /* Icon Selector
45
  ------------------------------------------------------ */
46
 
47
  .fl-icons-filter {
48
+ left: 10px;
49
+ right: auto;
50
  }
51
  .fl-icons-section h2 {
52
+ text-align: right;
53
  }
54
 
55
  /* Tooltips
56
  ------------------------------------------------------ */
57
 
58
  .fl-help-tooltip-text {
59
+ left: auto;
60
+ right: 23px;
61
  }
css/fl-builder.css CHANGED
@@ -2,46 +2,46 @@
2
  ------------------------------------------------------ */
3
 
4
  html.fl-builder-edit {
5
- margin-top: 43px !important;
6
  }
7
  .fl-builder-edit body {
8
- position: static;
9
  }
10
  .fl-builder-edit #wpadminbar {
11
- display: none;
12
  }
13
  .fl-clear {
14
- clear: both;
15
  }
16
  .fl-builder-hidden-editor {
17
- display: none;
18
  }
19
  .fl-builder-loading {
20
- background: rgba(240, 240, 240, 0.8) url(../img/ajax-loader.gif) center center no-repeat;
21
- bottom: 0;
22
- display: none;
23
- left: 0;
24
- position: fixed;
25
- right: 0;
26
- text-align: center;
27
- top: 0;
28
- z-index: 200000;
29
  }
30
  .fl-builder-settings .fl-builder-loading {
31
  background: rgba(255, 255, 255, 0.8) url(../img/ajax-loader.gif) center center no-repeat;
32
- display: block;
33
- position: absolute;
34
  }
35
  #tiptip_holder {
36
- z-index: 200000;
37
  }
38
  .screen-reader-text{
39
- position: absolute;
40
- left: -1000em;
41
- top: -1000em;
42
- height: 1px;
43
- width: 1px;
44
- overflow: hidden;
45
  }
46
 
47
  /* Simple UI
@@ -56,7 +56,7 @@ html.fl-builder-edit {
56
  .fl-builder-simple .fl-block-overlay-actions .fl-block-copy,
57
  .fl-builder-simple .fl-block-overlay-actions .fl-block-remove,
58
  .fl-builder-simple .fl-col-highlight {
59
- display: none !important;
60
  }
61
 
62
  /* Responsive Utilities
@@ -67,66 +67,66 @@ html.fl-builder-edit {
67
  .fl-visible-medium,
68
  .fl-visible-medium-mobile,
69
  .fl-visible-mobile {
70
- display: block;
71
  }
72
 
73
  /* Builder Buttons
74
  ------------------------------------------------------ */
75
 
76
  .fl-builder-button {
77
- color: #555;
78
- border-color: #ccc;
79
- background: #f7f7f7;
80
- -webkit-box-shadow: inset 0 1px 0 #fff,0 1px 0 rgba(0,0,0,.08);
81
- box-shadow: inset 0 1px 0 #fff,0 1px 0 rgba(0,0,0,.08);
82
- vertical-align: top;
83
- display: inline-block;
84
- text-decoration: none;
85
- font-size: 13px !important;
86
- line-height: 13px !important;
87
- height: 28px;
88
- margin: 0;
89
- padding: 7px 10px;
90
- cursor: pointer;
91
- border-width: 1px;
92
- border-style: solid;
93
- -webkit-border-radius: 3px;
94
- -webkit-appearance: none;
95
- border-radius: 3px;
96
- white-space: nowrap;
97
- -webkit-box-sizing: border-box !important;
98
- -moz-box-sizing: border-box !important;
99
- box-sizing: border-box !important;
100
  }
101
  .fl-builder-button:hover {
102
- background: #fafafa;
103
- border-color: #999;
104
- color: #222;
105
  }
106
  .fl-builder-button-primary {
107
- background: #2ea2cc;
108
- border-color: #0074a2;
109
- -webkit-box-shadow: inset 0 1px 0 rgba(120,200,230,.5),0 1px 0 rgba(0,0,0,.15);
110
- box-shadow: inset 0 1px 0 rgba(120,200,230,.5),0 1px 0 rgba(0,0,0,.15);
111
- color: #fff !important;
112
- text-decoration: none;
113
  }
114
  .fl-builder-button-primary:hover {
115
- background: #1e8cbe;
116
- border-color: #0074a2;
117
- -webkit-box-shadow: inset 0 1px 0 rgba(120,200,230,.6);
118
- box-shadow: inset 0 1px 0 rgba(120,200,230,.6);
119
- color: #fff !important;
120
  }
121
  .fl-builder-button-large {
122
- height: 30px;
123
- line-height: 30px !important;
124
- padding: 0 12px 2px;
125
  }
126
  .fl-builder-button-small {
127
- font-size: 11px !important;
128
- line-height: 11px !important;
129
- height: 24px;
130
  }
131
  .fl-builder-help-button {
132
  color: #b3b3b3;
@@ -144,259 +144,259 @@ html.fl-builder-edit {
144
  ------------------------------------------------------ */
145
 
146
  .fl-builder-bar {
147
- left: 0;
148
- position: fixed;
149
- right: 0;
150
- top: 0;
151
- z-index: 100008;
152
  }
153
  .fl-builder-bar-content {
154
- background: #f4f4f4;
155
- border-bottom: 1px solid #ccc;
156
- box-shadow: 0 0 8px rgba(0,0,0,0.2);
157
- -moz-box-shadow: 0 0 8px rgba(0,0,0,0.2);
158
- -webkit-box-shadow: 0 0 8px rgba(0,0,0,0.2);
159
- color: #999999;
160
- font-family: Helvetica, Verdana, sans-serif;
161
- font-size: 14px;
162
- height: 43px;
163
  }
164
  .fl-builder-bar-title {
165
- color: #333;
166
- display: block;
167
- float: left;
168
- font-size: 20px;
169
- font-weight: 300;
170
- line-height: 20px;
171
- padding: 7px 10px;
172
  }
173
  .fl-builder-bar-title img {
174
- height: 30px !important;
175
- margin: 0 1px 0 0 !important;
176
- vertical-align: middle !important;
177
  }
178
  .fl-builder-bar-title span {
179
- vertical-align: middle;
180
  }
181
  .fl-builder-bar-title.fl-builder-bar-title-no-icon {
182
- padding: 12px;
183
  }
184
  .fl-builder-bar-actions {
185
- float: right;
186
- padding: 7px;
187
  }
188
  .fl-builder-bar .fl-builder-button {
189
- float: right;
190
- margin: 0 0 0 6px;
191
  }
192
  .fl-builder-bar .fl-builder-add-content-button {
193
- display: none;
194
  }
195
 
196
  /* Upgrade button */
197
  .fl-builder-upgrade-button {
198
- background: #f7951e;
199
- border-color: #de7c04;
200
- -webkit-box-shadow: inset 0 1px 0 rgba(255,177,82,.5),0 1px 0 rgba(0,0,0,.15);
201
- box-shadow: inset 0 1px 0 rgba(255,177,82,.5),0 1px 0 rgba(0,0,0,.15);
202
- color: #fff !important;
203
- text-decoration: none;
204
  }
205
  .fl-builder-upgrade-button:hover {
206
- background: #de861b;
207
- border-color: #c46e04;
208
- -webkit-box-shadow: inset 0 1px 0 rgba(255,177,82,.5),0 1px 0 rgba(0,0,0,.15);
209
- box-shadow: inset 0 1px 0 rgba(255,177,82,.5),0 1px 0 rgba(0,0,0,.15);
210
- color: #fff !important;
211
  }
212
 
213
  /* Builder Panel
214
  ------------------------------------------------------ */
215
 
216
  .fl-builder-panel {
217
- background: #f0f0f0;
218
- border-left: 1px solid #ccc;
219
- bottom: 0;
220
- box-shadow: 0 0 8px rgba(0,0,0,0.2);
221
- -moz-box-shadow: 0 0 8px rgba(0,0,0,0.2);
222
- -webkit-box-shadow: 0 0 8px rgba(0,0,0,0.2);
223
- color: #999999;
224
- font-family: Helvetica, Verdana, sans-serif;
225
- font-size: 14px;
226
- opacity: 1;
227
- position: fixed;
228
- right: 0;
229
- top: 43px;
230
- width: 300px;
231
- z-index: 100007;
232
- -webkit-transform: translateZ(0);
233
- transition: opacity 0.2s;
234
- -webkit-transition: opacity 0.2s;
235
- -moz-transition: opacity 0.2s;
236
- -o-transition: opacity 0.2s;
237
- -ms-transition: opacity 0.2s;
238
- -webkit-touch-callout: none;
239
- -webkit-user-select: none;
240
- -khtml-user-select: none;
241
- -moz-user-select: none;
242
- -ms-user-select: none;
243
- user-select: none;
244
  }
245
 
246
  /* Builder Panel Actions
247
  ------------------------------------------------------ */
248
 
249
  .fl-builder-panel-actions {
250
- background: #f4f4f4;
251
- border-bottom: 1px solid #dbdbdb;
252
- height: 43px;
253
- left: 0;
254
- position: absolute;
255
- right: 0;
256
- top: 0;
257
- text-align: right;
258
- z-index: 100009;
259
  }
260
  .fl-builder-panel-actions .fl-builder-panel-close {
261
- color: #bfbfbf;
262
- cursor: pointer;
263
- float: left;
264
- font-size: 18px;
265
- margin: 12px 18px;
266
  }
267
  .fl-builder-panel-actions .fl-builder-panel-close:hover {
268
- color: #333;
269
  }
270
 
271
  /* Builder Panel Content
272
  ------------------------------------------------------ */
273
 
274
  .fl-builder-panel-content-wrap {
275
- bottom: 0;
276
- height: auto;
277
- left: 0;
278
- overflow: hidden;
279
- position: absolute;
280
- right: 0;
281
- top: 43px;
282
  }
283
  .fl-builder-panel-content {
284
- padding-bottom: 60px;
285
  }
286
  .fl-builder-blocks-section span {
287
- cursor: pointer;
288
- display: block;
289
- line-height: 14px;
290
- padding: 15px 20px;
291
  }
292
  .fl-builder-blocks-section > span {
293
- border-top: 1px solid #fff;
294
- border-bottom: 1px solid #dfdfdf;
295
- color: #333;
296
- font-weight: normal;
297
  }
298
  .fl-builder-blocks-section > span i {
299
- color: #bfbfbf;
300
- float: right;
301
  }
302
  .fl-builder-blocks-section > span:hover,
303
  .fl-builder-blocks-section > span:hover i {
304
- background: #e5e5e5;
305
  }
306
  .fl-builder-blocks-section-content {
307
- background: #fff;
308
- display: none;
309
  }
310
  .fl-builder-blocks-section.fl-active .fl-builder-blocks-section-content {
311
- display: block;
312
  }
313
  .fl-builder-blocks-section-content span {
314
- border-bottom: 1px solid #ebebeb;
315
- overflow: hidden;
316
- text-overflow: ellipsis;
317
- white-space: nowrap;
318
  }
319
  .fl-builder-blocks-section-content span i {
320
- color: #d9d9d9;
321
- margin-right: 10px;
322
  }
323
  .fl-builder-blocks-section-content span:hover {
324
- background: #0074a1;
325
- color: #fff;
326
- cursor: move;
327
  }
328
 
329
  /* Drag and Drop
330
  ------------------------------------------------------ */
331
 
332
  .fl-builder-empty {
333
- border: 1px dashed #3ba0ff;
334
- color: #3ba0ff;
335
- font-family: Helvetica, Verdana, sans-serif !important;
336
- font-size: 14px;
337
- margin: 10px;
338
- padding: 100px 20px;
339
- text-align: center;
340
- text-transform: uppercase;
341
  }
342
  .fl-builder-empty .fl-builder-drop-zone {
343
- margin: 10px;
344
  }
345
  .fl-builder-block.ui-draggable-dragging,
346
  .fl-builder-block-drag-helper {
347
- background: #fff !important;
348
- border: 1px solid #ccc;
349
- box-shadow: 0 0 8px rgba(0,0,0,0.2);
350
- -moz-box-shadow: 0 0 8px rgba(0,0,0,0.2);
351
- -webkit-box-shadow: 0 0 8px rgba(0,0,0,0.2);
352
- color: #999999 !important;
353
- font-family: Helvetica, Verdana, sans-serif !important;
354
- font-size: 14px !important;
355
- height: 45px !important;
356
- line-height: 42px !important;
357
- overflow: hidden;
358
- padding: 0 18px;
359
- position: fixed !important;
360
- text-overflow: ellipsis;
361
- white-space: nowrap;
362
- width: 140px !important;
363
- z-index: 100010;
364
  }
365
  .fl-builder-drop-zone {
366
- background: #3ba0ff;
367
- color: #fff;
368
- display: block;
369
- font-family: Helvetica, Verdana, sans-serif !important;
370
- font-weight: bold;
371
- font-size: 14px;
372
- margin: 10px;
373
- padding: 10px;
374
- text-shadow: none;
375
  }
376
  .fl-builder-content > .fl-builder-drop-zone {
377
- margin: 10px 20px;
378
  }
379
  .fl-row-content > .fl-builder-drop-zone {
380
- margin: 5px;
381
  }
382
  .fl-row-highlight {
383
- padding: 5px 0;
384
  }
385
  .fl-row-highlight .fl-row-content {
386
- border: 1px dashed #ff0000;
387
- padding: 5px;
388
  }
389
  .fl-col-highlight {
390
- padding: 15px 5px;
391
  }
392
  .fl-col-highlight .fl-col-content {
393
- border-style: dashed;
394
- border-color: #3ba0ff;
395
- border-top-width: 1px;
396
- border-bottom-width: 1px;
397
- border-left-width: 1px;
398
- border-right-width: 1px;
399
- min-height: 100px;
400
  }
401
 
402
  /* Action Overlays
@@ -404,63 +404,63 @@ html.fl-builder-edit {
404
 
405
  .fl-block-overlay,
406
  .fl-block-overlay * {
407
- text-shadow: none;
408
  }
409
  .fl-block-overlay-active {
410
- position: relative;
411
  }
412
  .fl-block-overlay-actions {
413
- background: #3ba0ff;
414
- float: left;
415
- text-shadow: none;
416
  }
417
  .fl-block-overlay-actions i {
418
- color: #fff !important;
419
- cursor: pointer;
420
- display: inline-block !important;
421
- font-size: 16px !important;
422
- height: 30px !important;
423
- font-weight: 100 !important;
424
- line-height: 30px !important;
425
- opacity: 0.8;
426
- filter: alpha(opacity = 80);
427
- text-align: center;
428
- vertical-align: middle;
429
- width: 36px !important;
430
  }
431
  .fl-block-overlay-actions i:hover {
432
- opacity: 1;
433
- filter: alpha(opacity = 100);
434
  }
435
  .fl-block-overlay-actions i.fl-block-move {
436
- cursor: move;
437
  }
438
  .fl-block-overlay-title {
439
- border-right: 1px solid #5eb1ff;
440
- color: #fff !important;
441
- float: left;
442
- font-family: Helvetica, Verdana, sans-serif;
443
- font-size: 13px;
444
- height: 30px;
445
- line-height: 29px;
446
- margin-right: 4px;
447
- padding: 0 10px;
448
  }
449
 
450
  /* Rows */
451
  .fl-row-overlay {
452
- background: rgba(59, 160, 255, 0.15);
453
- border: 1px solid #3ba0ff;
454
- bottom: 0;
455
- box-sizing: border-box !important;
456
- -moz-box-sizing: border-box !important;
457
- -webkit-box-sizing: border-box !important;
458
- color: #fff;
459
- left: 0;
460
- position: absolute;
461
- top: -30px;
462
- width: 100%;
463
- z-index: 100006;
464
  }
465
  .fl-row-overlay-header-bottom {
466
  bottom: -30px;
@@ -474,284 +474,284 @@ html.fl-builder-edit {
474
  position: relative;
475
  }
476
  .fl-block-overlay-active .fl-row-content {
477
- position: relative;
478
- z-index: 100007;
479
  }
480
 
481
  /* Columns */
482
  .fl-col-overlay {
483
- background: rgba(59, 160, 255, 0.15);
484
- border: 1px solid #3ba0ff;
485
- bottom: 15px;
486
- cursor: pointer;
487
- color: #fff;
488
- left: 5px;
489
- position: absolute;
490
- right: 5px;
491
- top: 15px;
492
- z-index: 100007;
493
  }
494
 
495
  /* Modules */
496
  .fl-module-overlay {
497
- background: rgba(59, 160, 255, 0.15);
498
- border: 1px solid #3ba0ff;
499
- bottom: 4px;
500
- cursor: pointer;
501
- color: #fff;
502
- left: 4px;
503
- min-height: 32px;
504
- position: absolute;
505
- right: 4px;
506
- top: 4px;
507
- z-index: 100007;
508
  }
509
  .fl-module-adjust-height {
510
- padding-bottom: 15px;
511
- padding-top: 15px;
512
  }
513
 
514
  /* Muted */
515
  .fl-block-overlay-muted .fl-row-overlay {
516
- background: rgba(153, 153, 153, 0.1);
517
- border: 1px solid #8c8c8c;
518
  }
519
  .fl-block-overlay-muted .fl-row-overlay .fl-block-overlay-actions {
520
- background: #8c8c8c;
521
  }
522
  .fl-block-overlay-muted .fl-row-overlay .fl-block-overlay-title {
523
- border-right: 1px solid #a6a6a6;
524
  }
525
 
526
  /* Actions Lightbox
527
  ------------------------------------------------------ */
528
 
529
  .fl-builder-actions-lightbox .fl-lightbox {
530
- width: 300px;
531
  }
532
  .fl-builder-actions-lightbox .fl-builder-actions {
533
- display: block;
534
- padding: 25px;
535
- text-align: center;
536
  }
537
  .fl-builder-actions-title {
538
- color: #333 !important;
539
- display: block;
540
- font-family: Helvetica, Verdana, sans-serif !important;
541
- font-size: 16px !important;
542
- margin-bottom: 20px;
543
  }
544
  .fl-builder-actions .fl-builder-button {
545
- display: block;
546
- margin-bottom: 7px;
547
  }
548
 
549
  /* Alert Lightbox
550
  ------------------------------------------------------ */
551
 
552
  .fl-builder-alert-lightbox .fl-lightbox {
553
- width: 440px !important;
554
  }
555
  .fl-builder-alert-lightbox .fl-lightbox-message {
556
- color: #333 !important;
557
- font-family: Helvetica, Verdana, sans-serif !important;
558
- font-size: 16px !important;
559
- line-height: 24px;
560
- padding: 30px;
561
  }
562
 
563
  /* Template Selector
564
  ------------------------------------------------------ */
565
 
566
  .fl-user-templates {
567
- border-top: 1px solid #dfdfdf;
568
- margin-bottom: 20px;
569
- margin-right: 8px;
570
  }
571
  .fl-user-template {
572
- border-bottom: 1px solid #dfdfdf;
573
- padding: 15px;
574
- position: relative;
575
  }
576
  .fl-user-template:hover {
577
- background: #0074a1;
578
- color: #fff !important;
579
- cursor: pointer;
580
  }
581
  .fl-user-template:hover * {
582
- color: #fff !important;
583
  }
584
  .fl-user-template-actions {
585
- bottom: 0;
586
- position: absolute;
587
- right: 0;
588
- top: 0;
589
  }
590
  .fl-user-template-actions a {
591
- color: #bfbfbf !important;
592
- display: inline-block;
593
- padding: 15px;
594
  }
595
  .fl-user-template:hover a {
596
- color: #99c7d9 !important;
597
  }
598
  .fl-user-template:hover a:hover {
599
- color: #fff !important;
600
  }
601
  .fl-user-templates-message {
602
- display: none;
603
  }
604
  .fl-template-selector .fl-builder-settings-tab-description {
605
- font-size: 15px!important;
606
- margin: 0 !important;
607
- padding: 10px 0 25px;
608
- text-align: center;
609
  }
610
  .fl-template-preview {
611
- float: left;
612
- margin: 0 20px 30px 0;
613
- position: relative;
614
- text-align: center;
615
- width: 170px;
616
  }
617
  .fl-template-preview.fl-last {
618
- margin-right: 0;
619
  }
620
  .fl-template-image {
621
- border: 1px solid #d9d9d9;
622
- cursor: pointer;
623
- margin-bottom: 12px;
624
- height: 164px;
625
- overflow: hidden;
626
  }
627
  .fl-template-image:hover {
628
- border-color: #ff0000;
629
  }
630
  .fl-template-image img {
631
- max-height: none;
632
- width: 100%;
633
  }
634
  .fl-template-preview span {
635
- display: block;
636
- text-align: center;
637
  }
638
 
639
  /* User Template Settings
640
  ------------------------------------------------------ */
641
 
642
  .fl-builder-user-template-settings .fl-builder-settings-fields {
643
- height: 150px;
644
  }
645
 
646
  /* Settings
647
  ------------------------------------------------------ */
648
 
649
  .fl-builder-lightbox .fl-lightbox {
650
- width: 600px;
651
  }
652
  form.fl-builder-settings {
653
- margin: 0;
654
- padding: 0;
655
  }
656
  .fl-builder-settings-message {
657
- font-size: 15px !important;
658
- line-height: 23px !important;
659
- padding: 20px 25px !important;
660
- background: #f2f2f2 !important;
661
  }
662
  .fl-builder-preview-loader {
663
- position: relative;
664
- top: -1px;
665
- margin-left: 3px;
666
  }
667
  .fl-lightbox-header .fl-builder-preview-loader {
668
- margin: 0;
669
- position: absolute;
670
- right: 15px;
671
- top: 15px;
672
  }
673
 
674
  /* Settings Tabs
675
  ------------------------------------------------------ */
676
 
677
  .fl-builder-settings-tabs {
678
- background: #f5f5f5;
679
- border-bottom: 1px solid #dfdfdf;
680
- padding: 15px 20px 0 20px;
681
  }
682
  .fl-builder-settings-tabs a {
683
- color: #999;
684
- display: inline-block;
685
- padding: 10px 20px;
686
- text-decoration: none;
687
  }
688
  .fl-builder-settings-tabs a:hover {
689
- color: #333;
690
  }
691
  .fl-builder-settings-tabs a.fl-active {
692
- background: #fff;
693
- border: 1px solid #dfdfdf;
694
- border-bottom: none;
695
- color: #222;
696
- position: relative;
697
- top: 1px;
698
  }
699
  .fl-builder-settings-tabs a.error {
700
- color: #d03436;
701
- padding-right: 10px;
702
  }
703
  .fl-builder-settings-tabs a.error .fl-error-icon {
704
- background: url('../img/sprite.png') -148px -5px no-repeat;
705
- display: inline-block;
706
- height: 16px;
707
- margin-left: 7px;
708
- position: relative;
709
- top: 3px;
710
- width: 16px;
711
  }
712
  .fl-builder-settings-tab {
713
- display: none;
714
- width: 550px;
715
  }
716
  .fl-builder-settings-tab.fl-active {
717
- display: block;
718
  }
719
  .fl-builder-settings-tab-description {
720
- padding: 0 10px 15px 10px;
721
  }
722
 
723
  /* Settings Tables
724
  ------------------------------------------------------ */
725
 
726
  .fl-form-table {
727
- border: none;
728
- width: 100%;
729
  }
730
  .fl-form-table th {
731
- border: none !important;
732
- background: #fff !important;
733
- font-weight: normal !important;
734
- padding: 10px !important;
735
- text-align: left !important;
736
- vertical-align: top !important;
737
- width: 200px !important;
738
  }
739
  .fl-form-table td {
740
- border: none;
741
- padding: 8px 10px;
742
  }
743
 
744
  /* Settings Fields
745
  ------------------------------------------------------ */
746
 
747
  .fl-builder-settings-fields {
748
- height: 410px;
749
- margin: 5px 0 0 0;
750
- overflow: hidden;
751
- position: relative;
752
  }
753
  .fl-builder-settings-fields .fl-nanoscroller-content {
754
- padding: 15px 20px 20px 20px;
755
  }
756
  .fl-builder-settings-fields textarea,
757
  .fl-builder-settings-fields input[type=text],
@@ -763,25 +763,25 @@ form.fl-builder-settings {
763
  .fl-builder-settings-fields input[type=tel],
764
  .fl-builder-settings-fields input[type=url],
765
  .fl-builder-settings-fields select {
766
- background-color: #fff;
767
- border-color: #dfdfdf;
768
- border-style: solid;
769
- border-width: 1px;
770
- border-radius: 3px;
771
- -moz-border-radius: 3px;
772
- -webkit-border-radius: 3px;
773
- box-shadow: none;
774
- -moz-box-shadow: none;
775
- -webkit-box-shadow: none;
776
- color: #333;
777
- display: inline;
778
- font-size: 12px;
779
- height: auto;
780
- line-height: 15px;
781
- margin: 1px;
782
- outline: none;
783
- padding: 3px;
784
- width: auto;
785
  }
786
  .fl-builder-settings-fields textarea:focus,
787
  .fl-builder-settings-fields input[type=text]:focus,
@@ -793,87 +793,87 @@ form.fl-builder-settings {
793
  .fl-builder-settings-fields input[type=tel]:focus,
794
  .fl-builder-settings-fields input[type=url]:focus,
795
  .fl-builder-settings-fields select:focus {
796
- background: transparent;
797
- border-color: #aaa;
798
  }
799
  .fl-builder-settings-fields ::-webkit-input-placeholder { /* WebKit browsers */
800
- color: #999 !important;
801
  }
802
  .fl-builder-settings-fields input:-moz-placeholder { /* Mozilla Firefox 4 to 18 */
803
- color: #999;
804
  }
805
  .fl-builder-settings-fields ::-moz-placeholder { /* Mozilla Firefox 19+ */
806
- color: #999 !important;
807
  }
808
  .fl-builder-settings-fields input:-ms-input-placeholder { /* Internet Explorer 10+ */
809
- color: #999;
810
  }
811
  .fl-builder-settings-fields label {
812
- font-weight: normal;
813
  }
814
  .fl-builder-settings-fields select {
815
- height: 2em;
816
- color: #000;
817
- padding: 2px;
818
  }
819
  .fl-builder-settings-description {
820
- border-bottom: 1px solid #dfdfdf;
821
- margin: 0 0 10px 0;
822
- padding-bottom: 10px !important;
823
  }
824
  .fl-builder-settings-fields table {
825
- margin: 0;
826
  }
827
  .fl-builder-settings-fields h3.fl-builder-settings-title {
828
- border-bottom: 1px solid #dfdfdf;
829
- color: #333;
830
- font-size: 14px;
831
- font-weight: bold;
832
- margin: 0 0 20px !important;
833
- padding: 10px;
834
  }
835
  .fl-builder-settings-section {
836
- margin-bottom: 15px;
837
  }
838
 
839
  /* Text Field */
840
  .fl-builder-settings-fields input.text-full {
841
- width: 97%;
842
  }
843
 
844
  /* Textarea */
845
  .fl-builder-settings-fields textarea {
846
- width: 97%;
847
  }
848
 
849
  /* Color Picker */
850
  .fl-color-picker {
851
- cursor: pointer;
852
  height: 30px;
853
  width: 48px;
854
  }
855
  .fl-color-picker.fl-color-picker-empty .fl-color-picker-color {
856
- background: url(../img/sprite.png) 0 -24px no-repeat;
857
  }
858
  .fl-color-picker .fl-color-picker-color {
859
- border: 1px solid #ccc;
860
- float: left;
861
  height: 30px;
862
  width: 30px;
863
  }
864
  .fl-color-picker.fl-color-picker-empty .fl-color-picker-clear {
865
- display: none;
866
  }
867
  .fl-color-picker .fl-color-picker-clear {
868
- background: url(../img/sprite.png) -124px 2px no-repeat;
869
- border: 1px solid #ccc;
870
- border-left: none;
871
- float: left;
872
  height: 30px;
873
  width: 15px;
874
  }
875
  .fl-color-picker .fl-color-picker-clear:hover {
876
- background-color: #ededed;
877
  }
878
  .colorpicker input {
879
  padding: 0 !important;
@@ -885,123 +885,123 @@ form.fl-builder-settings {
885
  border: none !important;
886
  }
887
  .colorpicker .colorpicker_hex input {
888
- width: 45px !important;
889
  }
890
 
891
  /* Custom Fields */
892
  .fl-builder-custom-field {
893
- border: 1px solid #dfdfdf;
894
- border-radius: 3px;
895
- padding: 5px 10px;
896
  }
897
  .fl-builder-custom-field a {
898
- color: #21759b !important;
899
- text-decoration: underline !important;
900
  }
901
  .fl-builder-custom-field a:hover {
902
- color: #d54e21 !important;
903
  }
904
  .fl-builder-custom-field label.error {
905
- margin-top: 5px;
906
  }
907
 
908
  /* Photo Fields */
909
  .fl-photo-field .fl-photo-select,
910
  .fl-photo-field.fl-photo-empty .fl-photo-preview {
911
- display: none;
912
  }
913
  .fl-photo-field.fl-photo-empty .fl-photo-select {
914
- display: block;
915
  }
916
  .fl-photo-field .fl-photo-preview-img {
917
- float: left;
918
- line-height: 0;
919
- margin: 5px 0;
920
  }
921
  .fl-photo-field .fl-photo-preview-img img {
922
- max-width: 60px;
923
  }
924
  .fl-photo-field .fl-photo-preview select {
925
- margin: 8px 0 8px 10px;
926
- width: 200px;
927
  }
928
  .fl-photo-field .fl-photo-edit {
929
- margin: 0 0 0 11px;
930
  }
931
  .fl-photo-field .fl-photo-replace {
932
- margin: 0 0 0 8px;
933
  }
934
 
935
  /* Media Uploader */
936
  .fl-builder-edit .media-modal-content .thumbnail {
937
- padding: 0;
938
- border: none;
939
- border-radius: 0;
940
  }
941
 
942
  /* Multiple Photo Fields */
943
  .fl-multiple-photos-lightbox .gallery-settings,
944
  .fl-multiple-photos-field .fl-multiple-photos-select {
945
- display: none;
946
  }
947
  .fl-multiple-photos-field.fl-multiple-photos-empty .fl-multiple-photos-count,
948
  .fl-multiple-photos-field.fl-multiple-photos-empty .fl-multiple-photos-edit,
949
  .fl-multiple-photos-field.fl-multiple-photos-empty .fl-multiple-photos-add {
950
- display: none;
951
  }
952
  .fl-multiple-photos-field .fl-multiple-photos-add {
953
- margin: 0 0 0 8px;
954
  }
955
  .fl-multiple-photos-field.fl-multiple-photos-empty .fl-multiple-photos-select {
956
- display: inline;
957
  }
958
  .fl-multiple-photos-count {
959
- font-weight: bold;
960
- margin-bottom: 3px;
961
  }
962
 
963
  /* Video Fields */
964
  .fl-video-field .fl-video-select,
965
  .fl-video-field.fl-video-empty .fl-video-preview {
966
- display: none;
967
  }
968
  .fl-video-field.fl-video-empty .fl-video-select {
969
- display: block;
970
  }
971
  .fl-video-field .fl-video-preview-img {
972
- float: left;
973
- line-height: 0;
974
- margin: 5px 0;
975
  }
976
  .fl-video-field .fl-video-preview-img img {
977
- max-width: 60px;
978
  }
979
  .fl-video-field .fl-video-preview-filename {
980
- display: inline-block;
981
- font-size: 14px;
982
- font-weight: bold;
983
- margin: 7px 0 0 11px;
984
  }
985
  .fl-video-field .fl-video-replace {
986
- margin: 0 0 0 11px;
987
  }
988
 
989
  /* Icon Fields */
990
  .fl-icon-field .fl-icon-select,
991
  .fl-icon-field.fl-icon-empty .fl-icon-preview {
992
- display: none;
993
  }
994
  .fl-icon-field.fl-icon-empty .fl-icon-select {
995
- display: block;
996
  }
997
  .fl-icon-field .fl-icon-preview i {
998
- display: inline-block;
999
- font-size: 28px;
1000
- margin: 10px 10px 9px 2px;
1001
- vertical-align: middle;
1002
  }
1003
  .fl-icon-field .fl-icon-remove {
1004
- margin: 0 0 0 8px;
1005
  }
1006
 
1007
  /* Text Editors */
@@ -1012,10 +1012,10 @@ form.fl-builder-settings {
1012
  color: #333;
1013
  }
1014
  .fl-builder-settings .wp-editor-container {
1015
- border: 1px solid #e5e5e5;
1016
  }
1017
  .fl-builder-settings .mce-toolbar .mce-btn-group .mce-btn {
1018
- margin: 2px 0;
1019
  }
1020
  .mce-close:hover,
1021
  .mce-close:active,
@@ -1023,170 +1023,171 @@ form.fl-builder-settings {
1023
  .mce-window .mce-btn button:active,
1024
  .mce-toolbar .mce-btn button:hover,
1025
  .mce-toolbar .mce-btn button:active {
1026
- background: transparent;
1027
- border: none;
1028
  }
1029
  .mce-ico {
1030
- font-family: tinymce, Arial !important;
1031
  }
1032
  .mce-toolbar i.mce-ico {
1033
- font: 400 20px/1 dashicons !important;
1034
  }
1035
  .wp-core-ui .quicktags-toolbar input.button.button-small {
1036
- margin: 1px !important;
1037
  }
1038
  .wp-editor-container textarea.wp-editor-area {
1039
- background: transparent;
1040
- border: none;
1041
- padding: 10px;
1042
- box-sizing: border-box;
1043
- -moz-box-sizing: border-box;
1044
- -webkit-box-sizing: border-box;
1045
  }
1046
 
1047
  /* Editor Link Modal */
1048
  .fl-builder form#wp-link {
1049
- color: #000;
1050
- font-family: Helvetica, Verdana, sans-serif;
1051
- font-size: 13px;
1052
  }
1053
  .fl-builder form#wp-link #link-options label {
1054
- display: block;
1055
- margin-bottom: 2px;
1056
  }
1057
  .fl-builder form#wp-link #link-options label span {
1058
- padding-right: 10px;
1059
- width: 60px;
1060
- vertical-align: middle;
1061
  }
1062
  .fl-builder form#wp-link #link-options input[type="text"] {
1063
- display: inline-block;
1064
- height: auto;
1065
- padding: 3px 5px;
1066
- width: 80%;
 
1067
  }
1068
 
1069
  /* Code Editors */
1070
  .ace_editor, .ace_editor * {
1071
- font-family: "Monaco", "Menlo", "Ubuntu Mono", "Droid Sans Mono", "Consolas", monospace !important;
1072
- font-size: 12px !important;
1073
- font-weight: 400 !important;
1074
- letter-spacing: 0 !important;
1075
  }
1076
 
1077
  /* Layout Fields */
1078
  .fl-layout-field-option {
1079
- border: 2px solid #d9d9d9;
1080
- border-radius: 3px;
1081
- -moz-border-radius: 3px;
1082
- -webkit-border-radius: 3px;
1083
- box-sizing: border-box !important;
1084
- -moz-box-sizing: border-box !important;
1085
- -webkit-box-sizing: border-box !important;
1086
- cursor: pointer;
1087
- float: left;
1088
- line-height: 0;
1089
- max-width: 23%;
1090
- margin: 0 1% 2%;
1091
- padding: 5px;
1092
  }
1093
  .fl-layout-field-option-selected,
1094
  .fl-layout-field-option:hover {
1095
- border-color: #ff0000;
1096
  }
1097
  .fl-layout-field-option img {
1098
- max-width: 100%;
1099
  }
1100
 
1101
  /* Link Field */
1102
  .fl-link-field-input {
1103
- width: 244px !important;
1104
  }
1105
  .fl-link-field-search {
1106
- display: none;
1107
- border: 1px solid #dfdfdf;
1108
- border-radius: 3px;
1109
- -moz-border-radius: 3px;
1110
- -webkit-border-radius: 3px;
1111
- margin: 4px 0 0 0;
1112
- padding: 10px;
1113
  }
1114
  .fl-link-field-search-title {
1115
- display: block;
1116
- margin: 0 0 3px 2px;
1117
  }
1118
  .fl-link-field-search-cancel {
1119
- margin-top: 6px;
1120
  }
1121
 
1122
  /* Tooltips */
1123
  .fl-help-tooltip {
1124
- display: inline-block;
1125
- position: relative;
1126
  }
1127
  .fl-help-tooltip-icon {
1128
- color: #999 !important;
1129
- cursor: pointer;
1130
- font-family: FontAwesome;
1131
- font-size: 15px !important;
1132
- padding: 5px;
1133
- vertical-align: middle;
1134
  }
1135
  .fl-help-tooltip-text {
1136
- background: #fff;
1137
- border: 1px solid #ccc;
1138
- box-shadow: 0 0 5px #ccc;
1139
- -moz-box-shadow: 0 0 5px #ccc;
1140
- -webkit-box-shadow: 0 0 5px #ccc;
1141
- display: none;
1142
- font-weight: normal;
1143
- left: 23px;
1144
- padding: 10px 13px;
1145
- position: absolute;
1146
- top: -6px;
1147
- width: 250px;
1148
- z-index: 1000;
1149
  }
1150
 
1151
  /* Multiples */
1152
  .fl-form-field-preview-text .fa {
1153
- font-size: 18px;
1154
- line-height: 22px;
1155
  }
1156
  .fl-builder-field-actions {
1157
- padding-left: 0 !important;
1158
- padding-right: 0 !important;
1159
- text-align: center;
1160
- vertical-align: middle;
1161
- width: 85px;
1162
  }
1163
  .fl-builder-field-actions i {
1164
- color: #999 !important;
1165
- cursor: pointer;
1166
- font-size: 13px !important;
1167
- height: 24px;
1168
- line-height: 29px !important;
1169
- width: 24px;
1170
  }
1171
  .fl-builder-field-actions i:hover {
1172
- color: #000 !important;
1173
  }
1174
  .fl-builder-field-actions i.fl-builder-field-copy,
1175
  .fl-builder-field-actions i.fl-builder-field-delete {
1176
- margin-left: 5px;
1177
  }
1178
  .fl-builder-field-actions i.fl-builder-field-move {
1179
- cursor: move;
1180
  }
1181
  .fl-builder-field-dd-helper {
1182
- background: #ccc;
1183
- height: 30px !important;
1184
- float: left;
1185
- width: 130px !important;
1186
  }
1187
  .fl-builder-field-dd-zone {
1188
- border: 1px dashed #cccccc;
1189
- height: 30px;
1190
  }
1191
  .fl-builder-field-actions-single {
1192
  width: auto;
@@ -1198,130 +1199,130 @@ form.fl-builder-settings {
1198
 
1199
  /* Wordpress Widgets */
1200
  .fl-builder-widget-settings input {
1201
- display: inline-block !important;
1202
- margin: 5px 10px 8px 10px !important;
1203
  }
1204
 
1205
  /* Misc */
1206
  .fl-builder-lightbox-loading {
1207
- background: url(../img/ajax-loader.gif) center center no-repeat;
1208
- height: 100px;
1209
  }
1210
  .fl-builder-settings .error,
1211
  .fl-builder-settings input.error {
1212
- border-color: #d03436;
1213
  }
1214
  .fl-builder-settings label.error,
1215
  .fl-builder-settings p.error {
1216
- color: #d03436;
1217
- display: block;
1218
- margin-top: 5px;
1219
  }
1220
  .fl-builder-settings .fl-form-table .fl-field-description {
1221
- color: #999;
1222
- font-style: normal;
1223
  }
1224
 
1225
  /* Auto Suggest */
1226
  ul.as-selections {
1227
- background-color: #fff;
1228
- border-color: #dfdfdf;
1229
- border-style: solid;
1230
- border-width: 1px;
1231
- border-radius: 3px;
1232
- -moz-border-radius: 3px;
1233
- -webkit-border-radius: 3px;
1234
- box-shadow: none;
1235
- -moz-box-shadow: none;
1236
- -webkit-box-shadow: none;
1237
- color: #333;
1238
- font-size: 12px;
1239
- height: auto;
1240
- line-height: 15px;
1241
- margin: 1px;
1242
- outline: none;
1243
- padding: 3px;
1244
- width: auto;
1245
  }
1246
  ul.as-selections.loading {
1247
- background: url('../img/ajax-loader-small.gif') 98% center no-repeat;
1248
  }
1249
  ul.as-selections li.as-selection-item {
1250
- background: #d4eaf6;
1251
- border: none;
1252
- -webkit-border-radius: 0;
1253
- -moz-border-radius: 0px;
1254
- -ms-border-radius: 0;
1255
- -o-border-radius: 0;
1256
- border-radius: 0;
1257
- font-size: 11px;
1258
- line-height: 14px;
1259
- margin-bottom: 4px;
1260
- padding-bottom: 0;
1261
- padding-top: 0;
1262
  }
1263
  ul.as-selections li.as-selection-item.blur {
1264
- background: #f4f4f4;
1265
  }
1266
  ul.as-selections li.as-selection-item a.as-close {
1267
- line-height: 12px;
1268
  }
1269
  ul.as-selections li.as-original {
1270
- margin: 0;
1271
  }
1272
  ul.as-selections li.as-original input {
1273
- height: auto;
1274
- font-size: 12px;
1275
- margin: 0;
1276
- padding: 0;
1277
  }
1278
  ul.as-list {
1279
- margin: 0;
1280
- font-size: 13px;
1281
- color: #000;
1282
- font-family: Helvetica, Verdana, sans-serif;
1283
- background-color: #fff;
1284
- background-color: rgba(255,255,255,.95);
1285
- z-index: 2;
1286
- -webkit-box-shadow: 0 0 10px rgba(0,0,0,0.1);
1287
- -moz-box-shadow: 0 0 10px rgba(0,0,0,0.1);
1288
- box-shadow: 0 0 10px rgba(0,0,0,0.1);
1289
- -webkit-border-radius: 0;
1290
- -moz-border-radius: 0;
1291
- -ms-border-radius: 0;
1292
- -o-border-radius: 0;
1293
- border-radius: 0;
1294
  }
1295
  ul.as-list {
1296
- border: none;
1297
- border: 1px solid #dfdfdf;
1298
- border-radius: 3px;
1299
- -moz-border-radius: 3px;
1300
- -webkit-border-radius: 3px;
1301
  }
1302
  li.as-result-item, li.as-message {
1303
- border: none;
1304
  }
1305
  li.as-result-item.active {
1306
- background: #e5e5e5;
1307
- -webkit-border-radius: 0;
1308
- -moz-border-radius: 0;
1309
- -ms-border-radius: 0;
1310
- -o-border-radius: 0;
1311
- border-radius: 0;
1312
- color: #333;
1313
- text-shadow: none;
1314
  }
1315
  li.as-result-item em {
1316
- background: none !important;
1317
- color: #333 !important;
1318
- font-size: 12px;
1319
- padding: 0 !important;
1320
  }
1321
 
1322
  /* Loop Builder */
1323
  .fl-loop-builder-filter {
1324
- display: none;
1325
  }
1326
 
1327
  /* Service Fields */
2
  ------------------------------------------------------ */
3
 
4
  html.fl-builder-edit {
5
+ margin-top: 43px !important;
6
  }
7
  .fl-builder-edit body {
8
+ position: static;
9
  }
10
  .fl-builder-edit #wpadminbar {
11
+ display: none;
12
  }
13
  .fl-clear {
14
+ clear: both;
15
  }
16
  .fl-builder-hidden-editor {
17
+ display: none;
18
  }
19
  .fl-builder-loading {
20
+ background: rgba(240, 240, 240, 0.8) url(../img/ajax-loader.gif) center center no-repeat;
21
+ bottom: 0;
22
+ display: none;
23
+ left: 0;
24
+ position: fixed;
25
+ right: 0;
26
+ text-align: center;
27
+ top: 0;
28
+ z-index: 200000;
29
  }
30
  .fl-builder-settings .fl-builder-loading {
31
  background: rgba(255, 255, 255, 0.8) url(../img/ajax-loader.gif) center center no-repeat;
32
+ display: block;
33
+ position: absolute;
34
  }
35
  #tiptip_holder {
36
+ z-index: 200000;
37
  }
38
  .screen-reader-text{
39
+ position: absolute;
40
+ left: -1000em;
41
+ top: -1000em;
42
+ height: 1px;
43
+ width: 1px;
44
+ overflow: hidden;
45
  }
46
 
47
  /* Simple UI
56
  .fl-builder-simple .fl-block-overlay-actions .fl-block-copy,
57
  .fl-builder-simple .fl-block-overlay-actions .fl-block-remove,
58
  .fl-builder-simple .fl-col-highlight {
59
+ display: none !important;
60
  }
61
 
62
  /* Responsive Utilities
67
  .fl-visible-medium,
68
  .fl-visible-medium-mobile,
69
  .fl-visible-mobile {
70
+ display: block;
71
  }
72
 
73
  /* Builder Buttons
74
  ------------------------------------------------------ */
75
 
76
  .fl-builder-button {
77
+ color: #555;
78
+ border-color: #ccc;
79
+ background: #f7f7f7;
80
+ -webkit-box-shadow: inset 0 1px 0 #fff,0 1px 0 rgba(0,0,0,.08);
81
+ box-shadow: inset 0 1px 0 #fff,0 1px 0 rgba(0,0,0,.08);
82
+ vertical-align: top;
83
+ display: inline-block;
84
+ text-decoration: none;
85
+ font-size: 13px !important;
86
+ line-height: 13px !important;
87
+ height: 28px;
88
+ margin: 0;
89
+ padding: 7px 10px;
90
+ cursor: pointer;
91
+ border-width: 1px;
92
+ border-style: solid;
93
+ -webkit-border-radius: 3px;
94
+ -webkit-appearance: none;
95
+ border-radius: 3px;
96
+ white-space: nowrap;
97
+ -webkit-box-sizing: border-box !important;
98
+ -moz-box-sizing: border-box !important;
99
+ box-sizing: border-box !important;
100
  }
101
  .fl-builder-button:hover {
102
+ background: #fafafa;
103
+ border-color: #999;
104
+ color: #222;
105
  }
106
  .fl-builder-button-primary {
107
+ background: #2ea2cc;
108
+ border-color: #0074a2;
109
+ -webkit-box-shadow: inset 0 1px 0 rgba(120,200,230,.5),0 1px 0 rgba(0,0,0,.15);
110
+ box-shadow: inset 0 1px 0 rgba(120,200,230,.5),0 1px 0 rgba(0,0,0,.15);
111
+ color: #fff !important;
112
+ text-decoration: none;
113
  }
114
  .fl-builder-button-primary:hover {
115
+ background: #1e8cbe;
116
+ border-color: #0074a2;
117
+ -webkit-box-shadow: inset 0 1px 0 rgba(120,200,230,.6);
118
+ box-shadow: inset 0 1px 0 rgba(120,200,230,.6);
119
+ color: #fff !important;
120
  }
121
  .fl-builder-button-large {
122
+ height: 30px;
123
+ line-height: 30px !important;
124
+ padding: 0 12px 2px;
125
  }
126
  .fl-builder-button-small {
127
+ font-size: 11px !important;
128
+ line-height: 11px !important;
129
+ height: 24px;
130
  }
131
  .fl-builder-help-button {
132
  color: #b3b3b3;
144
  ------------------------------------------------------ */
145
 
146
  .fl-builder-bar {
147
+ left: 0;
148
+ position: fixed;
149
+ right: 0;
150
+ top: 0;
151
+ z-index: 100008;
152
  }
153
  .fl-builder-bar-content {
154
+ background: #f4f4f4;
155
+ border-bottom: 1px solid #ccc;
156
+ box-shadow: 0 0 8px rgba(0,0,0,0.2);
157
+ -moz-box-shadow: 0 0 8px rgba(0,0,0,0.2);
158
+ -webkit-box-shadow: 0 0 8px rgba(0,0,0,0.2);
159
+ color: #999999;
160
+ font-family: Helvetica, Verdana, sans-serif;
161
+ font-size: 14px;
162
+ height: 43px;
163
  }
164
  .fl-builder-bar-title {
165
+ color: #333;
166
+ display: block;
167
+ float: left;
168
+ font-size: 20px;
169
+ font-weight: 300;
170
+ line-height: 20px;
171
+ padding: 7px 10px;
172
  }
173
  .fl-builder-bar-title img {
174
+ height: 30px !important;
175
+ margin: 0 1px 0 0 !important;
176
+ vertical-align: middle !important;
177
  }
178
  .fl-builder-bar-title span {
179
+ vertical-align: middle;
180
  }
181
  .fl-builder-bar-title.fl-builder-bar-title-no-icon {
182
+ padding: 12px;
183
  }
184
  .fl-builder-bar-actions {
185
+ float: right;
186
+ padding: 7px;
187
  }
188
  .fl-builder-bar .fl-builder-button {
189
+ float: right;
190
+ margin: 0 0 0 6px;
191
  }
192
  .fl-builder-bar .fl-builder-add-content-button {
193
+ display: none;
194
  }
195
 
196
  /* Upgrade button */
197
  .fl-builder-upgrade-button {
198
+ background: #f7951e;
199
+ border-color: #de7c04;
200
+ -webkit-box-shadow: inset 0 1px 0 rgba(255,177,82,.5),0 1px 0 rgba(0,0,0,.15);
201
+ box-shadow: inset 0 1px 0 rgba(255,177,82,.5),0 1px 0 rgba(0,0,0,.15);
202
+ color: #fff !important;
203
+ text-decoration: none;
204
  }
205
  .fl-builder-upgrade-button:hover {
206
+ background: #de861b;
207
+ border-color: #c46e04;
208
+ -webkit-box-shadow: inset 0 1px 0 rgba(255,177,82,.5),0 1px 0 rgba(0,0,0,.15);
209
+ box-shadow: inset 0 1px 0 rgba(255,177,82,.5),0 1px 0 rgba(0,0,0,.15);
210
+ color: #fff !important;
211
  }
212
 
213
  /* Builder Panel
214
  ------------------------------------------------------ */
215
 
216
  .fl-builder-panel {
217
+ background: #f0f0f0;
218
+ border-left: 1px solid #ccc;
219
+ bottom: 0;
220
+ box-shadow: 0 0 8px rgba(0,0,0,0.2);
221
+ -moz-box-shadow: 0 0 8px rgba(0,0,0,0.2);
222
+ -webkit-box-shadow: 0 0 8px rgba(0,0,0,0.2);
223
+ color: #999999;
224
+ font-family: Helvetica, Verdana, sans-serif;
225
+ font-size: 14px;
226
+ opacity: 1;
227
+ position: fixed;
228
+ right: 0;
229
+ top: 43px;
230
+ width: 300px;
231
+ z-index: 100007;
232
+ -webkit-transform: translateZ(0);
233
+ transition: opacity 0.2s;
234
+ -webkit-transition: opacity 0.2s;
235
+ -moz-transition: opacity 0.2s;
236
+ -o-transition: opacity 0.2s;
237
+ -ms-transition: opacity 0.2s;
238
+ -webkit-touch-callout: none;
239
+ -webkit-user-select: none;
240
+ -khtml-user-select: none;
241
+ -moz-user-select: none;
242
+ -ms-user-select: none;
243
+ user-select: none;
244
  }
245
 
246
  /* Builder Panel Actions
247
  ------------------------------------------------------ */
248
 
249
  .fl-builder-panel-actions {
250
+ background: #f4f4f4;
251
+ border-bottom: 1px solid #dbdbdb;
252
+ height: 43px;
253
+ left: 0;
254
+ position: absolute;
255
+ right: 0;
256
+ top: 0;
257
+ text-align: right;
258
+ z-index: 100009;
259
  }
260
  .fl-builder-panel-actions .fl-builder-panel-close {
261
+ color: #bfbfbf;
262
+ cursor: pointer;
263
+ float: left;
264
+ font-size: 18px;
265
+ margin: 12px 18px;
266
  }
267
  .fl-builder-panel-actions .fl-builder-panel-close:hover {
268
+ color: #333;
269
  }
270
 
271
  /* Builder Panel Content
272
  ------------------------------------------------------ */
273
 
274
  .fl-builder-panel-content-wrap {
275
+ bottom: 0;
276
+ height: auto;
277
+ left: 0;
278
+ overflow: hidden;
279
+ position: absolute;
280
+ right: 0;
281
+ top: 43px;
282
  }
283
  .fl-builder-panel-content {
284
+ padding-bottom: 60px;
285
  }
286
  .fl-builder-blocks-section span {
287
+ cursor: pointer;
288
+ display: block;
289
+ line-height: 14px;
290
+ padding: 15px 20px;
291
  }
292
  .fl-builder-blocks-section > span {
293
+ border-top: 1px solid #fff;
294
+ border-bottom: 1px solid #dfdfdf;
295
+ color: #333;
296
+ font-weight: normal;
297
  }
298
  .fl-builder-blocks-section > span i {
299
+ color: #bfbfbf;
300
+ float: right;
301
  }
302
  .fl-builder-blocks-section > span:hover,
303
  .fl-builder-blocks-section > span:hover i {
304
+ background: #e5e5e5;
305
  }
306
  .fl-builder-blocks-section-content {
307
+ background: #fff;
308
+ display: none;
309
  }
310
  .fl-builder-blocks-section.fl-active .fl-builder-blocks-section-content {
311
+ display: block;
312
  }
313
  .fl-builder-blocks-section-content span {
314
+ border-bottom: 1px solid #ebebeb;
315
+ overflow: hidden;
316
+ text-overflow: ellipsis;
317
+ white-space: nowrap;
318
  }
319
  .fl-builder-blocks-section-content span i {
320
+ color: #d9d9d9;
321
+ margin-right: 10px;
322
  }
323
  .fl-builder-blocks-section-content span:hover {
324
+ background: #0074a1;
325
+ color: #fff;
326
+ cursor: move;
327
  }
328
 
329
  /* Drag and Drop
330
  ------------------------------------------------------ */
331
 
332
  .fl-builder-empty {
333
+ border: 1px dashed #3ba0ff;
334
+ color: #3ba0ff;
335
+ font-family: Helvetica, Verdana, sans-serif !important;
336
+ font-size: 14px;
337
+ margin: 10px;
338
+ padding: 100px 20px;
339
+ text-align: center;
340
+ text-transform: uppercase;
341
  }
342
  .fl-builder-empty .fl-builder-drop-zone {
343
+ margin: 10px;
344
  }
345
  .fl-builder-block.ui-draggable-dragging,
346
  .fl-builder-block-drag-helper {
347
+ background: #fff !important;
348
+ border: 1px solid #ccc;
349
+ box-shadow: 0 0 8px rgba(0,0,0,0.2);
350
+ -moz-box-shadow: 0 0 8px rgba(0,0,0,0.2);
351
+ -webkit-box-shadow: 0 0 8px rgba(0,0,0,0.2);
352
+ color: #999999 !important;
353
+ font-family: Helvetica, Verdana, sans-serif !important;
354
+ font-size: 14px !important;
355
+ height: 45px !important;
356
+ line-height: 42px !important;
357
+ overflow: hidden;
358
+ padding: 0 18px;
359
+ position: fixed !important;
360
+ text-overflow: ellipsis;
361
+ white-space: nowrap;
362
+ width: 140px !important;
363
+ z-index: 100010;
364
  }
365
  .fl-builder-drop-zone {
366
+ background: #3ba0ff;
367
+ color: #fff;
368
+ display: block;
369
+ font-family: Helvetica, Verdana, sans-serif !important;
370
+ font-weight: bold;
371
+ font-size: 14px;
372
+ margin: 10px;
373
+ padding: 10px;
374
+ text-shadow: none;
375
  }
376
  .fl-builder-content > .fl-builder-drop-zone {
377
+ margin: 10px 20px;
378
  }
379
  .fl-row-content > .fl-builder-drop-zone {
380
+ margin: 5px;
381
  }
382
  .fl-row-highlight {
383
+ padding: 5px 0;
384
  }
385
  .fl-row-highlight .fl-row-content {
386
+ border: 1px dashed #ff0000;
387
+ padding: 5px;
388
  }
389
  .fl-col-highlight {
390
+ padding: 15px 5px;
391
  }
392
  .fl-col-highlight .fl-col-content {
393
+ border-style: dashed;
394
+ border-color: #3ba0ff;
395
+ border-top-width: 1px;
396
+ border-bottom-width: 1px;
397
+ border-left-width: 1px;
398
+ border-right-width: 1px;
399
+ min-height: 100px;
400
  }
401
 
402
  /* Action Overlays
404
 
405
  .fl-block-overlay,
406
  .fl-block-overlay * {
407
+ text-shadow: none;
408
  }
409
  .fl-block-overlay-active {
410
+ position: relative;
411
  }
412
  .fl-block-overlay-actions {
413
+ background: #3ba0ff;
414
+ float: left;
415
+ text-shadow: none;
416
  }
417
  .fl-block-overlay-actions i {
418
+ color: #fff !important;
419
+ cursor: pointer;
420
+ display: inline-block !important;
421
+ font-size: 16px !important;
422
+ height: 30px !important;
423
+ font-weight: 100 !important;
424
+ line-height: 30px !important;
425
+ opacity: 0.8;
426
+ filter: alpha(opacity = 80);
427
+ text-align: center;
428
+ vertical-align: middle;
429
+ width: 36px !important;
430
  }
431
  .fl-block-overlay-actions i:hover {
432
+ opacity: 1;
433
+ filter: alpha(opacity = 100);
434
  }
435
  .fl-block-overlay-actions i.fl-block-move {
436
+ cursor: move;
437
  }
438
  .fl-block-overlay-title {
439
+ border-right: 1px solid #5eb1ff;
440
+ color: #fff !important;
441
+ float: left;
442
+ font-family: Helvetica, Verdana, sans-serif;
443
+ font-size: 13px;
444
+ height: 30px;
445
+ line-height: 29px;
446
+ margin-right: 4px;
447
+ padding: 0 10px;
448
  }
449
 
450
  /* Rows */
451
  .fl-row-overlay {
452
+ background: rgba(59, 160, 255, 0.15);
453
+ border: 1px solid #3ba0ff;
454
+ bottom: 0;
455
+ box-sizing: border-box !important;
456
+ -moz-box-sizing: border-box !important;
457
+ -webkit-box-sizing: border-box !important;
458
+ color: #fff;
459
+ left: 0;
460
+ position: absolute;
461
+ top: -30px;
462
+ width: 100%;
463
+ z-index: 100006;
464
  }
465
  .fl-row-overlay-header-bottom {
466
  bottom: -30px;
474
  position: relative;
475
  }
476
  .fl-block-overlay-active .fl-row-content {
477
+ position: relative;
478
+ z-index: 100007;
479
  }
480
 
481
  /* Columns */
482
  .fl-col-overlay {
483
+ background: rgba(59, 160, 255, 0.15);
484
+ border: 1px solid #3ba0ff;
485
+ bottom: 15px;
486
+ cursor: pointer;
487
+ color: #fff;
488
+ left: 5px;
489
+ position: absolute;
490
+ right: 5px;
491
+ top: 15px;
492
+ z-index: 100007;
493
  }
494
 
495
  /* Modules */
496
  .fl-module-overlay {
497
+ background: rgba(59, 160, 255, 0.15);
498
+ border: 1px solid #3ba0ff;
499
+ bottom: 4px;
500
+ cursor: pointer;
501
+ color: #fff;
502
+ left: 4px;
503
+ min-height: 32px;
504
+ position: absolute;
505
+ right: 4px;
506
+ top: 4px;
507
+ z-index: 100007;
508
  }
509
  .fl-module-adjust-height {
510
+ padding-bottom: 15px;
511
+ padding-top: 15px;
512
  }
513
 
514
  /* Muted */
515
  .fl-block-overlay-muted .fl-row-overlay {
516
+ background: rgba(153, 153, 153, 0.1);
517
+ border: 1px solid #8c8c8c;
518
  }
519
  .fl-block-overlay-muted .fl-row-overlay .fl-block-overlay-actions {
520
+ background: #8c8c8c;
521
  }
522
  .fl-block-overlay-muted .fl-row-overlay .fl-block-overlay-title {
523
+ border-right: 1px solid #a6a6a6;
524
  }
525
 
526
  /* Actions Lightbox
527
  ------------------------------------------------------ */
528
 
529
  .fl-builder-actions-lightbox .fl-lightbox {
530
+ width: 300px;
531
  }
532
  .fl-builder-actions-lightbox .fl-builder-actions {
533
+ display: block;
534
+ padding: 25px;
535
+ text-align: center;
536
  }
537
  .fl-builder-actions-title {
538
+ color: #333 !important;
539
+ display: block;
540
+ font-family: Helvetica, Verdana, sans-serif !important;
541
+ font-size: 16px !important;
542
+ margin-bottom: 20px;
543
  }
544
  .fl-builder-actions .fl-builder-button {
545
+ display: block;
546
+ margin-bottom: 7px;
547
  }
548
 
549
  /* Alert Lightbox
550
  ------------------------------------------------------ */
551
 
552
  .fl-builder-alert-lightbox .fl-lightbox {
553
+ width: 440px !important;
554
  }
555
  .fl-builder-alert-lightbox .fl-lightbox-message {
556
+ color: #333 !important;
557
+ font-family: Helvetica, Verdana, sans-serif !important;
558
+ font-size: 16px !important;
559
+ line-height: 24px;
560
+ padding: 30px;
561
  }
562
 
563
  /* Template Selector
564
  ------------------------------------------------------ */
565
 
566
  .fl-user-templates {
567
+ border-top: 1px solid #dfdfdf;
568
+ margin-bottom: 20px;
569
+ margin-right: 8px;
570
  }
571
  .fl-user-template {
572
+ border-bottom: 1px solid #dfdfdf;
573
+ padding: 15px;
574
+ position: relative;
575
  }
576
  .fl-user-template:hover {
577
+ background: #0074a1;
578
+ color: #fff !important;
579
+ cursor: pointer;
580
  }
581
  .fl-user-template:hover * {
582
+ color: #fff !important;
583
  }
584
  .fl-user-template-actions {
585
+ bottom: 0;
586
+ position: absolute;
587
+ right: 0;
588
+ top: 0;
589
  }
590
  .fl-user-template-actions a {
591
+ color: #bfbfbf !important;
592
+ display: inline-block;
593
+ padding: 15px;
594
  }
595
  .fl-user-template:hover a {
596
+ color: #99c7d9 !important;
597
  }
598
  .fl-user-template:hover a:hover {
599
+ color: #fff !important;
600
  }
601
  .fl-user-templates-message {
602
+ display: none;
603
  }
604
  .fl-template-selector .fl-builder-settings-tab-description {
605
+ font-size: 15px!important;
606
+ margin: 0 !important;
607
+ padding: 10px 0 25px;
608
+ text-align: center;
609
  }
610
  .fl-template-preview {
611
+ float: left;
612
+ margin: 0 20px 30px 0;
613
+ position: relative;
614
+ text-align: center;
615
+ width: 170px;
616
  }
617
  .fl-template-preview.fl-last {
618
+ margin-right: 0;
619
  }
620
  .fl-template-image {
621
+ border: 1px solid #d9d9d9;
622
+ cursor: pointer;
623
+ margin-bottom: 12px;
624
+ height: 164px;
625
+ overflow: hidden;
626
  }
627
  .fl-template-image:hover {
628
+ border-color: #ff0000;
629
  }
630
  .fl-template-image img {
631
+ max-height: none;
632
+ width: 100%;
633
  }
634
  .fl-template-preview span {
635
+ display: block;
636
+ text-align: center;
637
  }
638
 
639
  /* User Template Settings
640
  ------------------------------------------------------ */
641
 
642
  .fl-builder-user-template-settings .fl-builder-settings-fields {
643
+ height: 150px;
644
  }
645
 
646
  /* Settings
647
  ------------------------------------------------------ */
648
 
649
  .fl-builder-lightbox .fl-lightbox {
650
+ width: 600px;
651
  }
652
  form.fl-builder-settings {
653
+ margin: 0;
654
+ padding: 0;
655
  }
656
  .fl-builder-settings-message {
657
+ font-size: 15px !important;
658
+ line-height: 23px !important;
659
+ padding: 20px 25px !important;
660
+ background: #f2f2f2 !important;
661
  }
662
  .fl-builder-preview-loader {
663
+ position: relative;
664
+ top: -1px;
665
+ margin-left: 3px;
666
  }
667
  .fl-lightbox-header .fl-builder-preview-loader {
668
+ margin: 0;
669
+ position: absolute;
670
+ right: 15px;
671
+ top: 15px;
672
  }
673
 
674
  /* Settings Tabs
675
  ------------------------------------------------------ */
676
 
677
  .fl-builder-settings-tabs {
678
+ background: #f5f5f5;
679
+ border-bottom: 1px solid #dfdfdf;
680
+ padding: 15px 20px 0 20px;
681
  }
682
  .fl-builder-settings-tabs a {
683
+ color: #999;
684
+ display: inline-block;
685
+ padding: 10px 20px;
686
+ text-decoration: none;
687
  }
688
  .fl-builder-settings-tabs a:hover {
689
+ color: #333;
690
  }
691
  .fl-builder-settings-tabs a.fl-active {
692
+ background: #fff;
693
+ border: 1px solid #dfdfdf;
694
+ border-bottom: none;
695
+ color: #222;
696
+ position: relative;
697
+ top: 1px;
698
  }
699
  .fl-builder-settings-tabs a.error {
700
+ color: #d03436;
701
+ padding-right: 10px;
702
  }
703
  .fl-builder-settings-tabs a.error .fl-error-icon {
704
+ background: url('../img/sprite.png') -148px -5px no-repeat;
705
+ display: inline-block;
706
+ height: 16px;
707
+ margin-left: 7px;
708
+ position: relative;
709
+ top: 3px;
710
+ width: 16px;
711
  }
712
  .fl-builder-settings-tab {
713
+ display: none;
714
+ width: 550px;
715
  }
716
  .fl-builder-settings-tab.fl-active {
717
+ display: block;
718
  }
719
  .fl-builder-settings-tab-description {
720
+ padding: 0 10px 15px 10px;
721
  }
722
 
723
  /* Settings Tables
724
  ------------------------------------------------------ */
725
 
726
  .fl-form-table {
727
+ border: none;
728
+ width: 100%;
729
  }
730
  .fl-form-table th {
731
+ border: none !important;
732
+ background: #fff !important;
733
+ font-weight: normal !important;
734
+ padding: 10px !important;
735
+ text-align: left !important;
736
+ vertical-align: top !important;
737
+ width: 200px !important;
738
  }
739
  .fl-form-table td {
740
+ border: none;
741
+ padding: 8px 10px;
742
  }
743
 
744
  /* Settings Fields
745
  ------------------------------------------------------ */
746
 
747
  .fl-builder-settings-fields {
748
+ height: 410px;
749
+ margin: 5px 0 0 0;
750
+ overflow: hidden;
751
+ position: relative;
752
  }
753
  .fl-builder-settings-fields .fl-nanoscroller-content {
754
+ padding: 15px 20px 20px 20px;
755
  }
756
  .fl-builder-settings-fields textarea,
757
  .fl-builder-settings-fields input[type=text],
763
  .fl-builder-settings-fields input[type=tel],
764
  .fl-builder-settings-fields input[type=url],
765
  .fl-builder-settings-fields select {
766
+ background-color: #fff;
767
+ border-color: #dfdfdf;
768
+ border-style: solid;
769
+ border-width: 1px;
770
+ border-radius: 3px;
771
+ -moz-border-radius: 3px;
772
+ -webkit-border-radius: 3px;
773
+ box-shadow: none;
774
+ -moz-box-shadow: none;
775
+ -webkit-box-shadow: none;
776
+ color: #333;
777
+ display: inline;
778
+ font-size: 12px;
779
+ height: auto;
780
+ line-height: 15px;
781
+ margin: 1px;
782
+ outline: none;
783
+ padding: 3px;
784
+ width: auto;
785
  }
786
  .fl-builder-settings-fields textarea:focus,
787
  .fl-builder-settings-fields input[type=text]:focus,
793
  .fl-builder-settings-fields input[type=tel]:focus,
794
  .fl-builder-settings-fields input[type=url]:focus,
795
  .fl-builder-settings-fields select:focus {
796
+ background: transparent;
797
+ border-color: #aaa;
798
  }
799
  .fl-builder-settings-fields ::-webkit-input-placeholder { /* WebKit browsers */
800
+ color: #999 !important;
801
  }
802
  .fl-builder-settings-fields input:-moz-placeholder { /* Mozilla Firefox 4 to 18 */
803
+ color: #999;
804
  }
805
  .fl-builder-settings-fields ::-moz-placeholder { /* Mozilla Firefox 19+ */
806
+ color: #999 !important;
807
  }
808
  .fl-builder-settings-fields input:-ms-input-placeholder { /* Internet Explorer 10+ */
809
+ color: #999;
810
  }
811
  .fl-builder-settings-fields label {
812
+ font-weight: normal;
813
  }
814
  .fl-builder-settings-fields select {
815
+ height: 2em;
816
+ color: #000;
817
+ padding: 2px;
818
  }
819
  .fl-builder-settings-description {
820
+ border-bottom: 1px solid #dfdfdf;
821
+ margin: 0 0 10px 0;
822
+ padding-bottom: 10px !important;
823
  }
824
  .fl-builder-settings-fields table {
825
+ margin: 0;
826
  }
827
  .fl-builder-settings-fields h3.fl-builder-settings-title {
828
+ border-bottom: 1px solid #dfdfdf;
829
+ color: #333;
830
+ font-size: 14px;
831
+ font-weight: bold;
832
+ margin: 0 0 20px !important;
833
+ padding: 10px;
834
  }
835
  .fl-builder-settings-section {
836
+ margin-bottom: 15px;
837
  }
838
 
839
  /* Text Field */
840
  .fl-builder-settings-fields input.text-full {
841
+ width: 97%;
842
  }
843
 
844
  /* Textarea */
845
  .fl-builder-settings-fields textarea {
846
+ width: 97%;
847
  }
848
 
849
  /* Color Picker */
850
  .fl-color-picker {
851
+ cursor: pointer;
852
  height: 30px;
853
  width: 48px;
854
  }
855
  .fl-color-picker.fl-color-picker-empty .fl-color-picker-color {
856
+ background: url(../img/sprite.png) 0 -24px no-repeat;
857
  }
858
  .fl-color-picker .fl-color-picker-color {
859
+ border: 1px solid #ccc;
860
+ float: left;
861
  height: 30px;
862
  width: 30px;
863
  }
864
  .fl-color-picker.fl-color-picker-empty .fl-color-picker-clear {
865
+ display: none;
866
  }
867
  .fl-color-picker .fl-color-picker-clear {
868
+ background: url(../img/sprite.png) -124px 2px no-repeat;
869
+ border: 1px solid #ccc;
870
+ border-left: none;
871
+ float: left;
872
  height: 30px;
873
  width: 15px;
874
  }
875
  .fl-color-picker .fl-color-picker-clear:hover {
876
+ background-color: #ededed;
877
  }
878
  .colorpicker input {
879
  padding: 0 !important;
885
  border: none !important;
886
  }
887
  .colorpicker .colorpicker_hex input {
888
+ width: 45px !important;
889
  }
890
 
891
  /* Custom Fields */
892
  .fl-builder-custom-field {
893
+ border: 1px solid #dfdfdf;
894
+ border-radius: 3px;
895
+ padding: 5px 10px;
896
  }
897
  .fl-builder-custom-field a {
898
+ color: #21759b !important;
899
+ text-decoration: underline !important;
900
  }
901
  .fl-builder-custom-field a:hover {
902
+ color: #d54e21 !important;
903
  }
904
  .fl-builder-custom-field label.error {
905
+ margin-top: 5px;
906
  }
907
 
908
  /* Photo Fields */
909
  .fl-photo-field .fl-photo-select,
910
  .fl-photo-field.fl-photo-empty .fl-photo-preview {
911
+ display: none;
912
  }
913
  .fl-photo-field.fl-photo-empty .fl-photo-select {
914
+ display: block;
915
  }
916
  .fl-photo-field .fl-photo-preview-img {
917
+ float: left;
918
+ line-height: 0;
919
+ margin: 5px 0;
920
  }
921
  .fl-photo-field .fl-photo-preview-img img {
922
+ max-width: 60px;
923
  }
924
  .fl-photo-field .fl-photo-preview select {
925
+ margin: 8px 0 8px 10px;
926
+ width: 200px;
927
  }
928
  .fl-photo-field .fl-photo-edit {
929
+ margin: 0 0 0 11px;
930
  }
931
  .fl-photo-field .fl-photo-replace {
932
+ margin: 0 0 0 8px;
933
  }
934
 
935
  /* Media Uploader */
936
  .fl-builder-edit .media-modal-content .thumbnail {
937
+ padding: 0;
938
+ border: none;
939
+ border-radius: 0;
940
  }
941
 
942
  /* Multiple Photo Fields */
943
  .fl-multiple-photos-lightbox .gallery-settings,
944
  .fl-multiple-photos-field .fl-multiple-photos-select {
945
+ display: none;
946
  }
947
  .fl-multiple-photos-field.fl-multiple-photos-empty .fl-multiple-photos-count,
948
  .fl-multiple-photos-field.fl-multiple-photos-empty .fl-multiple-photos-edit,
949
  .fl-multiple-photos-field.fl-multiple-photos-empty .fl-multiple-photos-add {
950
+ display: none;
951
  }
952
  .fl-multiple-photos-field .fl-multiple-photos-add {
953
+ margin: 0 0 0 8px;
954
  }
955
  .fl-multiple-photos-field.fl-multiple-photos-empty .fl-multiple-photos-select {
956
+ display: inline;
957
  }
958
  .fl-multiple-photos-count {
959
+ font-weight: bold;
960
+ margin-bottom: 3px;
961
  }
962
 
963
  /* Video Fields */
964
  .fl-video-field .fl-video-select,
965
  .fl-video-field.fl-video-empty .fl-video-preview {
966
+ display: none;
967
  }
968
  .fl-video-field.fl-video-empty .fl-video-select {
969
+ display: block;
970
  }
971
  .fl-video-field .fl-video-preview-img {
972
+ float: left;
973
+ line-height: 0;
974
+ margin: 5px 0;
975
  }
976
  .fl-video-field .fl-video-preview-img img {
977
+ max-width: 60px;
978
  }
979
  .fl-video-field .fl-video-preview-filename {
980
+ display: inline-block;
981
+ font-size: 14px;
982
+ font-weight: bold;
983
+ margin: 7px 0 0 11px;
984
  }
985
  .fl-video-field .fl-video-replace {
986
+ margin: 0 0 0 11px;
987
  }
988
 
989
  /* Icon Fields */
990
  .fl-icon-field .fl-icon-select,
991
  .fl-icon-field.fl-icon-empty .fl-icon-preview {
992
+ display: none;
993
  }
994
  .fl-icon-field.fl-icon-empty .fl-icon-select {
995
+ display: block;
996
  }
997
  .fl-icon-field .fl-icon-preview i {
998
+ display: inline-block;
999
+ font-size: 28px;
1000
+ margin: 10px 10px 9px 2px;
1001
+ vertical-align: middle;
1002
  }
1003
  .fl-icon-field .fl-icon-remove {
1004
+ margin: 0 0 0 8px;
1005
  }
1006
 
1007
  /* Text Editors */
1012
  color: #333;
1013
  }
1014
  .fl-builder-settings .wp-editor-container {
1015
+ border: 1px solid #e5e5e5;
1016
  }
1017
  .fl-builder-settings .mce-toolbar .mce-btn-group .mce-btn {
1018
+ margin: 2px 0;
1019
  }
1020
  .mce-close:hover,
1021
  .mce-close:active,
1023
  .mce-window .mce-btn button:active,
1024
  .mce-toolbar .mce-btn button:hover,
1025
  .mce-toolbar .mce-btn button:active {
1026
+ background: transparent;
1027
+ border: none;
1028
  }
1029
  .mce-ico {
1030
+ font-family: tinymce, Arial !important;
1031
  }
1032
  .mce-toolbar i.mce-ico {
1033
+ font: 400 20px/1 dashicons !important;
1034
  }
1035
  .wp-core-ui .quicktags-toolbar input.button.button-small {
1036
+ margin: 1px !important;
1037
  }
1038
  .wp-editor-container textarea.wp-editor-area {
1039
+ background: transparent;
1040
+ border: none;
1041
+ padding: 10px;
1042
+ box-sizing: border-box;
1043
+ -moz-box-sizing: border-box;
1044
+ -webkit-box-sizing: border-box;
1045
  }
1046
 
1047
  /* Editor Link Modal */
1048
  .fl-builder form#wp-link {
1049
+ color: #000;
1050
+ font-family: Helvetica, Verdana, sans-serif;
1051
+ font-size: 13px;
1052
  }
1053
  .fl-builder form#wp-link #link-options label {
1054
+ display: block;
1055
+ margin-bottom: 2px;
1056
  }
1057
  .fl-builder form#wp-link #link-options label span {
1058
+ padding-right: 10px;
1059
+ width: 60px;
1060
+ vertical-align: middle;
1061
  }
1062
  .fl-builder form#wp-link #link-options input[type="text"] {
1063
+ display: inline-block;
1064
+ height: auto;
1065
+ margin: 5px 0 0;
1066
+ padding: 3px 5px;
1067
+ width: 80%;
1068
  }
1069
 
1070
  /* Code Editors */
1071
  .ace_editor, .ace_editor * {
1072
+ font-family: "Monaco", "Menlo", "Ubuntu Mono", "Droid Sans Mono", "Consolas", monospace !important;
1073
+ font-size: 12px !important;
1074
+ font-weight: 400 !important;
1075
+ letter-spacing: 0 !important;
1076
  }
1077
 
1078
  /* Layout Fields */
1079
  .fl-layout-field-option {
1080
+ border: 2px solid #d9d9d9;
1081
+ border-radius: 3px;
1082
+ -moz-border-radius: 3px;
1083
+ -webkit-border-radius: 3px;
1084
+ box-sizing: border-box !important;
1085
+ -moz-box-sizing: border-box !important;
1086
+ -webkit-box-sizing: border-box !important;
1087
+ cursor: pointer;
1088
+ float: left;
1089
+ line-height: 0;
1090
+ max-width: 23%;
1091
+ margin: 0 1% 2%;
1092
+ padding: 5px;
1093
  }
1094
  .fl-layout-field-option-selected,
1095
  .fl-layout-field-option:hover {
1096
+ border-color: #ff0000;
1097
  }
1098
  .fl-layout-field-option img {
1099
+ max-width: 100%;
1100
  }
1101
 
1102
  /* Link Field */
1103
  .fl-link-field-input {
1104
+ width: 244px !important;
1105
  }
1106
  .fl-link-field-search {
1107
+ display: none;
1108
+ border: 1px solid #dfdfdf;
1109
+ border-radius: 3px;
1110
+ -moz-border-radius: 3px;
1111
+ -webkit-border-radius: 3px;
1112
+ margin: 4px 0 0 0;
1113
+ padding: 10px;
1114
  }
1115
  .fl-link-field-search-title {
1116
+ display: block;
1117
+ margin: 0 0 3px 2px;
1118
  }
1119
  .fl-link-field-search-cancel {
1120
+ margin-top: 6px;
1121
  }
1122
 
1123
  /* Tooltips */
1124
  .fl-help-tooltip {
1125
+ display: inline-block;
1126
+ position: relative;
1127
  }
1128
  .fl-help-tooltip-icon {
1129
+ color: #999 !important;
1130
+ cursor: pointer;
1131
+ font-family: FontAwesome;
1132
+ font-size: 15px !important;
1133
+ padding: 5px;
1134
+ vertical-align: middle;
1135
  }
1136
  .fl-help-tooltip-text {
1137
+ background: #fff;
1138
+ border: 1px solid #ccc;
1139
+ box-shadow: 0 0 5px #ccc;
1140
+ -moz-box-shadow: 0 0 5px #ccc;
1141
+ -webkit-box-shadow: 0 0 5px #ccc;
1142
+ display: none;
1143
+ font-weight: normal;
1144
+ left: 23px;
1145
+ padding: 10px 13px;
1146
+ position: absolute;
1147
+ top: -6px;
1148
+ width: 250px;
1149
+ z-index: 1000;
1150
  }
1151
 
1152
  /* Multiples */
1153
  .fl-form-field-preview-text .fa {
1154
+ font-size: 18px;
1155
+ line-height: 22px;
1156
  }
1157
  .fl-builder-field-actions {
1158
+ padding-left: 0 !important;
1159
+ padding-right: 0 !important;
1160
+ text-align: center;
1161
+ vertical-align: middle;
1162
+ width: 85px;
1163
  }
1164
  .fl-builder-field-actions i {
1165
+ color: #999 !important;
1166
+ cursor: pointer;
1167
+ font-size: 13px !important;
1168
+ height: 24px;
1169
+ line-height: 29px !important;
1170
+ width: 24px;
1171
  }
1172
  .fl-builder-field-actions i:hover {
1173
+ color: #000 !important;
1174
  }
1175
  .fl-builder-field-actions i.fl-builder-field-copy,
1176
  .fl-builder-field-actions i.fl-builder-field-delete {
1177
+ margin-left: 5px;
1178
  }
1179
  .fl-builder-field-actions i.fl-builder-field-move {
1180
+ cursor: move;
1181
  }
1182
  .fl-builder-field-dd-helper {
1183
+ background: #ccc;
1184
+ height: 30px !important;
1185
+ float: left;
1186
+ width: 130px !important;
1187
  }
1188
  .fl-builder-field-dd-zone {
1189
+ border: 1px dashed #cccccc;
1190
+ height: 30px;
1191
  }
1192
  .fl-builder-field-actions-single {
1193
  width: auto;
1199
 
1200
  /* Wordpress Widgets */
1201
  .fl-builder-widget-settings input {
1202
+ display: inline-block !important;
1203
+ margin: 5px 10px 8px 10px !important;
1204
  }
1205
 
1206
  /* Misc */
1207
  .fl-builder-lightbox-loading {
1208
+ background: url(../img/ajax-loader.gif) center center no-repeat;
1209
+ height: 100px;
1210
  }
1211
  .fl-builder-settings .error,
1212
  .fl-builder-settings input.error {
1213
+ border-color: #d03436;
1214
  }
1215
  .fl-builder-settings label.error,
1216
  .fl-builder-settings p.error {
1217
+ color: #d03436;
1218
+ display: block;
1219
+ margin-top: 5px;
1220
  }
1221
  .fl-builder-settings .fl-form-table .fl-field-description {
1222
+ color: #999;
1223
+ font-style: normal;
1224
  }
1225
 
1226
  /* Auto Suggest */
1227
  ul.as-selections {
1228
+ background-color: #fff;
1229
+ border-color: #dfdfdf;
1230
+ border-style: solid;
1231
+ border-width: 1px;
1232
+ border-radius: 3px;
1233
+ -moz-border-radius: 3px;
1234
+ -webkit-border-radius: 3px;
1235
+ box-shadow: none;
1236
+ -moz-box-shadow: none;
1237
+ -webkit-box-shadow: none;
1238
+ color: #333;
1239
+ font-size: 12px;
1240
+ height: auto;
1241
+ line-height: 15px;
1242
+ margin: 1px;
1243
+ outline: none;
1244
+ padding: 3px;
1245
+ width: auto;
1246
  }
1247
  ul.as-selections.loading {
1248
+ background: url('../img/ajax-loader-small.gif') 98% center no-repeat;
1249
  }
1250
  ul.as-selections li.as-selection-item {
1251
+ background: #d4eaf6;
1252
+ border: none;
1253
+ -webkit-border-radius: 0;
1254
+ -moz-border-radius: 0px;
1255
+ -ms-border-radius: 0;
1256
+ -o-border-radius: 0;
1257
+ border-radius: 0;
1258
+ font-size: 11px;
1259
+ line-height: 14px;
1260
+ margin-bottom: 4px;
1261
+ padding-bottom: 0;
1262
+ padding-top: 0;
1263
  }
1264
  ul.as-selections li.as-selection-item.blur {
1265
+ background: #f4f4f4;
1266
  }
1267
  ul.as-selections li.as-selection-item a.as-close {
1268
+ line-height: 12px;
1269
  }
1270
  ul.as-selections li.as-original {
1271
+ margin: 0;
1272
  }
1273
  ul.as-selections li.as-original input {
1274
+ height: auto;
1275
+ font-size: 12px;
1276
+ margin: 0;
1277
+ padding: 0;
1278
  }
1279
  ul.as-list {
1280
+ margin: 0;
1281
+ font-size: 13px;
1282
+ color: #000;
1283
+ font-family: Helvetica, Verdana, sans-serif;
1284
+ background-color: #fff;
1285
+ background-color: rgba(255,255,255,.95);
1286
+ z-index: 2;
1287
+ -webkit-box-shadow: 0 0 10px rgba(0,0,0,0.1);
1288
+ -moz-box-shadow: 0 0 10px rgba(0,0,0,0.1);
1289
+ box-shadow: 0 0 10px rgba(0,0,0,0.1);
1290
+ -webkit-border-radius: 0;
1291
+ -moz-border-radius: 0;
1292
+ -ms-border-radius: 0;
1293
+ -o-border-radius: 0;
1294
+ border-radius: 0;
1295
  }
1296
  ul.as-list {
1297
+ border: none;
1298
+ border: 1px solid #dfdfdf;
1299
+ border-radius: 3px;
1300
+ -moz-border-radius: 3px;
1301
+ -webkit-border-radius: 3px;
1302
  }
1303
  li.as-result-item, li.as-message {
1304
+ border: none;
1305
  }
1306
  li.as-result-item.active {
1307
+ background: #e5e5e5;
1308
+ -webkit-border-radius: 0;
1309
+ -moz-border-radius: 0;
1310
+ -ms-border-radius: 0;
1311
+ -o-border-radius: 0;
1312
+ border-radius: 0;
1313
+ color: #333;
1314
+ text-shadow: none;
1315
  }
1316
  li.as-result-item em {
1317
+ background: none !important;
1318
+ color: #333 !important;
1319
+ font-size: 12px;
1320
+ padding: 0 !important;
1321
  }
1322
 
1323
  /* Loop Builder */
1324
  .fl-loop-builder-filter {
1325
+ display: none;
1326
  }
1327
 
1328
  /* Service Fields */
css/fl-icon-selector.css CHANGED
@@ -1,12 +1,12 @@
1
  .fl-icon-selector .fl-lightbox {
2
- height: 100%;
3
  }
4
  .fl-icons-filter {
5
  height: auto !important;
6
  margin: 0 !important;
7
- position: absolute !important;
8
- right: 10px;
9
- top: 10px;
10
  }
11
  .fl-icons-filter select {
12
  vertical-align: middle;
@@ -18,51 +18,51 @@
18
  width: 160px;
19
  }
20
  .fl-icons-list {
21
- bottom: 52px;
22
- left: 0;
23
- overflow: auto;
24
- padding: 20px;
25
- position: absolute;
26
- right: 0;
27
- top: 48px;
28
  }
29
  .fl-icons-list::-webkit-scrollbar {
30
- background-color: #ccc;
31
- -webkit-appearance: none;
32
- width: 10px;
33
  }
34
  .fl-icons-list::-webkit-scrollbar-thumb {
35
- background-color: #666;
36
- border: 1px solid #ccc;
37
  }
38
  .fl-icons-section {
39
- text-align: center;
40
  }
41
  .fl-icons-section h2 {
42
- border-bottom: 1px solid #dfdfdf;
43
- color: #333 !important;
44
- font-family: Helvetica, Verdana, sans-serif !important;
45
- font-size: 16px !important;
46
- font-weight: bold !important;
47
- margin: 0 0 20px 0 !important;
48
- padding: 0 0 10px 0 !important;
49
- text-align: left;
50
  }
51
  .fl-icons-list i,
52
  .fl-icons-list i:before {
53
- cursor: pointer;
54
- display: inline-block;
55
- font-size: 32px;
56
- height: 80px;
57
- line-height: 80px;
58
- width: 80px;
59
  }
60
  .fl-icons-list i:hover {
61
- background: #e5e5e5;
62
  }
63
  .fl-icon-selector-footer {
64
- bottom: 0;
65
- left: 0;
66
- position: absolute;
67
- right: 0;
68
  }
1
  .fl-icon-selector .fl-lightbox {
2
+ height: 100%;
3
  }
4
  .fl-icons-filter {
5
  height: auto !important;
6
  margin: 0 !important;
7
+ position: absolute !important;
8
+ right: 10px;
9
+ top: 10px;
10
  }
11
  .fl-icons-filter select {
12
  vertical-align: middle;
18
  width: 160px;
19
  }
20
  .fl-icons-list {
21
+ bottom: 52px;
22
+ left: 0;
23
+ overflow: auto;
24
+ padding: 20px;
25
+ position: absolute;
26
+ right: 0;
27
+ top: 48px;
28
  }
29
  .fl-icons-list::-webkit-scrollbar {
30
+ background-color: #ccc;
31
+ -webkit-appearance: none;
32
+ width: 10px;
33
  }
34
  .fl-icons-list::-webkit-scrollbar-thumb {
35
+ background-color: #666;
36
+ border: 1px solid #ccc;
37
  }
38
  .fl-icons-section {
39
+ text-align: center;
40
  }
41
  .fl-icons-section h2 {
42
+ border-bottom: 1px solid #dfdfdf;
43
+ color: #333 !important;
44
+ font-family: Helvetica, Verdana, sans-serif !important;
45
+ font-size: 16px !important;
46
+ font-weight: bold !important;
47
+ margin: 0 0 20px 0 !important;
48
+ padding: 0 0 10px 0 !important;
49
+ text-align: left;
50
  }
51
  .fl-icons-list i,
52
  .fl-icons-list i:before {
53
+ cursor: pointer;
54
+ display: inline-block;
55
+ font-size: 32px;
56
+ height: 80px;
57
+ line-height: 80px;
58
+ width: 80px;
59
  }
60
  .fl-icons-list i:hover {
61
+ background: #e5e5e5;
62
  }
63
  .fl-icon-selector-footer {
64
+ bottom: 0;
65
+ left: 0;
66
+ position: absolute;
67
+ right: 0;
68
  }
css/fl-lightbox.css CHANGED
@@ -1,100 +1,100 @@
1
  .fl-lightbox-wrap {
2
- bottom: 0;
3
- display: none;
4
- left: 0;
5
- overflow: auto;
6
- padding: 30px;
7
- position: fixed;
8
- right: 0;
9
- top: 0;
10
- z-index: 100010;
11
- -webkit-backface-visibility: hidden;
12
- -webkit-transform: translateZ(0);
13
  }
14
  .fl-lightbox-wrap.fl-icon-selector {
15
- z-index: 100011;
16
  }
17
  .fl-lightbox-mask {
18
- background: #000;
19
- bottom: 0;
20
- left: 0;
21
- opacity: 0.7;
22
- filter: alpha(opacity = 70);
23
- position: fixed;
24
- right: 0;
25
- top: 0;
26
- z-index: 100010;
27
  }
28
  .fl-lightbox {
29
- background: #fff;
30
- box-shadow: rgba(0,0,0,1) 0 4px 30px;
31
- -moz-box-shadow: rgba(0,0,0,1) 0 4px 30px;
32
- -webkit-box-shadow: rgba(0,0,0,1) 0 4px 30px;
33
- position: relative;
34
- z-index: 100011;
35
  }
36
  .fl-lightbox *:not(i) {
37
- color: #333;
38
- font-family: Helvetica, Verdana, sans-serif;
39
- font-size: 12px;
40
- line-height: 16px;
41
- text-decoration: none;
42
- text-transform: none;
43
  }
44
  .fl-lightbox *,
45
  .fl-lightbox *:before,
46
  .fl-lightbox *:after {
47
- -webkit-box-sizing: content-box;
48
- -moz-box-sizing: content-box;
49
- box-sizing: content-box;
50
  }
51
  .fl-lightbox .fl-nanoscroller-pane {
52
- bottom: 4px;
53
- right: 4px;
54
- width: 8px;
55
  }
56
  .fl-lightbox .fa {
57
- font-family: FontAwesome;
58
  }
59
  .fl-lightbox-content-wrap {
60
- height: 100%;
61
  }
62
  .fl-lightbox.ui-draggable {
63
- box-shadow: rgba(0,0,0,0.5) 0 4px 30px;
64
- -moz-box-shadow: rgba(0,0,0,0.5) 0 4px 30px;
65
- -webkit-box-shadow: rgba(0,0,0,0.5) 0 4px 30px;
66
  }
67
 
68
  /* Header */
69
  .fl-lightbox-header {
70
- background: #fff;
71
- border-bottom: 1px solid #dfdfdf;
72
- box-shadow: 0 4px 4px -4px rgba(0,0,0,0.1);
73
- -moz-box-shadow: 0 4px 4px -4px rgba(0,0,0,0.1);
74
- -webkit-box-shadow: 0 4px 4px -4px rgba(0,0,0,0.1);
75
- position: relative;
76
  }
77
  .fl-lightbox-header h1 {
78
- color: #333 !important;
79
- font-size: 18px !important;
80
- font-family: Helvetica, Verdana, sans-serif !important;
81
- font-weight: 300 !important;
82
- margin: 0 !important;
83
- padding: 15px 20px !important;
84
  }
85
  .fl-lightbox.ui-draggable .fl-lightbox-header {
86
- cursor: move;
87
  }
88
 
89
  /* Footer */
90
  .fl-lightbox-footer {
91
- border-top: 1px solid #dfdfdf;
92
- box-shadow: 0 -4px 4px -4px rgba(0,0,0,0.1);
93
- -moz-box-shadow: 0 -4px 4px -4px rgba(0,0,0,0.1);
94
- -webkit-box-shadow: 0 -4px 4px -4px rgba(0,0,0,0.1);
95
- padding: 10px;
96
- text-align: right;
97
  }
98
  .fl-lightbox-footer .fl-builder-button {
99
- margin-left: 5px !important;
100
  }
1
  .fl-lightbox-wrap {
2
+ bottom: 0;
3
+ display: none;
4
+ left: 0;
5
+ overflow: auto;
6
+ padding: 30px;
7
+ position: fixed;
8
+ right: 0;
9
+ top: 0;
10
+ z-index: 100010;
11
+ -webkit-backface-visibility: hidden;
12
+ -webkit-transform: translateZ(0);
13
  }
14
  .fl-lightbox-wrap.fl-icon-selector {
15
+ z-index: 100011;
16
  }
17
  .fl-lightbox-mask {
18
+ background: #000;
19
+ bottom: 0;
20
+ left: 0;
21
+ opacity: 0.7;
22
+ filter: alpha(opacity = 70);
23
+ position: fixed;
24
+ right: 0;
25
+ top: 0;
26
+ z-index: 100010;
27
  }
28
  .fl-lightbox {
29
+ background: #fff;
30
+ box-shadow: rgba(0,0,0,1) 0 4px 30px;
31
+ -moz-box-shadow: rgba(0,0,0,1) 0 4px 30px;
32
+ -webkit-box-shadow: rgba(0,0,0,1) 0 4px 30px;
33
+ position: relative;
34
+ z-index: 100011;
35
  }
36
  .fl-lightbox *:not(i) {
37
+ color: #333;
38
+ font-family: Helvetica, Verdana, sans-serif;
39
+ font-size: 12px;
40
+ line-height: 16px;
41
+ text-decoration: none;
42
+ text-transform: none;
43
  }
44
  .fl-lightbox *,
45
  .fl-lightbox *:before,
46
  .fl-lightbox *:after {
47
+ -webkit-box-sizing: content-box;
48
+ -moz-box-sizing: content-box;
49
+ box-sizing: content-box;
50
  }
51
  .fl-lightbox .fl-nanoscroller-pane {
52
+ bottom: 4px;
53
+ right: 4px;
54
+ width: 8px;
55
  }
56
  .fl-lightbox .fa {
57
+ font-family: FontAwesome;
58
  }
59
  .fl-lightbox-content-wrap {
60
+ height: 100%;
61
  }
62
  .fl-lightbox.ui-draggable {
63
+ box-shadow: rgba(0,0,0,0.5) 0 4px 30px;
64
+ -moz-box-shadow: rgba(0,0,0,0.5) 0 4px 30px;
65
+ -webkit-box-shadow: rgba(0,0,0,0.5) 0 4px 30px;
66
  }
67
 
68
  /* Header */
69
  .fl-lightbox-header {
70
+ background: #fff;
71
+ border-bottom: 1px solid #dfdfdf;
72
+ box-shadow: 0 4px 4px -4px rgba(0,0,0,0.1);
73
+ -moz-box-shadow: 0 4px 4px -4px rgba(0,0,0,0.1);
74
+ -webkit-box-shadow: 0 4px 4px -4px rgba(0,0,0,0.1);
75
+ position: relative;
76
  }
77
  .fl-lightbox-header h1 {
78
+ color: #333 !important;
79
+ font-size: 18px !important;
80
+ font-family: Helvetica, Verdana, sans-serif !important;
81
+ font-weight: 300 !important;
82
+ margin: 0 !important;
83
+ padding: 15px 20px !important;
84
  }
85
  .fl-lightbox.ui-draggable .fl-lightbox-header {
86
+ cursor: move;
87
  }
88
 
89
  /* Footer */
90
  .fl-lightbox-footer {
91
+ border-top: 1px solid #dfdfdf;
92
+ box-shadow: 0 -4px 4px -4px rgba(0,0,0,0.1);
93
+ -moz-box-shadow: 0 -4px 4px -4px rgba(0,0,0,0.1);
94
+ -webkit-box-shadow: 0 -4px 4px -4px rgba(0,0,0,0.1);
95
+ padding: 10px;
96
+ text-align: right;
97
  }
98
  .fl-lightbox-footer .fl-builder-button {
99
+ margin-left: 5px !important;
100
  }
css/fl-slideshow.css CHANGED
@@ -16,9 +16,9 @@
16
  color: #8c8d8e;
17
  font-family: Helvetica, Verdana, Arial, sans-serif;
18
  font-size: 13px;
19
- letter-spacing: normal;
20
  position: relative;
21
- word-spacing: normal;
22
  }
23
  .fl-slideshow-content {
24
  position: relative;
@@ -40,7 +40,7 @@
40
  --------------------------------------------------------------*/
41
 
42
  .fl-loading-image {
43
- width: 42px;
44
  height: 42px;
45
  background: #000;
46
  border-radius: 6px;
@@ -146,13 +146,13 @@
146
  --------------------------------------------------------------*/
147
 
148
  .fl-slideshow-transition-slice {
149
- opacity: 0;
150
- overflow: hidden;
151
- position: absolute;
152
  }
153
  .fl-slideshow-transition-slice img {
154
- display: block;
155
- position: absolute;
156
  }
157
 
158
  /* Main Image
@@ -172,7 +172,7 @@
172
  height: 100%;
173
  }
174
  .fl-slideshow-frame.fl-click-action-enabled .fl-slideshow-image-img {
175
- cursor: pointer;
176
  }
177
 
178
  /* Nav
@@ -222,44 +222,44 @@
222
  padding: 14px 14px 0px;
223
  }
224
 
225
- .fl-slideshow-nav-thumbs { background-position: 0 0; }
226
- .fl-slideshow-nav-thumbs:hover { background-position: 0 -40px; }
227
 
228
- .fl-slideshow-nav-buy { background-position: -40px 0; }
229
  .fl-slideshow-nav-buy:hover { background-position: -40px -40px; }
230
 
231
- .fl-slideshow-nav-caption { background-position: -80px 0; }
232
- .fl-slideshow-nav-caption:hover { background-position: -80px -40px; }
233
  .fl-slideshow-nav-caption-disabled,
234
  .fl-slideshow-nav-caption-disabled:hover { background-position: -80px 0; opacity: 0.35; cursor: default; }
235
 
236
- .fl-slideshow-nav-social { background-position: -120px 0; }
237
- .fl-slideshow-nav-social:hover { background-position: -120px -40px; }
238
 
239
  .fl-slideshow-nav-prev,
240
- .fl-slideshow-nav-prevPage { background-position: -160px 0; }
241
  .fl-slideshow-nav-prev:hover,
242
- .fl-slideshow-nav-prevPage:hover { background-position: -160px -40px; }
243
 
244
- .fl-slideshow-nav-pause { background-position: -200px 0; }
245
- .fl-slideshow-nav-pause:hover { background-position: -200px -40px; }
246
 
247
- .fl-slideshow-nav-play { background-position: -240px 0; }
248
- .fl-slideshow-nav-play:hover { background-position: -240px -40px; }
249
 
250
  .fl-slideshow-nav-next,
251
- .fl-slideshow-nav-nextPage { background-position: -280px 0; }
252
  .fl-slideshow-nav-next:hover,
253
- .fl-slideshow-nav-nextPage:hover { background-position: -280px -40px; }
254
 
255
- .fl-slideshow-nav-fullscreen { background-position: -320px 0; }
256
- .fl-slideshow-nav-fullscreen:hover { background-position: -320px -40px; }
257
 
258
- .fl-fullscreen-active .fl-slideshow-nav-fullscreen { background-position: -360px 0; }
259
- .fl-fullscreen-active .fl-slideshow-nav-fullscreen:hover { background-position: -360px -40px; }
260
 
261
- .fl-slideshow-nav-close { background-position: -400px 0; }
262
- .fl-slideshow-nav-close:hover { background-position: -400px -40px; }
263
 
264
  /* Image Nav
265
  --------------------------------------------------------------*/
@@ -305,7 +305,7 @@
305
  .fl-slideshow-image-nav-right .fl-slideshow-nav-buttons,
306
  .fl-slideshow-image-nav-right a {
307
  width: 100%;
308
- }
309
 
310
  /* Mouse Nav
311
  --------------------------------------------------------------*/
@@ -516,23 +516,23 @@
516
  width: 24px;
517
  }
518
  .fl-slideshow-nav-count.fonticons-enabled {
519
- display: inline-block;
520
- font-size: 13px;
521
- height: 24px;
522
- line-height: 32px;
523
- margin: 5px 15px;
524
- padding: 0;
525
- vertical-align: middle;
526
  }
527
 
528
  /* Video */
529
  .fl-slideshow-video-close.sm-fonticon {
530
  background-image: none !important;
531
- height: 16px;
532
  font-size: 32px;
533
- line-height: 16px;
534
  text-decoration: none;
535
- width: 16px;
536
  }
537
 
538
  /* Overlays */
16
  color: #8c8d8e;
17
  font-family: Helvetica, Verdana, Arial, sans-serif;
18
  font-size: 13px;
19
+ letter-spacing: normal;
20
  position: relative;
21
+ word-spacing: normal;
22
  }
23
  .fl-slideshow-content {
24
  position: relative;
40
  --------------------------------------------------------------*/
41
 
42
  .fl-loading-image {
43
+ width: 42px;
44
  height: 42px;
45
  background: #000;
46
  border-radius: 6px;
146
  --------------------------------------------------------------*/
147
 
148
  .fl-slideshow-transition-slice {
149
+ opacity: 0;
150
+ overflow: hidden;
151
+ position: absolute;
152
  }
153
  .fl-slideshow-transition-slice img {
154
+ display: block;
155
+ position: absolute;
156
  }
157
 
158
  /* Main Image
172
  height: 100%;
173
  }
174
  .fl-slideshow-frame.fl-click-action-enabled .fl-slideshow-image-img {
175
+ cursor: pointer;
176
  }
177
 
178
  /* Nav
222
  padding: 14px 14px 0px;
223
  }
224
 
225
+ .fl-slideshow-nav-thumbs { background-position: 0 0; }
226
+ .fl-slideshow-nav-thumbs:hover { background-position: 0 -40px; }
227
 
228
+ .fl-slideshow-nav-buy { background-position: -40px 0; }
229
  .fl-slideshow-nav-buy:hover { background-position: -40px -40px; }
230
 
231
+ .fl-slideshow-nav-caption { background-position: -80px 0; }
232
+ .fl-slideshow-nav-caption:hover { background-position: -80px -40px; }
233
  .fl-slideshow-nav-caption-disabled,
234
  .fl-slideshow-nav-caption-disabled:hover { background-position: -80px 0; opacity: 0.35; cursor: default; }
235
 
236
+ .fl-slideshow-nav-social { background-position: -120px 0; }
237
+ .fl-slideshow-nav-social:hover { background-position: -120px -40px; }
238
 
239
  .fl-slideshow-nav-prev,
240
+ .fl-slideshow-nav-prevPage { background-position: -160px 0; }
241
  .fl-slideshow-nav-prev:hover,
242
+ .fl-slideshow-nav-prevPage:hover { background-position: -160px -40px; }
243
 
244
+ .fl-slideshow-nav-pause { background-position: -200px 0; }
245
+ .fl-slideshow-nav-pause:hover { background-position: -200px -40px; }
246
 
247
+ .fl-slideshow-nav-play { background-position: -240px 0; }
248
+ .fl-slideshow-nav-play:hover { background-position: -240px -40px; }
249
 
250
  .fl-slideshow-nav-next,
251
+ .fl-slideshow-nav-nextPage { background-position: -280px 0; }
252
  .fl-slideshow-nav-next:hover,
253
+ .fl-slideshow-nav-nextPage:hover { background-position: -280px -40px; }
254
 
255
+ .fl-slideshow-nav-fullscreen { background-position: -320px 0; }
256
+ .fl-slideshow-nav-fullscreen:hover { background-position: -320px -40px; }
257
 
258
+ .fl-fullscreen-active .fl-slideshow-nav-fullscreen { background-position: -360px 0; }
259
+ .fl-fullscreen-active .fl-slideshow-nav-fullscreen:hover { background-position: -360px -40px; }
260
 
261
+ .fl-slideshow-nav-close { background-position: -400px 0; }
262
+ .fl-slideshow-nav-close:hover { background-position: -400px -40px; }
263
 
264
  /* Image Nav
265
  --------------------------------------------------------------*/
305
  .fl-slideshow-image-nav-right .fl-slideshow-nav-buttons,
306
  .fl-slideshow-image-nav-right a {
307
  width: 100%;
308
+ }
309
 
310
  /* Mouse Nav
311
  --------------------------------------------------------------*/
516
  width: 24px;
517
  }
518
  .fl-slideshow-nav-count.fonticons-enabled {
519
+ display: inline-block;
520
+ font-size: 13px;
521
+ height: 24px;
522
+ line-height: 32px;
523
+ margin: 5px 15px;
524
+ padding: 0;
525
+ vertical-align: middle;
526
  }
527
 
528
  /* Video */
529
  .fl-slideshow-video-close.sm-fonticon {
530
  background-image: none !important;
531
+ height: 16px;
532
  font-size: 32px;
533
+ line-height: 16px;
534
  text-decoration: none;
535
+ width: 16px;
536
  }
537
 
538
  /* Overlays */
css/font-awesome.min.css CHANGED
@@ -1,4 +1,4 @@
1
  /*!
2
- * Font Awesome 4.2.0 by @davegandy - http://fontawesome.io - @fontawesome
3
  * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
4
- */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.2.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.2.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff?v=4.2.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.2.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.2.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}
1
  /*!
2
+ * Font Awesome 4.3.0 by @davegandy - http://fontawesome.io - @fontawesome
3
  * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
4
+ */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.3.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.3.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff2?v=4.3.0') format('woff2'),url('../fonts/fontawesome-webfont.woff?v=4.3.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.3.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.3.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;transform:translate(0, 0)}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-genderless:before,.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-hotel:before,.fa-bed:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}
css/foundation-icons.css CHANGED
@@ -5,14 +5,14 @@
5
  */
6
 
7
  @font-face {
8
- font-family: "foundation-icons";
9
- src: url("../fonts/foundation-icons.eot");
10
- src: url("../fonts/foundation-icons.eot?#iefix") format("embedded-opentype"),
11
- url("../fonts/foundation-icons.woff") format("woff"),
12
- url("../fonts/foundation-icons.ttf") format("truetype"),
13
- url("../fonts/foundation-icons.svg#fontcustom") format("svg");
14
- font-weight: normal;
15
- font-style: normal;
16
  }
17
 
18
  .fi-address-book:before,
@@ -298,15 +298,15 @@
298
  .fi-yen:before,
299
  .fi-zoom-in:before,
300
  .fi-zoom-out:before {
301
- font-family: "foundation-icons";
302
- font-style: normal;
303
- font-weight: normal;
304
- font-variant: normal;
305
- text-transform: none;
306
- line-height: 1;
307
- -webkit-font-smoothing: antialiased;
308
- display: inline-block;
309
- text-decoration: inherit;
310
  }
311
 
312
  .fi-address-book:before { content: "\f100"; }
5
  */
6
 
7
  @font-face {
8
+ font-family: "foundation-icons";
9
+ src: url("../fonts/foundation-icons.eot");
10
+ src: url("../fonts/foundation-icons.eot?#iefix") format("embedded-opentype"),
11
+ url("../fonts/foundation-icons.woff") format("woff"),
12
+ url("../fonts/foundation-icons.ttf") format("truetype"),
13
+ url("../fonts/foundation-icons.svg#fontcustom") format("svg");
14
+ font-weight: normal;
15
+ font-style: normal;
16
  }
17
 
18
  .fi-address-book:before,
298
  .fi-yen:before,
299
  .fi-zoom-in:before,
300
  .fi-zoom-out:before {
301
+ font-family: "foundation-icons";
302
+ font-style: normal;
303
+ font-weight: normal;
304
+ font-variant: normal;
305
+ text-transform: none;
306
+ line-height: 1;
307
+ -webkit-font-smoothing: antialiased;
308
+ display: inline-block;
309
+ text-decoration: inherit;
310
  }
311
 
312
  .fi-address-book:before { content: "\f100"; }
css/jquery.bxslider.css CHANGED
@@ -40,9 +40,9 @@
40
  /*fix other elements on the page moving (on Chrome)*/
41
  -webkit-transform: translatez(0);
42
  -moz-transform: translatez(0);
43
- -ms-transform: translatez(0);
44
- -o-transform: translatez(0);
45
- transform: translatez(0);
46
  }
47
 
48
  .bx-wrapper .bx-pager,
40
  /*fix other elements on the page moving (on Chrome)*/
41
  -webkit-transform: translatez(0);
42
  -moz-transform: translatez(0);
43
+ -ms-transform: translatez(0);
44
+ -o-transform: translatez(0);
45
+ transform: translatez(0);
46
  }
47
 
48
  .bx-wrapper .bx-pager,
css/jquery.magnificpopup.css CHANGED
@@ -1,365 +1,365 @@
1
  /* Magnific Popup CSS */
2
  .mfp-bg {
3
- top: 0;
4
- left: 0;
5
- width: 100%;
6
- height: 100%;
7
- z-index: 1042;
8
- overflow: hidden;
9
- position: fixed;
10
- background: #0b0b0b;
11
- opacity: 0.8;
12
- filter: alpha(opacity=80); }
13
 
14
  .mfp-wrap {
15
- top: 0;
16
- left: 0;
17
- width: 100%;
18
- height: 100%;
19
- z-index: 1043;
20
- position: fixed;
21
- outline: none !important;
22
- -webkit-backface-visibility: hidden; }
23
 
24
  .mfp-container {
25
- text-align: center;
26
- position: absolute;
27
- width: 100%;
28
- height: 100%;
29
- left: 0;
30
- top: 0;
31
- padding: 0 8px;
32
- -webkit-box-sizing: border-box;
33
- -moz-box-sizing: border-box;
34
- box-sizing: border-box; }
35
 
36
  .mfp-container:before {
37
- content: '';
38
- display: inline-block;
39
- height: 100%;
40
- vertical-align: middle; }
41
 
42
  .mfp-align-top .mfp-container:before {
43
- display: none; }
44
 
45
  .mfp-content {
46
- position: relative;
47
- display: inline-block;
48
- vertical-align: middle;
49
- margin: 0 auto;
50
- text-align: left;
51
- z-index: 1045; }
52
 
53
  .mfp-inline-holder .mfp-content, .mfp-ajax-holder .mfp-content {
54
- width: 100%;
55
- cursor: auto; }
56
 
57
  .mfp-ajax-cur {
58
- cursor: progress; }
59
 
60
  .mfp-zoom-out-cur, .mfp-zoom-out-cur .mfp-image-holder .mfp-close {
61
- cursor: -moz-zoom-out;
62
- cursor: -webkit-zoom-out;
63
- cursor: zoom-out; }
64
 
65
  .mfp-zoom {
66
- cursor: pointer;
67
- cursor: -webkit-zoom-in;
68
- cursor: -moz-zoom-in;
69
- cursor: zoom-in; }
70
 
71
  .mfp-auto-cursor .mfp-content {
72
- cursor: auto; }
73
 
74
  .mfp-close, .mfp-arrow, .mfp-preloader, .mfp-counter {
75
- -webkit-user-select: none;
76
- -moz-user-select: none;
77
- user-select: none; }
78
 
79
  .mfp-loading.mfp-figure {
80
- display: none; }
81
 
82
  .mfp-hide {
83
- display: none !important; }
84
 
85
  .mfp-preloader {
86
- color: #cccccc;
87
- position: absolute;
88
- top: 50%;
89
- width: auto;
90
- text-align: center;
91
- margin-top: -0.8em;
92
- left: 8px;
93
- right: 8px;
94
- z-index: 1044; }
95
- .mfp-preloader a {
96
- color: #cccccc; }
97
- .mfp-preloader a:hover {
98
- color: white; }
99
 
100
  .mfp-s-ready .mfp-preloader {
101
- display: none; }
102
 
103
  .mfp-s-error .mfp-content {
104
- display: none; }
105
 
106
  button.mfp-close, button.mfp-arrow {
107
- overflow: visible;
108
- cursor: pointer;
109
- background: transparent;
110
- border: 0;
111
- -webkit-appearance: none;
112
- display: block;
113
- outline: none;
114
- padding: 0;
115
- z-index: 1046;
116
- -webkit-box-shadow: none;
117
- box-shadow: none; }
118
  button::-moz-focus-inner {
119
- padding: 0;
120
- border: 0; }
121
 
122
  .mfp-close {
123
- width: 44px;
124
- height: 44px;
125
- line-height: 44px;
126
- position: absolute;
127
- right: 0;
128
- top: 0;
129
- text-decoration: none;
130
- text-align: center;
131
- opacity: 0.65;
132
- padding: 0 0 18px 10px;
133
- color: white;
134
- font-style: normal;
135
- font-size: 28px;
136
- font-family: Arial, Baskerville, monospace; }
137
- .mfp-close:hover, .mfp-close:focus {
138
- opacity: 1; }
139
- .mfp-close:active {
140
- top: 1px; }
141
 
142
  .mfp-close-btn-in .mfp-close {
143
- color: #333333; }
144
 
145
  .mfp-image-holder .mfp-close, .mfp-iframe-holder .mfp-close {
146
- color: white;
147
- right: -6px;
148
- text-align: right;
149
- padding-right: 6px;
150
- width: 100%; }
151
 
152
  .mfp-counter {
153
- position: absolute;
154
- top: 0;
155
- right: 0;
156
- color: #cccccc;
157
- font-size: 12px;
158
- line-height: 18px; }
159
 
160
  .mfp-arrow {
161
- position: absolute;
162
- opacity: 0.65;
163
- margin: 0;
164
- top: 50%;
165
- margin-top: -55px;
166
- padding: 0;
167
- width: 90px;
168
- height: 110px;
169
- -webkit-tap-highlight-color: rgba(0, 0, 0, 0); }
170
- .mfp-arrow:active {
171
- margin-top: -54px; }
172
- .mfp-arrow:hover, .mfp-arrow:focus {
173
- opacity: 1; }
174
- .mfp-arrow:before, .mfp-arrow:after, .mfp-arrow .mfp-b, .mfp-arrow .mfp-a {
175
- content: '';
176
- display: block;
177
- width: 0;
178
- height: 0;
179
- position: absolute;
180
- left: 0;
181
- top: 0;
182
- margin-top: 35px;
183
- margin-left: 35px;
184
- border: medium inset transparent; }
185
- .mfp-arrow:after, .mfp-arrow .mfp-a {
186
- border-top-width: 13px;
187
- border-bottom-width: 13px;
188
- top: 8px; }
189
- .mfp-arrow:before, .mfp-arrow .mfp-b {
190
- border-top-width: 21px;
191
- border-bottom-width: 21px; }
192
 
193
  .mfp-arrow-left {
194
- left: 0; }
195
- .mfp-arrow-left:after, .mfp-arrow-left .mfp-a {
196
- border-right: 17px solid white;
197
- margin-left: 31px; }
198
- .mfp-arrow-left:before, .mfp-arrow-left .mfp-b {
199
- margin-left: 25px;
200
- border-right: 27px solid #3f3f3f; }
201
 
202
  .mfp-arrow-right {
203
- right: 0; }
204
- .mfp-arrow-right:after, .mfp-arrow-right .mfp-a {
205
- border-left: 17px solid white;
206
- margin-left: 39px; }
207
- .mfp-arrow-right:before, .mfp-arrow-right .mfp-b {
208
- border-left: 27px solid #3f3f3f; }
209
 
210
  .mfp-iframe-holder {
211
- padding-top: 40px;
212
- padding-bottom: 40px; }
213
- .mfp-iframe-holder .mfp-content {
214
- line-height: 0;
215
- width: 100%;
216
- max-width: 900px; }
217
- .mfp-iframe-holder .mfp-close {
218
- top: -40px; }
219
 
220
  .mfp-iframe-scaler {
221
- width: 100%;
222
- height: 0;
223
- overflow: hidden;
224
- padding-top: 56.25%; }
225
- .mfp-iframe-scaler iframe {
226
- position: absolute;
227
- display: block;
228
- top: 0;
229
- left: 0;
230
- width: 100%;
231
- height: 100%;
232
- box-shadow: 0 0 8px rgba(0, 0, 0, 0.6);
233
- background: black; }
234
 
235
  /* Main image in popup */
236
  img.mfp-img {
237
- width: auto;
238
- max-width: 100%;
239
- height: auto;
240
- display: block;
241
- line-height: 0;
242
- -webkit-box-sizing: border-box;
243
- -moz-box-sizing: border-box;
244
- box-sizing: border-box;
245
- padding: 40px 0 40px;
246
- margin: 0 auto; }
247
 
248
  /* The shadow behind the image */
249
  .mfp-figure {
250
- line-height: 0; }
251
- .mfp-figure:after {
252
- content: '';
253
- position: absolute;
254
- left: 0;
255
- top: 40px;
256
- bottom: 40px;
257
- display: block;
258
- right: 0;
259
- width: auto;
260
- height: auto;
261
- z-index: -1;
262
- box-shadow: 0 0 8px rgba(0, 0, 0, 0.6);
263
- background: #444444; }
264
- .mfp-figure small {
265
- color: #bdbdbd;
266
- display: block;
267
- font-size: 12px;
268
- line-height: 14px; }
269
- .mfp-figure figure {
270
- margin: 0; }
271
 
272
  .mfp-bottom-bar {
273
- margin-top: -36px;
274
- position: absolute;
275
- top: 100%;
276
- left: 0;
277
- width: 100%;
278
- cursor: auto; }
279
 
280
  .mfp-title {
281
- text-align: left;
282
- line-height: 18px;
283
- color: #f3f3f3;
284
- word-wrap: break-word;
285
- padding-right: 36px; }
286
 
287
  .mfp-image-holder .mfp-content {
288
- max-width: 100%; }
289
 
290
  .mfp-gallery .mfp-image-holder .mfp-figure {
291
- cursor: pointer; }
292
 
293
  @media screen and (max-width: 800px) and (orientation: landscape), screen and (max-height: 300px) {
294
- /**
295
- * Remove all paddings around the image on small screen
296
- */
297
- .mfp-img-mobile .mfp-image-holder {
298
- padding-left: 0;
299
- padding-right: 0; }
300
- .mfp-img-mobile img.mfp-img {
301
- padding: 0; }
302
- .mfp-img-mobile .mfp-figure {
303
- /* The shadow behind the image */ }
304
- .mfp-img-mobile .mfp-figure:after {
305
- top: 0;
306
- bottom: 0; }
307
- .mfp-img-mobile .mfp-figure small {
308
- display: inline;
309
- margin-left: 5px; }
310
- .mfp-img-mobile .mfp-bottom-bar {
311
- background: rgba(0, 0, 0, 0.6);
312
- bottom: 0;
313
- margin: 0;
314
- top: auto;
315
- padding: 3px 5px;
316
- position: fixed;
317
- -webkit-box-sizing: border-box;
318
- -moz-box-sizing: border-box;
319
- box-sizing: border-box; }
320
- .mfp-img-mobile .mfp-bottom-bar:empty {
321
- padding: 0; }
322
- .mfp-img-mobile .mfp-counter {
323
- right: 5px;
324
- top: 3px; }
325
- .mfp-img-mobile .mfp-close {
326
- top: 0;
327
- right: 0;
328
- width: 35px;
329
- height: 35px;
330
- line-height: 35px;
331
- background: rgba(0, 0, 0, 0.6);
332
- position: fixed;
333
- text-align: center;
334
- padding: 0; } }
335
 
336
  @media all and (max-width: 900px) {
337
- .mfp-arrow {
338
- -webkit-transform: scale(0.75);
339
- transform: scale(0.75); }
340
- .mfp-arrow-left {
341
- -webkit-transform-origin: 0;
342
- transform-origin: 0; }
343
- .mfp-arrow-right {
344
- -webkit-transform-origin: 100%;
345
- transform-origin: 100%; }
346
- .mfp-container {
347
- padding-left: 6px;
348
- padding-right: 6px; } }
349
 
350
  .mfp-ie7 .mfp-img {
351
- padding: 0; }
352
  .mfp-ie7 .mfp-bottom-bar {
353
- width: 600px;
354
- left: 50%;
355
- margin-left: -300px;
356
- margin-top: 5px;
357
- padding-bottom: 5px; }
358
  .mfp-ie7 .mfp-container {
359
- padding: 0; }
360
  .mfp-ie7 .mfp-content {
361
- padding-top: 44px; }
362
  .mfp-ie7 .mfp-close {
363
- top: 0;
364
- right: 0;
365
- padding-top: 0; }
1
  /* Magnific Popup CSS */
2
  .mfp-bg {
3
+ top: 0;
4
+ left: 0;
5
+ width: 100%;
6
+ height: 100%;
7
+ z-index: 1042;
8
+ overflow: hidden;
9
+ position: fixed;
10
+ background: #0b0b0b;
11
+ opacity: 0.8;
12
+ filter: alpha(opacity=80); }
13
 
14
  .mfp-wrap {
15
+ top: 0;
16
+ left: 0;
17
+ width: 100%;
18
+ height: 100%;
19
+ z-index: 1043;
20
+ position: fixed;
21
+ outline: none !important;
22
+ -webkit-backface-visibility: hidden; }
23
 
24
  .mfp-container {
25
+ text-align: center;
26
+ position: absolute;
27
+ width: 100%;
28
+ height: 100%;
29
+ left: 0;
30
+ top: 0;
31
+ padding: 0 8px;
32
+ -webkit-box-sizing: border-box;
33
+ -moz-box-sizing: border-box;
34
+ box-sizing: border-box; }
35
 
36
  .mfp-container:before {
37
+ content: '';
38
+ display: inline-block;
39
+ height: 100%;
40
+ vertical-align: middle; }
41
 
42
  .mfp-align-top .mfp-container:before {
43
+ display: none; }
44
 
45
  .mfp-content {
46
+ position: relative;
47
+ display: inline-block;
48
+ vertical-align: middle;
49
+ margin: 0 auto;
50
+ text-align: left;
51
+ z-index: 1045; }
52
 
53
  .mfp-inline-holder .mfp-content, .mfp-ajax-holder .mfp-content {
54
+ width: 100%;
55
+ cursor: auto; }
56
 
57
  .mfp-ajax-cur {
58
+ cursor: progress; }
59
 
60
  .mfp-zoom-out-cur, .mfp-zoom-out-cur .mfp-image-holder .mfp-close {
61
+ cursor: -moz-zoom-out;
62
+ cursor: -webkit-zoom-out;
63
+ cursor: zoom-out; }
64
 
65
  .mfp-zoom {
66
+ cursor: pointer;
67
+ cursor: -webkit-zoom-in;
68
+ cursor: -moz-zoom-in;
69
+ cursor: zoom-in; }
70
 
71
  .mfp-auto-cursor .mfp-content {
72
+ cursor: auto; }
73
 
74
  .mfp-close, .mfp-arrow, .mfp-preloader, .mfp-counter {
75
+ -webkit-user-select: none;
76
+ -moz-user-select: none;
77
+ user-select: none; }
78
 
79
  .mfp-loading.mfp-figure {
80
+ display: none; }
81
 
82
  .mfp-hide {
83
+ display: none !important; }
84
 
85
  .mfp-preloader {
86
+ color: #cccccc;
87
+ position: absolute;
88
+ top: 50%;
89
+ width: auto;
90
+ text-align: center;
91
+ margin-top: -0.8em;
92
+ left: 8px;
93
+ right: 8px;
94
+ z-index: 1044; }
95
+ .mfp-preloader a {
96
+ color: #cccccc; }
97
+ .mfp-preloader a:hover {
98
+ color: white; }
99
 
100
  .mfp-s-ready .mfp-preloader {
101
+ display: none; }
102
 
103
  .mfp-s-error .mfp-content {
104
+ display: none; }
105
 
106
  button.mfp-close, button.mfp-arrow {
107
+ overflow: visible;
108
+ cursor: pointer;
109
+ background: transparent;
110
+ border: 0;
111
+ -webkit-appearance: none;
112
+ display: block;
113
+ outline: none;
114
+ padding: 0;
115
+ z-index: 1046;
116
+ -webkit-box-shadow: none;
117
+ box-shadow: none; }
118
  button::-moz-focus-inner {
119
+ padding: 0;
120
+ border: 0; }
121
 
122
  .mfp-close {
123
+ width: 44px;
124
+ height: 44px;
125
+ line-height: 44px;
126
+ position: absolute;
127
+ right: 0;
128
+ top: 0;
129
+ text-decoration: none;
130
+ text-align: center;
131
+ opacity: 0.65;
132
+ padding: 0 0 18px 10px;
133
+ color: white;
134
+ font-style: normal;
135
+ font-size: 28px;
136
+ font-family: Arial, Baskerville, monospace; }
137
+ .mfp-close:hover, .mfp-close:focus {
138
+ opacity: 1; }
139
+ .mfp-close:active {
140
+ top: 1px; }
141
 
142
  .mfp-close-btn-in .mfp-close {
143
+ color: #333333; }
144
 
145
  .mfp-image-holder .mfp-close, .mfp-iframe-holder .mfp-close {
146
+ color: white;
147
+ right: -6px;
148
+ text-align: right;
149
+ padding-right: 6px;
150
+ width: 100%; }
151
 
152
  .mfp-counter {
153
+ position: absolute;
154
+ top: 0;
155
+ right: 0;
156
+ color: #cccccc;
157
+ font-size: 12px;
158
+ line-height: 18px; }
159
 
160
  .mfp-arrow {
161
+ position: absolute;
162
+ opacity: 0.65;
163
+ margin: 0;
164
+ top: 50%;
165
+ margin-top: -55px;
166
+ padding: 0;
167
+ width: 90px;
168
+ height: 110px;
169
+ -webkit-tap-highlight-color: rgba(0, 0, 0, 0); }
170
+ .mfp-arrow:active {
171
+ margin-top: -54px; }
172
+ .mfp-arrow:hover, .mfp-arrow:focus {
173
+ opacity: 1; }
174
+ .mfp-arrow:before, .mfp-arrow:after, .mfp-arrow .mfp-b, .mfp-arrow .mfp-a {
175
+ content: '';
176
+ display: block;
177
+ width: 0;
178
+ height: 0;
179
+ position: absolute;
180
+ left: 0;
181
+ top: 0;
182
+ margin-top: 35px;
183
+ margin-left: 35px;
184
+ border: medium inset transparent; }
185
+ .mfp-arrow:after, .mfp-arrow .mfp-a {
186
+ border-top-width: 13px;
187
+ border-bottom-width: 13px;
188
+ top: 8px; }
189
+ .mfp-arrow:before, .mfp-arrow .mfp-b {
190
+ border-top-width: 21px;
191
+ border-bottom-width: 21px; }
192
 
193
  .mfp-arrow-left {
194
+ left: 0; }
195
+ .mfp-arrow-left:after, .mfp-arrow-left .mfp-a {
196
+ border-right: 17px solid white;
197
+ margin-left: 31px; }
198
+ .mfp-arrow-left:before, .mfp-arrow-left .mfp-b {
199
+ margin-left: 25px;
200
+ border-right: 27px solid #3f3f3f; }
201
 
202
  .mfp-arrow-right {
203
+ right: 0; }
204
+ .mfp-arrow-right:after, .mfp-arrow-right .mfp-a {
205
+ border-left: 17px solid white;
206
+ margin-left: 39px; }
207
+ .mfp-arrow-right:before, .mfp-arrow-right .mfp-b {
208
+ border-left: 27px solid #3f3f3f; }
209
 
210
  .mfp-iframe-holder {
211
+ padding-top: 40px;
212
+ padding-bottom: 40px; }
213
+ .mfp-iframe-holder .mfp-content {
214
+ line-height: 0;
215
+ width: 100%;
216
+ max-width: 900px; }
217
+ .mfp-iframe-holder .mfp-close {
218
+ top: -40px; }
219
 
220
  .mfp-iframe-scaler {
221
+ width: 100%;
222
+ height: 0;
223
+ overflow: hidden;
224
+ padding-top: 56.25%; }
225
+ .mfp-iframe-scaler iframe {
226
+ position: absolute;
227
+ display: block;
228
+ top: 0;
229
+ left: 0;
230
+ width: 100%;
231
+ height: 100%;
232
+ box-shadow: 0 0 8px rgba(0, 0, 0, 0.6);
233
+ background: black; }
234
 
235
  /* Main image in popup */
236
  img.mfp-img {
237
+ width: auto;
238
+ max-width: 100%;
239
+ height: auto;
240
+ display: block;
241
+ line-height: 0;
242
+ -webkit-box-sizing: border-box;
243
+ -moz-box-sizing: border-box;
244
+ box-sizing: border-box;
245
+ padding: 40px 0 40px;
246
+ margin: 0 auto; }
247
 
248
  /* The shadow behind the image */
249
  .mfp-figure {
250
+ line-height: 0; }
251
+ .mfp-figure:after {
252
+ content: '';
253
+ position: absolute;
254
+ left: 0;
255
+ top: 40px;
256
+ bottom: 40px;
257
+ display: block;
258
+ right: 0;
259
+ width: auto;
260
+ height: auto;
261
+ z-index: -1;
262
+ box-shadow: 0 0 8px rgba(0, 0, 0, 0.6);
263
+ background: #444444; }
264
+ .mfp-figure small {
265
+ color: #bdbdbd;
266
+ display: block;
267
+ font-size: 12px;
268
+ line-height: 14px; }
269
+ .mfp-figure figure {
270
+ margin: 0; }
271
 
272
  .mfp-bottom-bar {
273
+ margin-top: -36px;
274
+ position: absolute;
275
+ top: 100%;
276
+ left: 0;
277
+ width: 100%;
278
+ cursor: auto; }
279
 
280
  .mfp-title {
281
+ text-align: left;
282
+ line-height: 18px;
283
+ color: #f3f3f3;
284
+ word-wrap: break-word;
285
+ padding-right: 36px; }
286
 
287
  .mfp-image-holder .mfp-content {
288
+ max-width: 100%; }
289
 
290
  .mfp-gallery .mfp-image-holder .mfp-figure {
291
+ cursor: pointer; }
292
 
293
  @media screen and (max-width: 800px) and (orientation: landscape), screen and (max-height: 300px) {
294
+ /**
295
+ * Remove all paddings around the image on small screen
296
+ */
297
+ .mfp-img-mobile .mfp-image-holder {
298
+ padding-left: 0;
299
+ padding-right: 0; }
300
+ .mfp-img-mobile img.mfp-img {
301
+ padding: 0; }
302
+ .mfp-img-mobile .mfp-figure {
303
+ /* The shadow behind the image */ }
304
+ .mfp-img-mobile .mfp-figure:after {
305
+ top: 0;
306
+ bottom: 0; }
307
+ .mfp-img-mobile .mfp-figure small {
308
+ display: inline;
309
+ margin-left: 5px; }
310
+ .mfp-img-mobile .mfp-bottom-bar {
311
+ background: rgba(0, 0, 0, 0.6);
312
+ bottom: 0;
313
+ margin: 0;
314
+ top: auto;
315
+ padding: 3px 5px;
316
+ position: fixed;
317
+ -webkit-box-sizing: border-box;
318
+ -moz-box-sizing: border-box;
319
+ box-sizing: border-box; }
320
+ .mfp-img-mobile .mfp-bottom-bar:empty {
321
+ padding: 0; }
322
+ .mfp-img-mobile .mfp-counter {
323
+ right: 5px;
324
+ top: 3px; }
325
+ .mfp-img-mobile .mfp-close {
326
+ top: 0;
327
+ right: 0;
328
+ width: 35px;
329
+ height: 35px;
330
+ line-height: 35px;
331
+ background: rgba(0, 0, 0, 0.6);
332
+ position: fixed;
333
+ text-align: center;
334
+ padding: 0; } }
335
 
336
  @media all and (max-width: 900px) {
337
+ .mfp-arrow {
338
+ -webkit-transform: scale(0.75);
339
+ transform: scale(0.75); }
340
+ .mfp-arrow-left {
341
+ -webkit-transform-origin: 0;
342
+ transform-origin: 0; }
343
+ .mfp-arrow-right {
344
+ -webkit-transform-origin: 100%;
345
+ transform-origin: 100%; }
346
+ .mfp-container {
347
+ padding-left: 6px;
348
+ padding-right: 6px; } }
349
 
350
  .mfp-ie7 .mfp-img {
351
+ padding: 0; }
352
  .mfp-ie7 .mfp-bottom-bar {
353
+ width: 600px;
354
+ left: 50%;
355
+ margin-left: -300px;
356
+ margin-top: 5px;
357
+ padding-bottom: 5px; }
358
  .mfp-ie7 .mfp-container {
359
+ padding: 0; }
360
  .mfp-ie7 .mfp-content {
361
+ padding-top: 44px; }
362
  .mfp-ie7 .mfp-close {
363
+ top: 0;
364
+ right: 0;
365
+ padding-top: 0; }
css/jquery.nanoscroller.css CHANGED
@@ -1,50 +1,50 @@
1
  /** initial setup **/
2
  .fl-nanoscroller {
3
- position : relative;
4
- width : 100%;
5
- height : 100%;
6
- overflow : hidden;
7
  }
8
  .fl-nanoscroller .fl-nanoscroller-content {
9
- position : absolute;
10
- overflow : scroll;
11
- overflow-x : hidden;
12
- top : 0;
13
- right : 0;
14
- bottom : 0;
15
- left : 0;
16
  }
17
  .fl-nanoscroller .fl-nanoscroller-content:focus {
18
- outline: thin dotted;
19
  }
20
  .fl-nanoscroller .fl-nanoscroller-content::-webkit-scrollbar {
21
- display: none;
22
- visibility: hidden;
23
  }
24
  .has-scrollbar .fl-nanoscroller-content::-webkit-scrollbar {
25
- display: block;
26
- visibility: visible;
27
  }
28
  .fl-nanoscroller > .fl-nanoscroller-pane {
29
- background : #bebebe;
30
- position : absolute;
31
- width : 10px;
32
- right : 0;
33
- top : 0;
34
- bottom : 0;
35
- visibility : hidden\9; /* Target only IE7 and IE8 with this hack */
36
- opacity : .01;
37
- -webkit-transition : .2s;
38
- -moz-transition : .2s;
39
- -o-transition : .2s;
40
- transition : .2s;
41
  }
42
  .fl-nanoscroller > .fl-nanoscroller-pane > .fl-nanoscroller-slider {
43
- background: #444;
44
- background: rgba(0,0,0,.5);
45
- position : relative;
46
  }
47
  .fl-nanoscroller:hover > .fl-nanoscroller-pane, .fl-nanoscroller-pane.active, .fl-nanoscroller-pane.flashed {
48
- visibility : visible\9; /* Target only IE7 and IE8 with this hack */
49
- opacity : 0.99;
50
  }
1
  /** initial setup **/
2
  .fl-nanoscroller {
3
+ position : relative;
4
+ width : 100%;
5
+ height : 100%;
6
+ overflow : hidden;
7
  }
8
  .fl-nanoscroller .fl-nanoscroller-content {
9
+ position : absolute;
10
+ overflow : scroll;
11
+ overflow-x : hidden;
12
+ top : 0;
13
+ right : 0;
14
+ bottom : 0;
15
+ left : 0;
16
  }
17
  .fl-nanoscroller .fl-nanoscroller-content:focus {
18
+ outline: thin dotted;
19
  }
20
  .fl-nanoscroller .fl-nanoscroller-content::-webkit-scrollbar {
21
+ display: none;
22
+ visibility: hidden;
23
  }
24
  .has-scrollbar .fl-nanoscroller-content::-webkit-scrollbar {
25
+ display: block;
26
+ visibility: visible;
27
  }
28
  .fl-nanoscroller > .fl-nanoscroller-pane {
29
+ background : #bebebe;
30
+ position : absolute;
31
+ width : 10px;
32
+ right : 0;
33
+ top : 0;
34
+ bottom : 0;
35
+ visibility : hidden\9; /* Target only IE7 and IE8 with this hack */
36
+ opacity : .01;
37
+ -webkit-transition : .2s;
38
+ -moz-transition : .2s;
39
+ -o-transition : .2s;
40
+ transition : .2s;
41
  }
42
  .fl-nanoscroller > .fl-nanoscroller-pane > .fl-nanoscroller-slider {
43
+ background: #444;
44
+ background: rgba(0,0,0,.5);
45
+ position : relative;
46
  }
47
  .fl-nanoscroller:hover > .fl-nanoscroller-pane, .fl-nanoscroller-pane.active, .fl-nanoscroller-pane.flashed {
48
+ visibility : visible\9; /* Target only IE7 and IE8 with this hack */
49
+ opacity : 0.99;
50
  }
css/jquery.tiptip.css CHANGED
@@ -99,7 +99,7 @@
99
  }
100
 
101
  /* Webkit Hacks */
102
- @media screen and (-webkit-min-device-pixel-ratio:0) {
103
  #tiptip_content {
104
  padding: 4px 8px 5px 8px;
105
  background-color: rgba(45,45,45,0.88);
99
  }
100
 
101
  /* Webkit Hacks */
102
+ @media screen and (-webkit-min-device-pixel-ratio:0) {
103
  #tiptip_content {
104
  padding: 4px 8px 5px 8px;
105
  background-color: rgba(45,45,45,0.88);
fl-builder.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: Beaver Builder Plugin (Lite Version)
4
  * Plugin URI: https://www.wpbeaverbuilder.com/?utm_source=external&utm_medium=builder&utm_campaign=plugins-page
5
  * Description: A drag and drop frontend WordPress page builder plugin that works with almost any theme!
6
- * Version: 1.5.5
7
  * Author: The Beaver Builder Team
8
  * Author URI: https://www.wpbeaverbuilder.com/?utm_source=external&utm_medium=builder&utm_campaign=plugins-page
9
  * Copyright: (c) 2014 Beaver Builder
@@ -11,7 +11,7 @@
11
  * License URI: http://www.gnu.org/licenses/gpl-2.0.html
12
  * Text Domain: fl-builder
13
  */
14
- define('FL_BUILDER_VERSION', '1.5.5');
15
  define('FL_BUILDER_DIR', plugin_dir_path(__FILE__));
16
  define('FL_BUILDER_URL', plugins_url('/', __FILE__));
17
  define('FL_BUILDER_LITE', true);
@@ -72,10 +72,10 @@ add_filter('all_plugins', 'FLBuilderAdmin::
72
  /* AJAX Actions */
73
  add_action('fl_ajax_fl_builder_save', 'FLBuilderModel::update');
74
  add_action('fl_ajax_fl_builder_autosuggest', 'FLBuilderAutoSuggest::init');
75
- add_action('fl_ajax_fl_builder_render_service_settings', 'FLBuilderServices::render_settings');
76
- add_action('fl_ajax_fl_builder_connect_service', 'FLBuilderServices::connect_service');
77
- add_action('fl_ajax_fl_builder_render_service_fields', 'FLBuilderServices::render_fields');
78
- add_action('fl_ajax_fl_builder_delete_service_account', 'FLBuilderServices::delete_account');
79
  add_action('fl_ajax_fl_builder_render_layout', 'FLBuilder::render_layout');
80
  add_action('fl_ajax_fl_builder_render_preview', 'FLBuilder::render_preview');
81
  add_action('fl_ajax_fl_builder_render_settings_form', 'FLBuilder::render_settings_form');
@@ -103,7 +103,7 @@ add_action('wp_footer', 'FLBuilder::inclu
103
  add_action('wp_footer', 'FLBuilder::render_ui');
104
 
105
  /* Filters */
106
- add_filter('found_posts', 'FLBuilderLoop::found_posts', 1, 2);
107
  add_filter('body_class', 'FLBuilder::body_class');
108
  add_filter('wp_default_editor', 'FLBuilder::default_editor');
109
  add_filter('mce_css', 'FLBuilder::add_editor_css');
3
  * Plugin Name: Beaver Builder Plugin (Lite Version)
4
  * Plugin URI: https://www.wpbeaverbuilder.com/?utm_source=external&utm_medium=builder&utm_campaign=plugins-page
5
  * Description: A drag and drop frontend WordPress page builder plugin that works with almost any theme!
6
+ * Version: 1.5.6
7
  * Author: The Beaver Builder Team
8
  * Author URI: https://www.wpbeaverbuilder.com/?utm_source=external&utm_medium=builder&utm_campaign=plugins-page
9
  * Copyright: (c) 2014 Beaver Builder
11
  * License URI: http://www.gnu.org/licenses/gpl-2.0.html
12
  * Text Domain: fl-builder
13
  */
14
+ define('FL_BUILDER_VERSION', '1.5.6');
15
  define('FL_BUILDER_DIR', plugin_dir_path(__FILE__));
16
  define('FL_BUILDER_URL', plugins_url('/', __FILE__));
17
  define('FL_BUILDER_LITE', true);
72
  /* AJAX Actions */
73
  add_action('fl_ajax_fl_builder_save', 'FLBuilderModel::update');
74
  add_action('fl_ajax_fl_builder_autosuggest', 'FLBuilderAutoSuggest::init');
75
+ add_action('fl_ajax_fl_builder_render_service_settings', 'FLBuilderServices::render_settings');
76
+ add_action('fl_ajax_fl_builder_connect_service', 'FLBuilderServices::connect_service');
77
+ add_action('fl_ajax_fl_builder_render_service_fields', 'FLBuilderServices::render_fields');
78
+ add_action('fl_ajax_fl_builder_delete_service_account', 'FLBuilderServices::delete_account');
79
  add_action('fl_ajax_fl_builder_render_layout', 'FLBuilder::render_layout');
80
  add_action('fl_ajax_fl_builder_render_preview', 'FLBuilder::render_preview');
81
  add_action('fl_ajax_fl_builder_render_settings_form', 'FLBuilder::render_settings_form');
103
  add_action('wp_footer', 'FLBuilder::render_ui');
104
 
105
  /* Filters */
106
+ add_filter('found_posts', 'FLBuilderLoop::found_posts', 1, 2);
107
  add_filter('body_class', 'FLBuilder::body_class');
108
  add_filter('wp_default_editor', 'FLBuilder::default_editor');
109
  add_filter('mce_css', 'FLBuilder::add_editor_css');
fonts/FontAwesome.otf CHANGED
Binary file
fonts/fontawesome-webfont.eot CHANGED
Binary file
fonts/fontawesome-webfont.svg CHANGED
@@ -1,6 +1,6 @@
1
  <?xml version="1.0" standalone="no"?>
2
  <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
3
- <svg xmlns="http://www.w3.org/2000/svg">
4
  <metadata></metadata>
5
  <defs>
6
  <font id="fontawesomeregular" horiz-adv-x="1536" >
@@ -147,14 +147,14 @@
147
  <glyph unicode="&#xf077;" horiz-adv-x="1792" d="M1683 205l-166 -165q-19 -19 -45 -19t-45 19l-531 531l-531 -531q-19 -19 -45 -19t-45 19l-166 165q-19 19 -19 45.5t19 45.5l742 741q19 19 45 19t45 -19l742 -741q19 -19 19 -45.5t-19 -45.5z" />
148
  <glyph unicode="&#xf078;" horiz-adv-x="1792" d="M1683 728l-742 -741q-19 -19 -45 -19t-45 19l-742 741q-19 19 -19 45.5t19 45.5l166 165q19 19 45 19t45 -19l531 -531l531 531q19 19 45 19t45 -19l166 -165q19 -19 19 -45.5t-19 -45.5z" />
149
  <glyph unicode="&#xf079;" horiz-adv-x="1920" d="M1280 32q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-8 0 -13.5 2t-9 7t-5.5 8t-3 11.5t-1 11.5v13v11v160v416h-192q-26 0 -45 19t-19 45q0 24 15 41l320 384q19 22 49 22t49 -22l320 -384q15 -17 15 -41q0 -26 -19 -45t-45 -19h-192v-384h576q16 0 25 -11l160 -192q7 -11 7 -21 zM1920 448q0 -24 -15 -41l-320 -384q-20 -23 -49 -23t-49 23l-320 384q-15 17 -15 41q0 26 19 45t45 19h192v384h-576q-16 0 -25 12l-160 192q-7 9 -7 20q0 13 9.5 22.5t22.5 9.5h960q8 0 13.5 -2t9 -7t5.5 -8t3 -11.5t1 -11.5v-13v-11v-160v-416h192q26 0 45 -19t19 -45z " />
150
- <glyph unicode="&#xf07a;" horiz-adv-x="1664" d="M640 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1536 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1664 1088v-512q0 -24 -16 -42.5t-41 -21.5 l-1044 -122q1 -7 4.5 -21.5t6 -26.5t2.5 -22q0 -16 -24 -64h920q26 0 45 -19t19 -45t-19 -45t-45 -19h-1024q-26 0 -45 19t-19 45q0 14 11 39.5t29.5 59.5t20.5 38l-177 823h-204q-26 0 -45 19t-19 45t19 45t45 19h256q16 0 28.5 -6.5t20 -15.5t13 -24.5t7.5 -26.5 t5.5 -29.5t4.5 -25.5h1201q26 0 45 -19t19 -45z" />
151
  <glyph unicode="&#xf07b;" horiz-adv-x="1664" d="M1664 928v-704q0 -92 -66 -158t-158 -66h-1216q-92 0 -158 66t-66 158v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h672q92 0 158 -66t66 -158z" />
152
  <glyph unicode="&#xf07c;" horiz-adv-x="1920" d="M1879 584q0 -31 -31 -66l-336 -396q-43 -51 -120.5 -86.5t-143.5 -35.5h-1088q-34 0 -60.5 13t-26.5 43q0 31 31 66l336 396q43 51 120.5 86.5t143.5 35.5h1088q34 0 60.5 -13t26.5 -43zM1536 928v-160h-832q-94 0 -197 -47.5t-164 -119.5l-337 -396l-5 -6q0 4 -0.5 12.5 t-0.5 12.5v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h544q92 0 158 -66t66 -158z" />
153
  <glyph unicode="&#xf07d;" horiz-adv-x="768" d="M704 1216q0 -26 -19 -45t-45 -19h-128v-1024h128q26 0 45 -19t19 -45t-19 -45l-256 -256q-19 -19 -45 -19t-45 19l-256 256q-19 19 -19 45t19 45t45 19h128v1024h-128q-26 0 -45 19t-19 45t19 45l256 256q19 19 45 19t45 -19l256 -256q19 -19 19 -45z" />
154
  <glyph unicode="&#xf07e;" horiz-adv-x="1792" d="M1792 640q0 -26 -19 -45l-256 -256q-19 -19 -45 -19t-45 19t-19 45v128h-1024v-128q0 -26 -19 -45t-45 -19t-45 19l-256 256q-19 19 -19 45t19 45l256 256q19 19 45 19t45 -19t19 -45v-128h1024v128q0 26 19 45t45 19t45 -19l256 -256q19 -19 19 -45z" />
155
  <glyph unicode="&#xf080;" horiz-adv-x="2048" d="M640 640v-512h-256v512h256zM1024 1152v-1024h-256v1024h256zM2048 0v-128h-2048v1536h128v-1408h1920zM1408 896v-768h-256v768h256zM1792 1280v-1152h-256v1152h256z" />
156
  <glyph unicode="&#xf081;" d="M1280 926q-56 -25 -121 -34q68 40 93 117q-65 -38 -134 -51q-61 66 -153 66q-87 0 -148.5 -61.5t-61.5 -148.5q0 -29 5 -48q-129 7 -242 65t-192 155q-29 -50 -29 -106q0 -114 91 -175q-47 1 -100 26v-2q0 -75 50 -133.5t123 -72.5q-29 -8 -51 -8q-13 0 -39 4 q21 -63 74.5 -104t121.5 -42q-116 -90 -261 -90q-26 0 -50 3q148 -94 322 -94q112 0 210 35.5t168 95t120.5 137t75 162t24.5 168.5q0 18 -1 27q63 45 105 109zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5 t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
157
- <glyph unicode="&#xf082;" d="M1536 160q0 -119 -84.5 -203.5t-203.5 -84.5h-192v608h203l30 224h-233v143q0 54 28 83t96 29l132 1v207q-96 9 -180 9q-136 0 -218 -80.5t-82 -225.5v-166h-224v-224h224v-608h-544q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960 q119 0 203.5 -84.5t84.5 -203.5v-960z" />
158
  <glyph unicode="&#xf083;" horiz-adv-x="1792" d="M928 704q0 14 -9 23t-23 9q-66 0 -113 -47t-47 -113q0 -14 9 -23t23 -9t23 9t9 23q0 40 28 68t68 28q14 0 23 9t9 23zM1152 574q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75t75 -181zM128 0h1536v128h-1536v-128zM1280 574q0 159 -112.5 271.5 t-271.5 112.5t-271.5 -112.5t-112.5 -271.5t112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5zM256 1216h384v128h-384v-128zM128 1024h1536v118v138h-828l-64 -128h-644v-128zM1792 1280v-1280q0 -53 -37.5 -90.5t-90.5 -37.5h-1536q-53 0 -90.5 37.5t-37.5 90.5v1280 q0 53 37.5 90.5t90.5 37.5h1536q53 0 90.5 -37.5t37.5 -90.5z" />
159
  <glyph unicode="&#xf084;" horiz-adv-x="1792" d="M832 1024q0 80 -56 136t-136 56t-136 -56t-56 -136q0 -42 19 -83q-41 19 -83 19q-80 0 -136 -56t-56 -136t56 -136t136 -56t136 56t56 136q0 42 -19 83q41 -19 83 -19q80 0 136 56t56 136zM1683 320q0 -17 -49 -66t-66 -49q-9 0 -28.5 16t-36.5 33t-38.5 40t-24.5 26 l-96 -96l220 -220q28 -28 28 -68q0 -42 -39 -81t-81 -39q-40 0 -68 28l-671 671q-176 -131 -365 -131q-163 0 -265.5 102.5t-102.5 265.5q0 160 95 313t248 248t313 95q163 0 265.5 -102.5t102.5 -265.5q0 -189 -131 -365l355 -355l96 96q-3 3 -26 24.5t-40 38.5t-33 36.5 t-16 28.5q0 17 49 66t66 49q13 0 23 -10q6 -6 46 -44.5t82 -79.5t86.5 -86t73 -78t28.5 -41z" />
160
  <glyph unicode="&#xf085;" horiz-adv-x="1920" d="M896 640q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1664 128q0 52 -38 90t-90 38t-90 -38t-38 -90q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1664 1152q0 52 -38 90t-90 38t-90 -38t-38 -90q0 -53 37.5 -90.5t90.5 -37.5 t90.5 37.5t37.5 90.5zM1280 731v-185q0 -10 -7 -19.5t-16 -10.5l-155 -24q-11 -35 -32 -76q34 -48 90 -115q7 -10 7 -20q0 -12 -7 -19q-23 -30 -82.5 -89.5t-78.5 -59.5q-11 0 -21 7l-115 90q-37 -19 -77 -31q-11 -108 -23 -155q-7 -24 -30 -24h-186q-11 0 -20 7.5t-10 17.5 l-23 153q-34 10 -75 31l-118 -89q-7 -7 -20 -7q-11 0 -21 8q-144 133 -144 160q0 9 7 19q10 14 41 53t47 61q-23 44 -35 82l-152 24q-10 1 -17 9.5t-7 19.5v185q0 10 7 19.5t16 10.5l155 24q11 35 32 76q-34 48 -90 115q-7 11 -7 20q0 12 7 20q22 30 82 89t79 59q11 0 21 -7 l115 -90q34 18 77 32q11 108 23 154q7 24 30 24h186q11 0 20 -7.5t10 -17.5l23 -153q34 -10 75 -31l118 89q8 7 20 7q11 0 21 -8q144 -133 144 -160q0 -9 -7 -19q-12 -16 -42 -54t-45 -60q23 -48 34 -82l152 -23q10 -2 17 -10.5t7 -19.5zM1920 198v-140q0 -16 -149 -31 q-12 -27 -30 -52q51 -113 51 -138q0 -4 -4 -7q-122 -71 -124 -71q-8 0 -46 47t-52 68q-20 -2 -30 -2t-30 2q-14 -21 -52 -68t-46 -47q-2 0 -124 71q-4 3 -4 7q0 25 51 138q-18 25 -30 52q-149 15 -149 31v140q0 16 149 31q13 29 30 52q-51 113 -51 138q0 4 4 7q4 2 35 20 t59 34t30 16q8 0 46 -46.5t52 -67.5q20 2 30 2t30 -2q51 71 92 112l6 2q4 0 124 -70q4 -3 4 -7q0 -25 -51 -138q17 -23 30 -52q149 -15 149 -31zM1920 1222v-140q0 -16 -149 -31q-12 -27 -30 -52q51 -113 51 -138q0 -4 -4 -7q-122 -71 -124 -71q-8 0 -46 47t-52 68 q-20 -2 -30 -2t-30 2q-14 -21 -52 -68t-46 -47q-2 0 -124 71q-4 3 -4 7q0 25 51 138q-18 25 -30 52q-149 15 -149 31v140q0 16 149 31q13 29 30 52q-51 113 -51 138q0 4 4 7q4 2 35 20t59 34t30 16q8 0 46 -46.5t52 -67.5q20 2 30 2t30 -2q51 71 92 112l6 2q4 0 124 -70 q4 -3 4 -7q0 -25 -51 -138q17 -23 30 -52q149 -15 149 -31z" />
@@ -275,7 +275,7 @@
275
  <glyph unicode="&#xf10c;" d="M768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103 t279.5 -279.5t103 -385.5z" />
276
  <glyph unicode="&#xf10d;" horiz-adv-x="1664" d="M768 576v-384q0 -80 -56 -136t-136 -56h-384q-80 0 -136 56t-56 136v704q0 104 40.5 198.5t109.5 163.5t163.5 109.5t198.5 40.5h64q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-64q-106 0 -181 -75t-75 -181v-32q0 -40 28 -68t68 -28h224q80 0 136 -56t56 -136z M1664 576v-384q0 -80 -56 -136t-136 -56h-384q-80 0 -136 56t-56 136v704q0 104 40.5 198.5t109.5 163.5t163.5 109.5t198.5 40.5h64q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-64q-106 0 -181 -75t-75 -181v-32q0 -40 28 -68t68 -28h224q80 0 136 -56t56 -136z" />
277
  <glyph unicode="&#xf10e;" horiz-adv-x="1664" d="M768 1216v-704q0 -104 -40.5 -198.5t-109.5 -163.5t-163.5 -109.5t-198.5 -40.5h-64q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h64q106 0 181 75t75 181v32q0 40 -28 68t-68 28h-224q-80 0 -136 56t-56 136v384q0 80 56 136t136 56h384q80 0 136 -56t56 -136zM1664 1216 v-704q0 -104 -40.5 -198.5t-109.5 -163.5t-163.5 -109.5t-198.5 -40.5h-64q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h64q106 0 181 75t75 181v32q0 40 -28 68t-68 28h-224q-80 0 -136 56t-56 136v384q0 80 56 136t136 56h384q80 0 136 -56t56 -136z" />
278
- <glyph unicode="&#xf110;" horiz-adv-x="1568" d="M496 192q0 -60 -42.5 -102t-101.5 -42q-60 0 -102 42t-42 102t42 102t102 42q59 0 101.5 -42t42.5 -102zM928 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM320 640q0 -66 -47 -113t-113 -47t-113 47t-47 113 t47 113t113 47t113 -47t47 -113zM1360 192q0 -46 -33 -79t-79 -33t-79 33t-33 79t33 79t79 33t79 -33t33 -79zM528 1088q0 -73 -51.5 -124.5t-124.5 -51.5t-124.5 51.5t-51.5 124.5t51.5 124.5t124.5 51.5t124.5 -51.5t51.5 -124.5zM992 1280q0 -80 -56 -136t-136 -56 t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1536 640q0 -40 -28 -68t-68 -28t-68 28t-28 68t28 68t68 28t68 -28t28 -68zM1328 1088q0 -33 -23.5 -56.5t-56.5 -23.5t-56.5 23.5t-23.5 56.5t23.5 56.5t56.5 23.5t56.5 -23.5t23.5 -56.5z" />
279
  <glyph unicode="&#xf111;" d="M1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
280
  <glyph unicode="&#xf112;" horiz-adv-x="1792" d="M1792 416q0 -166 -127 -451q-3 -7 -10.5 -24t-13.5 -30t-13 -22q-12 -17 -28 -17q-15 0 -23.5 10t-8.5 25q0 9 2.5 26.5t2.5 23.5q5 68 5 123q0 101 -17.5 181t-48.5 138.5t-80 101t-105.5 69.5t-133 42.5t-154 21.5t-175.5 6h-224v-256q0 -26 -19 -45t-45 -19t-45 19 l-512 512q-19 19 -19 45t19 45l512 512q19 19 45 19t45 -19t19 -45v-256h224q713 0 875 -403q53 -134 53 -333z" />
281
  <glyph unicode="&#xf113;" horiz-adv-x="1664" d="M640 320q0 -40 -12.5 -82t-43 -76t-72.5 -34t-72.5 34t-43 76t-12.5 82t12.5 82t43 76t72.5 34t72.5 -34t43 -76t12.5 -82zM1280 320q0 -40 -12.5 -82t-43 -76t-72.5 -34t-72.5 34t-43 76t-12.5 82t12.5 82t43 76t72.5 34t72.5 -34t43 -76t12.5 -82zM1440 320 q0 120 -69 204t-187 84q-41 0 -195 -21q-71 -11 -157 -11t-157 11q-152 21 -195 21q-118 0 -187 -84t-69 -204q0 -88 32 -153.5t81 -103t122 -60t140 -29.5t149 -7h168q82 0 149 7t140 29.5t122 60t81 103t32 153.5zM1664 496q0 -207 -61 -331q-38 -77 -105.5 -133t-141 -86 t-170 -47.5t-171.5 -22t-167 -4.5q-78 0 -142 3t-147.5 12.5t-152.5 30t-137 51.5t-121 81t-86 115q-62 123 -62 331q0 237 136 396q-27 82 -27 170q0 116 51 218q108 0 190 -39.5t189 -123.5q147 35 309 35q148 0 280 -32q105 82 187 121t189 39q51 -102 51 -218 q0 -87 -27 -168q136 -160 136 -398z" />
@@ -411,7 +411,7 @@
411
  <glyph unicode="&#xf19d;" horiz-adv-x="2304" d="M1774 700l18 -316q4 -69 -82 -128t-235 -93.5t-323 -34.5t-323 34.5t-235 93.5t-82 128l18 316l574 -181q22 -7 48 -7t48 7zM2304 1024q0 -23 -22 -31l-1120 -352q-4 -1 -10 -1t-10 1l-652 206q-43 -34 -71 -111.5t-34 -178.5q63 -36 63 -109q0 -69 -58 -107l58 -433 q2 -14 -8 -25q-9 -11 -24 -11h-192q-15 0 -24 11q-10 11 -8 25l58 433q-58 38 -58 107q0 73 65 111q11 207 98 330l-333 104q-22 8 -22 31t22 31l1120 352q4 1 10 1t10 -1l1120 -352q22 -8 22 -31z" />
412
  <glyph unicode="&#xf19e;" d="M859 579l13 -707q-62 11 -105 11q-41 0 -105 -11l13 707q-40 69 -168.5 295.5t-216.5 374.5t-181 287q58 -15 108 -15q43 0 111 15q63 -111 133.5 -229.5t167 -276.5t138.5 -227q37 61 109.5 177.5t117.5 190t105 176t107 189.5q54 -14 107 -14q56 0 114 14v0 q-28 -39 -60 -88.5t-49.5 -78.5t-56.5 -96t-49 -84q-146 -248 -353 -610z" />
413
  <glyph unicode="&#xf1a0;" horiz-adv-x="1280" d="M981 197q0 25 -7 49t-14.5 42t-27 41.5t-29.5 35t-38.5 34.5t-36.5 29t-41.5 30t-36.5 26q-16 2 -49 2q-53 0 -104.5 -7t-107 -25t-97 -46t-68.5 -74.5t-27 -105.5q0 -56 23.5 -102t61 -75.5t87 -50t100 -29t101.5 -8.5q58 0 111.5 13t99 39t73 73t27.5 109zM864 1055 q0 59 -17 125.5t-48 129t-84 103.5t-117 41q-42 0 -82.5 -19.5t-66.5 -52.5q-46 -59 -46 -160q0 -46 10 -97.5t31.5 -103t52 -92.5t75 -67t96.5 -26q37 0 77.5 16.5t65.5 43.5q53 56 53 159zM752 1536h417l-137 -88h-132q75 -63 113 -133t38 -160q0 -72 -24.5 -129.5 t-59.5 -93t-69.5 -65t-59 -61.5t-24.5 -66q0 -36 32 -70.5t77 -68t90.5 -73.5t77.5 -104t32 -142q0 -91 -49 -173q-71 -122 -209.5 -179.5t-298.5 -57.5q-132 0 -246.5 41.5t-172.5 137.5q-36 59 -36 131q0 81 44.5 150t118.5 115q131 82 404 100q-32 41 -47.5 73.5 t-15.5 73.5q0 40 21 85q-46 -4 -68 -4q-148 0 -249.5 96.5t-101.5 244.5q0 82 36 159t99 131q76 66 182 98t218 32z" />
414
- <glyph unicode="&#xf1a1;" horiz-adv-x="1984" d="M831 572q0 -56 -40.5 -96t-96.5 -40q-57 0 -98 40t-41 96q0 57 41.5 98t97.5 41t96.5 -41t40.5 -98zM1292 711q56 0 96.5 -41t40.5 -98q0 -56 -40.5 -96t-96.5 -40q-57 0 -98 40t-41 96q0 57 41.5 98t97.5 41zM1984 722q0 -62 -31 -114t-83 -82q5 -33 5 -61 q0 -121 -68.5 -230.5t-197.5 -193.5q-125 -82 -285.5 -125.5t-335.5 -43.5q-176 0 -336.5 43.5t-284.5 125.5q-129 84 -197.5 193t-68.5 231q0 29 5 66q-48 31 -77 81.5t-29 109.5q0 94 66 160t160 66q83 0 148 -55q248 158 592 164l134 423q4 14 17.5 21.5t28.5 4.5 l347 -82q22 50 68.5 81t102.5 31q77 0 131.5 -54.5t54.5 -131.5t-54.5 -132t-131.5 -55q-76 0 -130.5 54t-55.5 131l-315 74l-116 -366q327 -14 560 -166q64 58 151 58q94 0 160 -66t66 -160zM1664 1459q-45 0 -77 -32t-32 -77t32 -77t77 -32t77 32t32 77t-32 77t-77 32z M77 722q0 -67 51 -111q49 131 180 235q-36 25 -82 25q-62 0 -105.5 -43.5t-43.5 -105.5zM1567 105q112 73 171.5 166t59.5 194t-59.5 193.5t-171.5 165.5q-116 75 -265.5 115.5t-313.5 40.5t-313.5 -40.5t-265.5 -115.5q-112 -73 -171.5 -165.5t-59.5 -193.5t59.5 -194 t171.5 -166q116 -75 265.5 -115.5t313.5 -40.5t313.5 40.5t265.5 115.5zM1850 605q57 46 57 117q0 62 -43.5 105.5t-105.5 43.5q-49 0 -86 -28q131 -105 178 -238zM1258 237q11 11 27 11t27 -11t11 -27.5t-11 -27.5q-99 -99 -319 -99h-2q-220 0 -319 99q-11 11 -11 27.5 t11 27.5t27 11t27 -11q77 -77 265 -77h2q188 0 265 77z" />
415
  <glyph unicode="&#xf1a2;" d="M950 393q7 7 17.5 7t17.5 -7t7 -18t-7 -18q-65 -64 -208 -64h-1h-1q-143 0 -207 64q-8 7 -8 18t8 18q7 7 17.5 7t17.5 -7q49 -51 172 -51h1h1q122 0 173 51zM671 613q0 -37 -26 -64t-63 -27t-63 27t-26 64t26 63t63 26t63 -26t26 -63zM1214 1049q-29 0 -50 21t-21 50 q0 30 21 51t50 21q30 0 51 -21t21 -51q0 -29 -21 -50t-51 -21zM1216 1408q132 0 226 -94t94 -227v-894q0 -133 -94 -227t-226 -94h-896q-132 0 -226 94t-94 227v894q0 133 94 227t226 94h896zM1321 596q35 14 57 45.5t22 70.5q0 51 -36 87.5t-87 36.5q-60 0 -98 -48 q-151 107 -375 115l83 265l206 -49q1 -50 36.5 -85t84.5 -35q50 0 86 35.5t36 85.5t-36 86t-86 36q-36 0 -66 -20.5t-45 -53.5l-227 54q-9 2 -17.5 -2.5t-11.5 -14.5l-95 -302q-224 -4 -381 -113q-36 43 -93 43q-51 0 -87 -36.5t-36 -87.5q0 -37 19.5 -67.5t52.5 -45.5 q-7 -25 -7 -54q0 -98 74 -181.5t201.5 -132t278.5 -48.5q150 0 277.5 48.5t201.5 132t74 181.5q0 27 -6 54zM971 702q37 0 63 -26t26 -63t-26 -64t-63 -27t-63 27t-26 64t26 63t63 26z" />
416
  <glyph unicode="&#xf1a3;" d="M866 697l90 27v62q0 79 -58 135t-138 56t-138 -55.5t-58 -134.5v-283q0 -20 -14 -33.5t-33 -13.5t-32.5 13.5t-13.5 33.5v120h-151v-122q0 -82 57.5 -139t139.5 -57q81 0 138.5 56.5t57.5 136.5v280q0 19 13.5 33t33.5 14q19 0 32.5 -14t13.5 -33v-54zM1199 502v122h-150 v-126q0 -20 -13.5 -33.5t-33.5 -13.5q-19 0 -32.5 14t-13.5 33v123l-90 -26l-60 28v-123q0 -80 58 -137t139 -57t138.5 57t57.5 139zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103 t385.5 -103t279.5 -279.5t103 -385.5z" />
417
  <glyph unicode="&#xf1a4;" horiz-adv-x="1920" d="M1062 824v118q0 42 -30 72t-72 30t-72 -30t-30 -72v-612q0 -175 -126 -299t-303 -124q-178 0 -303.5 125.5t-125.5 303.5v266h328v-262q0 -43 30 -72.5t72 -29.5t72 29.5t30 72.5v620q0 171 126.5 292t301.5 121q176 0 302 -122t126 -294v-136l-195 -58zM1592 602h328 v-266q0 -178 -125.5 -303.5t-303.5 -125.5q-177 0 -303 124.5t-126 300.5v268l131 -61l195 58v-270q0 -42 30 -71.5t72 -29.5t72 29.5t30 71.5v275z" />
@@ -438,7 +438,7 @@
438
  <glyph unicode="&#xf1ba;" horiz-adv-x="2048" d="M1824 640q93 0 158.5 -65.5t65.5 -158.5v-384q0 -14 -9 -23t-23 -9h-96v-64q0 -80 -56 -136t-136 -56t-136 56t-56 136v64h-1024v-64q0 -80 -56 -136t-136 -56t-136 56t-56 136v64h-96q-14 0 -23 9t-9 23v384q0 93 65.5 158.5t158.5 65.5h28l105 419q23 94 104 157.5 t179 63.5h128v224q0 14 9 23t23 9h448q14 0 23 -9t9 -23v-224h128q98 0 179 -63.5t104 -157.5l105 -419h28zM320 160q66 0 113 47t47 113t-47 113t-113 47t-113 -47t-47 -113t47 -113t113 -47zM516 640h1016l-89 357q-2 8 -14 17.5t-21 9.5h-768q-9 0 -21 -9.5t-14 -17.5z M1728 160q66 0 113 47t47 113t-47 113t-113 47t-113 -47t-47 -113t47 -113t113 -47z" />
439
  <glyph unicode="&#xf1bb;" d="M1504 64q0 -26 -19 -45t-45 -19h-462q1 -17 6 -87.5t5 -108.5q0 -25 -18 -42.5t-43 -17.5h-320q-25 0 -43 17.5t-18 42.5q0 38 5 108.5t6 87.5h-462q-26 0 -45 19t-19 45t19 45l402 403h-229q-26 0 -45 19t-19 45t19 45l402 403h-197q-26 0 -45 19t-19 45t19 45l384 384 q19 19 45 19t45 -19l384 -384q19 -19 19 -45t-19 -45t-45 -19h-197l402 -403q19 -19 19 -45t-19 -45t-45 -19h-229l402 -403q19 -19 19 -45z" />
440
  <glyph unicode="&#xf1bc;" d="M1127 326q0 32 -30 51q-193 115 -447 115q-133 0 -287 -34q-42 -9 -42 -52q0 -20 13.5 -34.5t35.5 -14.5q5 0 37 8q132 27 243 27q226 0 397 -103q19 -11 33 -11q19 0 33 13.5t14 34.5zM1223 541q0 40 -35 61q-237 141 -548 141q-153 0 -303 -42q-48 -13 -48 -64 q0 -25 17.5 -42.5t42.5 -17.5q7 0 37 8q122 33 251 33q279 0 488 -124q24 -13 38 -13q25 0 42.5 17.5t17.5 42.5zM1331 789q0 47 -40 70q-126 73 -293 110.5t-343 37.5q-204 0 -364 -47q-23 -7 -38.5 -25.5t-15.5 -48.5q0 -31 20.5 -52t51.5 -21q11 0 40 8q133 37 307 37 q159 0 309.5 -34t253.5 -95q21 -12 40 -12q29 0 50.5 20.5t21.5 51.5zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
441
- <glyph unicode="&#xf1bd;" d="M1397 1408q58 0 98.5 -40.5t40.5 -98.5v-1258q0 -58 -40.5 -98.5t-98.5 -40.5h-1258q-58 0 -98.5 40.5t-40.5 98.5v1258q0 58 40.5 98.5t98.5 40.5h1258zM1465 11v1258q0 28 -20 48t-48 20h-1258q-28 0 -48 -20t-20 -48v-1258q0 -28 20 -48t48 -20h1258q28 0 48 20t20 48 zM694 749l188 -387l533 145v-496q0 -7 -5.5 -12.5t-12.5 -5.5h-1258q-7 0 -12.5 5.5t-5.5 12.5v141l711 195l-212 439q4 1 12 2.5t12 1.5q170 32 303.5 21.5t221 -46t143.5 -94.5q27 -28 -25 -42q-64 -16 -256 -62l-97 198q-111 7 -240 -16zM1397 1287q7 0 12.5 -5.5 t5.5 -12.5v-428q-85 30 -188 52q-294 64 -645 12l-18 -3l-65 134h-233l85 -190q-132 -51 -230 -137v560q0 7 5.5 12.5t12.5 5.5h1258zM286 387q-14 -3 -26 4.5t-14 21.5q-24 203 166 305l129 -270z" />
442
  <glyph unicode="&#xf1be;" horiz-adv-x="2304" d="M784 164l16 241l-16 523q-1 10 -7.5 17t-16.5 7q-9 0 -16 -7t-7 -17l-14 -523l14 -241q1 -10 7.5 -16.5t15.5 -6.5q22 0 24 23zM1080 193l11 211l-12 586q0 16 -13 24q-8 5 -16 5t-16 -5q-13 -8 -13 -24l-1 -6l-10 -579q0 -1 11 -236v-1q0 -10 6 -17q9 -11 23 -11 q11 0 20 9q9 7 9 20zM35 533l20 -128l-20 -126q-2 -9 -9 -9t-9 9l-17 126l17 128q2 9 9 9t9 -9zM121 612l26 -207l-26 -203q-2 -9 -10 -9q-9 0 -9 10l-23 202l23 207q0 9 9 9q8 0 10 -9zM401 159zM213 650l25 -245l-25 -237q0 -11 -11 -11q-10 0 -12 11l-21 237l21 245 q2 12 12 12q11 0 11 -12zM307 657l23 -252l-23 -244q-2 -13 -14 -13q-13 0 -13 13l-21 244l21 252q0 13 13 13q12 0 14 -13zM401 639l21 -234l-21 -246q-2 -16 -16 -16q-6 0 -10.5 4.5t-4.5 11.5l-20 246l20 234q0 6 4.5 10.5t10.5 4.5q14 0 16 -15zM784 164zM495 785 l21 -380l-21 -246q0 -7 -5 -12.5t-12 -5.5q-16 0 -18 18l-18 246l18 380q2 18 18 18q7 0 12 -5.5t5 -12.5zM589 871l19 -468l-19 -244q0 -8 -5.5 -13.5t-13.5 -5.5q-18 0 -20 19l-16 244l16 468q2 19 20 19q8 0 13.5 -5.5t5.5 -13.5zM687 911l18 -506l-18 -242 q-2 -21 -22 -21q-19 0 -21 21l-16 242l16 506q0 9 6.5 15.5t14.5 6.5q9 0 15 -6.5t7 -15.5zM1079 169v0v0zM881 915l15 -510l-15 -239q0 -10 -7.5 -17.5t-17.5 -7.5t-17 7t-8 18l-14 239l14 510q0 11 7.5 18t17.5 7t17.5 -7t7.5 -18zM980 896l14 -492l-14 -236q0 -11 -8 -19 t-19 -8t-19 8t-9 19l-12 236l12 492q1 12 9 20t19 8t18.5 -8t8.5 -20zM1192 404l-14 -231v0q0 -13 -9 -22t-22 -9t-22 9t-10 22l-6 114l-6 117l12 636v3q2 15 12 24q9 7 20 7q8 0 15 -5q14 -8 16 -26zM2304 423q0 -117 -83 -199.5t-200 -82.5h-786q-13 2 -22 11t-9 22v899 q0 23 28 33q85 34 181 34q195 0 338 -131.5t160 -323.5q53 22 110 22q117 0 200 -83t83 -201z" />
443
  <glyph unicode="&#xf1c0;" d="M768 768q237 0 443 43t325 127v-170q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5t-103 128v170q119 -84 325 -127t443 -43zM768 0q237 0 443 43t325 127v-170q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5t-103 128v170q119 -84 325 -127 t443 -43zM768 384q237 0 443 43t325 127v-170q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5t-103 128v170q119 -84 325 -127t443 -43zM768 1536q208 0 385 -34.5t280 -93.5t103 -128v-128q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5 t-103 128v128q0 69 103 128t280 93.5t385 34.5z" />
444
  <glyph unicode="&#xf1c1;" d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z M894 465q33 -26 84 -56q59 7 117 7q147 0 177 -49q16 -22 2 -52q0 -1 -1 -2l-2 -2v-1q-6 -38 -71 -38q-48 0 -115 20t-130 53q-221 -24 -392 -83q-153 -262 -242 -262q-15 0 -28 7l-24 12q-1 1 -6 5q-10 10 -6 36q9 40 56 91.5t132 96.5q14 9 23 -6q2 -2 2 -4q52 85 107 197 q68 136 104 262q-24 82 -30.5 159.5t6.5 127.5q11 40 42 40h21h1q23 0 35 -15q18 -21 9 -68q-2 -6 -4 -8q1 -3 1 -8v-30q-2 -123 -14 -192q55 -164 146 -238zM318 54q52 24 137 158q-51 -40 -87.5 -84t-49.5 -74zM716 974q-15 -42 -2 -132q1 7 7 44q0 3 7 43q1 4 4 8 q-1 1 -1 2t-0.5 1.5t-0.5 1.5q-1 22 -13 36q0 -1 -1 -2v-2zM592 313q135 54 284 81q-2 1 -13 9.5t-16 13.5q-76 67 -127 176q-27 -86 -83 -197q-30 -56 -45 -83zM1238 329q-24 24 -140 24q76 -28 124 -28q14 0 18 1q0 1 -2 3z" />
@@ -513,8 +513,53 @@
513
  <glyph unicode="&#xf20a;" horiz-adv-x="2048" d="M785 528h207q-14 -158 -98.5 -248.5t-214.5 -90.5q-162 0 -254.5 116t-92.5 316q0 194 93 311.5t233 117.5q148 0 232 -87t97 -247h-203q-5 64 -35.5 99t-81.5 35q-57 0 -88.5 -60.5t-31.5 -177.5q0 -48 5 -84t18 -69.5t40 -51.5t66 -18q95 0 109 139zM1497 528h206 q-14 -158 -98 -248.5t-214 -90.5q-162 0 -254.5 116t-92.5 316q0 194 93 311.5t233 117.5q148 0 232 -87t97 -247h-204q-4 64 -35 99t-81 35q-57 0 -88.5 -60.5t-31.5 -177.5q0 -48 5 -84t18 -69.5t39.5 -51.5t65.5 -18q49 0 76.5 38t33.5 101zM1856 647q0 207 -15.5 307 t-60.5 161q-6 8 -13.5 14t-21.5 15t-16 11q-86 63 -697 63q-625 0 -710 -63q-5 -4 -17.5 -11.5t-21 -14t-14.5 -14.5q-45 -60 -60 -159.5t-15 -308.5q0 -208 15 -307.5t60 -160.5q6 -8 15 -15t20.5 -14t17.5 -12q44 -33 239.5 -49t470.5 -16q610 0 697 65q5 4 17 11t20.5 14 t13.5 16q46 60 61 159t15 309zM2048 1408v-1536h-2048v1536h2048z" />
514
  <glyph unicode="&#xf20b;" d="M992 912v-496q0 -14 -9 -23t-23 -9h-160q-14 0 -23 9t-9 23v496q0 112 -80 192t-192 80h-272v-1152q0 -14 -9 -23t-23 -9h-160q-14 0 -23 9t-9 23v1344q0 14 9 23t23 9h464q135 0 249 -66.5t180.5 -180.5t66.5 -249zM1376 1376v-880q0 -135 -66.5 -249t-180.5 -180.5 t-249 -66.5h-464q-14 0 -23 9t-9 23v960q0 14 9 23t23 9h160q14 0 23 -9t9 -23v-768h272q112 0 192 80t80 192v880q0 14 9 23t23 9h160q14 0 23 -9t9 -23z" />
515
  <glyph unicode="&#xf20c;" d="M1311 694v-114q0 -24 -13.5 -38t-37.5 -14h-202q-24 0 -38 14t-14 38v114q0 24 14 38t38 14h202q24 0 37.5 -14t13.5 -38zM821 464v250q0 53 -32.5 85.5t-85.5 32.5h-133q-68 0 -96 -52q-28 52 -96 52h-130q-53 0 -85.5 -32.5t-32.5 -85.5v-250q0 -22 21 -22h55 q22 0 22 22v230q0 24 13.5 38t38.5 14h94q24 0 38 -14t14 -38v-230q0 -22 21 -22h54q22 0 22 22v230q0 24 14 38t38 14h97q24 0 37.5 -14t13.5 -38v-230q0 -22 22 -22h55q21 0 21 22zM1410 560v154q0 53 -33 85.5t-86 32.5h-264q-53 0 -86 -32.5t-33 -85.5v-410 q0 -21 22 -21h55q21 0 21 21v180q31 -42 94 -42h191q53 0 86 32.5t33 85.5zM1536 1176v-1072q0 -96 -68 -164t-164 -68h-1072q-96 0 -164 68t-68 164v1072q0 96 68 164t164 68h1072q96 0 164 -68t68 -164z" />
516
- <glyph unicode="&#xf20d;" horiz-adv-x="1792" />
517
- <glyph unicode="&#xf20e;" horiz-adv-x="1792" />
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
518
  <glyph unicode="&#xf500;" horiz-adv-x="1792" />
519
  </font>
520
  </defs></svg>
1
  <?xml version="1.0" standalone="no"?>
2
  <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
3
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
4
  <metadata></metadata>
5
  <defs>
6
  <font id="fontawesomeregular" horiz-adv-x="1536" >
147
  <glyph unicode="&#xf077;" horiz-adv-x="1792" d="M1683 205l-166 -165q-19 -19 -45 -19t-45 19l-531 531l-531 -531q-19 -19 -45 -19t-45 19l-166 165q-19 19 -19 45.5t19 45.5l742 741q19 19 45 19t45 -19l742 -741q19 -19 19 -45.5t-19 -45.5z" />
148
  <glyph unicode="&#xf078;" horiz-adv-x="1792" d="M1683 728l-742 -741q-19 -19 -45 -19t-45 19l-742 741q-19 19 -19 45.5t19 45.5l166 165q19 19 45 19t45 -19l531 -531l531 531q19 19 45 19t45 -19l166 -165q19 -19 19 -45.5t-19 -45.5z" />
149
  <glyph unicode="&#xf079;" horiz-adv-x="1920" d="M1280 32q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-8 0 -13.5 2t-9 7t-5.5 8t-3 11.5t-1 11.5v13v11v160v416h-192q-26 0 -45 19t-19 45q0 24 15 41l320 384q19 22 49 22t49 -22l320 -384q15 -17 15 -41q0 -26 -19 -45t-45 -19h-192v-384h576q16 0 25 -11l160 -192q7 -11 7 -21 zM1920 448q0 -24 -15 -41l-320 -384q-20 -23 -49 -23t-49 23l-320 384q-15 17 -15 41q0 26 19 45t45 19h192v384h-576q-16 0 -25 12l-160 192q-7 9 -7 20q0 13 9.5 22.5t22.5 9.5h960q8 0 13.5 -2t9 -7t5.5 -8t3 -11.5t1 -11.5v-13v-11v-160v-416h192q26 0 45 -19t19 -45z " />
150
+ <glyph unicode="&#xf07a;" horiz-adv-x="1664" d="M640 0q0 -52 -38 -90t-90 -38t-90 38t-38 90t38 90t90 38t90 -38t38 -90zM1536 0q0 -52 -38 -90t-90 -38t-90 38t-38 90t38 90t90 38t90 -38t38 -90zM1664 1088v-512q0 -24 -16.5 -42.5t-40.5 -21.5l-1044 -122q13 -60 13 -70q0 -16 -24 -64h920q26 0 45 -19t19 -45 t-19 -45t-45 -19h-1024q-26 0 -45 19t-19 45q0 11 8 31.5t16 36t21.5 40t15.5 29.5l-177 823h-204q-26 0 -45 19t-19 45t19 45t45 19h256q16 0 28.5 -6.5t19.5 -15.5t13 -24.5t8 -26t5.5 -29.5t4.5 -26h1201q26 0 45 -19t19 -45z" />
151
  <glyph unicode="&#xf07b;" horiz-adv-x="1664" d="M1664 928v-704q0 -92 -66 -158t-158 -66h-1216q-92 0 -158 66t-66 158v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h672q92 0 158 -66t66 -158z" />
152
  <glyph unicode="&#xf07c;" horiz-adv-x="1920" d="M1879 584q0 -31 -31 -66l-336 -396q-43 -51 -120.5 -86.5t-143.5 -35.5h-1088q-34 0 -60.5 13t-26.5 43q0 31 31 66l336 396q43 51 120.5 86.5t143.5 35.5h1088q34 0 60.5 -13t26.5 -43zM1536 928v-160h-832q-94 0 -197 -47.5t-164 -119.5l-337 -396l-5 -6q0 4 -0.5 12.5 t-0.5 12.5v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h544q92 0 158 -66t66 -158z" />
153
  <glyph unicode="&#xf07d;" horiz-adv-x="768" d="M704 1216q0 -26 -19 -45t-45 -19h-128v-1024h128q26 0 45 -19t19 -45t-19 -45l-256 -256q-19 -19 -45 -19t-45 19l-256 256q-19 19 -19 45t19 45t45 19h128v1024h-128q-26 0 -45 19t-19 45t19 45l256 256q19 19 45 19t45 -19l256 -256q19 -19 19 -45z" />
154
  <glyph unicode="&#xf07e;" horiz-adv-x="1792" d="M1792 640q0 -26 -19 -45l-256 -256q-19 -19 -45 -19t-45 19t-19 45v128h-1024v-128q0 -26 -19 -45t-45 -19t-45 19l-256 256q-19 19 -19 45t19 45l256 256q19 19 45 19t45 -19t19 -45v-128h1024v128q0 26 19 45t45 19t45 -19l256 -256q19 -19 19 -45z" />
155
  <glyph unicode="&#xf080;" horiz-adv-x="2048" d="M640 640v-512h-256v512h256zM1024 1152v-1024h-256v1024h256zM2048 0v-128h-2048v1536h128v-1408h1920zM1408 896v-768h-256v768h256zM1792 1280v-1152h-256v1152h256z" />
156
  <glyph unicode="&#xf081;" d="M1280 926q-56 -25 -121 -34q68 40 93 117q-65 -38 -134 -51q-61 66 -153 66q-87 0 -148.5 -61.5t-61.5 -148.5q0 -29 5 -48q-129 7 -242 65t-192 155q-29 -50 -29 -106q0 -114 91 -175q-47 1 -100 26v-2q0 -75 50 -133.5t123 -72.5q-29 -8 -51 -8q-13 0 -39 4 q21 -63 74.5 -104t121.5 -42q-116 -90 -261 -90q-26 0 -50 3q148 -94 322 -94q112 0 210 35.5t168 95t120.5 137t75 162t24.5 168.5q0 18 -1 27q63 45 105 109zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5 t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
157
+ <glyph unicode="&#xf082;" d="M1248 1408q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-188v595h199l30 232h-229v148q0 56 23.5 84t91.5 28l122 1v207q-63 9 -178 9q-136 0 -217.5 -80t-81.5 -226v-171h-200v-232h200v-595h-532q-119 0 -203.5 84.5t-84.5 203.5v960 q0 119 84.5 203.5t203.5 84.5h960z" />
158
  <glyph unicode="&#xf083;" horiz-adv-x="1792" d="M928 704q0 14 -9 23t-23 9q-66 0 -113 -47t-47 -113q0 -14 9 -23t23 -9t23 9t9 23q0 40 28 68t68 28q14 0 23 9t9 23zM1152 574q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75t75 -181zM128 0h1536v128h-1536v-128zM1280 574q0 159 -112.5 271.5 t-271.5 112.5t-271.5 -112.5t-112.5 -271.5t112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5zM256 1216h384v128h-384v-128zM128 1024h1536v118v138h-828l-64 -128h-644v-128zM1792 1280v-1280q0 -53 -37.5 -90.5t-90.5 -37.5h-1536q-53 0 -90.5 37.5t-37.5 90.5v1280 q0 53 37.5 90.5t90.5 37.5h1536q53 0 90.5 -37.5t37.5 -90.5z" />
159
  <glyph unicode="&#xf084;" horiz-adv-x="1792" d="M832 1024q0 80 -56 136t-136 56t-136 -56t-56 -136q0 -42 19 -83q-41 19 -83 19q-80 0 -136 -56t-56 -136t56 -136t136 -56t136 56t56 136q0 42 -19 83q41 -19 83 -19q80 0 136 56t56 136zM1683 320q0 -17 -49 -66t-66 -49q-9 0 -28.5 16t-36.5 33t-38.5 40t-24.5 26 l-96 -96l220 -220q28 -28 28 -68q0 -42 -39 -81t-81 -39q-40 0 -68 28l-671 671q-176 -131 -365 -131q-163 0 -265.5 102.5t-102.5 265.5q0 160 95 313t248 248t313 95q163 0 265.5 -102.5t102.5 -265.5q0 -189 -131 -365l355 -355l96 96q-3 3 -26 24.5t-40 38.5t-33 36.5 t-16 28.5q0 17 49 66t66 49q13 0 23 -10q6 -6 46 -44.5t82 -79.5t86.5 -86t73 -78t28.5 -41z" />
160
  <glyph unicode="&#xf085;" horiz-adv-x="1920" d="M896 640q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1664 128q0 52 -38 90t-90 38t-90 -38t-38 -90q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1664 1152q0 52 -38 90t-90 38t-90 -38t-38 -90q0 -53 37.5 -90.5t90.5 -37.5 t90.5 37.5t37.5 90.5zM1280 731v-185q0 -10 -7 -19.5t-16 -10.5l-155 -24q-11 -35 -32 -76q34 -48 90 -115q7 -10 7 -20q0 -12 -7 -19q-23 -30 -82.5 -89.5t-78.5 -59.5q-11 0 -21 7l-115 90q-37 -19 -77 -31q-11 -108 -23 -155q-7 -24 -30 -24h-186q-11 0 -20 7.5t-10 17.5 l-23 153q-34 10 -75 31l-118 -89q-7 -7 -20 -7q-11 0 -21 8q-144 133 -144 160q0 9 7 19q10 14 41 53t47 61q-23 44 -35 82l-152 24q-10 1 -17 9.5t-7 19.5v185q0 10 7 19.5t16 10.5l155 24q11 35 32 76q-34 48 -90 115q-7 11 -7 20q0 12 7 20q22 30 82 89t79 59q11 0 21 -7 l115 -90q34 18 77 32q11 108 23 154q7 24 30 24h186q11 0 20 -7.5t10 -17.5l23 -153q34 -10 75 -31l118 89q8 7 20 7q11 0 21 -8q144 -133 144 -160q0 -9 -7 -19q-12 -16 -42 -54t-45 -60q23 -48 34 -82l152 -23q10 -2 17 -10.5t7 -19.5zM1920 198v-140q0 -16 -149 -31 q-12 -27 -30 -52q51 -113 51 -138q0 -4 -4 -7q-122 -71 -124 -71q-8 0 -46 47t-52 68q-20 -2 -30 -2t-30 2q-14 -21 -52 -68t-46 -47q-2 0 -124 71q-4 3 -4 7q0 25 51 138q-18 25 -30 52q-149 15 -149 31v140q0 16 149 31q13 29 30 52q-51 113 -51 138q0 4 4 7q4 2 35 20 t59 34t30 16q8 0 46 -46.5t52 -67.5q20 2 30 2t30 -2q51 71 92 112l6 2q4 0 124 -70q4 -3 4 -7q0 -25 -51 -138q17 -23 30 -52q149 -15 149 -31zM1920 1222v-140q0 -16 -149 -31q-12 -27 -30 -52q51 -113 51 -138q0 -4 -4 -7q-122 -71 -124 -71q-8 0 -46 47t-52 68 q-20 -2 -30 -2t-30 2q-14 -21 -52 -68t-46 -47q-2 0 -124 71q-4 3 -4 7q0 25 51 138q-18 25 -30 52q-149 15 -149 31v140q0 16 149 31q13 29 30 52q-51 113 -51 138q0 4 4 7q4 2 35 20t59 34t30 16q8 0 46 -46.5t52 -67.5q20 2 30 2t30 -2q51 71 92 112l6 2q4 0 124 -70 q4 -3 4 -7q0 -25 -51 -138q17 -23 30 -52q149 -15 149 -31z" />
275
  <glyph unicode="&#xf10c;" d="M768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103 t279.5 -279.5t103 -385.5z" />
276
  <glyph unicode="&#xf10d;" horiz-adv-x="1664" d="M768 576v-384q0 -80 -56 -136t-136 -56h-384q-80 0 -136 56t-56 136v704q0 104 40.5 198.5t109.5 163.5t163.5 109.5t198.5 40.5h64q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-64q-106 0 -181 -75t-75 -181v-32q0 -40 28 -68t68 -28h224q80 0 136 -56t56 -136z M1664 576v-384q0 -80 -56 -136t-136 -56h-384q-80 0 -136 56t-56 136v704q0 104 40.5 198.5t109.5 163.5t163.5 109.5t198.5 40.5h64q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-64q-106 0 -181 -75t-75 -181v-32q0 -40 28 -68t68 -28h224q80 0 136 -56t56 -136z" />
277
  <glyph unicode="&#xf10e;" horiz-adv-x="1664" d="M768 1216v-704q0 -104 -40.5 -198.5t-109.5 -163.5t-163.5 -109.5t-198.5 -40.5h-64q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h64q106 0 181 75t75 181v32q0 40 -28 68t-68 28h-224q-80 0 -136 56t-56 136v384q0 80 56 136t136 56h384q80 0 136 -56t56 -136zM1664 1216 v-704q0 -104 -40.5 -198.5t-109.5 -163.5t-163.5 -109.5t-198.5 -40.5h-64q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h64q106 0 181 75t75 181v32q0 40 -28 68t-68 28h-224q-80 0 -136 56t-56 136v384q0 80 56 136t136 56h384q80 0 136 -56t56 -136z" />
278
+ <glyph unicode="&#xf110;" horiz-adv-x="1792" d="M526 142q0 -53 -37.5 -90.5t-90.5 -37.5q-52 0 -90 38t-38 90q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1024 -64q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM320 640q0 -53 -37.5 -90.5t-90.5 -37.5 t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1522 142q0 -52 -38 -90t-90 -38q-53 0 -90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM558 1138q0 -66 -47 -113t-113 -47t-113 47t-47 113t47 113t113 47t113 -47t47 -113z M1728 640q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1088 1344q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1618 1138q0 -93 -66 -158.5t-158 -65.5q-93 0 -158.5 65.5t-65.5 158.5 q0 92 65.5 158t158.5 66q92 0 158 -66t66 -158z" />
279
  <glyph unicode="&#xf111;" d="M1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
280
  <glyph unicode="&#xf112;" horiz-adv-x="1792" d="M1792 416q0 -166 -127 -451q-3 -7 -10.5 -24t-13.5 -30t-13 -22q-12 -17 -28 -17q-15 0 -23.5 10t-8.5 25q0 9 2.5 26.5t2.5 23.5q5 68 5 123q0 101 -17.5 181t-48.5 138.5t-80 101t-105.5 69.5t-133 42.5t-154 21.5t-175.5 6h-224v-256q0 -26 -19 -45t-45 -19t-45 19 l-512 512q-19 19 -19 45t19 45l512 512q19 19 45 19t45 -19t19 -45v-256h224q713 0 875 -403q53 -134 53 -333z" />
281
  <glyph unicode="&#xf113;" horiz-adv-x="1664" d="M640 320q0 -40 -12.5 -82t-43 -76t-72.5 -34t-72.5 34t-43 76t-12.5 82t12.5 82t43 76t72.5 34t72.5 -34t43 -76t12.5 -82zM1280 320q0 -40 -12.5 -82t-43 -76t-72.5 -34t-72.5 34t-43 76t-12.5 82t12.5 82t43 76t72.5 34t72.5 -34t43 -76t12.5 -82zM1440 320 q0 120 -69 204t-187 84q-41 0 -195 -21q-71 -11 -157 -11t-157 11q-152 21 -195 21q-118 0 -187 -84t-69 -204q0 -88 32 -153.5t81 -103t122 -60t140 -29.5t149 -7h168q82 0 149 7t140 29.5t122 60t81 103t32 153.5zM1664 496q0 -207 -61 -331q-38 -77 -105.5 -133t-141 -86 t-170 -47.5t-171.5 -22t-167 -4.5q-78 0 -142 3t-147.5 12.5t-152.5 30t-137 51.5t-121 81t-86 115q-62 123 -62 331q0 237 136 396q-27 82 -27 170q0 116 51 218q108 0 190 -39.5t189 -123.5q147 35 309 35q148 0 280 -32q105 82 187 121t189 39q51 -102 51 -218 q0 -87 -27 -168q136 -160 136 -398z" />
411
  <glyph unicode="&#xf19d;" horiz-adv-x="2304" d="M1774 700l18 -316q4 -69 -82 -128t-235 -93.5t-323 -34.5t-323 34.5t-235 93.5t-82 128l18 316l574 -181q22 -7 48 -7t48 7zM2304 1024q0 -23 -22 -31l-1120 -352q-4 -1 -10 -1t-10 1l-652 206q-43 -34 -71 -111.5t-34 -178.5q63 -36 63 -109q0 -69 -58 -107l58 -433 q2 -14 -8 -25q-9 -11 -24 -11h-192q-15 0 -24 11q-10 11 -8 25l58 433q-58 38 -58 107q0 73 65 111q11 207 98 330l-333 104q-22 8 -22 31t22 31l1120 352q4 1 10 1t10 -1l1120 -352q22 -8 22 -31z" />
412
  <glyph unicode="&#xf19e;" d="M859 579l13 -707q-62 11 -105 11q-41 0 -105 -11l13 707q-40 69 -168.5 295.5t-216.5 374.5t-181 287q58 -15 108 -15q43 0 111 15q63 -111 133.5 -229.5t167 -276.5t138.5 -227q37 61 109.5 177.5t117.5 190t105 176t107 189.5q54 -14 107 -14q56 0 114 14v0 q-28 -39 -60 -88.5t-49.5 -78.5t-56.5 -96t-49 -84q-146 -248 -353 -610z" />
413
  <glyph unicode="&#xf1a0;" horiz-adv-x="1280" d="M981 197q0 25 -7 49t-14.5 42t-27 41.5t-29.5 35t-38.5 34.5t-36.5 29t-41.5 30t-36.5 26q-16 2 -49 2q-53 0 -104.5 -7t-107 -25t-97 -46t-68.5 -74.5t-27 -105.5q0 -56 23.5 -102t61 -75.5t87 -50t100 -29t101.5 -8.5q58 0 111.5 13t99 39t73 73t27.5 109zM864 1055 q0 59 -17 125.5t-48 129t-84 103.5t-117 41q-42 0 -82.5 -19.5t-66.5 -52.5q-46 -59 -46 -160q0 -46 10 -97.5t31.5 -103t52 -92.5t75 -67t96.5 -26q37 0 77.5 16.5t65.5 43.5q53 56 53 159zM752 1536h417l-137 -88h-132q75 -63 113 -133t38 -160q0 -72 -24.5 -129.5 t-59.5 -93t-69.5 -65t-59 -61.5t-24.5 -66q0 -36 32 -70.5t77 -68t90.5 -73.5t77.5 -104t32 -142q0 -91 -49 -173q-71 -122 -209.5 -179.5t-298.5 -57.5q-132 0 -246.5 41.5t-172.5 137.5q-36 59 -36 131q0 81 44.5 150t118.5 115q131 82 404 100q-32 41 -47.5 73.5 t-15.5 73.5q0 40 21 85q-46 -4 -68 -4q-148 0 -249.5 96.5t-101.5 244.5q0 82 36 159t99 131q76 66 182 98t218 32z" />
414
+ <glyph unicode="&#xf1a1;" horiz-adv-x="2304" d="M1509 107q0 -14 -12 -29q-52 -59 -147.5 -83t-196.5 -24q-252 0 -346 107q-12 15 -12 29q0 17 12 29.5t29 12.5q15 0 30 -12q58 -49 125.5 -66t159.5 -17t160 17t127 66q15 12 30 12q17 0 29 -12.5t12 -29.5zM978 498q0 -61 -43 -104t-104 -43q-60 0 -104.5 43.5 t-44.5 103.5q0 61 44 105t105 44t104 -44t43 -105zM1622 498q0 -61 -43 -104t-104 -43q-60 0 -104.5 43.5t-44.5 103.5q0 61 44 105t105 44t104 -44t43 -105zM415 793q-39 27 -88 27q-66 0 -113 -47t-47 -113q0 -72 54 -121q53 141 194 254zM2020 382q0 222 -249 387 q-128 85 -291.5 126.5t-331.5 41.5t-331.5 -41.5t-292.5 -126.5q-249 -165 -249 -387t249 -387q129 -85 292.5 -126.5t331.5 -41.5t331.5 41.5t291.5 126.5q249 165 249 387zM2137 660q0 66 -47 113t-113 47q-50 0 -93 -30q140 -114 192 -256q61 48 61 126zM1993 1335 q0 49 -34.5 83.5t-82.5 34.5q-49 0 -83.5 -34.5t-34.5 -83.5q0 -48 34.5 -82.5t83.5 -34.5q48 0 82.5 34.5t34.5 82.5zM2220 660q0 -65 -33 -122t-89 -90q5 -35 5 -66q0 -139 -79 -255.5t-208 -201.5q-140 -92 -313.5 -136.5t-354.5 -44.5t-355 44.5t-314 136.5 q-129 85 -208 201.5t-79 255.5q0 36 6 71q-53 33 -83.5 88.5t-30.5 118.5q0 100 71 171.5t172 71.5q91 0 159 -60q265 170 638 177l144 456q10 29 40 29q24 0 384 -90q24 55 74 88t110 33q82 0 141 -59t59 -142t-59 -141.5t-141 -58.5q-83 0 -141.5 58.5t-59.5 140.5 l-339 80l-125 -395q349 -15 603 -179q71 63 163 63q101 0 172 -71.5t71 -171.5z" />
415
  <glyph unicode="&#xf1a2;" d="M950 393q7 7 17.5 7t17.5 -7t7 -18t-7 -18q-65 -64 -208 -64h-1h-1q-143 0 -207 64q-8 7 -8 18t8 18q7 7 17.5 7t17.5 -7q49 -51 172 -51h1h1q122 0 173 51zM671 613q0 -37 -26 -64t-63 -27t-63 27t-26 64t26 63t63 26t63 -26t26 -63zM1214 1049q-29 0 -50 21t-21 50 q0 30 21 51t50 21q30 0 51 -21t21 -51q0 -29 -21 -50t-51 -21zM1216 1408q132 0 226 -94t94 -227v-894q0 -133 -94 -227t-226 -94h-896q-132 0 -226 94t-94 227v894q0 133 94 227t226 94h896zM1321 596q35 14 57 45.5t22 70.5q0 51 -36 87.5t-87 36.5q-60 0 -98 -48 q-151 107 -375 115l83 265l206 -49q1 -50 36.5 -85t84.5 -35q50 0 86 35.5t36 85.5t-36 86t-86 36q-36 0 -66 -20.5t-45 -53.5l-227 54q-9 2 -17.5 -2.5t-11.5 -14.5l-95 -302q-224 -4 -381 -113q-36 43 -93 43q-51 0 -87 -36.5t-36 -87.5q0 -37 19.5 -67.5t52.5 -45.5 q-7 -25 -7 -54q0 -98 74 -181.5t201.5 -132t278.5 -48.5q150 0 277.5 48.5t201.5 132t74 181.5q0 27 -6 54zM971 702q37 0 63 -26t26 -63t-26 -64t-63 -27t-63 27t-26 64t26 63t63 26z" />
416
  <glyph unicode="&#xf1a3;" d="M866 697l90 27v62q0 79 -58 135t-138 56t-138 -55.5t-58 -134.5v-283q0 -20 -14 -33.5t-33 -13.5t-32.5 13.5t-13.5 33.5v120h-151v-122q0 -82 57.5 -139t139.5 -57q81 0 138.5 56.5t57.5 136.5v280q0 19 13.5 33t33.5 14q19 0 32.5 -14t13.5 -33v-54zM1199 502v122h-150 v-126q0 -20 -13.5 -33.5t-33.5 -13.5q-19 0 -32.5 14t-13.5 33v123l-90 -26l-60 28v-123q0 -80 58 -137t139 -57t138.5 57t57.5 139zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103 t385.5 -103t279.5 -279.5t103 -385.5z" />
417
  <glyph unicode="&#xf1a4;" horiz-adv-x="1920" d="M1062 824v118q0 42 -30 72t-72 30t-72 -30t-30 -72v-612q0 -175 -126 -299t-303 -124q-178 0 -303.5 125.5t-125.5 303.5v266h328v-262q0 -43 30 -72.5t72 -29.5t72 29.5t30 72.5v620q0 171 126.5 292t301.5 121q176 0 302 -122t126 -294v-136l-195 -58zM1592 602h328 v-266q0 -178 -125.5 -303.5t-303.5 -125.5q-177 0 -303 124.5t-126 300.5v268l131 -61l195 58v-270q0 -42 30 -71.5t72 -29.5t72 29.5t30 71.5v275z" />
438
  <glyph unicode="&#xf1ba;" horiz-adv-x="2048" d="M1824 640q93 0 158.5 -65.5t65.5 -158.5v-384q0 -14 -9 -23t-23 -9h-96v-64q0 -80 -56 -136t-136 -56t-136 56t-56 136v64h-1024v-64q0 -80 -56 -136t-136 -56t-136 56t-56 136v64h-96q-14 0 -23 9t-9 23v384q0 93 65.5 158.5t158.5 65.5h28l105 419q23 94 104 157.5 t179 63.5h128v224q0 14 9 23t23 9h448q14 0 23 -9t9 -23v-224h128q98 0 179 -63.5t104 -157.5l105 -419h28zM320 160q66 0 113 47t47 113t-47 113t-113 47t-113 -47t-47 -113t47 -113t113 -47zM516 640h1016l-89 357q-2 8 -14 17.5t-21 9.5h-768q-9 0 -21 -9.5t-14 -17.5z M1728 160q66 0 113 47t47 113t-47 113t-113 47t-113 -47t-47 -113t47 -113t113 -47z" />
439
  <glyph unicode="&#xf1bb;" d="M1504 64q0 -26 -19 -45t-45 -19h-462q1 -17 6 -87.5t5 -108.5q0 -25 -18 -42.5t-43 -17.5h-320q-25 0 -43 17.5t-18 42.5q0 38 5 108.5t6 87.5h-462q-26 0 -45 19t-19 45t19 45l402 403h-229q-26 0 -45 19t-19 45t19 45l402 403h-197q-26 0 -45 19t-19 45t19 45l384 384 q19 19 45 19t45 -19l384 -384q19 -19 19 -45t-19 -45t-45 -19h-197l402 -403q19 -19 19 -45t-19 -45t-45 -19h-229l402 -403q19 -19 19 -45z" />
440
  <glyph unicode="&#xf1bc;" d="M1127 326q0 32 -30 51q-193 115 -447 115q-133 0 -287 -34q-42 -9 -42 -52q0 -20 13.5 -34.5t35.5 -14.5q5 0 37 8q132 27 243 27q226 0 397 -103q19 -11 33 -11q19 0 33 13.5t14 34.5zM1223 541q0 40 -35 61q-237 141 -548 141q-153 0 -303 -42q-48 -13 -48 -64 q0 -25 17.5 -42.5t42.5 -17.5q7 0 37 8q122 33 251 33q279 0 488 -124q24 -13 38 -13q25 0 42.5 17.5t17.5 42.5zM1331 789q0 47 -40 70q-126 73 -293 110.5t-343 37.5q-204 0 -364 -47q-23 -7 -38.5 -25.5t-15.5 -48.5q0 -31 20.5 -52t51.5 -21q11 0 40 8q133 37 307 37 q159 0 309.5 -34t253.5 -95q21 -12 40 -12q29 0 50.5 20.5t21.5 51.5zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
441
+ <glyph unicode="&#xf1bd;" horiz-adv-x="1024" d="M1024 1233l-303 -582l24 -31h279v-415h-507l-44 -30l-142 -273l-30 -30h-301v303l303 583l-24 30h-279v415h507l44 30l142 273l30 30h301v-303z" />
442
  <glyph unicode="&#xf1be;" horiz-adv-x="2304" d="M784 164l16 241l-16 523q-1 10 -7.5 17t-16.5 7q-9 0 -16 -7t-7 -17l-14 -523l14 -241q1 -10 7.5 -16.5t15.5 -6.5q22 0 24 23zM1080 193l11 211l-12 586q0 16 -13 24q-8 5 -16 5t-16 -5q-13 -8 -13 -24l-1 -6l-10 -579q0 -1 11 -236v-1q0 -10 6 -17q9 -11 23 -11 q11 0 20 9q9 7 9 20zM35 533l20 -128l-20 -126q-2 -9 -9 -9t-9 9l-17 126l17 128q2 9 9 9t9 -9zM121 612l26 -207l-26 -203q-2 -9 -10 -9q-9 0 -9 10l-23 202l23 207q0 9 9 9q8 0 10 -9zM401 159zM213 650l25 -245l-25 -237q0 -11 -11 -11q-10 0 -12 11l-21 237l21 245 q2 12 12 12q11 0 11 -12zM307 657l23 -252l-23 -244q-2 -13 -14 -13q-13 0 -13 13l-21 244l21 252q0 13 13 13q12 0 14 -13zM401 639l21 -234l-21 -246q-2 -16 -16 -16q-6 0 -10.5 4.5t-4.5 11.5l-20 246l20 234q0 6 4.5 10.5t10.5 4.5q14 0 16 -15zM784 164zM495 785 l21 -380l-21 -246q0 -7 -5 -12.5t-12 -5.5q-16 0 -18 18l-18 246l18 380q2 18 18 18q7 0 12 -5.5t5 -12.5zM589 871l19 -468l-19 -244q0 -8 -5.5 -13.5t-13.5 -5.5q-18 0 -20 19l-16 244l16 468q2 19 20 19q8 0 13.5 -5.5t5.5 -13.5zM687 911l18 -506l-18 -242 q-2 -21 -22 -21q-19 0 -21 21l-16 242l16 506q0 9 6.5 15.5t14.5 6.5q9 0 15 -6.5t7 -15.5zM1079 169v0v0zM881 915l15 -510l-15 -239q0 -10 -7.5 -17.5t-17.5 -7.5t-17 7t-8 18l-14 239l14 510q0 11 7.5 18t17.5 7t17.5 -7t7.5 -18zM980 896l14 -492l-14 -236q0 -11 -8 -19 t-19 -8t-19 8t-9 19l-12 236l12 492q1 12 9 20t19 8t18.5 -8t8.5 -20zM1192 404l-14 -231v0q0 -13 -9 -22t-22 -9t-22 9t-10 22l-6 114l-6 117l12 636v3q2 15 12 24q9 7 20 7q8 0 15 -5q14 -8 16 -26zM2304 423q0 -117 -83 -199.5t-200 -82.5h-786q-13 2 -22 11t-9 22v899 q0 23 28 33q85 34 181 34q195 0 338 -131.5t160 -323.5q53 22 110 22q117 0 200 -83t83 -201z" />
443
  <glyph unicode="&#xf1c0;" d="M768 768q237 0 443 43t325 127v-170q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5t-103 128v170q119 -84 325 -127t443 -43zM768 0q237 0 443 43t325 127v-170q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5t-103 128v170q119 -84 325 -127 t443 -43zM768 384q237 0 443 43t325 127v-170q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5t-103 128v170q119 -84 325 -127t443 -43zM768 1536q208 0 385 -34.5t280 -93.5t103 -128v-128q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5 t-103 128v128q0 69 103 128t280 93.5t385 34.5z" />
444
  <glyph unicode="&#xf1c1;" d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z M894 465q33 -26 84 -56q59 7 117 7q147 0 177 -49q16 -22 2 -52q0 -1 -1 -2l-2 -2v-1q-6 -38 -71 -38q-48 0 -115 20t-130 53q-221 -24 -392 -83q-153 -262 -242 -262q-15 0 -28 7l-24 12q-1 1 -6 5q-10 10 -6 36q9 40 56 91.5t132 96.5q14 9 23 -6q2 -2 2 -4q52 85 107 197 q68 136 104 262q-24 82 -30.5 159.5t6.5 127.5q11 40 42 40h21h1q23 0 35 -15q18 -21 9 -68q-2 -6 -4 -8q1 -3 1 -8v-30q-2 -123 -14 -192q55 -164 146 -238zM318 54q52 24 137 158q-51 -40 -87.5 -84t-49.5 -74zM716 974q-15 -42 -2 -132q1 7 7 44q0 3 7 43q1 4 4 8 q-1 1 -1 2t-0.5 1.5t-0.5 1.5q-1 22 -13 36q0 -1 -1 -2v-2zM592 313q135 54 284 81q-2 1 -13 9.5t-16 13.5q-76 67 -127 176q-27 -86 -83 -197q-30 -56 -45 -83zM1238 329q-24 24 -140 24q76 -28 124 -28q14 0 18 1q0 1 -2 3z" />
513
  <glyph unicode="&#xf20a;" horiz-adv-x="2048" d="M785 528h207q-14 -158 -98.5 -248.5t-214.5 -90.5q-162 0 -254.5 116t-92.5 316q0 194 93 311.5t233 117.5q148 0 232 -87t97 -247h-203q-5 64 -35.5 99t-81.5 35q-57 0 -88.5 -60.5t-31.5 -177.5q0 -48 5 -84t18 -69.5t40 -51.5t66 -18q95 0 109 139zM1497 528h206 q-14 -158 -98 -248.5t-214 -90.5q-162 0 -254.5 116t-92.5 316q0 194 93 311.5t233 117.5q148 0 232 -87t97 -247h-204q-4 64 -35 99t-81 35q-57 0 -88.5 -60.5t-31.5 -177.5q0 -48 5 -84t18 -69.5t39.5 -51.5t65.5 -18q49 0 76.5 38t33.5 101zM1856 647q0 207 -15.5 307 t-60.5 161q-6 8 -13.5 14t-21.5 15t-16 11q-86 63 -697 63q-625 0 -710 -63q-5 -4 -17.5 -11.5t-21 -14t-14.5 -14.5q-45 -60 -60 -159.5t-15 -308.5q0 -208 15 -307.5t60 -160.5q6 -8 15 -15t20.5 -14t17.5 -12q44 -33 239.5 -49t470.5 -16q610 0 697 65q5 4 17 11t20.5 14 t13.5 16q46 60 61 159t15 309zM2048 1408v-1536h-2048v1536h2048z" />
514
  <glyph unicode="&#xf20b;" d="M992 912v-496q0 -14 -9 -23t-23 -9h-160q-14 0 -23 9t-9 23v496q0 112 -80 192t-192 80h-272v-1152q0 -14 -9 -23t-23 -9h-160q-14 0 -23 9t-9 23v1344q0 14 9 23t23 9h464q135 0 249 -66.5t180.5 -180.5t66.5 -249zM1376 1376v-880q0 -135 -66.5 -249t-180.5 -180.5 t-249 -66.5h-464q-14 0 -23 9t-9 23v960q0 14 9 23t23 9h160q14 0 23 -9t9 -23v-768h272q112 0 192 80t80 192v880q0 14 9 23t23 9h160q14 0 23 -9t9 -23z" />
515
  <glyph unicode="&#xf20c;" d="M1311 694v-114q0 -24 -13.5 -38t-37.5 -14h-202q-24 0 -38 14t-14 38v114q0 24 14 38t38 14h202q24 0 37.5 -14t13.5 -38zM821 464v250q0 53 -32.5 85.5t-85.5 32.5h-133q-68 0 -96 -52q-28 52 -96 52h-130q-53 0 -85.5 -32.5t-32.5 -85.5v-250q0 -22 21 -22h55 q22 0 22 22v230q0 24 13.5 38t38.5 14h94q24 0 38 -14t14 -38v-230q0 -22 21 -22h54q22 0 22 22v230q0 24 14 38t38 14h97q24 0 37.5 -14t13.5 -38v-230q0 -22 22 -22h55q21 0 21 22zM1410 560v154q0 53 -33 85.5t-86 32.5h-264q-53 0 -86 -32.5t-33 -85.5v-410 q0 -21 22 -21h55q21 0 21 21v180q31 -42 94 -42h191q53 0 86 32.5t33 85.5zM1536 1176v-1072q0 -96 -68 -164t-164 -68h-1072q-96 0 -164 68t-68 164v1072q0 96 68 164t164 68h1072q96 0 164 -68t68 -164z" />
516
+ <glyph unicode="&#xf20d;" d="M915 450h-294l147 551zM1001 128h311l-324 1024h-440l-324 -1024h311l383 314zM1536 1120v-960q0 -118 -85 -203t-203 -85h-960q-118 0 -203 85t-85 203v960q0 118 85 203t203 85h960q118 0 203 -85t85 -203z" />
517
+ <glyph unicode="&#xf20e;" horiz-adv-x="2048" d="M2048 641q0 -21 -13 -36.5t-33 -19.5l-205 -356q3 -9 3 -18q0 -20 -12.5 -35.5t-32.5 -19.5l-193 -337q3 -8 3 -16q0 -23 -16.5 -40t-40.5 -17q-25 0 -41 18h-400q-17 -20 -43 -20t-43 20h-399q-17 -20 -43 -20q-23 0 -40 16.5t-17 40.5q0 8 4 20l-193 335 q-20 4 -32.5 19.5t-12.5 35.5q0 9 3 18l-206 356q-20 5 -32.5 20.5t-12.5 35.5q0 21 13.5 36.5t33.5 19.5l199 344q0 1 -0.5 3t-0.5 3q0 36 34 51l209 363q-4 10 -4 18q0 24 17 40.5t40 16.5q26 0 44 -21h396q16 21 43 21t43 -21h398q18 21 44 21q23 0 40 -16.5t17 -40.5 q0 -6 -4 -18l207 -358q23 -1 39 -17.5t16 -38.5q0 -13 -7 -27l187 -324q19 -4 31.5 -19.5t12.5 -35.5zM1063 -158h389l-342 354h-143l-342 -354h360q18 16 39 16t39 -16zM112 654q1 -4 1 -13q0 -10 -2 -15l208 -360q2 0 4.5 -1t5.5 -2.5l5 -2.5l188 199v347l-187 194 q-13 -8 -29 -10zM986 1438h-388l190 -200l554 200h-280q-16 -16 -38 -16t-38 16zM1689 226q1 6 5 11l-64 68l-17 -79h76zM1583 226l22 105l-252 266l-296 -307l63 -64h463zM1495 -142l16 28l65 310h-427l333 -343q8 4 13 5zM578 -158h5l342 354h-373v-335l4 -6q14 -5 22 -13 zM552 226h402l64 66l-309 321l-157 -166v-221zM359 226h163v189l-168 -177q4 -8 5 -12zM358 1051q0 -1 0.5 -2t0.5 -2q0 -16 -8 -29l171 -177v269zM552 1121v-311l153 -157l297 314l-223 236zM556 1425l-4 -8v-264l205 74l-191 201q-6 -2 -10 -3zM1447 1438h-16l-621 -224 l213 -225zM1023 946l-297 -315l311 -319l296 307zM688 634l-136 141v-284zM1038 270l-42 -44h85zM1374 618l238 -251l132 624l-3 5l-1 1zM1718 1018q-8 13 -8 29v2l-216 376q-5 1 -13 5l-437 -463l310 -327zM522 1142v223l-163 -282zM522 196h-163l163 -283v283zM1607 196 l-48 -227l130 227h-82zM1729 266l207 361q-2 10 -2 14q0 1 3 16l-171 296l-129 -612l77 -82q5 3 15 7z" />
518
+ <glyph unicode="&#xf210;" d="M0 856q0 131 91.5 226.5t222.5 95.5h742l352 358v-1470q0 -132 -91.5 -227t-222.5 -95h-780q-131 0 -222.5 95t-91.5 227v790zM1232 102l-176 180v425q0 46 -32 79t-78 33h-484q-46 0 -78 -33t-32 -79v-492q0 -46 32.5 -79.5t77.5 -33.5h770z" />
519
+ <glyph unicode="&#xf211;" d="M934 1386q-317 -121 -556 -362.5t-358 -560.5q-20 89 -20 176q0 208 102.5 384.5t278.5 279t384 102.5q82 0 169 -19zM1203 1267q93 -65 164 -155q-389 -113 -674.5 -400.5t-396.5 -676.5q-93 72 -155 162q112 386 395 671t667 399zM470 -67q115 356 379.5 622t619.5 384 q40 -92 54 -195q-292 -120 -516 -345t-343 -518q-103 14 -194 52zM1536 -125q-193 50 -367 115q-135 -84 -290 -107q109 205 274 370.5t369 275.5q-21 -152 -101 -284q65 -175 115 -370z" />
520
+ <glyph unicode="&#xf212;" horiz-adv-x="2048" d="M1893 1144l155 -1272q-131 0 -257 57q-200 91 -393 91q-226 0 -374 -148q-148 148 -374 148q-193 0 -393 -91q-128 -57 -252 -57h-5l155 1272q224 127 482 127q233 0 387 -106q154 106 387 106q258 0 482 -127zM1398 157q129 0 232 -28.5t260 -93.5l-124 1021 q-171 78 -368 78q-224 0 -374 -141q-150 141 -374 141q-197 0 -368 -78l-124 -1021q105 43 165.5 65t148.5 39.5t178 17.5q202 0 374 -108q172 108 374 108zM1438 191l-55 907q-211 -4 -359 -155q-152 155 -374 155q-176 0 -336 -66l-114 -941q124 51 228.5 76t221.5 25 q209 0 374 -102q172 107 374 102z" />
521
+ <glyph unicode="&#xf213;" horiz-adv-x="2048" d="M1500 165v733q0 21 -15 36t-35 15h-93q-20 0 -35 -15t-15 -36v-733q0 -20 15 -35t35 -15h93q20 0 35 15t15 35zM1216 165v531q0 20 -15 35t-35 15h-101q-20 0 -35 -15t-15 -35v-531q0 -20 15 -35t35 -15h101q20 0 35 15t15 35zM924 165v429q0 20 -15 35t-35 15h-101 q-20 0 -35 -15t-15 -35v-429q0 -20 15 -35t35 -15h101q20 0 35 15t15 35zM632 165v362q0 20 -15 35t-35 15h-101q-20 0 -35 -15t-15 -35v-362q0 -20 15 -35t35 -15h101q20 0 35 15t15 35zM2048 311q0 -166 -118 -284t-284 -118h-1244q-166 0 -284 118t-118 284 q0 116 63 214.5t168 148.5q-10 34 -10 73q0 113 80.5 193.5t193.5 80.5q102 0 180 -67q45 183 194 300t338 117q149 0 275 -73.5t199.5 -199.5t73.5 -275q0 -66 -14 -122q135 -33 221 -142.5t86 -247.5z" />
522
+ <glyph unicode="&#xf214;" d="M0 1536h1536v-1392l-776 -338l-760 338v1392zM1436 209v926h-1336v-926l661 -294zM1436 1235v201h-1336v-201h1336zM181 937v-115h-37v115h37zM181 789v-115h-37v115h37zM181 641v-115h-37v115h37zM181 493v-115h-37v115h37zM181 345v-115h-37v115h37zM207 202l15 34 l105 -47l-15 -33zM343 142l15 34l105 -46l-15 -34zM478 82l15 34l105 -46l-15 -34zM614 23l15 33l104 -46l-15 -34zM797 10l105 46l15 -33l-105 -47zM932 70l105 46l15 -34l-105 -46zM1068 130l105 46l15 -34l-105 -46zM1203 189l105 47l15 -34l-105 -46zM259 1389v-36h-114 v36h114zM421 1389v-36h-115v36h115zM583 1389v-36h-115v36h115zM744 1389v-36h-114v36h114zM906 1389v-36h-114v36h114zM1068 1389v-36h-115v36h115zM1230 1389v-36h-115v36h115zM1391 1389v-36h-114v36h114zM181 1049v-79h-37v115h115v-36h-78zM421 1085v-36h-115v36h115z M583 1085v-36h-115v36h115zM744 1085v-36h-114v36h114zM906 1085v-36h-114v36h114zM1068 1085v-36h-115v36h115zM1230 1085v-36h-115v36h115zM1355 970v79h-78v36h115v-115h-37zM1355 822v115h37v-115h-37zM1355 674v115h37v-115h-37zM1355 526v115h37v-115h-37zM1355 378 v115h37v-115h-37zM1355 230v115h37v-115h-37zM760 265q-129 0 -221 91.5t-92 221.5q0 129 92 221t221 92q130 0 221.5 -92t91.5 -221q0 -130 -91.5 -221.5t-221.5 -91.5zM595 646q0 -36 19.5 -56.5t49.5 -25t64 -7t64 -2t49.5 -9t19.5 -30.5q0 -49 -112 -49q-97 0 -123 51 h-3l-31 -63q67 -42 162 -42q29 0 56.5 5t55.5 16t45.5 33t17.5 53q0 46 -27.5 69.5t-67.5 27t-79.5 3t-67 5t-27.5 25.5q0 21 20.5 33t40.5 15t41 3q34 0 70.5 -11t51.5 -34h3l30 58q-3 1 -21 8.5t-22.5 9t-19.5 7t-22 7t-20 4.5t-24 4t-23 1q-29 0 -56.5 -5t-54 -16.5 t-43 -34t-16.5 -53.5z" />
523
+ <glyph unicode="&#xf215;" horiz-adv-x="2048" d="M863 504q0 112 -79.5 191.5t-191.5 79.5t-191 -79.5t-79 -191.5t79 -191t191 -79t191.5 79t79.5 191zM1726 505q0 112 -79 191t-191 79t-191.5 -79t-79.5 -191q0 -113 79.5 -192t191.5 -79t191 79.5t79 191.5zM2048 1314v-1348q0 -44 -31.5 -75.5t-76.5 -31.5h-1832 q-45 0 -76.5 31.5t-31.5 75.5v1348q0 44 31.5 75.5t76.5 31.5h431q44 0 76 -31.5t32 -75.5v-161h754v161q0 44 32 75.5t76 31.5h431q45 0 76.5 -31.5t31.5 -75.5z" />
524
+ <glyph unicode="&#xf216;" horiz-adv-x="2048" d="M1430 953zM1690 749q148 0 253 -98.5t105 -244.5q0 -157 -109 -261.5t-267 -104.5q-85 0 -162 27.5t-138 73.5t-118 106t-109 126.5t-103.5 132.5t-108.5 126t-117 106t-136 73.5t-159 27.5q-154 0 -251.5 -91.5t-97.5 -244.5q0 -157 104 -250t263 -93q100 0 208 37.5 t193 98.5q5 4 21 18.5t30 24t22 9.5q14 0 24.5 -10.5t10.5 -24.5q0 -24 -60 -77q-101 -88 -234.5 -142t-260.5 -54q-133 0 -245.5 58t-180 165t-67.5 241q0 205 141.5 341t347.5 136q120 0 226.5 -43.5t185.5 -113t151.5 -153t139 -167.5t133.5 -153.5t149.5 -113 t172.5 -43.5q102 0 168.5 61.5t66.5 162.5q0 95 -64.5 159t-159.5 64q-30 0 -81.5 -18.5t-68.5 -18.5q-20 0 -35.5 15t-15.5 35q0 18 8.5 57t8.5 59q0 159 -107.5 263t-266.5 104q-58 0 -111.5 -18.5t-84 -40.5t-55.5 -40.5t-33 -18.5q-15 0 -25.5 10.5t-10.5 25.5 q0 19 25 46q59 67 147 103.5t182 36.5q191 0 318 -125.5t127 -315.5q0 -37 -4 -66q57 15 115 15z" />
525
+ <glyph unicode="&#xf217;" horiz-adv-x="1664" d="M1216 832q0 26 -19 45t-45 19h-128v128q0 26 -19 45t-45 19t-45 -19t-19 -45v-128h-128q-26 0 -45 -19t-19 -45t19 -45t45 -19h128v-128q0 -26 19 -45t45 -19t45 19t19 45v128h128q26 0 45 19t19 45zM640 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5 t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1536 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1664 1088v-512q0 -24 -16 -42.5t-41 -21.5l-1044 -122q1 -7 4.5 -21.5t6 -26.5t2.5 -22q0 -16 -24 -64h920 q26 0 45 -19t19 -45t-19 -45t-45 -19h-1024q-26 0 -45 19t-19 45q0 14 11 39.5t29.5 59.5t20.5 38l-177 823h-204q-26 0 -45 19t-19 45t19 45t45 19h256q16 0 28.5 -6.5t20 -15.5t13 -24.5t7.5 -26.5t5.5 -29.5t4.5 -25.5h1201q26 0 45 -19t19 -45z" />
526
+ <glyph unicode="&#xf218;" horiz-adv-x="1792" d="M1280 832q0 26 -19 45t-45 19t-45 -19l-147 -146v293q0 26 -19 45t-45 19t-45 -19t-19 -45v-293l-147 146q-19 19 -45 19t-45 -19t-19 -45t19 -45l256 -256q19 -19 45 -19t45 19l256 256q19 19 19 45zM640 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5 t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1536 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1664 1088v-512q0 -24 -16 -42.5t-41 -21.5l-1044 -122q1 -7 4.5 -21.5t6 -26.5t2.5 -22q0 -16 -24 -64h920 q26 0 45 -19t19 -45t-19 -45t-45 -19h-1024q-26 0 -45 19t-19 45q0 14 11 39.5t29.5 59.5t20.5 38l-177 823h-204q-26 0 -45 19t-19 45t19 45t45 19h256q16 0 28.5 -6.5t20 -15.5t13 -24.5t7.5 -26.5t5.5 -29.5t4.5 -25.5h1201q26 0 45 -19t19 -45z" />
527
+ <glyph unicode="&#xf219;" horiz-adv-x="2048" d="M212 768l623 -665l-300 665h-323zM1024 -4l349 772h-698zM538 896l204 384h-262l-288 -384h346zM1213 103l623 665h-323zM683 896h682l-204 384h-274zM1510 896h346l-288 384h-262zM1651 1382l384 -512q14 -18 13 -41.5t-17 -40.5l-960 -1024q-18 -20 -47 -20t-47 20 l-960 1024q-16 17 -17 40.5t13 41.5l384 512q18 26 51 26h1152q33 0 51 -26z" />
528
+ <glyph unicode="&#xf21a;" horiz-adv-x="2048" d="M1811 -19q19 19 45 19t45 -19l128 -128l-90 -90l-83 83l-83 -83q-18 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83 q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-128 128l90 90l83 -83l83 83q19 19 45 19t45 -19l83 -83l83 83q19 19 45 19t45 -19l83 -83l83 83q19 19 45 19t45 -19l83 -83l83 83q19 19 45 19t45 -19l83 -83l83 83q19 19 45 19t45 -19l83 -83l83 83 q19 19 45 19t45 -19l83 -83zM237 19q-19 -19 -45 -19t-45 19l-128 128l90 90l83 -82l83 82q19 19 45 19t45 -19l83 -82l64 64v293l-210 314q-17 26 -7 56.5t40 40.5l177 58v299h128v128h256v128h256v-128h256v-128h128v-299l177 -58q30 -10 40 -40.5t-7 -56.5l-210 -314 v-293l19 18q19 19 45 19t45 -19l83 -82l83 82q19 19 45 19t45 -19l128 -128l-90 -90l-83 83l-83 -83q-18 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83 q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83zM640 1152v-128l384 128l384 -128v128h-128v128h-512v-128h-128z" />
529
+ <glyph unicode="&#xf21b;" d="M576 0l96 448l-96 128l-128 64zM832 0l128 640l-128 -64l-96 -128zM992 1010q-2 4 -4 6q-10 8 -96 8q-70 0 -167 -19q-7 -2 -21 -2t-21 2q-97 19 -167 19q-86 0 -96 -8q-2 -2 -4 -6q2 -18 4 -27q2 -3 7.5 -6.5t7.5 -10.5q2 -4 7.5 -20.5t7 -20.5t7.5 -17t8.5 -17t9 -14 t12 -13.5t14 -9.5t17.5 -8t20.5 -4t24.5 -2q36 0 59 12.5t32.5 30t14.5 34.5t11.5 29.5t17.5 12.5h12q11 0 17.5 -12.5t11.5 -29.5t14.5 -34.5t32.5 -30t59 -12.5q13 0 24.5 2t20.5 4t17.5 8t14 9.5t12 13.5t9 14t8.5 17t7.5 17t7 20.5t7.5 20.5q2 7 7.5 10.5t7.5 6.5 q2 9 4 27zM1408 131q0 -121 -73 -190t-194 -69h-874q-121 0 -194 69t-73 190q0 61 4.5 118t19 125.5t37.5 123.5t63.5 103.5t93.5 74.5l-90 220h214q-22 64 -22 128q0 12 2 32q-194 40 -194 96q0 57 210 99q17 62 51.5 134t70.5 114q32 37 76 37q30 0 84 -31t84 -31t84 31 t84 31q44 0 76 -37q36 -42 70.5 -114t51.5 -134q210 -42 210 -99q0 -56 -194 -96q7 -81 -20 -160h214l-82 -225q63 -33 107.5 -96.5t65.5 -143.5t29 -151.5t8 -148.5z" />
530
+ <glyph unicode="&#xf21c;" horiz-adv-x="2304" d="M2301 500q12 -103 -22 -198.5t-99 -163.5t-158.5 -106t-196.5 -31q-161 11 -279.5 125t-134.5 274q-12 111 27.5 210.5t118.5 170.5l-71 107q-96 -80 -151 -194t-55 -244q0 -27 -18.5 -46.5t-45.5 -19.5h-256h-69q-23 -164 -149 -274t-294 -110q-185 0 -316.5 131.5 t-131.5 316.5t131.5 316.5t316.5 131.5q76 0 152 -27l24 45q-123 110 -304 110h-64q-26 0 -45 19t-19 45t19 45t45 19h128q78 0 145 -13.5t116.5 -38.5t71.5 -39.5t51 -36.5h512h115l-85 128h-222q-30 0 -49 22.5t-14 52.5q4 23 23 38t43 15h253q33 0 53 -28l70 -105 l114 114q19 19 46 19h101q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-179l115 -172q131 63 275 36q143 -26 244 -134.5t118 -253.5zM448 128q115 0 203 72.5t111 183.5h-314q-35 0 -55 31q-18 32 -1 63l147 277q-47 13 -91 13q-132 0 -226 -94t-94 -226t94 -226 t226 -94zM1856 128q132 0 226 94t94 226t-94 226t-226 94q-60 0 -121 -24l174 -260q15 -23 10 -49t-27 -40q-15 -11 -36 -11q-35 0 -53 29l-174 260q-93 -95 -93 -225q0 -132 94 -226t226 -94z" />
531
+ <glyph unicode="&#xf21d;" d="M1408 0q0 -63 -61.5 -113.5t-164 -81t-225 -46t-253.5 -15.5t-253.5 15.5t-225 46t-164 81t-61.5 113.5q0 49 33 88.5t91 66.5t118 44.5t131 29.5q26 5 48 -10.5t26 -41.5q5 -26 -10.5 -48t-41.5 -26q-58 -10 -106 -23.5t-76.5 -25.5t-48.5 -23.5t-27.5 -19.5t-8.5 -12 q3 -11 27 -26.5t73 -33t114 -32.5t160.5 -25t201.5 -10t201.5 10t160.5 25t114 33t73 33.5t27 27.5q-1 4 -8.5 11t-27.5 19t-48.5 23.5t-76.5 25t-106 23.5q-26 4 -41.5 26t-10.5 48q4 26 26 41.5t48 10.5q71 -12 131 -29.5t118 -44.5t91 -66.5t33 -88.5zM1024 896v-384 q0 -26 -19 -45t-45 -19h-64v-384q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v384h-64q-26 0 -45 19t-19 45v384q0 53 37.5 90.5t90.5 37.5h384q53 0 90.5 -37.5t37.5 -90.5zM928 1280q0 -93 -65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5 t158.5 -65.5t65.5 -158.5z" />
532
+ <glyph unicode="&#xf21e;" horiz-adv-x="1792" d="M1280 512h305q-5 -6 -10 -10.5t-9 -7.5l-3 -4l-623 -600q-18 -18 -44 -18t-44 18l-624 602q-5 2 -21 20h369q22 0 39.5 13.5t22.5 34.5l70 281l190 -667q6 -20 23 -33t39 -13q21 0 38 13t23 33l146 485l56 -112q18 -35 57 -35zM1792 940q0 -145 -103 -300h-369l-111 221 q-8 17 -25.5 27t-36.5 8q-45 -5 -56 -46l-129 -430l-196 686q-6 20 -23.5 33t-39.5 13t-39 -13.5t-22 -34.5l-116 -464h-423q-103 155 -103 300q0 220 127 344t351 124q62 0 126.5 -21.5t120 -58t95.5 -68.5t76 -68q36 36 76 68t95.5 68.5t120 58t126.5 21.5q224 0 351 -124 t127 -344z" />
533
+ <glyph unicode="&#xf221;" horiz-adv-x="1280" d="M1152 960q0 -221 -147.5 -384.5t-364.5 -187.5v-260h224q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-224v-224q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v224h-224q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h224v260q-150 16 -271.5 103t-186 224t-52.5 292 q11 134 80.5 249t182 188t245.5 88q170 19 319 -54t236 -212t87 -306zM128 960q0 -185 131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5z" />
534
+ <glyph unicode="&#xf222;" horiz-adv-x="1792" d="M1280 1504q0 14 9 23t23 9h416q26 0 45 -19t19 -45v-416q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v262l-419 -420q87 -104 129.5 -236.5t30.5 -276.5q-22 -250 -200.5 -431t-428.5 -206q-163 -17 -314 39.5t-256.5 162t-162 256.5t-39.5 314q25 250 206 428.5 t431 200.5q144 12 276.5 -30.5t236.5 -129.5l419 419h-261q-14 0 -23 9t-9 23v64zM704 -128q117 0 223.5 45.5t184 123t123 184t45.5 223.5t-45.5 223.5t-123 184t-184 123t-223.5 45.5t-223.5 -45.5t-184 -123t-123 -184t-45.5 -223.5t45.5 -223.5t123 -184t184 -123 t223.5 -45.5z" />
535
+ <glyph unicode="&#xf223;" horiz-adv-x="1280" d="M830 1220q145 -72 233.5 -210.5t88.5 -305.5q0 -221 -147.5 -384.5t-364.5 -187.5v-132h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96v-96q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v96h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96v132q-217 24 -364.5 187.5 t-147.5 384.5q0 167 88.5 305.5t233.5 210.5q-165 96 -228 273q-6 16 3.5 29.5t26.5 13.5h69q21 0 29 -20q44 -106 140 -171t214 -65t214 65t140 171q8 20 37 20h61q17 0 26.5 -13.5t3.5 -29.5q-63 -177 -228 -273zM576 256q185 0 316.5 131.5t131.5 316.5t-131.5 316.5 t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" />
536
+ <glyph unicode="&#xf224;" d="M1024 1504q0 14 9 23t23 9h288q26 0 45 -19t19 -45v-288q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v134l-254 -255q126 -158 126 -359q0 -221 -147.5 -384.5t-364.5 -187.5v-132h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96v-96q0 -14 -9 -23t-23 -9h-64 q-14 0 -23 9t-9 23v96h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96v132q-149 16 -270.5 103t-186.5 223.5t-53 291.5q16 204 160 353.5t347 172.5q118 14 228 -19t198 -103l255 254h-134q-14 0 -23 9t-9 23v64zM576 256q185 0 316.5 131.5t131.5 316.5t-131.5 316.5 t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" />
537
+ <glyph unicode="&#xf225;" horiz-adv-x="1792" d="M1280 1504q0 14 9 23t23 9h288q26 0 45 -19t19 -45v-288q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v134l-254 -255q126 -158 126 -359q0 -221 -147.5 -384.5t-364.5 -187.5v-132h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96v-96q0 -14 -9 -23t-23 -9h-64 q-14 0 -23 9t-9 23v96h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96v132q-217 24 -364.5 187.5t-147.5 384.5q0 201 126 359l-52 53l-101 -111q-9 -10 -22 -10.5t-23 7.5l-48 44q-10 8 -10.5 21.5t8.5 23.5l105 115l-111 112v-134q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9 t-9 23v288q0 26 19 45t45 19h288q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-133l106 -107l86 94q9 10 22 10.5t23 -7.5l48 -44q10 -8 10.5 -21.5t-8.5 -23.5l-90 -99l57 -56q158 126 359 126t359 -126l255 254h-134q-14 0 -23 9t-9 23v64zM832 256q185 0 316.5 131.5 t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" />
538
+ <glyph unicode="&#xf226;" horiz-adv-x="1792" d="M1790 1007q12 -155 -52.5 -292t-186 -224t-271.5 -103v-260h224q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-224v-224q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v224h-512v-224q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v224h-224q-14 0 -23 9t-9 23v64q0 14 9 23 t23 9h224v260q-150 16 -271.5 103t-186 224t-52.5 292q17 206 164.5 356.5t352.5 169.5q206 21 377 -94q171 115 377 94q205 -19 352.5 -169.5t164.5 -356.5zM896 647q128 131 128 313t-128 313q-128 -131 -128 -313t128 -313zM576 512q115 0 218 57q-154 165 -154 391 q0 224 154 391q-103 57 -218 57q-185 0 -316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5zM1152 128v260q-137 15 -256 94q-119 -79 -256 -94v-260h512zM1216 512q185 0 316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5q-115 0 -218 -57q154 -167 154 -391 q0 -226 -154 -391q103 -57 218 -57z" />
539
+ <glyph unicode="&#xf227;" horiz-adv-x="1920" d="M1536 1120q0 14 9 23t23 9h288q26 0 45 -19t19 -45v-288q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v134l-254 -255q76 -95 107.5 -214t9.5 -247q-31 -182 -166 -312t-318 -156q-210 -29 -384.5 80t-241.5 300q-117 6 -221 57.5t-177.5 133t-113.5 192.5t-32 230 q9 135 78 252t182 191.5t248 89.5q118 14 227.5 -19t198.5 -103l255 254h-134q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h288q26 0 45 -19t19 -45v-288q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v134l-254 -255q59 -74 93 -169q182 -9 328 -124l255 254h-134q-14 0 -23 9 t-9 23v64zM1024 704q0 20 -4 58q-162 -25 -271 -150t-109 -292q0 -20 4 -58q162 25 271 150t109 292zM128 704q0 -168 111 -294t276 -149q-3 29 -3 59q0 210 135 369.5t338 196.5q-53 120 -163.5 193t-245.5 73q-185 0 -316.5 -131.5t-131.5 -316.5zM1088 -128 q185 0 316.5 131.5t131.5 316.5q0 168 -111 294t-276 149q3 -29 3 -59q0 -210 -135 -369.5t-338 -196.5q53 -120 163.5 -193t245.5 -73z" />
540
+ <glyph unicode="&#xf228;" horiz-adv-x="2048" d="M1664 1504q0 14 9 23t23 9h288q26 0 45 -19t19 -45v-288q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v134l-254 -255q76 -95 107.5 -214t9.5 -247q-32 -180 -164.5 -310t-313.5 -157q-223 -34 -409 90q-117 -78 -256 -93v-132h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23 t-23 -9h-96v-96q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v96h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96v132q-155 17 -279.5 109.5t-187 237.5t-39.5 307q25 187 159.5 322.5t320.5 164.5q224 34 410 -90q146 97 320 97q201 0 359 -126l255 254h-134q-14 0 -23 9 t-9 23v64zM896 391q128 131 128 313t-128 313q-128 -131 -128 -313t128 -313zM128 704q0 -185 131.5 -316.5t316.5 -131.5q117 0 218 57q-154 167 -154 391t154 391q-101 57 -218 57q-185 0 -316.5 -131.5t-131.5 -316.5zM1216 256q185 0 316.5 131.5t131.5 316.5 t-131.5 316.5t-316.5 131.5q-117 0 -218 -57q154 -167 154 -391t-154 -391q101 -57 218 -57z" />
541
+ <glyph unicode="&#xf229;" horiz-adv-x="1792" d="M1728 1536q26 0 45 -19t19 -45v-416q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v262l-229 -230l156 -156q9 -10 9 -23t-9 -22l-46 -46q-9 -9 -22 -9t-23 9l-156 157l-99 -100q87 -104 129.5 -236.5t30.5 -276.5q-22 -250 -200.5 -431t-428.5 -206q-163 -17 -314 39.5 t-256.5 162t-162 256.5t-39.5 314q25 250 206 428.5t431 200.5q144 12 276.5 -30.5t236.5 -129.5l99 99l-156 156q-9 10 -9 23t9 22l46 46q9 9 22 9t23 -9l156 -156l229 229h-261q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h416zM1280 448q0 117 -45.5 223.5t-123 184t-184 123 t-223.5 45.5t-223.5 -45.5t-184 -123t-123 -184t-45.5 -223.5t45.5 -223.5t123 -184t184 -123t223.5 -45.5t223.5 45.5t184 123t123 184t45.5 223.5z" />
542
+ <glyph unicode="&#xf22a;" horiz-adv-x="1280" d="M640 892q217 -24 364.5 -187.5t147.5 -384.5q0 -167 -87 -306t-236 -212t-319 -54q-133 15 -245.5 88t-182 188t-80.5 249q-12 155 52.5 292t186 224t271.5 103v132h-160q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h160v165l-92 -92q-10 -9 -23 -9t-22 9l-46 46q-9 9 -9 22 t9 23l202 201q19 19 45 19t45 -19l202 -201q9 -10 9 -23t-9 -22l-46 -46q-9 -9 -22 -9t-23 9l-92 92v-165h160q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-160v-132zM576 -128q185 0 316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5 t131.5 -316.5t316.5 -131.5z" />
543
+ <glyph unicode="&#xf22b;" horiz-adv-x="2048" d="M2029 685q19 -19 19 -45t-19 -45l-294 -294q-9 -10 -22.5 -10t-22.5 10l-45 45q-10 9 -10 22.5t10 22.5l185 185h-294v-224q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v224h-131q-12 -119 -67 -226t-139 -183.5t-196.5 -121.5t-234.5 -45q-180 0 -330.5 91t-234.5 247 t-74 337q8 162 94 300t226.5 219.5t302.5 85.5q166 4 310.5 -71.5t235.5 -208.5t107 -296h131v224q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-224h294l-185 185q-10 9 -10 22.5t10 22.5l45 45q9 10 22.5 10t22.5 -10zM640 128q104 0 198.5 40.5t163.5 109.5t109.5 163.5 t40.5 198.5t-40.5 198.5t-109.5 163.5t-163.5 109.5t-198.5 40.5t-198.5 -40.5t-163.5 -109.5t-109.5 -163.5t-40.5 -198.5t40.5 -198.5t109.5 -163.5t163.5 -109.5t198.5 -40.5z" />
544
+ <glyph unicode="&#xf22c;" horiz-adv-x="1280" d="M1152 960q0 -221 -147.5 -384.5t-364.5 -187.5v-612q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v612q-217 24 -364.5 187.5t-147.5 384.5q0 117 45.5 223.5t123 184t184 123t223.5 45.5t223.5 -45.5t184 -123t123 -184t45.5 -223.5zM576 512q185 0 316.5 131.5 t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" />
545
+ <glyph unicode="&#xf22d;" horiz-adv-x="1792" />
546
+ <glyph unicode="&#xf22e;" horiz-adv-x="1792" />
547
+ <glyph unicode="&#xf22f;" horiz-adv-x="1792" />
548
+ <glyph unicode="&#xf230;" d="M1451 1408q35 0 60 -25t25 -60v-1366q0 -35 -25 -60t-60 -25h-391v595h199l30 232h-229v148q0 56 23.5 84t91.5 28l122 1v207q-63 9 -178 9q-136 0 -217.5 -80t-81.5 -226v-171h-200v-232h200v-595h-735q-35 0 -60 25t-25 60v1366q0 35 25 60t60 25h1366z" />
549
+ <glyph unicode="&#xf231;" horiz-adv-x="1280" d="M0 939q0 108 37.5 203.5t103.5 166.5t152 123t185 78t202 26q158 0 294 -66.5t221 -193.5t85 -287q0 -96 -19 -188t-60 -177t-100 -149.5t-145 -103t-189 -38.5q-68 0 -135 32t-96 88q-10 -39 -28 -112.5t-23.5 -95t-20.5 -71t-26 -71t-32 -62.5t-46 -77.5t-62 -86.5 l-14 -5l-9 10q-15 157 -15 188q0 92 21.5 206.5t66.5 287.5t52 203q-32 65 -32 169q0 83 52 156t132 73q61 0 95 -40.5t34 -102.5q0 -66 -44 -191t-44 -187q0 -63 45 -104.5t109 -41.5q55 0 102 25t78.5 68t56 95t38 110.5t20 111t6.5 99.5q0 173 -109.5 269.5t-285.5 96.5 q-200 0 -334 -129.5t-134 -328.5q0 -44 12.5 -85t27 -65t27 -45.5t12.5 -30.5q0 -28 -15 -73t-37 -45q-2 0 -17 3q-51 15 -90.5 56t-61 94.5t-32.5 108t-11 106.5z" />
550
+ <glyph unicode="&#xf232;" d="M985 562q13 0 97.5 -44t89.5 -53q2 -5 2 -15q0 -33 -17 -76q-16 -39 -71 -65.5t-102 -26.5q-57 0 -190 62q-98 45 -170 118t-148 185q-72 107 -71 194v8q3 91 74 158q24 22 52 22q6 0 18 -1.5t19 -1.5q19 0 26.5 -6.5t15.5 -27.5q8 -20 33 -88t25 -75q0 -21 -34.5 -57.5 t-34.5 -46.5q0 -7 5 -15q34 -73 102 -137q56 -53 151 -101q12 -7 22 -7q15 0 54 48.5t52 48.5zM782 32q127 0 243.5 50t200.5 134t134 200.5t50 243.5t-50 243.5t-134 200.5t-200.5 134t-243.5 50t-243.5 -50t-200.5 -134t-134 -200.5t-50 -243.5q0 -203 120 -368l-79 -233 l242 77q158 -104 345 -104zM782 1414q153 0 292.5 -60t240.5 -161t161 -240.5t60 -292.5t-60 -292.5t-161 -240.5t-240.5 -161t-292.5 -60q-195 0 -365 94l-417 -134l136 405q-108 178 -108 389q0 153 60 292.5t161 240.5t240.5 161t292.5 60z" />
551
+ <glyph unicode="&#xf233;" horiz-adv-x="1792" d="M128 128h1024v128h-1024v-128zM128 640h1024v128h-1024v-128zM1696 192q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM128 1152h1024v128h-1024v-128zM1696 704q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM1696 1216 q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM1792 384v-384h-1792v384h1792zM1792 896v-384h-1792v384h1792zM1792 1408v-384h-1792v384h1792z" />
552
+ <glyph unicode="&#xf234;" horiz-adv-x="2048" d="M704 640q-159 0 -271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5t-112.5 -271.5t-271.5 -112.5zM1664 512h352q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-352v-352q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5 t-9.5 22.5v352h-352q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h352v352q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5v-352zM928 288q0 -52 38 -90t90 -38h256v-238q-68 -50 -171 -50h-874q-121 0 -194 69t-73 190q0 53 3.5 103.5t14 109t26.5 108.5 t43 97.5t62 81t85.5 53.5t111.5 20q19 0 39 -17q79 -61 154.5 -91.5t164.5 -30.5t164.5 30.5t154.5 91.5q20 17 39 17q132 0 217 -96h-223q-52 0 -90 -38t-38 -90v-192z" />
553
+ <glyph unicode="&#xf235;" horiz-adv-x="2048" d="M704 640q-159 0 -271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5t-112.5 -271.5t-271.5 -112.5zM1781 320l249 -249q9 -9 9 -23q0 -13 -9 -22l-136 -136q-9 -9 -22 -9q-14 0 -23 9l-249 249l-249 -249q-9 -9 -23 -9q-13 0 -22 9l-136 136 q-9 9 -9 22q0 14 9 23l249 249l-249 249q-9 9 -9 23q0 13 9 22l136 136q9 9 22 9q14 0 23 -9l249 -249l249 249q9 9 23 9q13 0 22 -9l136 -136q9 -9 9 -22q0 -14 -9 -23zM1283 320l-181 -181q-37 -37 -37 -91q0 -53 37 -90l83 -83q-21 -3 -44 -3h-874q-121 0 -194 69 t-73 190q0 53 3.5 103.5t14 109t26.5 108.5t43 97.5t62 81t85.5 53.5t111.5 20q19 0 39 -17q154 -122 319 -122t319 122q20 17 39 17q28 0 57 -6q-28 -27 -41 -50t-13 -56q0 -54 37 -91z" />
554
+ <glyph unicode="&#xf236;" horiz-adv-x="2048" d="M256 512h1728q26 0 45 -19t19 -45v-448h-256v256h-1536v-256h-256v1216q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-704zM832 832q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM2048 576v64q0 159 -112.5 271.5t-271.5 112.5h-704 q-26 0 -45 -19t-19 -45v-384h1152z" />
555
+ <glyph unicode="&#xf237;" d="M1536 1536l-192 -448h192v-192h-274l-55 -128h329v-192h-411l-357 -832l-357 832h-411v192h329l-55 128h-274v192h192l-192 448h256l323 -768h378l323 768h256zM768 320l108 256h-216z" />
556
+ <glyph unicode="&#xf238;" d="M1088 1536q185 0 316.5 -93.5t131.5 -226.5v-896q0 -130 -125.5 -222t-305.5 -97l213 -202q16 -15 8 -35t-30 -20h-1056q-22 0 -30 20t8 35l213 202q-180 5 -305.5 97t-125.5 222v896q0 133 131.5 226.5t316.5 93.5h640zM768 192q80 0 136 56t56 136t-56 136t-136 56 t-136 -56t-56 -136t56 -136t136 -56zM1344 768v512h-1152v-512h1152z" />
557
+ <glyph unicode="&#xf239;" d="M1088 1536q185 0 316.5 -93.5t131.5 -226.5v-896q0 -130 -125.5 -222t-305.5 -97l213 -202q16 -15 8 -35t-30 -20h-1056q-22 0 -30 20t8 35l213 202q-180 5 -305.5 97t-125.5 222v896q0 133 131.5 226.5t316.5 93.5h640zM288 224q66 0 113 47t47 113t-47 113t-113 47 t-113 -47t-47 -113t47 -113t113 -47zM704 768v512h-544v-512h544zM1248 224q66 0 113 47t47 113t-47 113t-113 47t-113 -47t-47 -113t47 -113t113 -47zM1408 768v512h-576v-512h576z" />
558
+ <glyph unicode="&#xf23a;" horiz-adv-x="1792" d="M1792 204v-209h-642v209h134v926h-6l-314 -1135h-243l-310 1135h-8v-926h135v-209h-538v209h69q21 0 43 19.5t22 37.5v881q0 18 -22 40t-43 22h-69v209h672l221 -821h6l223 821h670v-209h-71q-19 0 -41 -22t-22 -40v-881q0 -18 21.5 -37.5t41.5 -19.5h71z" />
559
+ <glyph unicode="&#xf23b;" horiz-adv-x="1792" />
560
+ <glyph unicode="&#xf23c;" horiz-adv-x="1792" />
561
+ <glyph unicode="&#xf23d;" horiz-adv-x="1792" />
562
+ <glyph unicode="&#xf23e;" horiz-adv-x="1792" />
563
  <glyph unicode="&#xf500;" horiz-adv-x="1792" />
564
  </font>
565
  </defs></svg>
fonts/fontawesome-webfont.ttf CHANGED
Binary file
fonts/fontawesome-webfont.woff CHANGED
Binary file
fonts/fontawesome-webfont.woff2 ADDED
Binary file
includes/admin-posts.php CHANGED
@@ -1,18 +1,18 @@
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( '%s is currently active for this page.', '%s stands for custom branded "Page Builder" name.', 'fl-builder' ), FLBuilderModel::get_branding() ); ?></h3>
8
  <a href="<?php echo FLBuilderModel::get_edit_url(); ?>" class="fl-launch-builder button button-primary button-large"><?php printf( _x( 'Launch %s', '%s stands for custom branded "Page Builder" name.', 'fl-builder' ), FLBuilderModel::get_branding() ); ?></a>
9
- </div>
10
- <div class="fl-builder-loading"></div>
11
  </div>
12
  <script type="text/javascript">
13
 
14
  FLBuilderAdminPostsStrings = {
15
- switchToEditor: '<?php printf( esc_attr_x( 'Switching to Text Editor mode will disable your %s layout until it is enabled again. Any edits made while in Text Editor mode will not be made on your %s layout. Do you want to continue?', '%s stands for custom branded "Page Builder" name.', 'fl-builder' ), FLBuilderModel::get_branding(), FLBuilderModel::get_branding() ); ?>'
16
  };
17
 
18
  </script>
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( '%s is currently active for this page.', '%s stands for custom branded "Page Builder" name.', 'fl-builder' ), FLBuilderModel::get_branding() ); ?></h3>
8
  <a href="<?php echo FLBuilderModel::get_edit_url(); ?>" class="fl-launch-builder button button-primary button-large"><?php printf( _x( 'Launch %s', '%s stands for custom branded "Page Builder" name.', 'fl-builder' ), FLBuilderModel::get_branding() ); ?></a>
9
+ </div>
10
+ <div class="fl-builder-loading"></div>
11
  </div>
12
  <script type="text/javascript">
13
 
14
  FLBuilderAdminPostsStrings = {
15
+ switchToEditor: '<?php printf( esc_attr_x( 'Switching to Text Editor mode will disable your %s layout until it is enabled again. Any edits made while in Text Editor mode will not be made on your %s layout. Do you want to continue?', '%s stands for custom branded "Page Builder" name.', 'fl-builder' ), FLBuilderModel::get_branding(), FLBuilderModel::get_branding() ); ?>'
16
  };
17
 
18
  </script>
includes/admin-settings-cache.php CHANGED
@@ -1,23 +1,23 @@
1
  <div id="fl-cache-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
 
7
- <div class="fl-settings-form-content">
8
-
9
  <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>
10
 
11
  <?php if ( is_network_admin() ) : ?>
12
- <p><strong><?php _e( 'NOTE:', 'fl-builder' ); ?></strong> <?php _e('This applies to all sites on the network.', 'fl-builder'); ?></p>
13
- <?php elseif ( ! is_network_admin() && is_multisite() ) : ?>
14
- <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>
15
- <?php endif; ?>
16
-
17
- </div>
18
- <p class="submit">
19
- <input type="submit" name="update" class="button-primary" value="<?php esc_attr_e( 'Clear Cache', 'fl-builder' ); ?>" />
20
- <?php wp_nonce_field('cache', 'fl-cache-nonce'); ?>
21
- </p>
22
- </form>
23
  </div>
1
  <div id="fl-cache-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
 
7
+ <div class="fl-settings-form-content">
8
+
9
  <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>
10
 
11
  <?php if ( is_network_admin() ) : ?>
12
+ <p><strong><?php _e( 'NOTE:', 'fl-builder' ); ?></strong> <?php _e('This applies to all sites on the network.', 'fl-builder'); ?></p>
13
+ <?php elseif ( ! is_network_admin() && is_multisite() ) : ?>
14
+ <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>
15
+ <?php endif; ?>
16
+
17
+ </div>
18
+ <p class="submit">
19
+ <input type="submit" name="update" class="button-primary" value="<?php esc_attr_e( 'Clear Cache', 'fl-builder' ); ?>" />
20
+ <?php wp_nonce_field('cache', 'fl-cache-nonce'); ?>
21
+ </p>
22
+ </form>
23
  </div>
includes/admin-settings-editing.php CHANGED
@@ -1,26 +1,26 @@
1
  <div id="fl-editing-form" class="fl-settings-form">
2
 
3
- <h3 class="fl-settings-form-header"><?php _e('Editing Settings', 'fl-builder'); ?></h3>
4
 
5
- <form id="editing-form" action="<?php FLBuilderAdminSettings::render_form_action( 'editing' ); ?>" 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_editing_capability')) 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 printf( __( 'Set the <a%s>capability</a> required for users to access advanced builder editing such as adding, deleting or moving modules.', 'fl-builder' ), ' href="http://codex.wordpress.org/Roles_and_Capabilities#Capability_vs._Role_Table" target="_blank"' ); ?></p>
17
 
18
- <input type="text" name="fl-editing-capability" value="<?php echo esc_html(FLBuilderModel::get_editing_capability()); ?>" class="regular-text" />
19
 
20
- </div>
21
- <p class="submit">
22
- <input type="submit" name="update" class="button-primary" value="<?php esc_attr_e( 'Save Editing Settings', 'fl-builder' ); ?>" />
23
- <?php wp_nonce_field('editing', 'fl-editing-nonce'); ?>
24
- </p>
25
- </form>
26
  </div>
1
  <div id="fl-editing-form" class="fl-settings-form">
2
 
3
+ <h3 class="fl-settings-form-header"><?php _e('Editing Settings', 'fl-builder'); ?></h3>
4
 
5
+ <form id="editing-form" action="<?php FLBuilderAdminSettings::render_form_action( 'editing' ); ?>" 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_editing_capability')) 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 printf( __( 'Set the <a%s>capability</a> required for users to access advanced builder editing such as adding, deleting or moving modules.', 'fl-builder' ), ' href="http://codex.wordpress.org/Roles_and_Capabilities#Capability_vs._Role_Table" target="_blank"' ); ?></p>
17
 
18
+ <input type="text" name="fl-editing-capability" value="<?php echo esc_html(FLBuilderModel::get_editing_capability()); ?>" class="regular-text" />
19
 
20
+ </div>
21
+ <p class="submit">
22
+ <input type="submit" name="update" class="button-primary" value="<?php esc_attr_e( 'Save Editing Settings', 'fl-builder' ); ?>" />
23
+ <?php wp_nonce_field('editing', 'fl-editing-nonce'); ?>
24
+ </p>
25
+ </form>
26
  </div>
includes/admin-settings-js-config.php CHANGED
@@ -1,8 +1,8 @@
1
  <script type="text/javascript">
2
 
3
  FLBuilderAdminSettingsStrings = {
4
- selectFile: '<?php esc_attr_e('Select File', 'fl-builder'); ?>',
5
- 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'); ?>'
6
  };
7
 
8
  </script>
1
  <script type="text/javascript">
2
 
3
  FLBuilderAdminSettingsStrings = {
4
+ selectFile: '<?php esc_attr_e('Select File', 'fl-builder'); ?>',
5
+ 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'); ?>'
6
  };
7
 
8
  </script>
includes/admin-settings-modules.php CHANGED
@@ -1,31 +1,31 @@
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>
25
- <input class="fl-module-all-cb" type="checkbox" name="fl-modules[]" value="all" <?php echo $checked; ?> />
26
- <?php _ex( 'All', 'Plugin setup page: Modules.', 'fl-builder' ); ?>
27
- </label>
28
- <?php foreach ( $categories as $title => $modules ) : ?>
29
  <h3><?php echo $title; ?></h3>
30
  <?php
31
 
@@ -35,34 +35,34 @@
35
 
36
  ?>
37
  <p>
38
- <label>
39
- <input class="fl-module-cb" type="checkbox" name="fl-modules[]" value="widget" <?php echo $checked; ?> />
40
- <?php echo $title; ?>
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>
56
- <input class="fl-module-cb" type="checkbox" name="fl-modules[]" value="<?php echo $module->slug; ?>" <?php echo $checked; ?> />
57
- <?php echo $module->name; ?>
58
- </label>
59
- </p>
60
- <?php endforeach; ?>
61
- <?php endforeach; ?>
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>
25
+ <input class="fl-module-all-cb" type="checkbox" name="fl-modules[]" value="all" <?php echo $checked; ?> />
26
+ <?php _ex( 'All', 'Plugin setup page: Modules.', 'fl-builder' ); ?>
27
+ </label>
28
+ <?php foreach ( $categories as $title => $modules ) : ?>
29
  <h3><?php echo $title; ?></h3>
30
  <?php
31
 
35
 
36
  ?>
37
  <p>
38
+ <label>
39
+ <input class="fl-module-cb" type="checkbox" name="fl-modules[]" value="widget" <?php echo $checked; ?> />
40
+ <?php echo $title; ?>
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>
56
+ <input class="fl-module-cb" type="checkbox" name="fl-modules[]" value="<?php echo $module->slug; ?>" <?php echo $checked; ?> />
57
+ <?php echo $module->name; ?>
58
+ </label>
59
+ </p>
60
+ <?php endforeach; ?>
61
+ <?php endforeach; ?>
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,74 +1,74 @@
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
 
46
- foreach($post_types as $post_type) :
47
 
48
- $checked = in_array($post_type->name, $saved_post_types) ? 'checked' : '';
49
 
50
- if($post_type->name == 'attachment') {
51
- continue;
52
- }
53
- if($post_type->name == 'fl-builder-template') {
54
- continue;
55
- }
56
 
57
- ?>
58
- <p>
59
- <label>
60
- <input type="checkbox" name="fl-post-types[]" value="<?php echo $post_type->name; ?>" <?php echo $checked; ?> />
61
- <?php echo $post_type->labels->name; ?>
62
- </label>
63
- </p>
64
- <?php endforeach; ?>
65
-
66
- <?php endif; ?>
67
-
68
- </div>
69
- <p class="submit">
70
- <input type="submit" name="update" class="button-primary" value="<?php esc_attr_e( 'Save Post Types', 'fl-builder' ); ?>" />
71
- <?php wp_nonce_field('post-types', 'fl-post-types-nonce'); ?>
72
- </p>
73
- </form>
74
  </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($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
 
46
+ foreach($post_types as $post_type) :
47
 
48
+ $checked = in_array($post_type->name, $saved_post_types) ? 'checked' : '';
49
 
50
+ if($post_type->name == 'attachment') {
51
+ continue;
52
+ }
53
+ if($post_type->name == 'fl-builder-template') {
54
+ continue;
55
+ }
56
 
57
+ ?>
58
+ <p>
59
+ <label>
60
+ <input type="checkbox" name="fl-post-types[]" value="<?php echo $post_type->name; ?>" <?php echo $checked; ?> />
61
+ <?php echo $post_type->labels->name; ?>
62
+ </label>
63
+ </p>
64
+ <?php endforeach; ?>
65
+
66
+ <?php endif; ?>
67
+
68
+ </div>
69
+ <p class="submit">
70
+ <input type="submit" name="update" class="button-primary" value="<?php esc_attr_e( 'Save Post Types', 'fl-builder' ); ?>" />
71
+ <?php wp_nonce_field('post-types', 'fl-post-types-nonce'); ?>
72
+ </p>
73
+ </form>
74
  </div>
includes/admin-settings-uninstall.php CHANGED
@@ -1,19 +1,19 @@
1
  <div id="fl-uninstall-form" class="fl-settings-form">
2
 
3
- <h3 class="fl-settings-form-header"><?php _e('Uninstall', 'fl-builder'); ?></h3>
4
 
5
- <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>
6
 
7
  <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>
8
 
9
- <?php if(is_multisite()) : ?>
10
- <p><strong style="color:#ff0000;"><?php _e( 'NOTE:', 'fl-builder' ); ?></strong> <?php _e('This applies to all sites on the network.', 'fl-builder'); ?></p>
11
- <?php endif; ?>
12
 
13
- <form id="uninstall-form" action="<?php FLBuilderAdminSettings::render_form_action( 'uninstall' ); ?>" method="post">
14
- <p>
15
- <input type="submit" name="uninstall-submit" class="button button-primary" value="<?php _e('Uninstall', 'fl-builder'); ?>">
16
- <?php wp_nonce_field('uninstall', 'fl-uninstall'); ?>
17
- </p>
18
- </form>
19
  </div>
1
  <div id="fl-uninstall-form" class="fl-settings-form">
2
 
3
+ <h3 class="fl-settings-form-header"><?php _e('Uninstall', 'fl-builder'); ?></h3>
4
 
5
+ <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>
6
 
7
  <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>
8
 
9
+ <?php if(is_multisite()) : ?>
10
+ <p><strong style="color:#ff0000;"><?php _e( 'NOTE:', 'fl-builder' ); ?></strong> <?php _e('This applies to all sites on the network.', 'fl-builder'); ?></p>
11
+ <?php endif; ?>
12
 
13
+ <form id="uninstall-form" action="<?php FLBuilderAdminSettings::render_form_action( 'uninstall' ); ?>" method="post">
14
+ <p>
15
+ <input type="submit" name="uninstall-submit" class="button button-primary" value="<?php _e('Uninstall', 'fl-builder'); ?>">
16
+ <?php wp_nonce_field('uninstall', 'fl-uninstall'); ?>
17
+ </p>
18
+ </form>
19
  </div>
includes/admin-settings-upgrade.php CHANGED
@@ -1,11 +1,11 @@
1
  <div id="fl-upgrade-form" class="fl-settings-form">
2
 
3
- <h3 class="fl-settings-form-header"><?php _e('Upgrade', 'fl-builder'); ?></h3>
4
 
5
- <p><?php _e('You are currently running the lite version of the Beaver Builder plugin. Upgrade today for access to premium features such as advanced modules, templates, support and more!', 'fl-builder'); ?></p>
6
 
7
- <input type="button" class="button button-primary" value="<?php _e('Upgrade Now', 'fl-builder'); ?>" onclick="window.location.href='<?php echo FLBuilderModel::get_upgrade_url( array( 'utm_source' => 'external', 'utm_medium' => 'builder', 'utm_campaign' => 'settings-page' ) ); ?>';" style="margin-right: 10px;">
8
 
9
- <input type="button" class="button button-primary" value="<?php _e('Learn More', 'fl-builder'); ?>" onclick="window.location.href='http://www.wpbeaverbuilder.com/?utm_source=external&utm_medium=builder&utm_campaign=settings-page';">
10
 
11
  </div>
1
  <div id="fl-upgrade-form" class="fl-settings-form">
2
 
3
+ <h3 class="fl-settings-form-header"><?php _e('Upgrade', 'fl-builder'); ?></h3>
4
 
5
+ <p><?php _e('You are currently running the lite version of the Beaver Builder plugin. Upgrade today for access to premium features such as advanced modules, templates, support and more!', 'fl-builder'); ?></p>
6
 
7
+ <input type="button" class="button button-primary" value="<?php _e('Upgrade Now', 'fl-builder'); ?>" onclick="window.location.href='<?php echo FLBuilderModel::get_upgrade_url( array( 'utm_source' => 'external', 'utm_medium' => 'builder', 'utm_campaign' => 'settings-page' ) ); ?>';" style="margin-right: 10px;">
8
 
9
+ <input type="button" class="button button-primary" value="<?php _e('Learn More', 'fl-builder'); ?>" onclick="window.location.href='http://www.wpbeaverbuilder.com/?utm_source=external&utm_medium=builder&utm_campaign=settings-page';">
10
 
11
  </div>
includes/admin-settings.php CHANGED
@@ -1,15 +1,15 @@
1
  <div class="wrap <?php FLBuilderAdminSettings::render_page_class(); ?>">
2
 
3
- <h2 class="fl-settings-heading">
4
- <?php FLBuilderAdminSettings::render_page_heading(); ?>
5
  </h2>
6
-
7
- <?php FLBuilderAdminSettings::render_update_message(); ?>
8
 
9
  <div class="fl-settings-nav">
10
- <ul>
11
- <?php FLBuilderAdminSettings::render_nav_items(); ?>
12
- </ul>
13
  </div>
14
 
15
  <div class="fl-settings-content">
1
  <div class="wrap <?php FLBuilderAdminSettings::render_page_class(); ?>">
2
 
3
+ <h2 class="fl-settings-heading">
4
+ <?php FLBuilderAdminSettings::render_page_heading(); ?>
5
  </h2>
6
+
7
+ <?php FLBuilderAdminSettings::render_update_message(); ?>
8
 
9
  <div class="fl-settings-nav">
10
+ <ul>
11
+ <?php FLBuilderAdminSettings::render_nav_items(); ?>
12
+ </ul>
13
  </div>
14
 
15
  <div class="fl-settings-content">
includes/column-css.php CHANGED
@@ -11,47 +11,47 @@
11
  .fl-node-<?php echo $col->node; ?> h4,
12
  .fl-node-<?php echo $col->node; ?> h5,
13
  .fl-node-<?php echo $col->node; ?> h6 {
14
- color: #<?php echo $col->settings->text_color; ?>;
15
  }
16
  <?php endif; ?>
17
 
18
  <?php if(!empty($col->settings->bg_color)) : ?>
19
  .fl-node-<?php echo $col->node; ?> .fl-col-content {
20
- background-color: #<?php echo $col->settings->bg_color; ?>;
21
- background-color: rgba(<?php echo implode(',', FLBuilderColor::hex_to_rgb($col->settings->bg_color)) ?>, <?php echo $col->settings->bg_opacity/100; ?>);
22
  }
23
  <?php endif; ?>
24
 
25
  <?php if(!empty($col->settings->border_type)) : ?>
26
  .fl-builder-content .fl-node-<?php echo $col->node; ?> .fl-col-content {
27
- border-style: <?php echo $col->settings->border_type; ?>;
28
- border-color: #<?php echo $col->settings->border_color; ?>;
29
- border-color: rgba(<?php echo implode(',', FLBuilderColor::hex_to_rgb($col->settings->border_color)) ?>, <?php echo $col->settings->border_opacity/100; ?>);
30
- border-top-width: <?php echo is_numeric($col->settings->border_top) ? $col->settings->border_top : '0'; ?>px;
31
- border-bottom-width: <?php echo is_numeric($col->settings->border_bottom) ? $col->settings->border_bottom : '0'; ?>px;
32
- border-left-width: <?php echo is_numeric($col->settings->border_left) ? $col->settings->border_left : '0'; ?>px;
33
- border-right-width: <?php echo is_numeric($col->settings->border_right) ? $col->settings->border_right : '0'; ?>px;
34
  }
35
  <?php endif; ?>
36
 
37
  <?php if($global_settings->responsive_enabled) : ?>
38
 
39
- <?php if($col->settings->medium_size == 'custom') : ?>
40
- @media(max-width: <?php echo $global_settings->medium_breakpoint; ?>px) {
41
- .fl-builder-content .fl-node-<?php echo $col->node; ?> {
42
- width: <?php echo $col->settings->custom_medium_size; ?>% !important;
43
- }
44
- }
45
- <?php endif; ?>
46
-
47
- <?php if($col->settings->responsive_size == 'custom') : ?>
48
- @media(max-width: <?php echo $global_settings->responsive_breakpoint; ?>px) {
49
- .fl-builder-content .fl-node-<?php echo $col->node; ?> {
50
- clear: none;
51
- float: left;
52
- width: <?php echo $col->settings->custom_responsive_size; ?>% !important;
53
- }
54
- }
55
- <?php endif; ?>
56
-
57
  <?php endif; ?>
11
  .fl-node-<?php echo $col->node; ?> h4,
12
  .fl-node-<?php echo $col->node; ?> h5,
13
  .fl-node-<?php echo $col->node; ?> h6 {
14
+ color: #<?php echo $col->settings->text_color; ?>;
15
  }
16
  <?php endif; ?>
17
 
18
  <?php if(!empty($col->settings->bg_color)) : ?>
19
  .fl-node-<?php echo $col->node; ?> .fl-col-content {
20
+ background-color: #<?php echo $col->settings->bg_color; ?>;
21
+ background-color: rgba(<?php echo implode(',', FLBuilderColor::hex_to_rgb($col->settings->bg_color)) ?>, <?php echo $col->settings->bg_opacity/100; ?>);
22
  }
23
  <?php endif; ?>
24
 
25
  <?php if(!empty($col->settings->border_type)) : ?>
26
  .fl-builder-content .fl-node-<?php echo $col->node; ?> .fl-col-content {
27
+ border-style: <?php echo $col->settings->border_type; ?>;
28
+ border-color: #<?php echo $col->settings->border_color; ?>;
29
+ border-color: rgba(<?php echo implode(',', FLBuilderColor::hex_to_rgb($col->settings->border_color)) ?>, <?php echo $col->settings->border_opacity/100; ?>);
30
+ border-top-width: <?php echo is_numeric($col->settings->border_top) ? $col->settings->border_top : '0'; ?>px;
31
+ border-bottom-width: <?php echo is_numeric($col->settings->border_bottom) ? $col->settings->border_bottom : '0'; ?>px;
32
+ border-left-width: <?php echo is_numeric($col->settings->border_left) ? $col->settings->border_left : '0'; ?>px;
33
+ border-right-width: <?php echo is_numeric($col->settings->border_right) ? $col->settings->border_right : '0'; ?>px;
34
  }
35
  <?php endif; ?>
36
 
37
  <?php if($global_settings->responsive_enabled) : ?>
38
 
39
+ <?php if($col->settings->medium_size == 'custom') : ?>
40
+ @media(max-width: <?php echo $global_settings->medium_breakpoint; ?>px) {
41
+ .fl-builder-content .fl-node-<?php echo $col->node; ?> {
42
+ width: <?php echo $col->settings->custom_medium_size; ?>% !important;
43
+ }
44
+ }
45
+ <?php endif; ?>
46
+
47
+ <?php if($col->settings->responsive_size == 'custom') : ?>
48
+ @media(max-width: <?php echo $global_settings->responsive_breakpoint; ?>px) {
49
+ .fl-builder-content .fl-node-<?php echo $col->node; ?> {
50
+ clear: none;
51
+ float: left;
52
+ width: <?php echo $col->settings->custom_responsive_size; ?>% !important;
53
+ }
54
+ }
55
+ <?php endif; ?>
56
+
57
  <?php endif; ?>
includes/column-group.php CHANGED
@@ -1,9 +1,9 @@
1
  <div<?php FLBuilder::render_column_group_attributes( $group ); ?>>
2
- <?php foreach ( $cols as $col ) : ?>
3
- <div<?php echo FLBuilder::render_column_attributes( $col ); ?>>
4
- <div class="fl-col-content fl-node-content">
5
- <?php FLBuilder::render_modules( $col->node ); ?>
6
- </div>
7
- </div>
8
- <?php endforeach; ?>
9
  </div>
1
  <div<?php FLBuilder::render_column_group_attributes( $group ); ?>>
2
+ <?php foreach ( $cols as $col ) : ?>
3
+ <div<?php echo FLBuilder::render_column_attributes( $col ); ?>>
4
+ <div class="fl-col-content fl-node-content">
5
+ <?php FLBuilder::render_modules( $col->node ); ?>
6
+ </div>
7
+ </div>
8
+ <?php endforeach; ?>
9
  </div>
includes/column-settings.php CHANGED
@@ -1,379 +1,379 @@
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
- )
24
- ),
25
- 'text' => array(
26
- 'title' => __('Text', 'fl-builder'),
27
- 'fields' => array(
28
- 'text_color' => array(
29
- 'type' => 'color',
30
- 'label' => __('Color', 'fl-builder'),
31
- 'show_reset' => true,
32
- 'preview' => array(
33
- 'type' => 'none'
34
- )
35
- )
36
- )
37
- ),
38
- 'bg_color' => array(
39
- 'title' => __('Background Color', 'fl-builder'),
40
- 'fields' => array(
41
- 'bg_color' => array(
42
- 'type' => 'color',
43
- 'label' => __('Color', 'fl-builder'),
44
- 'show_reset' => true,
45
- 'preview' => array(
46
- 'type' => 'none'
47
- )
48
- ),
49
- 'bg_opacity' => array(
50
- 'type' => 'text',
51
- 'label' => __('Opacity', 'fl-builder'),
52
- 'default' => '100',
53
- 'description' => '%',
54
- 'maxlength' => '3',
55
- 'size' => '5',
56
- 'preview' => array(
57
- 'type' => 'none'
58
- )
59
- )
60
- )
61
- ),
62
- 'border' => array(
63
- 'title' => __('Border', 'fl-builder'),
64
- 'fields' => array(
65
- 'border_type' => array(
66
- 'type' => 'select',
67
- 'label' => __('Type', 'fl-builder'),
68
- 'default' => '',
69
- 'help' => __('The type of border to use. Double borders must have a width of at least 3px to render properly.', 'fl-builder'),
70
- 'options' => array(
71
  '' => _x( 'None', 'Border type.', 'fl-builder' ),
72
  'solid' => _x( 'Solid', 'Border type.', 'fl-builder' ),
73
  'dashed' => _x( 'Dashed', 'Border type.', 'fl-builder' ),
74
  'dotted' => _x( 'Dotted', 'Border type.', 'fl-builder' ),
75
  'double' => _x( 'Double', 'Border type.', 'fl-builder' )
76
- ),
77
- 'toggle' => array(
78
- '' => array(
79
- 'fields' => array()
80
- ),
81
- 'solid' => array(
82
- 'fields' => array('border_color', 'border_opacity', 'border_top', 'border_bottom', 'border_left', 'border_right')
83
- ),
84
- 'dashed' => array(
85
- 'fields' => array('border_color', 'border_opacity', 'border_top', 'border_bottom', 'border_left', 'border_right')
86
- ),
87
- 'dotted' => array(
88
- 'fields' => array('border_color', 'border_opacity', 'border_top', 'border_bottom', 'border_left', 'border_right')
89
- ),
90
- 'double' => array(
91
- 'fields' => array('border_color', 'border_opacity', 'border_top', 'border_bottom', 'border_left', 'border_right')
92
- )
93
- ),
94
- 'preview' => array(
95
- 'type' => 'none'
96
- )
97
- ),
98
- 'border_color' => array(
99
- 'type' => 'color',
100
- 'label' => __('Color', 'fl-builder'),
101
- 'show_reset' => true,
102
- 'preview' => array(
103
- 'type' => 'none'
104
- )
105
- ),
106
- 'border_opacity' => array(
107
- 'type' => 'text',
108
- 'label' => __('Opacity', 'fl-builder'),
109
- 'default' => '100',
110
- 'description' => '%',
111
- 'maxlength' => '3',
112
- 'size' => '5',
113
- 'preview' => array(
114
- 'type' => 'none'
115
- )
116
- ),
117
- 'border_top' => array(
118
- 'type' => 'text',
119
- 'label' => __('Top Width', 'fl-builder'),
120
- 'default' => '1',
121
- 'description' => 'px',
122
- 'maxlength' => '3',
123
- 'size' => '5',
124
- 'placeholder' => '0',
125
- 'preview' => array(
126
- 'type' => 'none'
127
- )
128
- ),
129
- 'border_bottom' => array(
130
- 'type' => 'text',
131
- 'label' => __('Bottom Width', 'fl-builder'),
132
- 'default' => '1',
133
- 'description' => 'px',
134
- 'maxlength' => '3',
135
- 'size' => '5',
136
- 'placeholder' => '0',
137
- 'preview' => array(
138
- 'type' => 'none'
139
- )
140
- ),
141
- 'border_left' => array(
142
- 'type' => 'text',
143
- 'label' => __('Left Width', 'fl-builder'),
144
- 'default' => '1',
145
- 'description' => 'px',
146
- 'maxlength' => '3',
147
- 'size' => '5',
148
- 'placeholder' => '0',
149
- 'preview' => array(
150
- 'type' => 'none'
151
- )
152
- ),
153
- 'border_right' => array(
154
- 'type' => 'text',
155
- 'label' => __('Right Width', 'fl-builder'),
156
- 'default' => '1',
157
- 'description' => 'px',
158
- 'maxlength' => '3',
159
- 'size' => '5',
160
- 'placeholder' => '0',
161
- 'preview' => array(
162
- 'type' => 'none'
163
- )
164
- )
165
- )
166
- ),
167
- )
168
- ),
169
- 'advanced' => array(
170
- 'title' => __('Advanced', 'fl-builder'),
171
- 'sections' => array(
172
- 'margins' => array(
173
- 'title' => __('Margins', 'fl-builder'),
174
- 'fields' => array(
175
- 'margin_top' => array(
176
- 'type' => 'text',
177
- 'label' => __( 'Top', 'fl-builder' ),
178
- 'default' => '',
179
- 'description' => 'px',
180
- 'maxlength' => '4',
181
- 'size' => '5',
182
- 'placeholder' => '0',
183
- 'preview' => array(
184
- 'type' => 'none'
185
- )
186
- ),
187
- 'margin_bottom' => array(
188
- 'type' => 'text',
189
- 'label' => __( 'Bottom', 'fl-builder' ),
190
- 'default' => '',
191
- 'description' => 'px',
192
- 'maxlength' => '4',
193
- 'size' => '5',
194
- 'placeholder' => '0',
195
- 'preview' => array(
196
- 'type' => 'none'
197
- )
198
- ),
199
- 'margin_left' => array(
200
- 'type' => 'text',
201
- 'label' => __( 'Left', 'fl-builder' ),
202
- 'default' => '',
203
- 'description' => 'px',
204
- 'maxlength' => '4',
205
- 'size' => '5',
206
- 'placeholder' => '0',
207
- 'preview' => array(
208
- 'type' => 'none'
209
- )
210
- ),
211
- 'margin_right' => array(
212
- 'type' => 'text',
213
- 'label' => __( 'Right', 'fl-builder' ),
214
- 'default' => '',
215
- 'description' => 'px',
216
- 'maxlength' => '4',
217
- 'size' => '5',
218
- 'placeholder' => '0',
219
- 'preview' => array(
220
- 'type' => 'none'
221
- )
222
- )
223
- )
224
- ),
225
- 'padding' => array(
226
- 'title' => __('Padding', 'fl-builder'),
227
- 'fields' => array(
228
- 'padding_top' => array(
229
- 'type' => 'text',
230
- 'label' => __( 'Top', 'fl-builder' ),
231
- 'default' => '',
232
- 'description' => 'px',
233
- 'maxlength' => '4',
234
- 'size' => '5',
235
- 'placeholder' => '0',
236
- 'preview' => array(
237
- 'type' => 'none'
238
- )
239
- ),
240
- 'padding_bottom' => array(
241
- 'type' => 'text',
242
- 'label' => __( 'Bottom', 'fl-builder' ),
243
- 'default' => '',
244
- 'description' => 'px',
245
- 'maxlength' => '4',
246
- 'size' => '5',
247
- 'placeholder' => '0',
248
- 'preview' => array(
249
- 'type' => 'none'
250
- )
251
- ),
252
- 'padding_left' => array(
253
- 'type' => 'text',
254
- 'label' => __( 'Left', 'fl-builder' ),
255
- 'default' => '',
256
- 'description' => 'px',
257
- 'maxlength' => '4',
258
- 'size' => '5',
259
- 'placeholder' => '0',
260
- 'preview' => array(
261
- 'type' => 'none'
262
- )
263
- ),
264
- 'padding_right' => array(
265
- 'type' => 'text',
266
- 'label' => __( 'Right', 'fl-builder' ),
267
- 'default' => '',
268
- 'description' => 'px',
269
- 'maxlength' => '4',
270
- 'size' => '5',
271
- 'placeholder' => '0',
272
- 'preview' => array(
273
- 'type' => 'none'
274
- )
275
- )
276
- )
277
- ),
278
- 'responsive' => array(
279
- 'title' => __('Responsive Layout', 'fl-builder'),
280
- 'fields' => array(
281
- 'responsive_display' => array(
282
- 'type' => 'select',
283
- 'label' => __('Display', 'fl-builder'),
284
- 'options' => array(
285
- '' => __('Always', 'fl-builder'),
286
- 'desktop' => __('Large Devices Only', 'fl-builder'),
287
- 'desktop-medium' => __('Large &amp; Medium Devices Only', 'fl-builder'),
288
- 'medium' => __('Medium Devices Only', 'fl-builder'),
289
- 'medium-mobile' => __('Medium &amp; Small Devices Only', 'fl-builder'),
290
- 'mobile' => __('Small Devices Only', 'fl-builder'),
291
- ),
292
- 'help' => __( 'Choose whether to show or hide this column at different device sizes.', 'fl-builder' ),
293
- 'preview' => array(
294
- 'type' => 'none'
295
- )
296
- ),
297
- 'medium_size' => array(
298
- 'type' => 'select',
299
- 'label' => __('Medium Device Width', 'fl-builder'),
300
- 'help' => __( 'The width of this column on medium devices such as tablets.', 'fl-builder' ),
301
- 'options' => array(
302
- 'default' => __('Default', 'fl-builder'),
303
- 'custom' => __('Custom', 'fl-builder'),
304
- ),
305
- 'toggle' => array(
306
- 'custom' => array(
307
- 'fields' => array('custom_medium_size')
308
- )
309
- ),
310
- 'preview' => array(
311
- 'type' => 'none'
312
- )
313
- ),
314
- 'custom_medium_size' => array(
315
- 'type' => 'text',
316
- 'label' => __('Custom Medium Device Width', 'fl-builder'),
317
- 'default' => '100',
318
- 'description' => '%',
319
- 'maxlength' => '5',
320
- 'size' => '6',
321
- 'preview' => array(
322
- 'type' => 'none'
323
- )
324
- ),
325
- 'responsive_size' => array(
326
- 'type' => 'select',
327
- 'label' => __('Small Device Width', 'fl-builder'),
328
- 'help' => __( 'The width of this column on small devices such as phones.', 'fl-builder' ),
329
- 'options' => array(
330
- 'default' => __('Default', 'fl-builder'),
331
- 'custom' => __('Custom', 'fl-builder'),
332
- ),
333
- 'toggle' => array(
334
- 'custom' => array(
335
- 'fields' => array('custom_responsive_size')
336
- )
337
- ),
338
- 'preview' => array(
339
- 'type' => 'none'
340
- )
341
- ),
342
- 'custom_responsive_size' => array(
343
- 'type' => 'text',
344
- 'label' => __( 'Custom Small Device Width', 'fl-builder' ),
345
- 'default' => '100',
346
- 'description' => '%',
347
- 'maxlength' => '5',
348
- 'size' => '6',
349
- 'preview' => array(
350
- 'type' => 'none'
351
- )
352
- )
353
- )
354
- ),
355
- 'css_selectors' => array(
356
- 'title' => __('CSS Selectors', 'fl-builder'),
357
- 'fields' => array(
358
- 'id' => array(
359
- 'type' => 'text',
360
- 'label' => __('ID', 'fl-builder'),
361
- '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' ),
362
- 'preview' => array(
363
- 'type' => 'none'
364
- )
365
- ),
366
- 'class' => array(
367
- 'type' => 'text',
368
- 'label' => __('CSS Class', 'fl-builder'),
369
- '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' ),
370
- 'preview' => array(
371
- 'type' => 'none'
372
- )
373
- )
374
- )
375
- )
376
- )
377
- )
378
- )
379
  ));
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
+ )
24
+ ),
25
+ 'text' => array(
26
+ 'title' => __('Text', 'fl-builder'),
27
+ 'fields' => array(
28
+ 'text_color' => array(
29
+ 'type' => 'color',
30
+ 'label' => __('Color', 'fl-builder'),
31
+ 'show_reset' => true,
32
+ 'preview' => array(
33
+ 'type' => 'none'
34
+ )
35
+ )
36
+ )
37
+ ),
38
+ 'bg_color' => array(
39
+ 'title' => __('Background Color', 'fl-builder'),
40
+ 'fields' => array(
41
+ 'bg_color' => array(
42
+ 'type' => 'color',
43
+ 'label' => __('Color', 'fl-builder'),
44
+ 'show_reset' => true,
45
+ 'preview' => array(
46
+ 'type' => 'none'
47
+ )
48
+ ),
49
+ 'bg_opacity' => array(
50
+ 'type' => 'text',
51
+ 'label' => __('Opacity', 'fl-builder'),
52
+ 'default' => '100',
53
+ 'description' => '%',
54
+ 'maxlength' => '3',
55
+ 'size' => '5',
56
+ 'preview' => array(
57
+ 'type' => 'none'
58
+ )
59
+ )
60
+ )
61
+ ),
62
+ 'border' => array(
63
+ 'title' => __('Border', 'fl-builder'),
64
+ 'fields' => array(
65
+ 'border_type' => array(
66
+ 'type' => 'select',
67
+ 'label' => __('Type', 'fl-builder'),
68
+ 'default' => '',
69
+ 'help' => __('The type of border to use. Double borders must have a width of at least 3px to render properly.', 'fl-builder'),
70
+ 'options' => array(
71
  '' => _x( 'None', 'Border type.', 'fl-builder' ),
72
  'solid' => _x( 'Solid', 'Border type.', 'fl-builder' ),
73
  'dashed' => _x( 'Dashed', 'Border type.', 'fl-builder' ),
74
  'dotted' => _x( 'Dotted', 'Border type.', 'fl-builder' ),
75
  'double' => _x( 'Double', 'Border type.', 'fl-builder' )
76
+ ),
77
+ 'toggle' => array(
78
+ '' => array(
79
+ 'fields' => array()
80
+ ),
81
+ 'solid' => array(
82
+ 'fields' => array('border_color', 'border_opacity', 'border_top', 'border_bottom', 'border_left', 'border_right')
83
+ ),
84
+ 'dashed' => array(
85
+ 'fields' => array('border_color', 'border_opacity', 'border_top', 'border_bottom', 'border_left', 'border_right')
86
+ ),
87
+ 'dotted' => array(
88
+ 'fields' => array('border_color', 'border_opacity', 'border_top', 'border_bottom', 'border_left', 'border_right')
89
+ ),
90
+ 'double' => array(
91
+ 'fields' => array('border_color', 'border_opacity', 'border_top', 'border_bottom', 'border_left', 'border_right')
92
+ )
93
+ ),
94
+ 'preview' => array(
95
+ 'type' => 'none'
96
+ )
97
+ ),
98
+ 'border_color' => array(
99
+ 'type' => 'color',
100
+ 'label' => __('Color', 'fl-builder'),
101
+ 'show_reset' => true,
102
+ 'preview' => array(
103
+ 'type' => 'none'
104
+ )
105
+ ),
106
+ 'border_opacity' => array(
107
+ 'type' => 'text',
108
+ 'label' => __('Opacity', 'fl-builder'),
109
+ 'default' => '100',
110
+ 'description' => '%',
111
+ 'maxlength' => '3',
112
+ 'size' => '5',
113
+ 'preview' => array(
114
+ 'type' => 'none'
115
+ )
116
+ ),
117
+ 'border_top' => array(
118
+ 'type' => 'text',
119
+ 'label' => __('Top Width', 'fl-builder'),
120
+ 'default' => '1',
121
+ 'description' => 'px',
122
+ 'maxlength' => '3',
123
+ 'size' => '5',
124
+ 'placeholder' => '0',
125
+ 'preview' => array(
126
+ 'type' => 'none'
127
+ )
128
+ ),
129
+ 'border_bottom' => array(
130
+ 'type' => 'text',
131
+ 'label' => __('Bottom Width', 'fl-builder'),
132
+ 'default' => '1',
133
+ 'description' => 'px',
134
+ 'maxlength' => '3',
135
+ 'size' => '5',
136
+ 'placeholder' => '0',
137
+ 'preview' => array(
138
+ 'type' => 'none'
139
+ )
140
+ ),
141
+ 'border_left' => array(
142
+ 'type' => 'text',
143
+ 'label' => __('Left Width', 'fl-builder'),
144
+ 'default' => '1',
145
+ 'description' => 'px',
146
+ 'maxlength' => '3',
147
+ 'size' => '5',
148
+ 'placeholder' => '0',
149
+ 'preview' => array(
150
+ 'type' => 'none'
151
+ )
152
+ ),
153
+ 'border_right' => array(
154
+ 'type' => 'text',
155
+ 'label' => __('Right Width', 'fl-builder'),
156
+ 'default' => '1',
157
+ 'description' => 'px',
158
+ 'maxlength' => '3',
159
+ 'size' => '5',
160
+ 'placeholder' => '0',
161
+ 'preview' => array(
162
+ 'type' => 'none'
163
+ )
164
+ )
165
+ )
166
+ ),
167
+ )
168
+ ),
169
+ 'advanced' => array(
170
+ 'title' => __('Advanced', 'fl-builder'),
171
+ 'sections' => array(
172
+ 'margins' => array(
173
+ 'title' => __('Margins', 'fl-builder'),
174
+ 'fields' => array(
175
+ 'margin_top' => array(
176
+ 'type' => 'text',
177
+ 'label' => __( 'Top', 'fl-builder' ),
178
+ 'default' => '',
179
+ 'description' => 'px',
180
+ 'maxlength' => '4',
181
+ 'size' => '5',
182
+ 'placeholder' => '0',
183
+ 'preview' => array(
184
+ 'type' => 'none'
185
+ )
186
+ ),
187
+ 'margin_bottom' => array(
188
+ 'type' => 'text',
189
+ 'label' => __( 'Bottom', 'fl-builder' ),
190
+ 'default' => '',
191
+ 'description' => 'px',
192
+ 'maxlength' => '4',
193
+ 'size' => '5',
194
+ 'placeholder' => '0',
195
+ 'preview' => array(
196
+ 'type' => 'none'
197
+ )
198
+ ),
199
+ 'margin_left' => array(
200
+ 'type' => 'text',
201
+ 'label' => __( 'Left', 'fl-builder' ),
202
+ 'default' => '',
203
+ 'description' => 'px',
204
+ 'maxlength' => '4',
205
+ 'size' => '5',
206
+ 'placeholder' => '0',
207
+ 'preview' => array(
208
+ 'type' => 'none'
209
+ )
210
+ ),
211
+ 'margin_right' => array(
212
+ 'type' => 'text',
213
+ 'label' => __( 'Right', 'fl-builder' ),
214
+ 'default' => '',
215
+ 'description' => 'px',
216
+ 'maxlength' => '4',
217
+ 'size' => '5',
218
+ 'placeholder' => '0',
219
+ 'preview' => array(
220
+ 'type' => 'none'
221
+ )
222
+ )
223
+ )
224
+ ),
225
+ 'padding' => array(
226
+ 'title' => __('Padding', 'fl-builder'),
227
+ 'fields' => array(
228
+ 'padding_top' => array(
229
+ 'type' => 'text',
230
+ 'label' => __( 'Top', 'fl-builder' ),
231
+ 'default' => '',
232
+ 'description' => 'px',
233
+ 'maxlength' => '4',
234
+ 'size' => '5',
235
+ 'placeholder' => '0',
236
+ 'preview' => array(
237
+ 'type' => 'none'
238
+ )
239
+ ),
240
+ 'padding_bottom' => array(
241
+ 'type' => 'text',
242
+ 'label' => __( 'Bottom', 'fl-builder' ),
243
+ 'default' => '',
244
+ 'description' => 'px',
245
+ 'maxlength' => '4',
246
+ 'size' => '5',
247
+ 'placeholder' => '0',
248
+ 'preview' => array(
249
+ 'type' => 'none'
250
+ )
251
+ ),
252
+ 'padding_left' => array(
253
+ 'type' => 'text',
254
+ 'label' => __( 'Left', 'fl-builder' ),
255
+ 'default' => '',
256
+ 'description' => 'px',
257
+ 'maxlength' => '4',
258
+ 'size' => '5',
259
+ 'placeholder' => '0',
260
+ 'preview' => array(
261
+ 'type' => 'none'
262
+ )
263
+ ),
264
+ 'padding_right' => array(
265
+ 'type' => 'text',
266
+ 'label' => __( 'Right', 'fl-builder' ),
267
+ 'default' => '',
268
+ 'description' => 'px',
269
+ 'maxlength' => '4',
270
+ 'size' => '5',
271
+ 'placeholder' => '0',
272
+ 'preview' => array(
273
+ 'type' => 'none'
274
+ )
275
+ )
276
+ )
277
+ ),
278
+ 'responsive' => array(
279
+ 'title' => __('Responsive Layout', 'fl-builder'),
280
+ 'fields' => array(
281
+ 'responsive_display' => array(
282
+ 'type' => 'select',
283
+ 'label' => __('Display', 'fl-builder'),
284
+ 'options' => array(
285
+ '' => __('Always', 'fl-builder'),
286
+ 'desktop' => __('Large Devices Only', 'fl-builder'),
287
+ 'desktop-medium' => __('Large &amp; Medium Devices Only', 'fl-builder'),
288
+ 'medium' => __('Medium Devices Only', 'fl-builder'),
289
+ 'medium-mobile' => __('Medium &amp; Small Devices Only', 'fl-builder'),
290
+ 'mobile' => __('Small Devices Only', 'fl-builder'),
291
+ ),
292
+ 'help' => __( 'Choose whether to show or hide this column at different device sizes.', 'fl-builder' ),
293
+ 'preview' => array(
294
+ 'type' => 'none'
295
+ )
296
+ ),
297
+ 'medium_size' => array(
298
+ 'type' => 'select',
299
+ 'label' => __('Medium Device Width', 'fl-builder'),
300
+ 'help' => __( 'The width of this column on medium devices such as tablets.', 'fl-builder' ),
301
+ 'options' => array(
302
+ 'default' => __('Default', 'fl-builder'),
303
+ 'custom' => __('Custom', 'fl-builder'),
304
+ ),
305
+ 'toggle' => array(
306
+ 'custom' => array(
307
+ 'fields' => array('custom_medium_size')
308
+ )
309
+ ),
310
+ 'preview' => array(
311
+ 'type' => 'none'
312
+ )
313
+ ),
314
+ 'custom_medium_size' => array(
315
+ 'type' => 'text',
316
+ 'label' => __('Custom Medium Device Width', 'fl-builder'),
317
+ 'default' => '100',
318
+ 'description' => '%',
319
+ 'maxlength' => '5',
320
+ 'size' => '6',
321
+ 'preview' => array(
322
+ 'type' => 'none'
323
+ )
324
+ ),
325
+ 'responsive_size' => array(
326
+ 'type' => 'select',
327
+ 'label' => __('Small Device Width', 'fl-builder'),
328
+ 'help' => __( 'The width of this column on small devices such as phones.', 'fl-builder' ),
329
+ 'options' => array(
330
+ 'default' => __('Default', 'fl-builder'),
331
+ 'custom' => __('Custom', 'fl-builder'),
332
+ ),
333
+ 'toggle' => array(
334
+ 'custom' => array(
335
+ 'fields' => array('custom_responsive_size')
336
+ )
337
+ ),
338
+ 'preview' => array(
339
+ 'type' => 'none'
340
+ )
341
+ ),
342
+ 'custom_responsive_size' => array(
343
+ 'type' => 'text',
344
+ 'label' => __( 'Custom Small Device Width', 'fl-builder' ),
345
+ 'default' => '100',
346
+ 'description' => '%',
347
+ 'maxlength' => '5',
348
+ 'size' => '6',
349
+ 'preview' => array(
350
+ 'type' => 'none'
351
+ )
352
+ )
353
+ )
354
+ ),
355
+ 'css_selectors' => array(
356
+ 'title' => __('CSS Selectors', 'fl-builder'),
357
+ 'fields' => array(
358
+ 'id' => array(
359
+ 'type' => 'text',
360
+ 'label' => __('ID', 'fl-builder'),
361
+ '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' ),
362
+ 'preview' => array(
363
+ 'type' => 'none'
364
+ )
365
+ ),
366
+ 'class' => array(
367
+ 'type' => 'text',
368
+ 'label' => __('CSS Class', 'fl-builder'),
369
+ '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' ),
370
+ 'preview' => array(
371
+ 'type' => 'none'
372
+ )
373
+ )
374
+ )
375
+ )
376
+ )
377
+ )
378
+ )
379
  ));
includes/compatibility.php CHANGED
@@ -1,5 +1,5 @@
1
  <?php
2
-
3
  /**
4
  * Misc functions for compatibility with other plugins.
5
  */
@@ -12,31 +12,31 @@
12
  * throws an error if it doesn't exist.
13
  */
14
  function fl_builder_option_tree_support() {
15
-
16
- if ( !function_exists( 'ot_get_media_post_ID' ) ) {
17
-
18
- function ot_get_media_post_ID() {
19
-
20
- // Option ID
21
- $option_id = 'ot_media_post_ID';
22
-
23
- // Get the media post ID
24
- $post_ID = get_option( $option_id, false );
25
-
26
- // Add $post_ID to the DB
27
- if ( $post_ID === false ) {
28
-
29
- global $wpdb;
30
-
31
- // Get the media post ID
32
- $post_ID = $wpdb->get_var( "SELECT ID FROM $wpdb->posts WHERE `post_title` = 'Media' AND `post_type` = 'option-tree' AND `post_status` = 'private'" );
33
-
34
- // Add to the DB
35
- add_option( $option_id, $post_ID );
36
- }
37
-
38
- return $post_ID;
39
- }
40
- }
41
  }
42
  add_action('after_setup_theme', 'fl_builder_option_tree_support');
1
  <?php
2
+
3
  /**
4
  * Misc functions for compatibility with other plugins.
5
  */
12
  * throws an error if it doesn't exist.
13
  */
14
  function fl_builder_option_tree_support() {
15
+
16
+ if ( !function_exists( 'ot_get_media_post_ID' ) ) {
17
+
18
+ function ot_get_media_post_ID() {
19
+
20
+ // Option ID
21
+ $option_id = 'ot_media_post_ID';
22
+
23
+ // Get the media post ID
24
+ $post_ID = get_option( $option_id, false );
25
+
26
+ // Add $post_ID to the DB
27
+ if ( $post_ID === false ) {
28
+
29
+ global $wpdb;
30
+
31
+ // Get the media post ID
32
+ $post_ID = $wpdb->get_var( "SELECT ID FROM $wpdb->posts WHERE `post_title` = 'Media' AND `post_type` = 'option-tree' AND `post_status` = 'private'" );
33
+
34
+ // Add to the DB
35
+ add_option( $option_id, $post_ID );
36
+ }
37
+
38
+ return $post_ID;
39
+ }
40
+ }
41
  }
42
  add_action('after_setup_theme', 'fl_builder_option_tree_support');
includes/field-code.php CHANGED
@@ -6,21 +6,21 @@
6
  jQuery(function(){
7
 
8
  var textarea = jQuery('#<?php echo $editor_id; ?>'),
9
- mode = textarea.data('editor'),
10
- editDiv = jQuery('<div>', {
11
- position: 'absolute',
12
- height: parseInt(textarea.attr('rows'), 10) * 20
13
- }),
14
- editor = null;
15
 
16
  editDiv.insertBefore(textarea);
17
- textarea.css('display', 'none');
18
 
19
- editor = ace.edit(editDiv[0]);
20
- editor.getSession().setValue(textarea.val());
21
- editor.getSession().setMode('ace/mode/' + mode);
22
-
23
- editor.getSession().on('change', function(e) {
24
  textarea.val(editor.getSession().getValue()).trigger('change');
25
  });
26
  });
6
  jQuery(function(){
7
 
8
  var textarea = jQuery('#<?php echo $editor_id; ?>'),
9
+ mode = textarea.data('editor'),
10
+ editDiv = jQuery('<div>', {
11
+ position: 'absolute',
12
+ height: parseInt(textarea.attr('rows'), 10) * 20
13
+ }),
14
+ editor = null;
15
 
16
  editDiv.insertBefore(textarea);
17
+ textarea.css('display', 'none');
18
 
19
+ editor = ace.edit(editDiv[0]);
20
+ editor.getSession().setValue(textarea.val());
21
+ editor.getSession().setMode('ace/mode/' + mode);
22
+
23
+ editor.getSession().on('change', function(e) {
24
  textarea.val(editor.getSession().getValue()).trigger('change');
25
  });
26
  });
includes/field-color.php CHANGED
@@ -1,7 +1,7 @@
1
  <div class="fl-color-picker<?php if(empty($value)) echo ' fl-color-picker-empty'; if(isset($field['class'])) echo ' ' . $field['class']; ?>">
2
- <div class="fl-color-picker-color fl-picker-<?php echo $name; ?>"></div>
3
- <?php if(isset($field['show_reset']) && $field['show_reset']) : ?>
4
- <div class="fl-color-picker-clear"></div>
5
- <?php endif; ?>
6
- <input name="<?php echo $name; ?>" type="hidden" value="<?php echo $value; ?>" class="fl-color-picker-value" />
7
  </div>
1
  <div class="fl-color-picker<?php if(empty($value)) echo ' fl-color-picker-empty'; if(isset($field['class'])) echo ' ' . $field['class']; ?>">
2
+ <div class="fl-color-picker-color fl-picker-<?php echo $name; ?>"></div>
3
+ <?php if(isset($field['show_reset']) && $field['show_reset']) : ?>
4
+ <div class="fl-color-picker-clear"></div>
5
+ <?php endif; ?>
6
+ <input name="<?php echo $name; ?>" type="hidden" value="<?php echo $value; ?>" class="fl-color-picker-value" />
7
  </div>
includes/field-editor.php CHANGED
@@ -1,60 +1,60 @@
1
  <div class="fl-editor-field" id="<?php echo $name; ?>">
2
- <?php
3
 
4
- // Remove 3rd party editor buttons.
5
- remove_all_actions('media_buttons', 999999);
6
- remove_all_actions('media_buttons_context', 999999);
7
- remove_all_filters('mce_external_plugins', 999999);
8
-
9
- global $wp_version;
10
 
11
- $editor_id = 'flrich' . time() . '_' . $name;;
12
-
13
- wp_editor($value, $editor_id, array(
14
- 'media_buttons' => isset($field['media_buttons']) ? $field['media_buttons'] : true,
15
- 'textarea_rows' => isset($field['rows']) ? $field['rows'] : 16,
16
- 'wpautop' => true
17
- ));
18
-
19
- ?>
20
- <script type="text/javascript">
21
-
22
- <?php if(version_compare($wp_version, '3.8.9', '<=')) : // Pre 3.9 editor init. ?>
23
- jQuery(function()
24
- {
25
- var editorId = '<?php echo $editor_id; ?>';
26
-
27
- quicktags({id : editorId});
28
- QTags._buttonsInit();
29
-
30
- if(typeof tinymce != 'undefined') {
31
- tinymce.execCommand('mceAddControl', true, editorId);
32
- }
33
-
34
- FLBuilder.initEditorField(editorId);
35
- });
36
- <?php else : // 3.9 and above editor init. ?>
37
- jQuery(function()
38
- {
39
- var editorId = '<?php echo $editor_id; ?>',
40
- hiddenEditor = tinyMCEPreInit.mceInit['flhiddeneditor'],
41
- editorProps = null;
42
-
43
- if(typeof tinymce != 'undefined') {
44
- editorProps = tinymce.extend({}, hiddenEditor);
45
- editorProps.selector = '#' + editorId;
46
- editorProps.body_class = editorProps.body_class.replace('flhiddeneditor', editorId);
47
- tinyMCEPreInit.mceInit[editorId] = editorProps;
48
- tinymce.init(editorProps);
49
- }
50
- if(typeof quicktags != 'undefined') {
51
- quicktags({id : editorId});
52
- QTags._buttonsInit();
53
- }
54
-
55
- window.wpActiveEditor = editorId;
56
- });
57
- <?php endif; ?>
58
-
59
- </script>
60
  </div>
1
  <div class="fl-editor-field" id="<?php echo $name; ?>">
2
+ <?php
3
 
4
+ // Remove 3rd party editor buttons.
5
+ remove_all_actions('media_buttons', 999999);
6
+ remove_all_actions('media_buttons_context', 999999);
7
+ remove_all_filters('mce_external_plugins', 999999);
8
+
9
+ global $wp_version;
10
 
11
+ $editor_id = 'flrich' . time() . '_' . $name;;
12
+
13
+ wp_editor($value, $editor_id, array(
14
+ 'media_buttons' => isset($field['media_buttons']) ? $field['media_buttons'] : true,
15
+ 'textarea_rows' => isset($field['rows']) ? $field['rows'] : 16,
16
+ 'wpautop' => true
17
+ ));
18
+
19
+ ?>
20
+ <script type="text/javascript">
21
+
22
+ <?php if(version_compare($wp_version, '3.8.9', '<=')) : // Pre 3.9 editor init. ?>
23
+ jQuery(function()
24
+ {
25
+ var editorId = '<?php echo $editor_id; ?>';
26
+
27
+ quicktags({id : editorId});
28
+ QTags._buttonsInit();
29
+
30
+ if(typeof tinymce != 'undefined') {
31
+ tinymce.execCommand('mceAddControl', true, editorId);
32
+ }
33
+
34
+ FLBuilder.initEditorField(editorId);
35
+ });
36
+ <?php else : // 3.9 and above editor init. ?>
37
+ jQuery(function()
38
+ {
39
+ var editorId = '<?php echo $editor_id; ?>',
40
+ hiddenEditor = tinyMCEPreInit.mceInit['flhiddeneditor'],
41
+ editorProps = null;
42
+
43
+ if(typeof tinymce != 'undefined') {
44
+ editorProps = tinymce.extend({}, hiddenEditor);
45
+ editorProps.selector = '#' + editorId;
46
+ editorProps.body_class = editorProps.body_class.replace('flhiddeneditor', editorId);
47
+ tinyMCEPreInit.mceInit[editorId] = editorProps;
48
+ tinymce.init(editorProps);
49
+ }
50
+ if(typeof quicktags != 'undefined') {
51
+ quicktags({id : editorId});
52
+ QTags._buttonsInit();
53
+ }
54
+
55
+ window.wpActiveEditor = editorId;
56
+ });
57
+ <?php endif; ?>
58
+
59
+ </script>
60
  </div>
includes/field-form.php CHANGED
@@ -1,30 +1,30 @@
1
  <div class="fl-form-field fl-builder-custom-field"<?php if ( isset( $field['preview_text'] ) ) echo ' data-preview-text="'. $field['preview_text'] .'"'; ?>>
2
- <div class="fl-form-field-preview-text">
3
- <?php
4
 
5
- if ( isset( $field['preview_text'] ) && is_object( $value ) ) {
6
-
7
- $form = FLBuilderModel::get_settings_form( $field['form'] );
8
- $form_fields = FLBuilderModel::get_settings_form_fields( $form['tabs'] );
9
-
10
- if ( isset( $form_fields[ $field['preview_text'] ] ) ) {
11
-
12
- $preview_field = $form_fields[ $field['preview_text'] ];
13
-
14
- if ( 'icon' == $preview_field['type'] ) {
15
- echo '<i class="' . $value->$field['preview_text'] . '"></i>';
16
- }
17
- else if ( 'select' == $preview_field['type'] ) {
18
- echo $preview_field['options'][ $value->$field['preview_text'] ];
19
- }
20
- else if ( ! empty( $value->$field['preview_text'] ) ) {
21
- echo FLBuilderUtils::snippetwop( strip_tags( str_replace( '&#39;', "'", $value->$field['preview_text'] ) ), 35 );
22
- }
23
- }
24
- }
25
 
26
- ?>
27
- </div>
28
  <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>
29
- <input name="<?php echo $name; ?>" type="hidden" value='<?php if ( ! empty( $value ) ) echo str_replace( "'", '&#39;', json_encode( $value ) ); ?>' />
30
  </div>
1
  <div class="fl-form-field fl-builder-custom-field"<?php if ( isset( $field['preview_text'] ) ) echo ' data-preview-text="'. $field['preview_text'] .'"'; ?>>
2
+ <div class="fl-form-field-preview-text">
3
+ <?php
4
 
5
+ if ( isset( $field['preview_text'] ) && is_object( $value ) ) {
6
+
7
+ $form = FLBuilderModel::get_settings_form( $field['form'] );
8
+ $form_fields = FLBuilderModel::get_settings_form_fields( $form['tabs'] );
9
+
10
+ if ( isset( $form_fields[ $field['preview_text'] ] ) ) {
11
+
12
+ $preview_field = $form_fields[ $field['preview_text'] ];
13
+
14
+ if ( 'icon' == $preview_field['type'] ) {
15
+ echo '<i class="' . $value->$field['preview_text'] . '"></i>';
16
+ }
17
+ else if ( 'select' == $preview_field['type'] ) {
18
+ echo $preview_field['options'][ $value->$field['preview_text'] ];
19
+ }
20
+ else if ( ! empty( $value->$field['preview_text'] ) ) {
21
+ echo FLBuilderUtils::snippetwop( strip_tags( str_replace( '&#39;', "'", $value->$field['preview_text'] ) ), 35 );
22
+ }
23
+ }
24
+ }
25
 
26
+ ?>
27
+ </div>
28
  <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>
29
+ <input name="<?php echo $name; ?>" type="hidden" value='<?php if ( ! empty( $value ) ) echo str_replace( "'", '&#39;', json_encode( $value ) ); ?>' />
30
  </div>
includes/field-icon.php CHANGED
@@ -1,11 +1,11 @@
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'; 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>
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 esc_url($value); ?>" class="text fl-link-field-input" placeholder="http://www.example.com" />
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 esc_url($value); ?>" class="text fl-link-field-input" placeholder="http://www.example.com" />
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-photos.php CHANGED
@@ -1,17 +1,17 @@
1
  <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']; ?>">
2
- <div class="fl-multiple-photos-count">
3
- <?php
4
 
5
- $count = is_array($value) ? count($value) : false;
6
 
7
  if ( $count ) {
8
  printf( _n( '1 Photo Selected', '%d Photos Selected', $count, 'fl-builder' ), $count );
9
  }
10
 
11
- ?>
12
- </div>
13
- <a class="fl-multiple-photos-select" href="javascript:void(0);" onclick="return false;"><?php _e('Create Gallery', 'fl-builder'); ?></a>
14
- <a class="fl-multiple-photos-edit" href="javascript:void(0);" onclick="return false;"><?php _e('Edit Gallery', 'fl-builder'); ?></a>
15
- <a class="fl-multiple-photos-add" href="javascript:void(0);" onclick="return false;"><?php _e('Add Photos', 'fl-builder'); ?></a>
16
- <input name="<?php echo $name; ?>" type="hidden" value='<?php if(!empty($value)) echo json_encode($value); ?>' />
17
  </div>
1
  <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']; ?>">
2
+ <div class="fl-multiple-photos-count">
3
+ <?php
4
 
5
+ $count = is_array($value) ? count($value) : false;
6
 
7
  if ( $count ) {
8
  printf( _n( '1 Photo Selected', '%d Photos Selected', $count, 'fl-builder' ), $count );
9
  }
10
 
11
+ ?>
12
+ </div>
13
+ <a class="fl-multiple-photos-select" href="javascript:void(0);" onclick="return false;"><?php _e('Create Gallery', 'fl-builder'); ?></a>
14
+ <a class="fl-multiple-photos-edit" href="javascript:void(0);" onclick="return false;"><?php _e('Edit Gallery', 'fl-builder'); ?></a>
15
+ <a class="fl-multiple-photos-add" href="javascript:void(0);" onclick="return false;"><?php _e('Add Photos', 'fl-builder'); ?></a>
16
+ <input name="<?php echo $name; ?>" type="hidden" value='<?php if(!empty($value)) echo json_encode($value); ?>' />
17
  </div>
includes/field-photo-sizes.php CHANGED
@@ -1,11 +1,11 @@
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
  </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
  </select>
includes/field-photo.php CHANGED
@@ -1,17 +1,17 @@
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
- <a class="fl-photo-replace" href="javascript:void(0);" onclick="return false;"><?php _e('Replace', 'fl-builder'); ?></a>
14
- <div class="fl-clear"></div>
15
- </div>
16
- <input name="<?php echo $name; ?>" type="hidden" value='<?php echo $value; ?>' />
17
  </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'; 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
+ <a class="fl-photo-replace" href="javascript:void(0);" onclick="return false;"><?php _e('Replace', 'fl-builder'); ?></a>
14
+ <div class="fl-clear"></div>
15
+ </div>
16
+ <input name="<?php echo $name; ?>" type="hidden" value='<?php echo $value; ?>' />
17
  </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
@@ -1,15 +1,15 @@
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
3
-
4
- foreach($field['options'] as $key => $val) :
5
-
6
- $label = is_array($val) ? $val['label'] : $val;
7
-
8
- if(is_array($val) && isset($val['premium']) && $val['premium'] && FL_BUILDER_LITE === true) {
9
- continue;
10
- }
11
-
12
- ?>
13
- <option value="<?php echo $key; ?>" <?php selected($value, $key); ?>><?php echo $label; ?></option>
14
- <?php endforeach; ?>
15
  </select>
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
3
+
4
+ foreach($field['options'] as $key => $val) :
5
+
6
+ $label = is_array($val) ? $val['label'] : $val;
7
+
8
+ if(is_array($val) && isset($val['premium']) && $val['premium'] && FL_BUILDER_LITE === true) {
9
+ continue;
10
+ }
11
+
12
+ ?>
13
+ <option value="<?php echo $key; ?>" <?php selected($value, $key); ?>><?php echo $label; ?></option>
14
+ <?php endforeach; ?>
15
  </select>
includes/field-video.php CHANGED
@@ -1,21 +1,21 @@
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>
9
- <span class="fl-video-preview-filename"><?php echo $video->filename; ?></span>
10
- <?php else : ?>
11
- <div class="fl-video-preview-img">
12
- <img src="<?php echo FL_BUILDER_URL; ?>img/spacer.png" />
13
- </div>
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'; 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>
9
+ <span class="fl-video-preview-filename"><?php echo $video->filename; ?></span>
10
+ <?php else : ?>
11
+ <div class="fl-video-preview-img">
12
+ <img src="<?php echo FL_BUILDER_URL; ?>img/spacer.png" />
13
+ </div>
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>
includes/field.php CHANGED
@@ -1,46 +1,46 @@
1
  <?php if(empty($field['label'])) : ?>
2
  <td colspan="2">
3
  <?php else : ?>
4
- <th>
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>
25
- </span>
26
- <?php endif; ?>
27
- </label>
28
- </th>
29
  <td>
30
  <?php endif; ?>
31
- <?php
32
-
33
- $field_file = FL_BUILDER_DIR . 'includes/field-' . $field['type'] . '.php';
34
-
35
- if(file_exists($field_file)) {
36
- include $field_file;
37
- }
38
- else {
39
- do_action('fl_builder_control_' . $field['type'], $name, $value, $field);
40
- }
41
-
42
- ?>
43
- <?php if(isset($field['description'])) : ?>
44
- <span class="fl-field-description"><?php echo $field['description']; ?></span>
45
- <?php endif; ?>
46
  </td>
1
  <?php if(empty($field['label'])) : ?>
2
  <td colspan="2">
3
  <?php else : ?>
4
+ <th>
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>
25
+ </span>
26
+ <?php endif; ?>
27
+ </label>
28
+ </th>
29
  <td>
30
  <?php endif; ?>
31
+ <?php
32
+
33
+ $field_file = FL_BUILDER_DIR . 'includes/field-' . $field['type'] . '.php';
34
+
35
+ if(file_exists($field_file)) {
36
+ include $field_file;
37
+ }
38
+ else {
39
+ do_action('fl_builder_control_' . $field['type'], $name, $value, $field);
40
+ }
41
+
42
+ ?>
43
+ <?php if(isset($field['description'])) : ?>
44
+ <span class="fl-field-description"><?php echo $field['description']; ?></span>
45
+ <?php endif; ?>
46
  </td>
includes/global-settings.php CHANGED
@@ -2,151 +2,151 @@
2
 
3
  FLBuilder::register_settings_form('global', array(
4
  'title' => sprintf( _x( '%s Settings', '%s stands for custom branded "Page Builder" name.', 'fl-builder' ), FLBuilderModel::get_branding() ),
5
- 'tabs' => array(
6
- 'general' => array(
7
- 'title' => __('General', 'fl-builder'),
8
- 'description' => __('Note: 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' => 'text',
41
- 'label' => __('Margins', 'fl-builder'),
42
- 'default' => '0',
43
- 'maxlength' => '3',
44
- 'size' => '5',
45
- 'description' => 'px'
46
- ),
47
- 'row_padding' => array(
48
- 'type' => 'text',
49
- 'label' => __('Padding', 'fl-builder'),
50
- 'default' => '20',
51
- 'maxlength' => '3',
52
- 'size' => '5',
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',
66
- 'label' => __( 'Default Row Width', 'fl-builder' ),
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(
79
- 'type' => 'select',
80
- 'label' => __( 'Default Row Content Width', 'fl-builder' ),
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' => 'text',
94
- 'label' => __('Margins', 'fl-builder'),
95
- 'default' => '20',
96
- 'maxlength' => '3',
97
- 'size' => '5',
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
- )
152
  ));
2
 
3
  FLBuilder::register_settings_form('global', array(
4
  'title' => sprintf( _x( '%s Settings', '%s stands for custom branded "Page Builder" name.', 'fl-builder' ), FLBuilderModel::get_branding() ),
5
+ 'tabs' => array(
6
+ 'general' => array(
7
+ 'title' => __('General', 'fl-builder'),
8
+ 'description' => __('Note: 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' => 'text',
41
+ 'label' => __('Margins', 'fl-builder'),
42
+ 'default' => '0',
43
+ 'maxlength' => '3',
44
+ 'size' => '5',
45
+ 'description' => 'px'
46
+ ),
47
+ 'row_padding' => array(
48
+ 'type' => 'text',
49
+ 'label' => __('Padding', 'fl-builder'),
50
+ 'default' => '20',
51
+ 'maxlength' => '3',
52
+ 'size' => '5',
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',
66
+ 'label' => __( 'Default Row Width', 'fl-builder' ),
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(
79
+ 'type' => 'select',
80
+ 'label' => __( 'Default Row Content Width', 'fl-builder' ),
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' => 'text',
94
+ 'label' => __('Margins', 'fl-builder'),
95
+ 'default' => '20',
96
+ 'maxlength' => '3',
97
+ 'size' => '5',
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
+ )
152
  ));
includes/icon-selector.php CHANGED
@@ -1,29 +1,29 @@
1
  <div class="fl-lightbox-header">
2
- <h1><?php _e( 'Select Icon', 'fl-builder' ); ?></h1>
3
- <div class="fl-icons-filter fl-builder-settings-fields">
4
- <select class="fl-icons-filter-select">
5
- <option value="all"><?php _ex( 'All Libraries', 'Select option for showing all icon libraries.', 'fl-builder' ); ?></option>
6
- <?php foreach ( $icon_sets as $set_key => $set_data ) : ?>
7
- <option value="<?php echo $set_key; ?>"><?php echo $set_data['name']; ?></option>
8
- <?php endforeach; ?>
9
- </select>
10
- <input type="text" class="fl-icons-filter-text" placeholder="Search..." />
11
- </div>
12
  </div>
13
  <div class="fl-icons-list">
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 : ?>
21
- <i class="<?php echo $icon; ?>"></i>
22
- <?php endif; ?>
23
- <?php endforeach; ?>
24
- </div>
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>
1
  <div class="fl-lightbox-header">
2
+ <h1><?php _e( 'Select Icon', 'fl-builder' ); ?></h1>
3
+ <div class="fl-icons-filter fl-builder-settings-fields">
4
+ <select class="fl-icons-filter-select">
5
+ <option value="all"><?php _ex( 'All Libraries', 'Select option for showing all icon libraries.', 'fl-builder' ); ?></option>
6
+ <?php foreach ( $icon_sets as $set_key => $set_data ) : ?>
7
+ <option value="<?php echo $set_key; ?>"><?php echo $set_data['name']; ?></option>
8
+ <?php endforeach; ?>
9
+ </select>
10
+ <input type="text" class="fl-icons-filter-text" placeholder="Search..." />
11
+ </div>
12
  </div>
13
  <div class="fl-icons-list">
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 : ?>
21
+ <i class="<?php echo $icon; ?>"></i>
22
+ <?php endif; ?>
23
+ <?php endforeach; ?>
24
+ </div>
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
@@ -1,8 +1,8 @@
1
  <script type="text/javascript">
2
 
3
  if(typeof jQuery == 'undefined' || typeof jQuery.fn.on == 'undefined') {
4
- document.write('<script src="<?php echo FL_BUILDER_URL ?>js/jquery.js"><\/script>');
5
- document.write('<script src="<?php echo FL_BUILDER_URL ?>js/jquery.migrate.min.js"><\/script>');
6
  }
7
 
8
  </script>
1
  <script type="text/javascript">
2
 
3
  if(typeof jQuery == 'undefined' || typeof jQuery.fn.on == 'undefined') {
4
+ document.write('<script src="<?php echo FL_BUILDER_URL ?>js/jquery.js"><\/script>');
5
+ document.write('<script src="<?php echo FL_BUILDER_URL ?>js/jquery.migrate.min.js"><\/script>');
6
  }
7
 
8
  </script>
includes/js-config.php CHANGED
@@ -1,107 +1,107 @@
1
  <script>
2
 
3
  var FLBuilderConfig = {
4
- debug: <?php if( defined( 'WP_DEBUG' ) && WP_DEBUG ) echo 'true'; else echo 'false'; ?>,
5
- enabledTemplates: '<?php echo $enabled_templates; ?>',
6
- help: <?php echo json_encode( $help_button ); ?>,
7
- homeUrl: '<?php echo home_url(); ?>',
8
- isRtl: <?php if(is_rtl()) echo 'true'; else echo 'false'; ?>,
9
- lite: <?php if(FL_BUILDER_LITE === true) echo 'true'; else echo 'false'; ?>,
10
- newUser: <?php if ( FLBuilderModel::is_new_user() ) echo 'true'; else echo 'false'; ?>,
11
- postId: <?php echo $post_id; ?>,
12
- postType: '<?php echo get_post_type(); ?>',
13
- simpleUi: <?php if(!current_user_can(FLBuilderModel::get_editing_capability())) echo 'true'; else echo 'false'; ?>,
14
- upgradeUrl: '<?php if(FL_BUILDER_LITE === true) $campaign = 'upgrade-button'; else $campaign = 'buy-button'; echo FLBuilderModel::get_upgrade_url( array( 'utm_source' => 'external', 'utm_medium' => 'builder', 'utm_campaign' => $campaign ) ); ?>'
15
  };
16
 
17
  var FLBuilderStrings = {
18
- actionsLightboxTitle: '<?php esc_attr_e('What would you like to do?', 'fl-builder'); ?>',
19
- cancel: '<?php esc_attr_e('Cancel', 'fl-builder'); ?>',
20
- changeTemplate: '<?php esc_attr_e('Change Template', 'fl-builder'); ?>',
21
- changeTemplateMessage: '<?php esc_attr_e('Warning! Changing the template will replace your existing layout. Do you really want to do this?', 'fl-builder'); ?>',
22
- column: '<?php esc_attr_e('Column', 'fl-builder') ?>',
23
- columnSettings: '<?php esc_attr_e('Column Settings', 'fl-builder') ?>',
24
- contentSliderSelectLayout: '<?php esc_attr_e('Please select either a background layout or content layout before submitting.', 'fl-builder'); ?>',
25
- deleteAccount: '<?php esc_attr_e('Remove Account', 'fl-builder'); ?>',
26
- deleteAccountWarning: '<?php esc_attr_e('Are you sure you want to remove this account? Other modules that are connected to it will be affected.', 'fl-builder'); ?>',
27
- deleteFieldMessage: '<?php esc_attr_e('Do you really want to delete this item?', 'fl-builder'); ?>',
28
- deleteModuleMessage: '<?php esc_attr_e('Do you really want to delete this module? All content data will be permanently deleted.', 'fl-builder') ?>',
29
- deleteRowMessage: '<?php esc_attr_e('Do you really want to delete this row? All content data will be permanently deleted.', 'fl-builder') ?>',
30
- deleteTemplate: '<?php esc_attr_e('Do you really want to delete this template?', 'fl-builder'); ?>',
31
- discard: '<?php esc_attr_e('Discard Draft', 'fl-builder'); ?>',
32
- discardMessage: '<?php esc_attr_e('Do you really want to discard this draft? All of your changes that are not published will be lost.', 'fl-builder'); ?>',
33
- done: '<?php esc_attr_e('Done', 'fl-builder'); ?>',
34
- draft: '<?php esc_attr_e('Save Draft', 'fl-builder'); ?>',
35
- duplicate: '<?php _ex( 'Duplicate', 'Duplicate page/post action label.', 'fl-builder' ); ?>',
36
- duplicatePage: '<?php esc_attr_e('Duplicate This Page', 'fl-builder'); ?>',
37
- duplicateTemplate: '<?php esc_attr_e('Duplicate This Template', 'fl-builder'); ?>',
38
- editGlobalSettings: '<?php esc_attr_e('Edit Global Settings', 'fl-builder'); ?>',
39
- emptyMessage: '<?php esc_attr_e('Drop a row layout or module to get started!', 'fl-builder') ?>',
40
- errorMessage: '<?php esc_attr_e('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') ?>',
41
- fullSize: '<?php esc_attr_e('Full Size', 'fl-builder'); ?>',
42
- getHelp: '<?php esc_attr_e('Get Help', 'fl-builder'); ?>',
43
- gettingStartedVideo: '<?php esc_attr_e('Getting Started Video', 'fl-builder'); ?>',
44
- globalErrorMessage: '<?php _e('"{message}" on line {line} of {file}.', 'fl-builder') ?>',
45
- insert: '<?php esc_attr_e('Insert', 'fl-builder'); ?>',
46
- large: '<?php esc_attr_e('Large', 'fl-builder'); ?>',
47
- manageTemplates: '<?php esc_attr_e('Manage Templates', 'fl-builder'); ?>',
48
- medium: '<?php esc_attr_e('Medium', 'fl-builder'); ?>',
49
- module: '<?php esc_attr_e('Module', 'fl-builder') ?>',
50
- move: '<?php esc_attr_e('Move', 'fl-builder'); ?>',
51
- newColumn: '<?php esc_attr_e('New Column', 'fl-builder') ?>',
52
- newRow: '<?php esc_attr_e('New Row', 'fl-builder') ?>',
53
- noResultsFound: '<?php esc_attr_e('No results found.', 'fl-builder') ?>',
54
- noThanks: '<?php esc_attr_e('No Thanks', 'fl-builder'); ?>',
55
- ok: '<?php esc_attr_e( 'OK', 'fl-builder' ); ?>',
56
- photoPage: '<?php esc_attr_e('Photo Page', 'fl-builder'); ?>',
57
- photoSelected: '<?php esc_attr_e('Photo Selected', 'fl-builder'); ?>',
58
- photosSelected: '<?php esc_attr_e('Photos Selected', 'fl-builder'); ?>',
59
- pleaseWait: '<?php esc_attr_e('Please Wait...', 'fl-builder'); ?>',
60
- publish: '<?php esc_attr_e('Publish Changes', 'fl-builder'); ?>',
61
- remove: '<?php esc_attr_e('Remove', 'fl-builder'); ?>',
62
- row: '<?php esc_attr_e('Row', 'fl-builder') ?>',
63
- rowSettings: '<?php esc_attr_e('Row Settings', 'fl-builder') ?>',
64
- saveCoreTemplate: '<?php esc_attr_e('Save Core Template', 'fl-builder'); ?>',
65
- saveTemplate: '<?php esc_attr_e('Save Template', 'fl-builder'); ?>',
66
- selectPhoto: '<?php esc_attr_e('Select Photo', 'fl-builder'); ?>',
67
- selectPhotos: '<?php esc_attr_e('Select Photos', 'fl-builder'); ?>',
68
- selectVideo: '<?php esc_attr_e('Select Video', 'fl-builder'); ?>',
69
- settings: '<?php _ex( '%s Settings', '%s stands for module name.', 'fl-builder' ); ?>',
70
- subscriptionModuleAccountError: '<?php esc_attr_e('Please select an account before saving.', 'fl-builder'); ?>',
71
- subscriptionModuleConnectError: '<?php esc_attr_e('Please connect an account before saving.', 'fl-builder'); ?>',
72
- subscriptionModuleListError: '<?php esc_attr_e('Please select a list before saving.', 'fl-builder'); ?>',
73
- takeHelpTour: '<?php esc_attr_e('Take a Tour', 'fl-builder'); ?>',
74
- templateAppend: '<?php esc_attr_e('Append New Layout', 'fl-builder'); ?>',
75
- templateReplace: '<?php esc_attr_e('Replace Existing Layout', 'fl-builder'); ?>',
76
- templateSaved: '<?php esc_attr_e('Template Saved!', 'fl-builder'); ?>',
77
- thumbnail: '<?php esc_attr_e('Thumbnail', 'fl-builder'); ?>',
78
- tourNext: '<?php esc_attr_e('Next', 'fl-builder'); ?>',
79
- tourEnd: '<?php esc_attr_e('Get Started', 'fl-builder'); ?>',
80
- tourTemplatesTitle: '<?php esc_attr_e('Choose a Template', 'fl-builder'); ?>',
81
- tourTemplates: '<?php esc_attr_e('Get started by choosing a layout template to customize, or build a page from scratch by selecting the blank layout template.', 'fl-builder'); ?>',
82
- tourAddRowsTitle: '<?php esc_attr_e('Add Rows', 'fl-builder'); ?>',
83
- tourAddRows: '<?php esc_attr_e('Add multi-column rows, adjust spacing, add backgrounds and more by dragging and dropping row layouts onto the page.', 'fl-builder'); ?>',
84
- tourAddContentTitle: '<?php esc_attr_e('Add Content', 'fl-builder'); ?>',
85
- tourAddContent: '<?php esc_attr_e('Add new content by dragging and dropping modules or widgets into your row layouts or to create a new row layout.', 'fl-builder'); ?>',
86
- tourEditContentTitle: '<?php esc_attr_e('Edit Content', 'fl-builder'); ?>',
87
- tourEditContent: '<?php esc_attr_e('Move your mouse over rows, columns or modules to edit and interact with them.', 'fl-builder'); ?>',
88
- tourEditContent2: '<?php esc_attr_e('Use the action buttons to perform actions such as moving, editing, duplicating or deleting rows, columns and modules.', 'fl-builder'); ?>',
89
- tourAddContentButtonTitle: '<?php esc_attr_e('Add More Content', 'fl-builder'); ?>',
90
- tourAddContentButton: '<?php esc_attr_e('Use the Add Content button to open the content panel and add new row layouts, modules or widgets.', 'fl-builder'); ?>',
91
- tourTemplatesButtonTitle: '<?php esc_attr_e('Change Templates', 'fl-builder'); ?>',
92
- tourTemplatesButton: '<?php esc_attr_e('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'); ?>',
93
- tourToolsButtonTitle: '<?php esc_attr_e('Helpful Tools', 'fl-builder'); ?>',
94
- tourToolsButton: '<?php esc_attr_e('The Tools button lets you duplicate a page, save a template or edit the global settings.', 'fl-builder'); ?>',
95
- tourDoneButtonTitle: '<?php esc_attr_e('Publish Your Changes', 'fl-builder'); ?>',
96
- tourDoneButton: '<?php esc_attr_e("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'); ?>',
97
- tourFinishedTitle: '<?php esc_attr_e("Let's Get Building!", 'fl-builder'); ?>',
98
- tourFinished: '<?php esc_attr_e("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'); ?>',
99
- unloadWarning: '<?php esc_attr_e('The settings you are currently editing will not be saved if you navigate away from this page.', 'fl-builder'); ?>',
100
- viewKnowledgeBase: '<?php esc_attr_e('View the Knowledge Base', 'fl-builder'); ?>',
101
- visitForums: '<?php esc_attr_e('Visit the Forums', 'fl-builder'); ?>',
102
- watchHelpVideo: '<?php esc_attr_e('Watch the Video', 'fl-builder'); ?>',
103
- welcomeMessage: '<?php esc_attr_e('Welcome! It looks like this might be your first time using the builder. Would you like to take a tour?', 'fl-builder'); ?>',
104
- yesPlease: '<?php esc_attr_e('Yes Please!', 'fl-builder'); ?>'
105
  };
106
 
107
  </script>
1
  <script>
2
 
3
  var FLBuilderConfig = {
4
+ debug: <?php if( defined( 'WP_DEBUG' ) && WP_DEBUG ) echo 'true'; else echo 'false'; ?>,
5
+ enabledTemplates: '<?php echo $enabled_templates; ?>',
6
+ help: <?php echo json_encode( $help_button ); ?>,
7
+ homeUrl: '<?php echo home_url(); ?>',
8
+ isRtl: <?php if(is_rtl()) echo 'true'; else echo 'false'; ?>,
9
+ lite: <?php if(FL_BUILDER_LITE === true) echo 'true'; else echo 'false'; ?>,
10
+ newUser: <?php if ( FLBuilderModel::is_new_user() ) echo 'true'; else echo 'false'; ?>,
11
+ postId: <?php echo $post_id; ?>,
12
+ postType: '<?php echo get_post_type(); ?>',
13
+ simpleUi: <?php if(!current_user_can(FLBuilderModel::get_editing_capability())) echo 'true'; else echo 'false'; ?>,
14
+ upgradeUrl: '<?php if(FL_BUILDER_LITE === true) $campaign = 'upgrade-button'; else $campaign = 'buy-button'; echo FLBuilderModel::get_upgrade_url( array( 'utm_source' => 'external', 'utm_medium' => 'builder', 'utm_campaign' => $campaign ) ); ?>'
15
  };
16
 
17
  var FLBuilderStrings = {
18
+ actionsLightboxTitle: '<?php esc_attr_e('What would you like to do?', 'fl-builder'); ?>',
19
+ cancel: '<?php esc_attr_e('Cancel', 'fl-builder'); ?>',
20
+ changeTemplate: '<?php esc_attr_e('Change Template', 'fl-builder'); ?>',
21
+ changeTemplateMessage: '<?php esc_attr_e('Warning! Changing the template will replace your existing layout. Do you really want to do this?', 'fl-builder'); ?>',
22
+ column: '<?php esc_attr_e('Column', 'fl-builder') ?>',
23
+ columnSettings: '<?php esc_attr_e('Column Settings', 'fl-builder') ?>',
24
+ contentSliderSelectLayout: '<?php esc_attr_e('Please select either a background layout or content layout before submitting.', 'fl-builder'); ?>',
25
+ deleteAccount: '<?php esc_attr_e('Remove Account', 'fl-builder'); ?>',
26
+ deleteAccountWarning: '<?php esc_attr_e('Are you sure you want to remove this account? Other modules that are connected to it will be affected.', 'fl-builder'); ?>',
27
+ deleteFieldMessage: '<?php esc_attr_e('Do you really want to delete this item?', 'fl-builder'); ?>',
28
+ deleteModuleMessage: '<?php esc_attr_e('Do you really want to delete this module? All content data will be permanently deleted.', 'fl-builder') ?>',
29
+ deleteRowMessage: '<?php esc_attr_e('Do you really want to delete this row? All content data will be permanently deleted.', 'fl-builder') ?>',
30
+ deleteTemplate: '<?php esc_attr_e('Do you really want to delete this template?', 'fl-builder'); ?>',
31
+ discard: '<?php esc_attr_e('Discard Draft', 'fl-builder'); ?>',
32
+ discardMessage: '<?php esc_attr_e('Do you really want to discard this draft? All of your changes that are not published will be lost.', 'fl-builder'); ?>',
33
+ done: '<?php esc_attr_e('Done', 'fl-builder'); ?>',
34
+ draft: '<?php esc_attr_e('Save Draft', 'fl-builder'); ?>',
35
+ duplicate: '<?php _ex( 'Duplicate', 'Duplicate page/post action label.', 'fl-builder' ); ?>',
36
+ duplicatePage: '<?php esc_attr_e('Duplicate This Page', 'fl-builder'); ?>',
37
+ duplicateTemplate: '<?php esc_attr_e('Duplicate This Template', 'fl-builder'); ?>',
38
+ editGlobalSettings: '<?php esc_attr_e('Edit Global Settings', 'fl-builder'); ?>',
39
+ emptyMessage: '<?php esc_attr_e('Drop a row layout or module to get started!', 'fl-builder') ?>',
40
+ errorMessage: '<?php esc_attr_e('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') ?>',
41
+ fullSize: '<?php esc_attr_e('Full Size', 'fl-builder'); ?>',
42
+ getHelp: '<?php esc_attr_e('Get Help', 'fl-builder'); ?>',
43
+ gettingStartedVideo: '<?php esc_attr_e('Getting Started Video', 'fl-builder'); ?>',
44
+ globalErrorMessage: '<?php _e('"{message}" on line {line} of {file}.', 'fl-builder') ?>',
45
+ insert: '<?php esc_attr_e('Insert', 'fl-builder'); ?>',
46
+ large: '<?php esc_attr_e('Large', 'fl-builder'); ?>',
47
+ manageTemplates: '<?php esc_attr_e('Manage Templates', 'fl-builder'); ?>',
48
+ medium: '<?php esc_attr_e('Medium', 'fl-builder'); ?>',
49
+ module: '<?php esc_attr_e('Module', 'fl-builder') ?>',
50
+ move: '<?php esc_attr_e('Move', 'fl-builder'); ?>',
51
+ newColumn: '<?php esc_attr_e('New Column', 'fl-builder') ?>',
52
+ newRow: '<?php esc_attr_e('New Row', 'fl-builder') ?>',
53
+ noResultsFound: '<?php esc_attr_e('No results found.', 'fl-builder') ?>',
54
+ noThanks: '<?php esc_attr_e('No Thanks', 'fl-builder'); ?>',
55
+ ok: '<?php esc_attr_e( 'OK', 'fl-builder' ); ?>',
56
+ photoPage: '<?php esc_attr_e('Photo Page', 'fl-builder'); ?>',
57
+ photoSelected: '<?php esc_attr_e('Photo Selected', 'fl-builder'); ?>',
58
+ photosSelected: '<?php esc_attr_e('Photos Selected', 'fl-builder'); ?>',
59
+ pleaseWait: '<?php esc_attr_e('Please Wait...', 'fl-builder'); ?>',
60
+ publish: '<?php esc_attr_e('Publish Changes', 'fl-builder'); ?>',
61
+ remove: '<?php esc_attr_e('Remove', 'fl-builder'); ?>',
62
+ row: '<?php esc_attr_e('Row', 'fl-builder') ?>',
63
+ rowSettings: '<?php esc_attr_e('Row Settings', 'fl-builder') ?>',
64
+ saveCoreTemplate: '<?php esc_attr_e('Save Core Template', 'fl-builder'); ?>',
65
+ saveTemplate: '<?php esc_attr_e('Save Template', 'fl-builder'); ?>',
66
+ selectPhoto: '<?php esc_attr_e('Select Photo', 'fl-builder'); ?>',
67
+ selectPhotos: '<?php esc_attr_e('Select Photos', 'fl-builder'); ?>',
68
+ selectVideo: '<?php esc_attr_e('Select Video', 'fl-builder'); ?>',
69
+ settings: '<?php _ex( '%s Settings', '%s stands for module name.', 'fl-builder' ); ?>',
70
+ subscriptionModuleAccountError: '<?php esc_attr_e('Please select an account before saving.', 'fl-builder'); ?>',
71
+ subscriptionModuleConnectError: '<?php esc_attr_e('Please connect an account before saving.', 'fl-builder'); ?>',
72
+ subscriptionModuleListError: '<?php esc_attr_e('Please select a list before saving.', 'fl-builder'); ?>',
73
+ takeHelpTour: '<?php esc_attr_e('Take a Tour', 'fl-builder'); ?>',
74
+ templateAppend: '<?php esc_attr_e('Append New Layout', 'fl-builder'); ?>',
75
+ templateReplace: '<?php esc_attr_e('Replace Existing Layout', 'fl-builder'); ?>',
76
+ templateSaved: '<?php esc_attr_e('Template Saved!', 'fl-builder'); ?>',
77
+ thumbnail: '<?php esc_attr_e('Thumbnail', 'fl-builder'); ?>',
78
+ tourNext: '<?php esc_attr_e('Next', 'fl-builder'); ?>',
79
+ tourEnd: '<?php esc_attr_e('Get Started', 'fl-builder'); ?>',
80
+ tourTemplatesTitle: '<?php esc_attr_e('Choose a Template', 'fl-builder'); ?>',
81
+ tourTemplates: '<?php esc_attr_e('Get started by choosing a layout template to customize, or build a page from scratch by selecting the blank layout template.', 'fl-builder'); ?>',
82
+ tourAddRowsTitle: '<?php esc_attr_e('Add Rows', 'fl-builder'); ?>',
83
+ tourAddRows: '<?php esc_attr_e('Add multi-column rows, adjust spacing, add backgrounds and more by dragging and dropping row layouts onto the page.', 'fl-builder'); ?>',
84
+ tourAddContentTitle: '<?php esc_attr_e('Add Content', 'fl-builder'); ?>',
85
+ tourAddContent: '<?php esc_attr_e('Add new content by dragging and dropping modules or widgets into your row layouts or to create a new row layout.', 'fl-builder'); ?>',
86
+ tourEditContentTitle: '<?php esc_attr_e('Edit Content', 'fl-builder'); ?>',
87
+ tourEditContent: '<?php esc_attr_e('Move your mouse over rows, columns or modules to edit and interact with them.', 'fl-builder'); ?>',
88
+ tourEditContent2: '<?php esc_attr_e('Use the action buttons to perform actions such as moving, editing, duplicating or deleting rows, columns and modules.', 'fl-builder'); ?>',
89
+ tourAddContentButtonTitle: '<?php esc_attr_e('Add More Content', 'fl-builder'); ?>',
90
+ tourAddContentButton: '<?php esc_attr_e('Use the Add Content button to open the content panel and add new row layouts, modules or widgets.', 'fl-builder'); ?>',
91
+ tourTemplatesButtonTitle: '<?php esc_attr_e('Change Templates', 'fl-builder'); ?>',
92
+ tourTemplatesButton: '<?php esc_attr_e('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'); ?>',
93
+ tourToolsButtonTitle: '<?php esc_attr_e('Helpful Tools', 'fl-builder'); ?>',
94
+ tourToolsButton: '<?php esc_attr_e('The Tools button lets you duplicate a page, save a template or edit the global settings.', 'fl-builder'); ?>',
95
+ tourDoneButtonTitle: '<?php esc_attr_e('Publish Your Changes', 'fl-builder'); ?>',
96
+ tourDoneButton: '<?php esc_attr_e("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'); ?>',
97
+ tourFinishedTitle: '<?php esc_attr_e("Let's Get Building!", 'fl-builder'); ?>',
98
+ tourFinished: '<?php esc_attr_e("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'); ?>',
99
+ unloadWarning: '<?php esc_attr_e('The settings you are currently editing will not be saved if you navigate away from this page.', 'fl-builder'); ?>',
100
+ viewKnowledgeBase: '<?php esc_attr_e('View the Knowledge Base', 'fl-builder'); ?>',
101
+ visitForums: '<?php esc_attr_e('Visit the Forums', 'fl-builder'); ?>',
102
+ watchHelpVideo: '<?php esc_attr_e('Watch the Video', 'fl-builder'); ?>',
103
+ welcomeMessage: '<?php esc_attr_e('Welcome! It looks like this might be your first time using the builder. Would you like to take a tour?', 'fl-builder'); ?>',
104
+ yesPlease: '<?php esc_attr_e('Yes Please!', 'fl-builder'); ?>'
105
  };
106
 
107
  </script>
includes/loop-settings.php CHANGED
@@ -1,106 +1,106 @@
1
  <?php
2
 
3
  FLBuilderModel::default_settings($settings, array(
4
- 'post_type' => 'post',
5
- 'order_by' => 'date',
6
- 'order' => 'DESC',
7
- 'offset' => 0,
8
- 'users' => ''
9
  ));
10
 
11
  ?>
12
  <div id="fl-builder-settings-section-general" class="fl-loop-builder fl-builder-settings-section">
13
 
14
- <table class="fl-form-table">
15
- <?php
16
-
17
- // Post type
18
- FLBuilder::render_settings_field('post_type', array(
19
- 'type' => 'post-type',
20
- 'label' => __('Post Type', 'fl-builder'),
21
- ), $settings);
22
-
23
- // Order by
24
- FLBuilder::render_settings_field('order_by', array(
25
- 'type' => 'select',
26
- 'label' => __('Order By', 'fl-builder'),
27
- 'options' => array(
28
- 'ID' => __('ID', 'fl-builder'),
29
- 'date' => __('Date', 'fl-builder'),
30
- 'modified' => __('Date Last Modified', 'fl-builder'),
31
- 'title' => __('Title', 'fl-builder'),
32
- 'author' => __('Author', 'fl-builder'),
33
- 'comment_count' => __('Comment Count', 'fl-builder'),
34
- 'menu_order' => __('Menu Order', 'fl-builder'),
35
- 'random' => __('Random', 'fl-builder'),
36
- )
37
- ), $settings);
38
-
39
- // Order
40
- FLBuilder::render_settings_field('order', array(
41
- 'type' => 'select',
42
- 'label' => __('Order', 'fl-builder'),
43
- 'options' => array(
44
- 'DESC' => __('Descending', 'fl-builder'),
45
- 'ASC' => __('Ascending', 'fl-builder'),
46
- )
47
- ), $settings);
48
-
49
- // Offset
50
- FLBuilder::render_settings_field('offset', array(
51
- 'type' => 'text',
52
- 'label' => __('Offset', 'fl-builder'),
53
- 'default' => '0',
54
- 'size' => '4',
55
- 'help' => __('Skip this many posts that match the specified criteria.', 'fl-builder')
56
- ), $settings);
57
-
58
- ?>
59
- </table>
60
  </div>
61
  <div id="fl-builder-settings-section-filter" class="fl-builder-settings-section">
62
- <h3 class="fl-builder-settings-title"><?php _e('Filter', 'fl-builder'); ?></h3>
63
- <?php foreach(FLBuilderLoop::post_types() as $slug => $type) : ?>
64
- <table class="fl-form-table fl-loop-builder-filter fl-loop-builder-<?php echo $slug; ?>-filter" <?php if($slug == $settings->post_type) echo 'style="display:table;"'; ?>>
65
- <?php
66
-
67
- // Posts
68
- FLBuilder::render_settings_field('posts_' . $slug, array(
69
- 'type' => 'suggest',
70
- 'action' => 'fl_as_posts',
71
- 'data' => $slug,
72
- 'label' => $type->label,
73
- 'help' => sprintf(__('Enter a comma separated list of %s. Only these %s will be shown.', 'fl-builder'), $type->label, $type->label)
74
- ), $settings);
75
-
76
- // Taxonomies
77
- $taxonomies = FLBuilderLoop::taxonomies($slug);
78
-
79
- foreach($taxonomies as $tax_slug => $tax) {
80
 
81
- FLBuilder::render_settings_field('tax_' . $slug . '_' . $tax_slug, array(
82
- 'type' => 'suggest',
83
- 'action' => 'fl_as_terms',
84
- 'data' => $tax_slug,
85
- 'label' => $tax->label,
86
- 'help' => sprintf(__('Enter a comma separated list of %s. Only posts with these %s will be shown.', 'fl-builder'), $tax->label, $tax->label)
87
- ), $settings);
88
- }
89
-
90
- ?>
91
- </table>
92
- <?php endforeach; ?>
93
- <table class="fl-form-table">
94
- <?php
95
 
96
- // Author
97
- FLBuilder::render_settings_field('users', array(
98
- 'type' => 'suggest',
99
- 'action' => 'fl_as_users',
100
- 'label' => __('Authors', 'fl-builder'),
101
- 'help' => __('Enter a comma separated list of authors usernames. Only posts with these authors will be shown.', 'fl-builder')
102
- ), $settings);
103
-
104
- ?>
105
- </table>
106
  </div>
1
  <?php
2
 
3
  FLBuilderModel::default_settings($settings, array(
4
+ 'post_type' => 'post',
5
+ 'order_by' => 'date',
6
+ 'order' => 'DESC',
7
+ 'offset' => 0,
8
+ 'users' => ''
9
  ));
10
 
11
  ?>
12
  <div id="fl-builder-settings-section-general" class="fl-loop-builder fl-builder-settings-section">
13
 
14
+ <table class="fl-form-table">
15
+ <?php
16
+
17
+ // Post type
18
+ FLBuilder::render_settings_field('post_type', array(
19
+ 'type' => 'post-type',
20
+ 'label' => __('Post Type', 'fl-builder'),
21
+ ), $settings);
22
+
23
+ // Order by
24
+ FLBuilder::render_settings_field('order_by', array(
25
+ 'type' => 'select',
26
+ 'label' => __('Order By', 'fl-builder'),
27
+ 'options' => array(
28
+ 'ID' => __('ID', 'fl-builder'),
29
+ 'date' => __('Date', 'fl-builder'),
30
+ 'modified' => __('Date Last Modified', 'fl-builder'),
31
+ 'title' => __('Title', 'fl-builder'),
32
+ 'author' => __('Author', 'fl-builder'),
33
+ 'comment_count' => __('Comment Count', 'fl-builder'),
34
+ 'menu_order' => __('Menu Order', 'fl-builder'),
35
+ 'random' => __('Random', 'fl-builder'),
36
+ )
37
+ ), $settings);
38
+
39
+ // Order
40
+ FLBuilder::render_settings_field('order', array(
41
+ 'type' => 'select',
42
+ 'label' => __('Order', 'fl-builder'),
43
+ 'options' => array(
44
+ 'DESC' => __('Descending', 'fl-builder'),
45
+ 'ASC' => __('Ascending', 'fl-builder'),
46
+ )
47
+ ), $settings);
48
+
49
+ // Offset
50
+ FLBuilder::render_settings_field('offset', array(
51
+ 'type' => 'text',
52
+ 'label' => _x('Offset', 'How many posts to skip.', 'fl-builder'),
53
+ 'default' => '0',
54
+ 'size' => '4',
55
+ 'help' => __('Skip this many posts that match the specified criteria.', 'fl-builder')
56
+ ), $settings);
57
+
58
+ ?>
59
+ </table>
60
  </div>
61
  <div id="fl-builder-settings-section-filter" class="fl-builder-settings-section">
62
+ <h3 class="fl-builder-settings-title"><?php _e('Filter', 'fl-builder'); ?></h3>
63
+ <?php foreach(FLBuilderLoop::post_types() as $slug => $type) : ?>
64
+ <table class="fl-form-table fl-loop-builder-filter fl-loop-builder-<?php echo $slug; ?>-filter" <?php if($slug == $settings->post_type) echo 'style="display:table;"'; ?>>
65
+ <?php
66
+
67
+ // Posts
68
+ FLBuilder::render_settings_field('posts_' . $slug, array(
69
+ 'type' => 'suggest',
70
+ 'action' => 'fl_as_posts',
71
+ 'data' => $slug,
72
+ 'label' => $type->label,
73
+ 'help' => sprintf(__('Enter a comma separated list of %s. Only these %s will be shown.', 'fl-builder'), $type->label, $type->label)
74
+ ), $settings);
75
+
76
+ // Taxonomies
77
+ $taxonomies = FLBuilderLoop::taxonomies($slug);
78
+
79
+ foreach($taxonomies as $tax_slug => $tax) {
80
 
81
+ FLBuilder::render_settings_field('tax_' . $slug . '_' . $tax_slug, array(
82
+ 'type' => 'suggest',
83
+ 'action' => 'fl_as_terms',
84
+ 'data' => $tax_slug,
85
+ 'label' => $tax->label,
86
+ 'help' => sprintf(__('Enter a comma separated list of %s. Only posts with these %s will be shown.', 'fl-builder'), $tax->label, $tax->label)
87
+ ), $settings);
88
+ }
89
+
90
+ ?>
91
+ </table>
92
+ <?php endforeach; ?>
93
+ <table class="fl-form-table">
94
+ <?php
95
 
96
+ // Author
97
+ FLBuilder::render_settings_field('users', array(
98
+ 'type' => 'suggest',
99
+ 'action' => 'fl_as_users',
100
+ 'label' => __('Authors', 'fl-builder'),
101
+ 'help' => __('Enter a comma separated list of authors usernames. Only posts with these authors will be shown.', 'fl-builder')
102
+ ), $settings);
103
+
104
+ ?>
105
+ </table>
106
  </div>
includes/module-settings.php CHANGED
@@ -3,134 +3,134 @@
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' => 'text',
13
- 'label' => __( 'Top', 'fl-builder' ),
14
- 'default' => '',
15
- 'description' => 'px',
16
- 'maxlength' => '4',
17
- 'size' => '5',
18
- 'placeholder' => $global_settings->module_margins,
19
- 'preview' => array(
20
- 'type' => 'none'
21
- )
22
- ),
23
- 'margin_bottom' => array(
24
- 'type' => 'text',
25
- 'label' => __( 'Bottom', 'fl-builder' ),
26
- 'default' => '',
27
- 'description' => 'px',
28
- 'maxlength' => '4',
29
- 'size' => '5',
30
- 'placeholder' => $global_settings->module_margins,
31
- 'preview' => array(
32
- 'type' => 'none'
33
- )
34
- ),
35
- 'margin_left' => array(
36
- 'type' => 'text',
37
- 'label' => __( 'Left', 'fl-builder' ),
38
- 'default' => '',
39
- 'description' => 'px',
40
- 'maxlength' => '4',
41
- 'size' => '5',
42
- 'placeholder' => $global_settings->module_margins,
43
- 'preview' => array(
44
- 'type' => 'none'
45
- )
46
- ),
47
- 'margin_right' => array(
48
- 'type' => 'text',
49
- 'label' => __( 'Right', 'fl-builder' ),
50
- 'default' => '',
51
- 'description' => 'px',
52
- 'maxlength' => '4',
53
- 'size' => '5',
54
- 'placeholder' => $global_settings->module_margins,
55
- 'preview' => array(
56
- 'type' => 'none'
57
- )
58
- )
59
- )
60
- ),
61
- 'responsive' => array(
62
- 'title' => __('Responsive Layout', 'fl-builder'),
63
- 'fields' => array(
64
- 'responsive_display' => array(
65
- 'type' => 'select',
66
- 'label' => __('Display', 'fl-builder'),
67
- 'options' => array(
68
- '' => __('Always', 'fl-builder'),
69
- 'desktop' => __('Large Devices Only', 'fl-builder'),
70
- 'desktop-medium' => __('Large &amp; Medium Devices Only', 'fl-builder'),
71
- 'medium' => __('Medium Devices Only', 'fl-builder'),
72
- 'medium-mobile' => __('Medium &amp; Small Devices Only', 'fl-builder'),
73
- 'mobile' => __('Small Devices Only', 'fl-builder'),
74
- ),
75
- 'help' => __( 'Choose whether to show or hide this module at different device sizes.', 'fl-builder' ),
76
- 'preview' => array(
77
- 'type' => 'none'
78
- )
79
- )
80
- )
81
- ),
82
- 'animation' => array(
83
- 'title' => __('Animation', 'fl-builder'),
84
- 'fields' => array(
85
- 'animation' => array(
86
- 'type' => 'select',
87
- 'label' => __('Style', 'fl-builder'),
88
- 'options' => array(
89
- '' => _x( 'None', 'Animation style.', 'fl-builder' ),
90
- 'fade-in' => _x( 'Fade In', 'Animation style.', 'fl-builder' ),
91
- 'slide-left' => _x( 'Slide Left', 'Animation style.', 'fl-builder' ),
92
- 'slide-right' => _x( 'Slide Right', 'Animation style.', 'fl-builder' ),
93
- 'slide-up' => _x( 'Slide Up', 'Animation style.', 'fl-builder' ),
94
- 'slide-down' => _x( 'Slide Down', 'Animation style.', 'fl-builder' ),
95
- ),
96
- 'preview' => array(
97
- 'type' => 'none'
98
- )
99
- ),
100
- 'animation_delay' => array(
101
- 'type' => 'text',
102
- 'label' => __('Delay', 'fl-builder'),
103
- 'default' => '0.0',
104
- 'maxlength' => '4',
105
- 'size' => '5',
106
- 'description' => _x( 'seconds', 'Value unit for form field of time in seconds. Such as: "5 seconds"', 'fl-builder' ),
107
- 'help' => __('The amount of time in seconds before this animation starts.', 'fl-builder'),
108
- 'preview' => array(
109
- 'type' => 'none'
110
- )
111
- )
112
- )
113
- ),
114
- 'css_selectors' => array(
115
- 'title' => __('CSS Selectors', 'fl-builder'),
116
- 'fields' => array(
117
- 'id' => array(
118
- 'type' => 'text',
119
- 'label' => __('ID', 'fl-builder'),
120
- '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' ),
121
- 'preview' => array(
122
- 'type' => 'none'
123
- )
124
- ),
125
- 'class' => array(
126
- 'type' => 'text',
127
- 'label' => __('Class', 'fl-builder'),
128
- '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' ),
129
- 'preview' => array(
130
- 'type' => 'none'
131
- )
132
- )
133
- )
134
- )
135
- )
136
  ));
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' => 'text',
13
+ 'label' => __( 'Top', 'fl-builder' ),
14
+ 'default' => '',
15
+ 'description' => 'px',
16
+ 'maxlength' => '4',
17
+ 'size' => '5',
18
+ 'placeholder' => $global_settings->module_margins,
19
+ 'preview' => array(
20
+ 'type' => 'none'
21
+ )
22
+ ),
23
+ 'margin_bottom' => array(
24
+ 'type' => 'text',
25
+ 'label' => __( 'Bottom', 'fl-builder' ),
26
+ 'default' => '',
27
+ 'description' => 'px',
28
+ 'maxlength' => '4',
29
+ 'size' => '5',
30
+ 'placeholder' => $global_settings->module_margins,
31
+ 'preview' => array(
32
+ 'type' => 'none'
33
+ )
34
+ ),
35
+ 'margin_left' => array(
36
+ 'type' => 'text',
37
+ 'label' => __( 'Left', 'fl-builder' ),
38
+ 'default' => '',
39
+ 'description' => 'px',
40
+ 'maxlength' => '4',
41
+ 'size' => '5',
42
+ 'placeholder' => $global_settings->module_margins,
43
+ 'preview' => array(
44
+ 'type' => 'none'
45
+ )
46
+ ),
47
+ 'margin_right' => array(
48
+ 'type' => 'text',
49
+ 'label' => __( 'Right', 'fl-builder' ),
50
+ 'default' => '',
51
+ 'description' => 'px',
52
+ 'maxlength' => '4',
53
+ 'size' => '5',
54
+ 'placeholder' => $global_settings->module_margins,
55
+ 'preview' => array(
56
+ 'type' => 'none'
57
+ )
58
+ )
59
+ )
60
+ ),
61
+ 'responsive' => array(
62
+ 'title' => __('Responsive Layout', 'fl-builder'),
63
+ 'fields' => array(
64
+ 'responsive_display' => array(
65
+ 'type' => 'select',
66
+ 'label' => __('Display', 'fl-builder'),
67
+ 'options' => array(
68
+ '' => __('Always', 'fl-builder'),
69
+ 'desktop' => __('Large Devices Only', 'fl-builder'),
70
+ 'desktop-medium' => __('Large &amp; Medium Devices Only', 'fl-builder'),
71
+ 'medium' => __('Medium Devices Only', 'fl-builder'),
72
+ 'medium-mobile' => __('Medium &amp; Small Devices Only', 'fl-builder'),
73
+ 'mobile' => __('Small Devices Only', 'fl-builder'),
74
+ ),
75
+ 'help' => __( 'Choose whether to show or hide this module at different device sizes.', 'fl-builder' ),
76
+ 'preview' => array(
77
+ 'type' => 'none'
78
+ )
79
+ )
80
+ )
81
+ ),
82
+ 'animation' => array(
83
+ 'title' => __('Animation', 'fl-builder'),
84
+ 'fields' => array(
85
+ 'animation' => array(
86
+ 'type' => 'select',
87
+ 'label' => __('Style', 'fl-builder'),
88
+ 'options' => array(
89
+ '' => _x( 'None', 'Animation style.', 'fl-builder' ),
90
+ 'fade-in' => _x( 'Fade In', 'Animation style.', 'fl-builder' ),
91
+ 'slide-left' => _x( 'Slide Left', 'Animation style.', 'fl-builder' ),
92
+ 'slide-right' => _x( 'Slide Right', 'Animation style.', 'fl-builder' ),
93
+ 'slide-up' => _x( 'Slide Up', 'Animation style.', 'fl-builder' ),
94
+ 'slide-down' => _x( 'Slide Down', 'Animation style.', 'fl-builder' ),
95
+ ),
96
+ 'preview' => array(
97
+ 'type' => 'none'
98
+ )
99
+ ),
100
+ 'animation_delay' => array(
101
+ 'type' => 'text',
102
+ 'label' => __('Delay', 'fl-builder'),
103
+ 'default' => '0.0',
104
+ 'maxlength' => '4',
105
+ 'size' => '5',
106
+ 'description' => _x( 'seconds', 'Value unit for form field of time in seconds. Such as: "5 seconds"', 'fl-builder' ),
107
+ 'help' => __('The amount of time in seconds before this animation starts.', 'fl-builder'),
108
+ 'preview' => array(
109
+ 'type' => 'none'
110
+ )
111
+ )
112
+ )
113
+ ),
114
+ 'css_selectors' => array(
115
+ 'title' => __('CSS Selectors', 'fl-builder'),
116
+ 'fields' => array(
117
+ 'id' => array(
118
+ 'type' => 'text',
119
+ 'label' => __('ID', 'fl-builder'),
120
+ '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' ),
121
+ 'preview' => array(
122
+ 'type' => 'none'
123
+ )
124
+ ),
125
+ 'class' => array(
126
+ 'type' => 'text',
127
+ 'label' => __('Class', 'fl-builder'),
128
+ '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' ),
129
+ 'preview' => array(
130
+ 'type' => 'none'
131
+ )
132
+ )
133
+ )
134
+ )
135
+ )
136
  ));
includes/module.php CHANGED
@@ -1,5 +1,5 @@
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 include $module->dir . 'includes/frontend.php'; ?>
4
+ </div>
5
  </div>
includes/row-css.php CHANGED
@@ -7,56 +7,56 @@
7
  .fl-node-<?php echo $row->node; ?> h4,
8
  .fl-node-<?php echo $row->node; ?> h5,
9
  .fl-node-<?php echo $row->node; ?> h6 {
10
- color: #<?php echo $row->settings->text_color; ?>;
11
  }
12
  <?php endif; ?>
13
 
14
  <?php if($row->settings->bg_type == 'color' && !empty($row->settings->bg_color)) : ?>
15
  .fl-node-<?php echo $row->node; ?> .fl-row-content-wrap {
16
- background-color: #<?php echo $row->settings->bg_color; ?>;
17
- background-color: rgba(<?php echo implode(',', FLBuilderColor::hex_to_rgb($row->settings->bg_color)) ?>, <?php echo $row->settings->bg_opacity/100; ?>);
18
  }
19
  <?php endif; ?>
20
 
21
  <?php if($row->settings->bg_type == 'photo' && !empty($row->settings->bg_image)) : ?>
22
  .fl-node-<?php echo $row->node; ?> .fl-row-content-wrap {
23
- background-image: url(<?php echo $row->settings->bg_image_src; ?>);
24
- background-repeat: <?php echo $row->settings->bg_repeat; ?>;
25
- background-position: <?php echo $row->settings->bg_position; ?>;
26
- background-attachment: <?php echo $row->settings->bg_attachment; ?>;
27
- background-size: <?php echo $row->settings->bg_size; ?>;
28
  }
29
  <?php endif; ?>
30
 
31
  <?php if( in_array( $row->settings->bg_type, array('photo', 'parallax', 'slideshow', 'video') ) && !empty($row->settings->bg_overlay_color)) : ?>
32
  .fl-node-<?php echo $row->node; ?> .fl-row-content-wrap:after {
33
- background-color: #<?php echo $row->settings->bg_overlay_color; ?>;
34
- background-color: rgba(<?php echo implode(',', FLBuilderColor::hex_to_rgb($row->settings->bg_overlay_color)) ?>, <?php echo $row->settings->bg_overlay_opacity/100; ?>);
35
  }
36
  <?php endif; ?>
37
 
38
  <?php if($row->settings->bg_type == 'parallax' && !empty($row->settings->bg_parallax_image_src)) : ?>
39
  .fl-node-<?php echo $row->node; ?> .fl-row-content-wrap {
40
- background-repeat: no-repeat;
41
- background-position: center center;
42
- background-attachment: fixed;
43
- background-size: cover;
44
  }
45
  .fl-builder-touch .fl-node-<?php echo $row->node; ?> .fl-row-content-wrap {
46
- background-image: url(<?php echo $row->settings->bg_parallax_image_src; ?>);
47
- background-attachment: scroll;
48
- background-position: center center;
49
  }
50
  <?php endif; ?>
51
 
52
  <?php if(!empty($row->settings->border_type)) : ?>
53
  .fl-node-<?php echo $row->node; ?> .fl-row-content-wrap {
54
- border-style: <?php echo $row->settings->border_type; ?>;
55
- border-color: #<?php echo $row->settings->border_color; ?>;
56
- border-color: rgba(<?php echo implode(',', FLBuilderColor::hex_to_rgb($row->settings->border_color)) ?>, <?php echo $row->settings->border_opacity/100; ?>);
57
- border-top-width: <?php echo is_numeric($row->settings->border_top) ? $row->settings->border_top : '0'; ?>px;
58
- border-bottom-width: <?php echo is_numeric($row->settings->border_bottom) ? $row->settings->border_bottom : '0'; ?>px;
59
- border-left-width: <?php echo is_numeric($row->settings->border_left) ? $row->settings->border_left : '0'; ?>px;
60
- border-right-width: <?php echo is_numeric($row->settings->border_right) ? $row->settings->border_right : '0'; ?>px;
61
  }
62
  <?php endif; ?>
7
  .fl-node-<?php echo $row->node; ?> h4,
8
  .fl-node-<?php echo $row->node; ?> h5,
9
  .fl-node-<?php echo $row->node; ?> h6 {
10
+ color: #<?php echo $row->settings->text_color; ?>;
11
  }
12
  <?php endif; ?>
13
 
14
  <?php if($row->settings->bg_type == 'color' && !empty($row->settings->bg_color)) : ?>
15
  .fl-node-<?php echo $row->node; ?> .fl-row-content-wrap {
16
+ background-color: #<?php echo $row->settings->bg_color; ?>;
17
+ background-color: rgba(<?php echo implode(',', FLBuilderColor::hex_to_rgb($row->settings->bg_color)) ?>, <?php echo $row->settings->bg_opacity/100; ?>);
18
  }
19
  <?php endif; ?>
20
 
21
  <?php if($row->settings->bg_type == 'photo' && !empty($row->settings->bg_image)) : ?>
22
  .fl-node-<?php echo $row->node; ?> .fl-row-content-wrap {
23
+ background-image: url(<?php echo $row->settings->bg_image_src; ?>);
24
+ background-repeat: <?php echo $row->settings->bg_repeat; ?>;
25
+ background-position: <?php echo $row->settings->bg_position; ?>;
26
+ background-attachment: <?php echo $row->settings->bg_attachment; ?>;
27
+ background-size: <?php echo $row->settings->bg_size; ?>;
28
  }
29
  <?php endif; ?>
30
 
31
  <?php if( in_array( $row->settings->bg_type, array('photo', 'parallax', 'slideshow', 'video') ) && !empty($row->settings->bg_overlay_color)) : ?>
32
  .fl-node-<?php echo $row->node; ?> .fl-row-content-wrap:after {
33
+ background-color: #<?php echo $row->settings->bg_overlay_color; ?>;
34
+ background-color: rgba(<?php echo implode(',', FLBuilderColor::hex_to_rgb($row->settings->bg_overlay_color)) ?>, <?php echo $row->settings->bg_overlay_opacity/100; ?>);
35
  }
36
  <?php endif; ?>
37
 
38
  <?php if($row->settings->bg_type == 'parallax' && !empty($row->settings->bg_parallax_image_src)) : ?>
39
  .fl-node-<?php echo $row->node; ?> .fl-row-content-wrap {
40
+ background-repeat: no-repeat;
41
+ background-position: center center;
42
+ background-attachment: fixed;
43
+ background-size: cover;
44
  }
45
  .fl-builder-touch .fl-node-<?php echo $row->node; ?> .fl-row-content-wrap {
46
+ background-image: url(<?php echo $row->settings->bg_parallax_image_src; ?>);
47
+ background-attachment: scroll;
48
+ background-position: center center;
49
  }
50
  <?php endif; ?>
51
 
52
  <?php if(!empty($row->settings->border_type)) : ?>
53
  .fl-node-<?php echo $row->node; ?> .fl-row-content-wrap {
54
+ border-style: <?php echo $row->settings->border_type; ?>;
55
+ border-color: #<?php echo $row->settings->border_color; ?>;
56
+ border-color: rgba(<?php echo implode(',', FLBuilderColor::hex_to_rgb($row->settings->border_color)) ?>, <?php echo $row->settings->border_opacity/100; ?>);
57
+ border-top-width: <?php echo is_numeric($row->settings->border_top) ? $row->settings->border_top : '0'; ?>px;
58
+ border-bottom-width: <?php echo is_numeric($row->settings->border_bottom) ? $row->settings->border_bottom : '0'; ?>px;
59
+ border-left-width: <?php echo is_numeric($row->settings->border_left) ? $row->settings->border_left : '0'; ?>px;
60
+ border-right-width: <?php echo is_numeric($row->settings->border_right) ? $row->settings->border_right : '0'; ?>px;
61
  }
62
  <?php endif; ?>
includes/row-js.php CHANGED
@@ -2,9 +2,9 @@
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) {
@@ -14,29 +14,29 @@ YUI({'logExclude': { 'yui': true } }).use('fl-slideshow', function(Y) {
14
  }
15
 
16
  var oldSlideshow = Y.one('.fl-node-<?php echo $id; ?> .fl-bg-slideshow .fl-slideshow'),
17
- newSlideshow = new Y.FL.Slideshow({
18
- autoPlay : true,
19
- crop : true,
20
- loadingImageEnabled : false,
21
- randomize : <?php echo $settings->ss_randomize; ?>,
22
- responsiveThreshold : 0,
23
- source : [{<?php echo $source; ?>}],
24
- speed : <?php echo $settings->ss_speed * 1000; ?>,
25
- stretchy : true,
26
- stretchyType : 'contain',
27
- transition : '<?php echo $settings->ss_transition; ?>',
28
- transitionDuration : <?php echo $settings->ss_transitionDuration; ?>
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
 
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) {
14
  }
15
 
16
  var oldSlideshow = Y.one('.fl-node-<?php echo $id; ?> .fl-bg-slideshow .fl-slideshow'),
17
+ newSlideshow = new Y.FL.Slideshow({
18
+ autoPlay : true,
19
+ crop : true,
20
+ loadingImageEnabled : false,
21
+ randomize : <?php echo $settings->ss_randomize; ?>,
22
+ responsiveThreshold : 0,
23
+ source : [{<?php echo $source; ?>}],
24
+ speed : <?php echo $settings->ss_speed * 1000; ?>,
25
+ stretchy : true,
26
+ stretchyType : 'contain',
27
+ transition : '<?php echo $settings->ss_transition; ?>',
28
+ transitionDuration : <?php echo $settings->ss_transitionDuration; ?>
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
 
includes/row-settings.php CHANGED
@@ -3,624 +3,624 @@
3
  $global_settings = FLBuilderModel::get_global_settings();
4
 
5
  FLBuilder::register_settings_form('row', array(
6
- 'title' => __('Row Settings', 'fl-builder'),
7
- 'tabs' => array(
8
- 'style' => array(
9
- 'title' => __('Style', 'fl-builder'),
10
- 'sections' => array(
11
- 'general' => array(
12
- 'title' => '',
13
- 'fields' => array(
14
- 'width' => array(
15
- 'type' => 'select',
16
- 'label' => __('Width', 'fl-builder'),
17
- 'default' => $global_settings->row_width_default,
18
- 'options' => array(
19
- 'fixed' => __('Fixed', 'fl-builder'),
20
- 'full' => __('Full Width', 'fl-builder')
21
- ),
22
- 'toggle' => array(
23
- 'full' => array(
24
- 'fields' => array('content_width')
25
- )
26
- ),
27
- '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'),
28
- 'preview' => array(
29
- 'type' => 'none'
30
- )
31
- ),
32
- 'content_width' => array(
33
- 'type' => 'select',
34
- 'label' => __('Content Width', 'fl-builder'),
35
- 'default' => $global_settings->row_content_width_default,
36
- 'options' => array(
37
- 'fixed' => __('Fixed', 'fl-builder'),
38
- 'full' => __('Full Width', 'fl-builder')
39
- ),
40
- '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'),
41
- 'preview' => array(
42
- 'type' => 'none'
43
- )
44
- ),
45
- )
46
- ),
47
- 'text' => array(
48
- 'title' => __('Text', 'fl-builder'),
49
- 'fields' => array(
50
- 'text_color' => array(
51
- 'type' => 'color',
52
- 'label' => __('Color', 'fl-builder'),
53
- 'show_reset' => true,
54
- 'preview' => array(
55
- 'type' => 'none'
56
- )
57
- )
58
- )
59
- ),
60
- 'background' => array(
61
- 'title' => __('Background', 'fl-builder'),
62
- 'fields' => array(
63
- 'bg_type' => array(
64
- 'type' => 'select',
65
- 'label' => __('Type', 'fl-builder'),
66
- 'default' => 'none',
67
- 'options' => array(
68
- 'none' => _x( 'None', 'Background type.', 'fl-builder' ),
69
- 'color' => _x( 'Color', 'Background type.', 'fl-builder' ),
70
- 'photo' => _x( 'Photo', 'Background type.', 'fl-builder' ),
71
- 'video' => _x( 'Video', 'Background type.', 'fl-builder' ),
72
- 'slideshow' => array(
73
- 'label' => _x( 'Slideshow', 'Background type.', 'fl-builder' ),
74
- 'premium' => true
75
- ),
76
- 'parallax' => array(
77
- 'label' => _x( 'Parallax', 'Background type.', 'fl-builder' ),
78
- 'premium' => true
79
- )
80
- ),
81
- 'toggle' => array(
82
- 'color' => array(
83
- 'sections' => array('bg_color')
84
- ),
85
- 'photo' => array(
86
- 'sections' => array('bg_photo', 'bg_overlay')
87
- ),
88
- 'video' => array(
89
- 'sections' => array('bg_video', 'bg_overlay')
90
- ),
91
- 'slideshow' => array(
92
- 'sections' => array('bg_slideshow', 'bg_overlay')
93
- ),
94
- 'parallax' => array(
95
- 'sections' => array('bg_parallax', 'bg_overlay')
96
- )
97
- ),
98
- 'preview' => array(
99
- 'type' => 'none'
100
- )
101
- )
102
- )
103
- ),
104
- 'bg_color' => array(
105
- 'title' => __('Background Color', 'fl-builder'),
106
- 'fields' => array(
107
- 'bg_color' => array(
108
- 'type' => 'color',
109
- 'label' => __('Color', 'fl-builder'),
110
- 'show_reset' => true,
111
- 'preview' => array(
112
- 'type' => 'none'
113
- )
114
- ),
115
- 'bg_opacity' => array(
116
- 'type' => 'text',
117
- 'label' => __('Opacity', 'fl-builder'),
118
- 'default' => '100',
119
- 'description' => '%',
120
- 'maxlength' => '3',
121
- 'size' => '5',
122
- 'preview' => array(
123
- 'type' => 'none'
124
- )
125
- )
126
- )
127
- ),
128
- 'bg_photo' => array(
129
- 'title' => __('Background Photo', 'fl-builder'),
130
- 'fields' => array(
131
- 'bg_image' => array(
132
- 'type' => 'photo',
133
- 'label' => __('Photo', 'fl-builder'),
134
- 'preview' => array(
135
- 'type' => 'none'
136
- )
137
- ),
138
- 'bg_repeat' => array(
139
- 'type' => 'select',
140
- 'label' => __('Repeat', 'fl-builder'),
141
- 'default' => 'none',
142
- 'options' => array(
143
- 'no-repeat' => _x( 'None', 'Background repeat.', 'fl-builder' ),
144
- 'repeat' => _x( 'Tile', 'Background repeat.', 'fl-builder' ),
145
- 'repeat-x' => _x( 'Horizontal', 'Background repeat.', 'fl-builder' ),
146
- 'repeat-y' => _x( 'Vertical', 'Background repeat.', 'fl-builder' )
147
- ),
148
- 'help' => __('Repeat applies to how the image should display in the row background. Choosing none will display the image as uploaded. Tile will repeat the image as many times as needed to fill the row horizontally and vertically. You can also specify the image to only repeat horizontally or vertically.', 'fl-builder'),
149
- 'preview' => array(
150
- 'type' => 'none'
151
- )
152
- ),
153
- 'bg_position' => array(
154
- 'type' => 'select',
155
- 'label' => __('Position', 'fl-builder'),
156
- 'default' => 'center center',
157
- 'options' => array(
158
- 'left top' => __('Left Top', 'fl-builder'),
159
- 'left center' => __('Left Center', 'fl-builder'),
160
- 'left bottom' => __('Left Bottom', 'fl-builder'),
161
- 'right top' => __('Right Top', 'fl-builder'),
162
- 'right center' => __('Right Center', 'fl-builder'),
163
- 'right bottom' => __('Right Bottom', 'fl-builder'),
164
- 'center top' => __('Center Top', 'fl-builder'),
165
- 'center center' => __( 'Center', 'fl-builder' ),
166
- 'center bottom' => __('Center Bottom', 'fl-builder')
167
- ),
168
- 'help' => __('Position will tell the image where it should sit in the row background.', 'fl-builder'),
169
- 'preview' => array(
170
- 'type' => 'none'
171
- )
172
- ),
173
- 'bg_attachment' => array(
174
- 'type' => 'select',
175
- 'label' => __('Attachment', 'fl-builder'),
176
- 'default' => 'scroll',
177
- 'options' => array(
178
- 'scroll' => __( 'Scroll', 'fl-builder' ),
179
- 'fixed' => __( 'Fixed', 'fl-builder' )
180
- ),
181
- '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 row background if fill is selected in the scale setting.', 'fl-builder'),
182
- 'preview' => array(
183
- 'type' => 'none'
184
- )
185
- ),
186
- 'bg_size' => array(
187
- 'type' => 'select',
188
- 'label' => __('Scale', 'fl-builder'),
189
- 'default' => 'cover',
190
- 'options' => array(
191
- '' => _x( 'None', 'Background scale.', 'fl-builder' ),
192
- 'contain' => __( 'Fit', 'fl-builder'),
193
- 'cover' => __( 'Fill', 'fl-builder')
194
- ),
195
- 'help' => __('Scale applies to how the image should display in the row background. You can select either fill or fit to the row background.', 'fl-builder'),
196
- 'preview' => array(
197
- 'type' => 'none'
198
- )
199
- )
200
- )
201
- ),
202
- 'bg_video' => array(
203
- 'title' => __('Background Video', 'fl-builder'),
204
- 'fields' => array(
205
- 'bg_video' => array(
206
- 'type' => 'video',
207
- 'label' => __('Video', 'fl-builder'),
208
- 'help' => __('An HTML5 video to use as the background of this row. Supported types are MP4, WebM and Ogg.', 'fl-builder'),
209
- 'preview' => array(
210
- 'type' => 'refresh'
211
- )
212
- ),
213
- 'bg_video_fallback' => array(
214
- 'type' => 'photo',
215
- 'label' => __('Fallback Photo', 'fl-builder'),
216
- 'help' => __('A photo that will be displayed if the video fails to load.', 'fl-builder'),
217
- 'preview' => array(
218
- 'type' => 'refresh'
219
- )
220
- )
221
- )
222
- ),
223
- 'bg_slideshow' => array(
224
- 'title' => __('Background Slideshow', 'fl-builder'),
225
- 'fields' => array(
226
- 'ss_source' => array(
227
- 'type' => 'select',
228
- 'label' => __('Source', 'fl-builder'),
229
- 'default' => 'wordpress',
230
- 'options' => array(
231
- 'wordpress' => __('Media Library', 'fl-builder'),
232
- 'smugmug' => 'SmugMug'
233
- ),
234
- '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'),
235
- 'toggle' => array(
236
- 'wordpress' => array(
237
- 'fields' => array('ss_photos')
238
- ),
239
- 'smugmug' => array(
240
- 'fields' => array('ss_feed_url')
241
- )
242
- ),
243
- 'preview' => array(
244
- 'type' => 'none'
245
- )
246
- ),
247
- 'ss_photos' => array(
248
- 'type' => 'multiple-photos',
249
- 'label' => __('Photos', 'fl-builder'),
250
- 'preview' => array(
251
- 'type' => 'none'
252
- )
253
- ),
254
- 'ss_feed_url' => array(
255
- 'type' => 'text',
256
- 'label' => __('Feed URL', 'fl-builder'),
257
- 'preview' => array(
258
- 'type' => 'none'
259
- )
260
- ),
261
- 'ss_speed' => array(
262
- 'type' => 'text',
263
- 'label' => __('Speed', 'fl-builder'),
264
- 'default' => '3',
265
- 'size' => '5',
266
- 'description' => _x( 'seconds', 'Value unit for form field of time in seconds. Such as: "5 seconds"', 'fl-builder' ),
267
- 'preview' => array(
268
- 'type' => 'none'
269
- )
270
- ),
271
- 'ss_transition' => array(
272
- 'type' => 'select',
273
- 'label' => __('Transition', 'fl-builder'),
274
- 'default' => 'fade',
275
- 'options' => array(
276
- 'none' => _x( 'None', 'Slideshow transition type.', 'fl-builder' ),
277
- 'fade' => __('Fade', 'fl-builder'),
278
- 'kenBurns' => __('Ken Burns', 'fl-builder'),
279
- 'slideHorizontal' => __('Slide Horizontal', 'fl-builder'),
280
- 'slideVertical' => __('Slide Vertical', 'fl-builder'),
281
- 'blinds' => __('Blinds', 'fl-builder'),
282
- 'bars' => __('Bars', 'fl-builder'),
283
- 'barsRandom' => __('Random Bars', 'fl-builder'),
284
- 'boxes' => __('Boxes', 'fl-builder'),
285
- 'boxesRandom' => __('Random Boxes', 'fl-builder'),
286
- 'boxesGrow' => __('Boxes Grow', 'fl-builder')
287
- ),
288
- 'preview' => array(
289
- 'type' => 'none'
290
- )
291
- ),
292
- 'ss_transitionDuration' => array(
293
- 'type' => 'text',
294
- 'label' => __('Transition Speed', 'fl-builder'),
295
- 'default' => '1',
296
- 'size' => '5',
297
- 'description' => _x( 'seconds', 'Value unit for form field of time in seconds. Such as: "5 seconds"', 'fl-builder' ),
298
- 'preview' => array(
299
- 'type' => 'none'
300
- )
301
- ),
302
- 'ss_randomize' => array(
303
- 'type' => 'select',
304
- 'label' => __('Randomize Photos', 'fl-builder'),
305
- 'default' => 'false',
306
- 'options' => array(
307
- 'false' => __('No', 'fl-builder'),
308
- 'true' => __('Yes', 'fl-builder')
309
- ),
310
- 'preview' => array(
311
- 'type' => 'none'
312
- )
313
- )
314
- )
315
- ),
316
- 'bg_parallax' => array(
317
- 'title' => __('Background Parallax', 'fl-builder'),
318
- 'fields' => array(
319
- 'bg_parallax_image' => array(
320
- 'type' => 'photo',
321
- 'label' => __('Photo', 'fl-builder'),
322
- 'preview' => array(
323
- 'type' => 'none'
324
- )
325
- ),
326
- 'bg_parallax_speed' => array(
327
- 'type' => 'select',
328
- 'label' => __('Speed', 'fl-builder'),
329
- 'default' => 'fast',
330
- 'options' => array(
331
- '2' => __('Fast', 'fl-builder'),
332
- '5' => _x( 'Medium', 'Speed.', 'fl-builder' ),
333
- '8' => __('Slow', 'fl-builder')
334
- ),
335
- 'preview' => array(
336
- 'type' => 'none'
337
- )
338
- )
339
- )
340
- ),
341
- 'bg_overlay' => array(
342
- 'title' => __('Background Overlay', 'fl-builder'),
343
- 'fields' => array(
344
- 'bg_overlay_color' => array(
345
- 'type' => 'color',
346
- 'label' => __('Overlay Color', 'fl-builder'),
347
- 'show_reset' => true,
348
- 'preview' => array(
349
- 'type' => 'none'
350
- )
351
- ),
352
- 'bg_overlay_opacity' => array(
353
- 'type' => 'text',
354
- 'label' => __('Overlay Opacity', 'fl-builder'),
355
- 'default' => '50',
356
- 'description' => '%',
357
- 'maxlength' => '3',
358
- 'size' => '5',
359
- 'preview' => array(
360
- 'type' => 'none'
361
- )
362
- )
363
- )
364
- ),
365
- 'border' => array(
366
- 'title' => __('Border', 'fl-builder'),
367
- 'fields' => array(
368
- 'border_type' => array(
369
- 'type' => 'select',
370
- 'label' => __('Type', 'fl-builder'),
371
- 'default' => '',
372
- 'help' => __('The type of border to use. Double borders must have a width of at least 3px to render properly.', 'fl-builder'),
373
- 'options' => array(
374
- '' => _x( 'None', 'Border type.', 'fl-builder' ),
375
- 'solid' => _x( 'Solid', 'Border type.', 'fl-builder' ),
376
- 'dashed' => _x( 'Dashed', 'Border type.', 'fl-builder' ),
377
- 'dotted' => _x( 'Dotted', 'Border type.', 'fl-builder' ),
378
- 'double' => _x( 'Double', 'Border type.', 'fl-builder' )
379
- ),
380
- 'toggle' => array(
381
- '' => array(
382
- 'fields' => array()
383
- ),
384
- 'solid' => array(
385
- 'fields' => array('border_color', 'border_opacity', 'border_top', 'border_bottom', 'border_left', 'border_right')
386
- ),
387
- 'dashed' => array(
388
- 'fields' => array('border_color', 'border_opacity', 'border_top', 'border_bottom', 'border_left', 'border_right')
389
- ),
390
- 'dotted' => array(
391
- 'fields' => array('border_color', 'border_opacity', 'border_top', 'border_bottom', 'border_left', 'border_right')
392
- ),
393
- 'double' => array(
394
- 'fields' => array('border_color', 'border_opacity', 'border_top', 'border_bottom', 'border_left', 'border_right')
395
- )
396
- ),
397
- 'preview' => array(
398
- 'type' => 'none'
399
- )
400
- ),
401
- 'border_color' => array(
402
- 'type' => 'color',
403
- 'label' => __('Color', 'fl-builder'),
404
- 'show_reset' => true,
405
- 'preview' => array(
406
- 'type' => 'none'
407
- )
408
- ),
409
- 'border_opacity' => array(
410
- 'type' => 'text',
411
- 'label' => __('Opacity', 'fl-builder'),
412
- 'default' => '100',
413
- 'description' => '%',
414
- 'maxlength' => '3',
415
- 'size' => '5',
416
- 'preview' => array(
417
- 'type' => 'none'
418
- )
419
- ),
420
- 'border_top' => array(
421
- 'type' => 'text',
422
- 'label' => __('Top Width', 'fl-builder'),
423
- 'default' => '1',
424
- 'description' => 'px',
425
- 'maxlength' => '3',
426
- 'size' => '5',
427
- 'placeholder' => '0',
428
- 'preview' => array(
429
- 'type' => 'none'
430
- )
431
- ),
432
- 'border_bottom' => array(
433
- 'type' => 'text',
434
- 'label' => __('Bottom Width', 'fl-builder'),
435
- 'default' => '1',
436
- 'description' => 'px',
437
- 'maxlength' => '3',
438
- 'size' => '5',
439
- 'placeholder' => '0',
440
- 'preview' => array(
441
- 'type' => 'none'
442
- )
443
- ),
444
- 'border_left' => array(
445
- 'type' => 'text',
446
- 'label' => __('Left Width', 'fl-builder'),
447
- 'default' => '0',
448
- 'description' => 'px',
449
- 'maxlength' => '3',
450
- 'size' => '5',
451
- 'placeholder' => '0',
452
- 'preview' => array(
453
- 'type' => 'none'
454
- )
455
- ),
456
- 'border_right' => array(
457
- 'type' => 'text',
458
- 'label' => __('Right Width', 'fl-builder'),
459
- 'default' => '0',
460
- 'description' => 'px',
461
- 'maxlength' => '3',
462
- 'size' => '5',
463
- 'placeholder' => '0',
464
- 'preview' => array(
465
- 'type' => 'none'
466
- )
467
- )
468
- )
469
- ),
470
- )
471
- ),
472
- 'advanced' => array(
473
- 'title' => __('Advanced', 'fl-builder'),
474
- 'sections' => array(
475
- 'margins' => array(
476
- 'title' => __('Margins', 'fl-builder'),
477
- 'fields' => array(
478
- 'margin_top' => array(
479
- 'type' => 'text',
480
- 'label' => __('Top', 'fl-builder'),
481
- 'default' => '',
482
- 'description' => 'px',
483
- 'maxlength' => '4',
484
- 'size' => '5',
485
- 'placeholder' => $global_settings->row_margins,
486
- 'preview' => array(
487
- 'type' => 'none'
488
- )
489
- ),
490
- 'margin_bottom' => array(
491
- 'type' => 'text',
492
- 'label' => __('Bottom', 'fl-builder'),
493
- 'default' => '',
494
- 'description' => 'px',
495
- 'maxlength' => '4',
496
- 'size' => '5',
497
- 'placeholder' => $global_settings->row_margins,
498
- 'preview' => array(
499
- 'type' => 'none'
500
- )
501
- ),
502
- 'margin_left' => array(
503
- 'type' => 'text',
504
- 'label' => __('Left', 'fl-builder'),
505
- 'default' => '',
506
- 'description' => 'px',
507
- 'maxlength' => '4',
508
- 'size' => '5',
509
- 'placeholder' => $global_settings->row_margins,
510
- 'preview' => array(
511
- 'type' => 'none'
512
- )
513
- ),
514
- 'margin_right' => array(
515
- 'type' => 'text',
516
- 'label' => __('Right', 'fl-builder'),
517
- 'default' => '',
518
- 'description' => 'px',
519
- 'maxlength' => '4',
520
- 'size' => '5',
521
- 'placeholder' => $global_settings->row_margins,
522
- 'preview' => array(
523
- 'type' => 'none'
524
- )
525
- )
526
- )
527
- ),
528
- 'padding' => array(
529
- 'title' => __('Padding', 'fl-builder'),
530
- 'fields' => array(
531
- 'padding_top' => array(
532
- 'type' => 'text',
533
- 'label' => __('Top', 'fl-builder'),
534
- 'default' => '',
535
- 'description' => 'px',
536
- 'maxlength' => '4',
537
- 'size' => '5',
538
- 'placeholder' => $global_settings->row_padding,
539
- 'preview' => array(
540
- 'type' => 'none'
541
- )
542
- ),
543
- 'padding_bottom' => array(
544
- 'type' => 'text',
545
- 'label' => __('Bottom', 'fl-builder'),
546
- 'default' => '',
547
- 'description' => 'px',
548
- 'maxlength' => '4',
549
- 'size' => '5',
550
- 'placeholder' => $global_settings->row_padding,
551
- 'preview' => array(
552
- 'type' => 'none'
553
- )
554
- ),
555
- 'padding_left' => array(
556
- 'type' => 'text',
557
- 'label' => __('Left', 'fl-builder'),
558
- 'default' => '',
559
- 'description' => 'px',
560
- 'maxlength' => '4',
561
- 'size' => '5',
562
- 'placeholder' => $global_settings->row_padding,
563
- 'preview' => array(
564
- 'type' => 'none'
565
- )
566
- ),
567
- 'padding_right' => array(
568
- 'type' => 'text',
569
- 'label' => __('Right', 'fl-builder'),
570
- 'default' => '',
571
- 'description' => 'px',
572
- 'maxlength' => '4',
573
- 'size' => '5',
574
- 'placeholder' => $global_settings->row_padding,
575
- 'preview' => array(
576
- 'type' => 'none'
577
- )
578
- )
579
- )
580
- ),
581
- 'responsive' => array(
582
- 'title' => __('Responsive Layout', 'fl-builder'),
583
- 'fields' => array(
584
- 'responsive_display' => array(
585
- 'type' => 'select',
586
- 'label' => __('Display', 'fl-builder'),
587
- 'options' => array(
588
- '' => __('Always', 'fl-builder'),
589
- 'desktop' => __('Large Devices Only', 'fl-builder'),
590
- 'desktop-medium' => __('Large &amp; Medium Devices Only', 'fl-builder'),
591
- 'medium' => __('Medium Devices Only', 'fl-builder'),
592
- 'medium-mobile' => __('Medium &amp; Small Devices Only', 'fl-builder'),
593
- 'mobile' => __('Small Devices Only', 'fl-builder'),
594
- ),
595
- 'help' => __( 'Choose whether to show or hide this row at different device sizes.', 'fl-builder' ),
596
- 'preview' => array(
597
- 'type' => 'none'
598
- )
599
- )
600
- )
601
- ),
602
- 'css_selectors' => array(
603
- 'title' => __('CSS Selectors', 'fl-builder'),
604
- 'fields' => array(
605
- 'id' => array(
606
- 'type' => 'text',
607
- 'label' => __('ID', 'fl-builder'),
608
- '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' ),
609
- 'preview' => array(
610
- 'type' => 'none'
611
- )
612
- ),
613
- 'class' => array(
614
- 'type' => 'text',
615
- 'label' => __('Class', 'fl-builder'),
616
- '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' ),
617
- 'preview' => array(
618
- 'type' => 'none'
619
- )
620
- )
621
- )
622
- )
623
- )
624
- )
625
- )
626
  ));
3
  $global_settings = FLBuilderModel::get_global_settings();
4
 
5
  FLBuilder::register_settings_form('row', array(
6
+ 'title' => __('Row Settings', 'fl-builder'),
7
+ 'tabs' => array(
8
+ 'style' => array(
9
+ 'title' => __('Style', 'fl-builder'),
10
+ 'sections' => array(
11
+ 'general' => array(
12
+ 'title' => '',
13
+ 'fields' => array(
14
+ 'width' => array(
15
+ 'type' => 'select',
16
+ 'label' => __('Width', 'fl-builder'),
17
+ 'default' => $global_settings->row_width_default,
18
+ 'options' => array(
19
+ 'fixed' => __('Fixed', 'fl-builder'),
20
+ 'full' => __('Full Width', 'fl-builder')
21
+ ),
22
+ 'toggle' => array(
23
+ 'full' => array(
24
+ 'fields' => array('content_width')
25
+ )
26
+ ),
27
+ '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'),
28
+ 'preview' => array(
29
+ 'type' => 'none'
30
+ )
31
+ ),
32
+ 'content_width' => array(
33
+ 'type' => 'select',
34
+ 'label' => __('Content Width', 'fl-builder'),
35
+ 'default' => $global_settings->row_content_width_default,
36
+ 'options' => array(
37
+ 'fixed' => __('Fixed', 'fl-builder'),
38
+ 'full' => __('Full Width', 'fl-builder')
39
+ ),
40
+ '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'),
41
+ 'preview' => array(
42
+ 'type' => 'none'
43
+ )
44
+ ),
45
+ )
46
+ ),
47
+ 'text' => array(
48
+ 'title' => __('Text', 'fl-builder'),
49
+ 'fields' => array(
50
+ 'text_color' => array(
51
+ 'type' => 'color',
52
+ 'label' => __('Color', 'fl-builder'),
53
+ 'show_reset' => true,
54
+ 'preview' => array(
55
+ 'type' => 'none'
56
+ )
57
+ )
58
+ )
59
+ ),
60
+ 'background' => array(
61
+ 'title' => __('Background', 'fl-builder'),
62
+ 'fields' => array(
63
+ 'bg_type' => array(
64
+ 'type' => 'select',
65
+ 'label' => __('Type', 'fl-builder'),
66
+ 'default' => 'none',
67
+ 'options' => array(
68
+ 'none' => _x( 'None', 'Background type.', 'fl-builder' ),
69
+ 'color' => _x( 'Color', 'Background type.', 'fl-builder' ),
70
+ 'photo' => _x( 'Photo', 'Background type.', 'fl-builder' ),
71
+ 'video' => _x( 'Video', 'Background type.', 'fl-builder' ),
72
+ 'slideshow' => array(
73
+ 'label' => _x( 'Slideshow', 'Background type.', 'fl-builder' ),
74
+ 'premium' => true
75
+ ),
76
+ 'parallax' => array(
77
+ 'label' => _x( 'Parallax', 'Background type.', 'fl-builder' ),
78
+ 'premium' => true
79
+ )
80
+ ),
81
+ 'toggle' => array(
82
+ 'color' => array(
83
+ 'sections' => array('bg_color')
84
+ ),
85
+ 'photo' => array(
86
+ 'sections' => array('bg_photo', 'bg_overlay')
87
+ ),
88
+ 'video' => array(
89
+ 'sections' => array('bg_video', 'bg_overlay')
90
+ ),
91
+ 'slideshow' => array(
92
+ 'sections' => array('bg_slideshow', 'bg_overlay')
93
+ ),
94
+ 'parallax' => array(
95
+ 'sections' => array('bg_parallax', 'bg_overlay')
96
+ )
97
+ ),
98
+ 'preview' => array(
99
+ 'type' => 'none'
100
+ )
101
+ )
102
+ )
103
+ ),
104
+ 'bg_color' => array(
105
+ 'title' => __('Background Color', 'fl-builder'),
106
+ 'fields' => array(
107
+ 'bg_color' => array(
108
+ 'type' => 'color',
109
+ 'label' => __('Color', 'fl-builder'),
110
+ 'show_reset' => true,
111
+ 'preview' => array(
112
+ 'type' => 'none'
113
+ )
114
+ ),
115
+ 'bg_opacity' => array(
116
+ 'type' => 'text',
117
+ 'label' => __('Opacity', 'fl-builder'),
118
+ 'default' => '100',
119
+ 'description' => '%',
120
+ 'maxlength' => '3',
121
+ 'size' => '5',
122
+ 'preview' => array(
123
+ 'type' => 'none'
124
+ )
125
+ )
126
+ )
127
+ ),
128
+ 'bg_photo' => array(
129
+ 'title' => __('Background Photo', 'fl-builder'),
130
+ 'fields' => array(
131
+ 'bg_image' => array(
132
+ 'type' => 'photo',
133
+ 'label' => __('Photo', 'fl-builder'),
134
+ 'preview' => array(
135
+ 'type' => 'none'
136
+ )
137
+ ),
138
+ 'bg_repeat' => array(
139
+ 'type' => 'select',
140
+ 'label' => __('Repeat', 'fl-builder'),
141
+ 'default' => 'none',
142
+ 'options' => array(
143
+ 'no-repeat' => _x( 'None', 'Background repeat.', 'fl-builder' ),
144
+ 'repeat' => _x( 'Tile', 'Background repeat.', 'fl-builder' ),
145
+ 'repeat-x' => _x( 'Horizontal', 'Background repeat.', 'fl-builder' ),
146
+ 'repeat-y' => _x( 'Vertical', 'Background repeat.', 'fl-builder' )
147
+ ),
148
+ 'help' => __('Repeat applies to how the image should display in the row background. Choosing none will display the image as uploaded. Tile will repeat the image as many times as needed to fill the row horizontally and vertically. You can also specify the image to only repeat horizontally or vertically.', 'fl-builder'),
149
+ 'preview' => array(
150
+ 'type' => 'none'
151
+ )
152
+ ),
153
+ 'bg_position' => array(
154
+ 'type' => 'select',
155
+ 'label' => __('Position', 'fl-builder'),
156
+ 'default' => 'center center',
157
+ 'options' => array(
158
+ 'left top' => __('Left Top', 'fl-builder'),
159
+ 'left center' => __('Left Center', 'fl-builder'),
160
+ 'left bottom' => __('Left Bottom', 'fl-builder'),
161
+ 'right top' => __('Right Top', 'fl-builder'),
162
+ 'right center' => __('Right Center', 'fl-builder'),
163
+ 'right bottom' => __('Right Bottom', 'fl-builder'),
164
+ 'center top' => __('Center Top', 'fl-builder'),
165
+ 'center center' => __( 'Center', 'fl-builder' ),
166
+ 'center bottom' => __('Center Bottom', 'fl-builder')
167
+ ),
168
+ 'help' => __('Position will tell the image where it should sit in the row background.', 'fl-builder'),
169
+ 'preview' => array(
170
+ 'type' => 'none'
171
+ )
172
+ ),
173
+ 'bg_attachment' => array(
174
+ 'type' => 'select',
175
+ 'label' => __('Attachment', 'fl-builder'),
176
+ 'default' => 'scroll',
177
+ 'options' => array(
178
+ 'scroll' => __( 'Scroll', 'fl-builder' ),
179
+ 'fixed' => __( 'Fixed', 'fl-builder' )
180
+ ),
181
+ '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 row background if fill is selected in the scale setting.', 'fl-builder'),
182
+ 'preview' => array(
183
+ 'type' => 'none'
184
+ )
185
+ ),
186
+ 'bg_size' => array(
187
+ 'type' => 'select',
188
+ 'label' => __('Scale', 'fl-builder'),
189
+ 'default' => 'cover',
190
+ 'options' => array(
191
+ '' => _x( 'None', 'Background scale.', 'fl-builder' ),
192
+ 'contain' => __( 'Fit', 'fl-builder'),
193
+ 'cover' => __( 'Fill', 'fl-builder')
194
+ ),
195
+ 'help' => __('Scale applies to how the image should display in the row background. You can select either fill or fit to the row background.', 'fl-builder'),
196
+ 'preview' => array(
197
+ 'type' => 'none'
198
+ )
199
+ )
200
+ )
201
+ ),
202
+ 'bg_video' => array(
203
+ 'title' => __('Background Video', 'fl-builder'),
204
+ 'fields' => array(
205
+ 'bg_video' => array(
206
+ 'type' => 'video',
207
+ 'label' => __('Video', 'fl-builder'),
208
+ 'help' => __('An HTML5 video to use as the background of this row. Supported types are MP4, WebM and Ogg.', 'fl-builder'),
209
+ 'preview' => array(
210
+ 'type' => 'refresh'
211
+ )
212
+ ),
213
+ 'bg_video_fallback' => array(
214
+ 'type' => 'photo',
215
+ 'label' => __('Fallback Photo', 'fl-builder'),
216
+ 'help' => __('A photo that will be displayed if the video fails to load.', 'fl-builder'),
217
+ 'preview' => array(
218
+ 'type' => 'refresh'
219
+ )
220
+ )
221
+ )
222
+ ),
223
+ 'bg_slideshow' => array(
224
+ 'title' => __('Background Slideshow', 'fl-builder'),
225
+ 'fields' => array(
226
+ 'ss_source' => array(
227
+ 'type' => 'select',
228
+ 'label' => __('Source', 'fl-builder'),
229
+ 'default' => 'wordpress',
230
+ 'options' => array(
231
+ 'wordpress' => __('Media Library', 'fl-builder'),
232
+ 'smugmug' => 'SmugMug'
233
+ ),
234
+ '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'),
235
+ 'toggle' => array(
236
+ 'wordpress' => array(
237
+ 'fields' => array('ss_photos')
238
+ ),
239
+ 'smugmug' => array(
240
+ 'fields' => array('ss_feed_url')
241
+ )
242
+ ),
243
+ 'preview' => array(
244
+ 'type' => 'none'
245
+ )
246
+ ),
247
+ 'ss_photos' => array(
248
+ 'type' => 'multiple-photos',
249
+ 'label' => __('Photos', 'fl-builder'),
250
+ 'preview' => array(
251
+ 'type' => 'none'
252
+ )
253
+ ),
254
+ 'ss_feed_url' => array(
255
+ 'type' => 'text',
256
+ 'label' => __('Feed URL', 'fl-builder'),
257
+ 'preview' => array(
258
+ 'type' => 'none'
259
+ )
260
+ ),
261
+ 'ss_speed' => array(
262
+ 'type' => 'text',
263
+ 'label' => __('Speed', 'fl-builder'),
264
+ 'default' => '3',
265
+ 'size' => '5',
266
+ 'description' => _x( 'seconds', 'Value unit for form field of time in seconds. Such as: "5 seconds"', 'fl-builder' ),
267
+ 'preview' => array(
268
+ 'type' => 'none'
269
+ )
270
+ ),
271
+ 'ss_transition' => array(
272
+ 'type' => 'select',
273
+ 'label' => __('Transition', 'fl-builder'),
274
+ 'default' => 'fade',
275
+ 'options' => array(
276
+ 'none' => _x( 'None', 'Slideshow transition type.', 'fl-builder' ),
277
+ 'fade' => __('Fade', 'fl-builder'),
278
+ 'kenBurns' => __('Ken Burns', 'fl-builder'),
279
+ 'slideHorizontal' => __('Slide Horizontal', 'fl-builder'),
280
+ 'slideVertical' => __('Slide Vertical', 'fl-builder'),
281
+ 'blinds' => __('Blinds', 'fl-builder'),
282
+ 'bars' => __('Bars', 'fl-builder'),
283
+ 'barsRandom' => __('Random Bars', 'fl-builder'),
284
+ 'boxes' => __('Boxes', 'fl-builder'),
285
+ 'boxesRandom' => __('Random Boxes', 'fl-builder'),
286
+ 'boxesGrow' => __('Boxes Grow', 'fl-builder')
287
+ ),
288
+ 'preview' => array(
289
+ 'type' => 'none'
290
+ )
291
+ ),
292
+ 'ss_transitionDuration' => array(
293
+ 'type' => 'text',
294
+ 'label' => __('Transition Speed', 'fl-builder'),
295
+ 'default' => '1',
296
+ 'size' => '5',
297
+ 'description' => _x( 'seconds', 'Value unit for form field of time in seconds. Such as: "5 seconds"', 'fl-builder' ),
298
+ 'preview' => array(
299
+ 'type' => 'none'
300
+ )
301
+ ),
302
+ 'ss_randomize' => array(
303
+ 'type' => 'select',
304
+ 'label' => __('Randomize Photos', 'fl-builder'),
305
+ 'default' => 'false',
306
+ 'options' => array(
307
+ 'false' => __('No', 'fl-builder'),
308
+ 'true' => __('Yes', 'fl-builder')
309
+ ),
310
+ 'preview' => array(
311
+ 'type' => 'none'
312
+ )
313
+ )
314
+ )
315
+ ),
316
+ 'bg_parallax' => array(
317
+ 'title' => __('Background Parallax', 'fl-builder'),
318
+ 'fields' => array(
319
+ 'bg_parallax_image' => array(
320
+ 'type' => 'photo',
321
+ 'label' => __('Photo', 'fl-builder'),
322
+ 'preview' => array(
323
+ 'type' => 'none'
324
+ )
325
+ ),
326
+ 'bg_parallax_speed' => array(
327
+ 'type' => 'select',
328
+ 'label' => __('Speed', 'fl-builder'),
329
+ 'default' => 'fast',
330
+ 'options' => array(
331
+ '2' => __('Fast', 'fl-builder'),
332
+ '5' => _x( 'Medium', 'Speed.', 'fl-builder' ),
333
+ '8' => __('Slow', 'fl-builder')
334
+ ),
335
+ 'preview' => array(
336
+ 'type' => 'none'
337
+ )
338
+ )
339
+ )
340
+ ),
341
+ 'bg_overlay' => array(
342
+ 'title' => __('Background Overlay', 'fl-builder'),
343
+ 'fields' => array(
344
+ 'bg_overlay_color' => array(
345
+ 'type' => 'color',
346
+ 'label' => __('Overlay Color', 'fl-builder'),
347
+ 'show_reset' => true,
348
+ 'preview' => array(
349
+ 'type' => 'none'
350
+ )
351
+ ),
352
+ 'bg_overlay_opacity' => array(
353
+ 'type' => 'text',
354
+ 'label' => __('Overlay Opacity', 'fl-builder'),
355
+ 'default' => '50',
356
+ 'description' => '%',
357
+ 'maxlength' => '3',
358
+ 'size' => '5',
359
+ 'preview' => array(
360
+ 'type' => 'none'
361
+ )
362
+ )
363
+ )
364
+ ),
365
+ 'border' => array(
366
+ 'title' => __('Border', 'fl-builder'),
367
+ 'fields' => array(
368
+ 'border_type' => array(
369
+ 'type' => 'select',
370
+ 'label' => __('Type', 'fl-builder'),
371
+ 'default' => '',
372
+ 'help' => __('The type of border to use. Double borders must have a width of at least 3px to render properly.', 'fl-builder'),
373
+ 'options' => array(
374
+ '' => _x( 'None', 'Border type.', 'fl-builder' ),
375
+ 'solid' => _x( 'Solid', 'Border type.', 'fl-builder' ),
376
+ 'dashed' => _x( 'Dashed', 'Border type.', 'fl-builder' ),
377
+ 'dotted' => _x( 'Dotted', 'Border type.', 'fl-builder' ),
378
+ 'double' => _x( 'Double', 'Border type.', 'fl-builder' )
379
+ ),
380
+ 'toggle' => array(
381
+ '' => array(
382
+ 'fields' => array()
383
+ ),
384
+ 'solid' => array(
385
+ 'fields' => array('border_color', 'border_opacity', 'border_top', 'border_bottom', 'border_left', 'border_right')
386
+ ),
387
+ 'dashed' => array(
388
+ 'fields' => array('border_color', 'border_opacity', 'border_top', 'border_bottom', 'border_left', 'border_right')
389
+ ),
390
+ 'dotted' => array(
391
+ 'fields' => array('border_color', 'border_opacity', 'border_top', 'border_bottom', 'border_left', 'border_right')
392
+ ),
393
+ 'double' => array(
394
+ 'fields' => array('border_color', 'border_opacity', 'border_top', 'border_bottom', 'border_left', 'border_right')
395
+ )
396
+ ),
397
+ 'preview' => array(
398
+ 'type' => 'none'
399
+ )
400
+ ),
401
+ 'border_color' => array(
402
+ 'type' => 'color',
403
+ 'label' => __('Color', 'fl-builder'),
404
+ 'show_reset' => true,
405
+ 'preview' => array(
406
+ 'type' => 'none'
407
+ )
408
+ ),
409
+ 'border_opacity' => array(
410
+ 'type' => 'text',
411
+ 'label' => __('Opacity', 'fl-builder'),
412
+ 'default' => '100',
413
+ 'description' => '%',
414
+ 'maxlength' => '3',
415
+ 'size' => '5',
416
+ 'preview' => array(
417
+ 'type' => 'none'
418
+ )
419
+ ),
420
+ 'border_top' => array(
421
+ 'type' => 'text',
422
+ 'label' => __('Top Width', 'fl-builder'),
423
+ 'default' => '1',
424
+ 'description' => 'px',
425
+ 'maxlength' => '3',
426
+ 'size' => '5',
427
+ 'placeholder' => '0',
428
+ 'preview' => array(
429
+ 'type' => 'none'
430
+ )
431
+ ),
432
+ 'border_bottom' => array(
433
+ 'type' => 'text',
434
+ 'label' => __('Bottom Width', 'fl-builder'),
435
+ 'default' => '1',
436
+ 'description' => 'px',
437
+ 'maxlength' => '3',
438
+ 'size' => '5',
439
+ 'placeholder' => '0',
440
+ 'preview' => array(
441
+ 'type' => 'none'
442
+ )
443
+ ),
444
+ 'border_left' => array(
445
+ 'type' => 'text',
446
+ 'label' => __('Left Width', 'fl-builder'),
447
+ 'default' => '0',
448
+ 'description' => 'px',
449
+ 'maxlength' => '3',
450
+ 'size' => '5',
451
+ 'placeholder' => '0',
452
+ 'preview' => array(
453
+ 'type' => 'none'
454
+ )
455
+ ),
456
+ 'border_right' => array(
457
+ 'type' => 'text',
458
+ 'label' => __('Right Width', 'fl-builder'),
459
+ 'default' => '0',
460
+ 'description' => 'px',
461
+ 'maxlength' => '3',
462
+ 'size' => '5',
463
+ 'placeholder' => '0',
464
+ 'preview' => array(
465
+ 'type' => 'none'
466
+ )
467
+ )
468
+ )
469
+ ),
470
+ )
471
+ ),
472
+ 'advanced' => array(
473
+ 'title' => __('Advanced', 'fl-builder'),
474
+ 'sections' => array(
475
+ 'margins' => array(
476
+ 'title' => __('Margins', 'fl-builder'),
477
+ 'fields' => array(
478
+ 'margin_top' => array(
479
+ 'type' => 'text',
480
+ 'label' => __('Top', 'fl-builder'),
481
+ 'default' => '',
482
+ 'description' => 'px',
483
+ 'maxlength' => '4',
484
+ 'size' => '5',
485
+ 'placeholder' => $global_settings->row_margins,
486
+ 'preview' => array(
487
+ 'type' => 'none'
488
+ )
489
+ ),
490
+ 'margin_bottom' => array(
491
+ 'type' => 'text',
492
+ 'label' => __('Bottom', 'fl-builder'),
493
+ 'default' => '',
494
+ 'description' => 'px',
495
+ 'maxlength' => '4',
496
+ 'size' => '5',
497
+ 'placeholder' => $global_settings->row_margins,
498
+ 'preview' => array(
499
+ 'type' => 'none'
500
+ )
501
+ ),
502
+ 'margin_left' => array(
503
+ 'type' => 'text',
504
+ 'label' => __('Left', 'fl-builder'),
505
+ 'default' => '',
506
+ 'description' => 'px',
507
+ 'maxlength' => '4',
508
+ 'size' => '5',
509
+ 'placeholder' => $global_settings->row_margins,
510
+ 'preview' => array(
511
+ 'type' => 'none'
512
+ )
513
+ ),
514
+ 'margin_right' => array(
515
+ 'type' => 'text',
516
+ 'label' => __('Right', 'fl-builder'),
517
+ 'default' => '',
518
+ 'description' => 'px',
519
+ 'maxlength' => '4',
520
+ 'size' => '5',
521
+ 'placeholder' => $global_settings->row_margins,
522
+ 'preview' => array(
523
+ 'type' => 'none'
524
+ )
525
+ )
526
+ )
527
+ ),
528
+ 'padding' => array(
529
+ 'title' => __('Padding', 'fl-builder'),
530
+ 'fields' => array(
531
+ 'padding_top' => array(
532
+ 'type' => 'text',
533
+ 'label' => __('Top', 'fl-builder'),
534
+ 'default' => '',
535
+ 'description' => 'px',
536
+ 'maxlength' => '4',
537
+ 'size' => '5',
538
+ 'placeholder' => $global_settings->row_padding,
539
+ 'preview' => array(
540
+ 'type' => 'none'
541
+ )
542
+ ),
543
+ 'padding_bottom' => array(
544
+ 'type' => 'text',
545
+ 'label' => __('Bottom', 'fl-builder'),
546
+ 'default' => '',
547
+ 'description' => 'px',
548
+ 'maxlength' => '4',
549
+ 'size' => '5',
550
+ 'placeholder' => $global_settings->row_padding,
551
+ 'preview' => array(
552
+ 'type' => 'none'
553
+ )
554
+ ),
555
+ 'padding_left' => array(
556
+ 'type' => 'text',
557
+ 'label' => __('Left', 'fl-builder'),
558
+ 'default' => '',
559
+ 'description' => 'px',
560
+ 'maxlength' => '4',
561
+ 'size' => '5',
562
+ 'placeholder' => $global_settings->row_padding,
563
+ 'preview' => array(
564
+ 'type' => 'none'
565
+ )
566
+ ),
567
+ 'padding_right' => array(
568
+ 'type' => 'text',
569
+ 'label' => __('Right', 'fl-builder'),
570
+ 'default' => '',
571
+ 'description' => 'px',
572
+ 'maxlength' => '4',
573
+ 'size' => '5',
574
+ 'placeholder' => $global_settings->row_padding,
575
+ 'preview' => array(
576
+ 'type' => 'none'
577
+ )
578
+ )
579
+ )
580
+ ),
581
+ 'responsive' => array(
582
+ 'title' => __('Responsive Layout', 'fl-builder'),
583
+ 'fields' => array(
584
+ 'responsive_display' => array(
585
+ 'type' => 'select',
586
+ 'label' => __('Display', 'fl-builder'),
587
+ 'options' => array(
588
+ '' => __('Always', 'fl-builder'),
589
+ 'desktop' => __('Large Devices Only', 'fl-builder'),
590
+ 'desktop-medium' => __('Large &amp; Medium Devices Only', 'fl-builder'),
591
+ 'medium' => __('Medium Devices Only', 'fl-builder'),
592
+ 'medium-mobile' => __('Medium &amp; Small Devices Only', 'fl-builder'),
593
+ 'mobile' => __('Small Devices Only', 'fl-builder'),
594
+ ),
595
+ 'help' => __( 'Choose whether to show or hide this row at different device sizes.', 'fl-builder' ),
596
+ 'preview' => array(
597
+ 'type' => 'none'
598
+ )
599
+ )
600
+ )
601
+ ),
602
+ 'css_selectors' => array(
603
+ 'title' => __('CSS Selectors', 'fl-builder'),
604
+ 'fields' => array(
605
+ 'id' => array(
606
+ 'type' => 'text',
607
+ 'label' => __('ID', 'fl-builder'),
608
+ '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' ),
609
+ 'preview' => array(
610
+ 'type' => 'none'
611
+ )
612
+ ),
613
+ 'class' => array(
614
+ 'type' => 'text',
615
+ 'label' => __('Class', 'fl-builder'),
616
+ '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' ),
617
+ 'preview' => array(
618
+ 'type' => 'none'
619
+ )
620
+ )
621
+ )
622
+ )
623
+ )
624
+ )
625
+ )
626
  ));
includes/row-video.php CHANGED
@@ -2,9 +2,9 @@
2
  <?php if ( wp_is_mobile() ) : ?>
3
  <div id="fl-bg-video-fallback-<?php echo $row->node; ?>" class="fl-bg-video-fallback"<?php if(!empty($vid_data->fallback)) echo ' style="background-image: url(' . $vid_data->fallback . ');"'; ?>></div>
4
  <?php else : ?>
5
- <video autoplay loop muted preload data-width="<?php echo @$vid_data->width; ?>" data-height="<?php echo @$vid_data->height; ?>">
6
- <source src="<?php echo $vid_data->url; ?>" type="video/<?php echo $vid_data->extension; ?>" onerror="var wrap = this.parentNode.parentNode, vid = this.parentNode; wrap.appendChild(document.getElementById('fl-bg-video-fallback-<?php echo $row->node; ?>')); wrap.removeChild(vid);">
7
- <div id="fl-bg-video-fallback-<?php echo $row->node; ?>" class="fl-bg-video-fallback"<?php if(!empty($vid_data->fallback)) echo ' style="background-image: url(' . $vid_data->fallback . ');"'; ?>></div>
8
- </video>
9
- <?php endif; ?>
10
  </div>
2
  <?php if ( wp_is_mobile() ) : ?>
3
  <div id="fl-bg-video-fallback-<?php echo $row->node; ?>" class="fl-bg-video-fallback"<?php if(!empty($vid_data->fallback)) echo ' style="background-image: url(' . $vid_data->fallback . ');"'; ?>></div>
4
  <?php else : ?>
5
+ <video autoplay loop muted preload data-width="<?php echo @$vid_data->width; ?>" data-height="<?php echo @$vid_data->height; ?>">
6
+ <source src="<?php echo $vid_data->url; ?>" type="video/<?php echo $vid_data->extension; ?>" onerror="var wrap = this.parentNode.parentNode, vid = this.parentNode; wrap.appendChild(document.getElementById('fl-bg-video-fallback-<?php echo $row->node; ?>')); wrap.removeChild(vid);">
7
+ <div id="fl-bg-video-fallback-<?php echo $row->node; ?>" class="fl-bg-video-fallback"<?php if(!empty($vid_data->fallback)) echo ' style="background-image: url(' . $vid_data->fallback . ');"'; ?>></div>
8
+ </video>
9
+ <?php endif; ?>
10
  </div>
includes/row.php CHANGED
@@ -1,14 +1,14 @@
1
  <div<?php FLBuilder::render_row_attributes( $row ); ?>>
2
- <div class="fl-row-content-wrap">
3
- <?php FLBuilder::render_row_bg( $row ); ?>
4
- <div class="<?php FLBuilder::render_row_content_class( $row ); ?>">
5
- <?php
6
-
7
- foreach ( $groups as $group ) {
8
- FLBuilder::render_column_group( $group );
9
- }
10
-
11
- ?>
12
- </div>
13
- </div>
14
  </div>
1
  <div<?php FLBuilder::render_row_attributes( $row ); ?>>
2
+ <div class="fl-row-content-wrap">
3
+ <?php FLBuilder::render_row_bg( $row ); ?>
4
+ <div class="<?php FLBuilder::render_row_content_class( $row ); ?>">
5
+ <?php
6
+
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
@@ -26,16 +26,16 @@
26
 
27
  // Render the service select.
28
  FLBuilder::render_settings_field( 'service', array(
29
- 'row_class' => 'fl-builder-service-select-row',
30
- 'class' => 'fl-builder-service-select',
31
- 'type' => 'select',
32
- 'label' => __( 'Service', 'fl-builder' ),
33
- 'options' => $options,
34
- 'preview' => array(
35
- 'type' => 'none'
36
- )
37
- ), $settings );
38
-
39
- ?>
40
  </table>
41
  </div>
26
 
27
  // Render the service select.
28
  FLBuilder::render_settings_field( 'service', array(
29
+ 'row_class' => 'fl-builder-service-select-row',
30
+ 'class' => 'fl-builder-service-select',
31
+ 'type' => 'select',
32
+ 'label' => __( 'Service', 'fl-builder' ),
33
+ 'options' => $options,
34
+ 'preview' => array(
35
+ 'type' => 'none'
36
+ )
37
+ ), $settings );
38
+
39
+ ?>
40
  </table>
41
  </div>
includes/settings.php CHANGED
@@ -1,65 +1,65 @@
1
  <form class="fl-builder-settings <?php echo $form['class']; ?>" <?php echo $form['attrs']; ?>>
2
- <div class="fl-lightbox-header">
3
- <h1><?php echo $form['title']; ?></h1>
4
- </div>
5
- <?php if(count($form['tabs']) > 1) : ?>
6
- <div class="fl-builder-settings-tabs">
7
- <?php $i = 0; foreach($form['tabs'] as $id => $tab) : ?>
8
- <a href="#fl-builder-settings-tab-<?php echo $id; ?>"<?php if($i == 0) echo ' class="fl-active"'; ?>><?php echo $tab['title']; ?></a>
9
- <?php $i++; endforeach; ?>
10
- </div>
11
- <?php endif; ?>
12
- <div class="fl-builder-settings-fields fl-nanoscroller">
13
- <div class="fl-nanoscroller-content">
14
- <?php $i = 0; foreach($form['tabs'] as $id => $tab) : // Tabs ?>
15
- <div id="fl-builder-settings-tab-<?php echo $id; ?>" class="fl-builder-settings-tab <?php if($i == 0) echo 'fl-active'; ?>">
16
-
17
- <?php if(isset($tab['file']) && file_exists($tab['file'])) : // Tab File ?>
18
-
19
- <?php include $tab['file']; ?>
20
-
21
- <?php else : ?>
22
-
23
- <?php if(!empty($tab['description'])) : // Tab Description ?>
24
- <p class="fl-builder-settings-tab-description"><?php echo $tab['description']; ?></p>
25
- <?php endif; ?>
26
-
27
- <?php foreach($tab['sections'] as $id => $section) : // Tab Sections ?>
28
- <div id="fl-builder-settings-section-<?php echo $id; ?>" class="fl-builder-settings-section">
29
-
30
- <?php if(isset($section['file']) && file_exists($section['file'])) : // Section File ?>
31
-
32
- <?php include $section['file']; ?>
33
-
34
- <?php else : ?>
35
-
36
- <?php if(!empty($section['title'])) : // Section Title ?>
37
- <h3 class="fl-builder-settings-title"><?php echo $section['title']; ?></h3>
38
- <?php endif; ?>
39
-
40
- <table class="fl-form-table">
41
- <?php
42
-
43
- foreach($section['fields'] as $name => $field) { // Fields
44
- FLBuilder::render_settings_field($name, $field, $settings);
45
- }
46
-
47
- ?>
48
- </table>
49
-
50
- <?php endif; ?>
51
-
52
- </div>
53
- <?php endforeach; ?>
54
-
55
- <?php endif; ?>
56
-
57
- </div>
58
- <?php $i++; endforeach; ?>
59
- </div>
60
- </div>
61
- <div class="fl-lightbox-footer">
62
- <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>
63
- <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>
64
- </div>
65
  </form>
1
  <form class="fl-builder-settings <?php echo $form['class']; ?>" <?php echo $form['attrs']; ?>>
2
+ <div class="fl-lightbox-header">
3
+ <h1><?php echo $form['title']; ?></h1>
4
+ </div>
5
+ <?php if(count($form['tabs']) > 1) : ?>
6
+ <div class="fl-builder-settings-tabs">
7
+ <?php $i = 0; foreach($form['tabs'] as $id => $tab) : ?>
8
+ <a href="#fl-builder-settings-tab-<?php echo $id; ?>"<?php if($i == 0) echo ' class="fl-active"'; ?>><?php echo $tab['title']; ?></a>
9
+ <?php $i++; endforeach; ?>
10
+ </div>
11
+ <?php endif; ?>
12
+ <div class="fl-builder-settings-fields fl-nanoscroller">
13
+ <div class="fl-nanoscroller-content">
14
+ <?php $i = 0; foreach($form['tabs'] as $id => $tab) : // Tabs ?>
15
+ <div id="fl-builder-settings-tab-<?php echo $id; ?>" class="fl-builder-settings-tab <?php if($i == 0) echo 'fl-active'; ?>">
16
+
17
+ <?php if(isset($tab['file']) && file_exists($tab['file'])) : // Tab File ?>
18
+
19
+ <?php include $tab['file']; ?>
20
+
21
+ <?php else : ?>
22
+
23
+ <?php if(!empty($tab['description'])) : // Tab Description ?>
24
+ <p class="fl-builder-settings-tab-description"><?php echo $tab['description']; ?></p>
25
+ <?php endif; ?>
26
+
27
+ <?php foreach($tab['sections'] as $id => $section) : // Tab Sections ?>
28
+ <div id="fl-builder-settings-section-<?php echo $id; ?>" class="fl-builder-settings-section">
29
+
30
+ <?php if(isset($section['file']) && file_exists($section['file'])) : // Section File ?>
31
+
32
+ <?php include $section['file']; ?>
33
+
34
+ <?php else : ?>
35
+
36
+ <?php if(!empty($section['title'])) : // Section Title ?>
37
+ <h3 class="fl-builder-settings-title"><?php echo $section['title']; ?></h3>
38
+ <?php endif; ?>
39
+
40
+ <table class="fl-form-table">
41
+ <?php
42
+
43
+ foreach($section['fields'] as $name => $field) { // Fields
44
+ FLBuilder::render_settings_field($name, $field, $settings);
45
+ }
46
+
47
+ ?>
48
+ </table>
49
+
50
+ <?php endif; ?>
51
+
52
+ </div>
53
+ <?php endforeach; ?>
54
+
55
+ <?php endif; ?>
56
+
57
+ </div>
58
+ <?php $i++; endforeach; ?>
59
+ </div>
60
+ </div>
61
+ <div class="fl-lightbox-footer">
62
+ <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>
63
+ <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>
64
+ </div>
65
  </form>
includes/ui.php CHANGED
@@ -1,112 +1,112 @@
1
  <div class="fl-builder-bar">
2
-
3
- <?php if(get_post_type() == 'fl-builder-template') : ?>
4
-
5
- <div class="fl-builder-bar-content">
6
- <span class="fl-builder-bar-title fl-builder-bar-title-no-icon">
7
- <?php echo sprintf(__('Template: %s', 'fl-builder'), get_the_title($post_id)); ?>
8
- </span>
9
- <div class="fl-builder-bar-actions">
10
- <span class="fl-builder-save-edit-template-button fl-builder-button fl-builder-button-primary"><?php _e('Save Template', 'fl-builder'); ?></span>
11
- <span class="fl-builder-cancel-edit-template-button fl-builder-button"><?php _e('Cancel', 'fl-builder'); ?></span>
12
- <div class="fl-clear"></div>
13
- </div>
14
- <div class="fl-clear"></div>
15
- </div>
16
-
17
- <?php else : ?>
18
-
19
- <div class="fl-builder-bar-content">
20
- <?php if(stristr(home_url(), 'demo.wpbeaverbuilder.com')) : ?>
21
- <span class="fl-builder-bar-title">
22
- <img src="<?php echo FL_BUILDER_URL; ?>/img/beaver.png" />
23
- <span><?php _e('Page Builder Demo', 'fl-builder'); ?></span>
24
- </span>
25
- <?php elseif(FLBuilderModel::get_branding_icon() == '') : ?>
26
- <span class="fl-builder-bar-title fl-builder-bar-title-no-icon">
27
- <?php echo FLBuilderModel::get_branding(); ?>
28
- </span>
29
- <?php else : ?>
30
- <span class="fl-builder-bar-title">
31
- <img src="<?php echo FLBuilderModel::get_branding_icon(); ?>" />
32
- <span><?php echo FLBuilderModel::get_branding(); ?></span>
33
- </span>
34
- <?php endif; ?>
35
- <div class="fl-builder-bar-actions">
36
- <?php if ( $help_button['enabled'] ) : ?>
37
- <span class="fl-builder-help-button fl-builder-button"><i class="fa fa-question-circle"></i></span>
38
- <?php endif ?>
39
- <?php if(stristr(home_url(), 'demo.wpbeaverbuilder.com')) : ?>
40
- <span class="fl-builder-upgrade-button fl-builder-button"><?php _e('Buy Now!', 'fl-builder'); ?></span>
41
- <?php elseif(FL_BUILDER_LITE === true) : ?>
42
- <span class="fl-builder-upgrade-button fl-builder-button"><?php _e('Upgrade!', 'fl-builder'); ?></span>
43
- <?php endif; ?>
44
- <span class="fl-builder-done-button fl-builder-button fl-builder-button-primary"><?php _e('Done', 'fl-builder'); ?></span>
45
- <span class="fl-builder-tools-button fl-builder-button"><?php _e('Tools', 'fl-builder'); ?></span>
46
- <?php if(FL_BUILDER_LITE !== true && $enabled_templates != 'disabled') : ?>
47
- <span class="fl-builder-templates-button fl-builder-button"><?php _e('Templates', 'fl-builder'); ?></span>
48
- <?php endif; ?>
49
- <span class="fl-builder-add-content-button fl-builder-button"><?php _e('Add Content', 'fl-builder'); ?></span>
50
- <div class="fl-clear"></div>
51
- </div>
52
- <div class="fl-clear"></div>
53
- </div>
54
-
55
- <?php endif; ?>
56
-
57
  </div>
58
  <div class="fl-builder-panel">
59
- <div class="fl-builder-panel-actions">
60
- <i class="fl-builder-panel-close fa fa-times"></i>
61
- </div>
62
- <div class="fl-builder-panel-content-wrap fl-nanoscroller">
63
- <div class="fl-builder-panel-content fl-nanoscroller-content">
64
- <div class="fl-builder-blocks">
65
- <div id="fl-builder-blocks-rows" class="fl-builder-blocks-section">
66
- <span class="fl-builder-blocks-section-title">
67
- <?php _e('Row Layouts', 'fl-builder'); ?>
68
- <i class="fa fa-chevron-down"></i>
69
- </span>
70
- <div class="fl-builder-blocks-section-content fl-builder-rows">
71
- <span class="fl-builder-block fl-builder-block-row" data-cols="1-col"><?php _e('1 Column', 'fl-builder'); ?></span>
72
- <span class="fl-builder-block fl-builder-block-row" data-cols="2-cols"><?php _e('2 Columns', 'fl-builder'); ?></span>
73
- <span class="fl-builder-block fl-builder-block-row" data-cols="3-cols"><?php _e('3 Columns', 'fl-builder'); ?></span>
74
- <span class="fl-builder-block fl-builder-block-row" data-cols="4-cols"><?php _e('4 Columns', 'fl-builder'); ?></span>
75
- <span class="fl-builder-block fl-builder-block-row" data-cols="5-cols"><?php _e('5 Columns', 'fl-builder'); ?></span>
76
- <span class="fl-builder-block fl-builder-block-row" data-cols="6-cols"><?php _e('6 Columns', 'fl-builder'); ?></span>
77
- <span class="fl-builder-block fl-builder-block-row" data-cols="left-sidebar"><?php _e('Left Sidebar', 'fl-builder'); ?></span>
78
- <span class="fl-builder-block fl-builder-block-row" data-cols="right-sidebar"><?php _e('Right Sidebar', 'fl-builder'); ?></span>
79
- <span class="fl-builder-block fl-builder-block-row" data-cols="left-right-sidebar"><?php _e('Left &amp; Right Sidebar', 'fl-builder'); ?></span>
80
- </div>
81
- </div>
82
- <?php foreach($categories as $title => $modules) : ?>
83
- <div id="fl-builder-blocks-<?php echo FLBuilderModel::get_module_category_slug( $title ); ?>" class="fl-builder-blocks-section">
84
- <span class="fl-builder-blocks-section-title">
85
- <?php echo $title; ?>
86
- <i class="fa fa-chevron-down"></i>
87
- </span>
88
- <?php if($title == __('WordPress Widgets', 'fl-builder')) : ?>
89
- <div class="fl-builder-blocks-section-content fl-builder-widgets">
90
- <?php foreach($modules as $module) : ?>
91
- <span class="fl-builder-block fl-builder-block-module" data-type="widget" data-widget="<?php echo $module->class; ?>"><?php echo $module->name; ?></span>
92
- <?php endforeach; ?>
93
- </div>
94
- <?php else : ?>
95
- <div class="fl-builder-blocks-section-content fl-builder-modules">
96
- <?php foreach($modules as $module) : ?>
97
- <span class="fl-builder-block fl-builder-block-module" data-type="<?php echo $module->slug; ?>"><?php echo $module->name; ?></span>
98
- <?php endforeach; ?>
99
- </div>
100
- <?php endif; ?>
101
- </div>
102
- <?php endforeach; ?>
103
- </div>
104
- </div>
105
- </div>
106
  </div>
107
  <div class="fl-builder-loading"></div>
108
  <div class="fl-builder-hidden-editor">
109
- <?php wp_editor(' ', 'flhiddeneditor', array('wpautop' => true)); ?>
110
  </div>
111
  <input type="hidden" id="fl-post-id" value="<?php echo $post_id; ?>" />
112
  <input type="hidden" id="fl-admin-url" value="<?php echo admin_url(); ?>" />
1
  <div class="fl-builder-bar">
2
+
3
+ <?php if(get_post_type() == 'fl-builder-template') : ?>
4
+
5
+ <div class="fl-builder-bar-content">
6
+ <span class="fl-builder-bar-title fl-builder-bar-title-no-icon">
7
+ <?php echo sprintf(__('Template: %s', 'fl-builder'), get_the_title($post_id)); ?>
8
+ </span>
9
+ <div class="fl-builder-bar-actions">
10
+ <span class="fl-builder-save-edit-template-button fl-builder-button fl-builder-button-primary"><?php _e('Save Template', 'fl-builder'); ?></span>
11
+ <span class="fl-builder-cancel-edit-template-button fl-builder-button"><?php _e('Cancel', 'fl-builder'); ?></span>
12
+ <div class="fl-clear"></div>
13
+ </div>
14
+ <div class="fl-clear"></div>
15
+ </div>
16
+
17
+ <?php else : ?>
18
+
19
+ <div class="fl-builder-bar-content">
20
+ <?php if(stristr(home_url(), 'demo.wpbeaverbuilder.com')) : ?>
21
+ <span class="fl-builder-bar-title">
22
+ <img src="<?php echo FL_BUILDER_URL; ?>/img/beaver.png" />
23
+ <span><?php _e('Page Builder Demo', 'fl-builder'); ?></span>
24
+ </span>
25
+ <?php elseif(FLBuilderModel::get_branding_icon() == '') : ?>
26
+ <span class="fl-builder-bar-title fl-builder-bar-title-no-icon">
27
+ <?php echo FLBuilderModel::get_branding(); ?>
28
+ </span>
29
+ <?php else : ?>
30
+ <span class="fl-builder-bar-title">
31
+ <img src="<?php echo FLBuilderModel::get_branding_icon(); ?>" />
32
+ <span><?php echo FLBuilderModel::get_branding(); ?></span>
33
+ </span>
34
+ <?php endif; ?>
35
+ <div class="fl-builder-bar-actions">
36
+ <?php if ( $help_button['enabled'] ) : ?>
37
+ <span class="fl-builder-help-button fl-builder-button"><i class="fa fa-question-circle"></i></span>
38
+ <?php endif ?>
39
+ <?php if(stristr(home_url(), 'demo.wpbeaverbuilder.com')) : ?>
40
+ <span class="fl-builder-upgrade-button fl-builder-button"><?php _e('Buy Now!', 'fl-builder'); ?></span>
41
+ <?php elseif(FL_BUILDER_LITE === true) : ?>
42
+ <span class="fl-builder-upgrade-button fl-builder-button"><?php _e('Upgrade!', 'fl-builder'); ?></span>
43
+ <?php endif; ?>
44
+ <span class="fl-builder-done-button fl-builder-button fl-builder-button-primary"><?php _e('Done', 'fl-builder'); ?></span>
45
+ <span class="fl-builder-tools-button fl-builder-button"><?php _e('Tools', 'fl-builder'); ?></span>
46
+ <?php if(FL_BUILDER_LITE !== true && $enabled_templates != 'disabled') : ?>
47
+ <span class="fl-builder-templates-button fl-builder-button"><?php _e('Templates', 'fl-builder'); ?></span>
48
+ <?php endif; ?>
49
+ <span class="fl-builder-add-content-button fl-builder-button"><?php _e('Add Content', 'fl-builder'); ?></span>
50
+ <div class="fl-clear"></div>
51
+ </div>
52
+ <div class="fl-clear"></div>
53
+ </div>
54
+
55
+ <?php endif; ?>
56
+
57
  </div>
58
  <div class="fl-builder-panel">
59
+ <div class="fl-builder-panel-actions">
60
+ <i class="fl-builder-panel-close fa fa-times"></i>
61
+ </div>
62
+ <div class="fl-builder-panel-content-wrap fl-nanoscroller">
63
+ <div class="fl-builder-panel-content fl-nanoscroller-content">
64
+ <div class="fl-builder-blocks">
65
+ <div id="fl-builder-blocks-rows" class="fl-builder-blocks-section">
66
+ <span class="fl-builder-blocks-section-title">
67
+ <?php _e('Row Layouts', 'fl-builder'); ?>
68
+ <i class="fa fa-chevron-down"></i>
69
+ </span>
70
+ <div class="fl-builder-blocks-section-content fl-builder-rows">
71
+ <span class="fl-builder-block fl-builder-block-row" data-cols="1-col"><?php _e('1 Column', 'fl-builder'); ?></span>
72
+ <span class="fl-builder-block fl-builder-block-row" data-cols="2-cols"><?php _e('2 Columns', 'fl-builder'); ?></span>
73
+ <span class="fl-builder-block fl-builder-block-row" data-cols="3-cols"><?php _e('3 Columns', 'fl-builder'); ?></span>
74
+ <span class="fl-builder-block fl-builder-block-row" data-cols="4-cols"><?php _e('4 Columns', 'fl-builder'); ?></span>
75
+ <span class="fl-builder-block fl-builder-block-row" data-cols="5-cols"><?php _e('5 Columns', 'fl-builder'); ?></span>
76
+ <span class="fl-builder-block fl-builder-block-row" data-cols="6-cols"><?php _e('6 Columns', 'fl-builder'); ?></span>
77
+ <span class="fl-builder-block fl-builder-block-row" data-cols="left-sidebar"><?php _e('Left Sidebar', 'fl-builder'); ?></span>
78
+ <span class="fl-builder-block fl-builder-block-row" data-cols="right-sidebar"><?php _e('Right Sidebar', 'fl-builder'); ?></span>
79
+ <span class="fl-builder-block fl-builder-block-row" data-cols="left-right-sidebar"><?php _e('Left &amp; Right Sidebar', 'fl-builder'); ?></span>
80
+ </div>
81
+ </div>
82
+ <?php foreach($categories as $title => $modules) : ?>
83
+ <div id="fl-builder-blocks-<?php echo FLBuilderModel::get_module_category_slug( $title ); ?>" class="fl-builder-blocks-section">
84
+ <span class="fl-builder-blocks-section-title">
85
+ <?php echo $title; ?>
86
+ <i class="fa fa-chevron-down"></i>
87
+ </span>
88
+ <?php if($title == __('WordPress Widgets', 'fl-builder')) : ?>
89
+ <div class="fl-builder-blocks-section-content fl-builder-widgets">
90
+ <?php foreach($modules as $module) : ?>
91
+ <span class="fl-builder-block fl-builder-block-module" data-type="widget" data-widget="<?php echo $module->class; ?>"><?php echo $module->name; ?></span>
92
+ <?php endforeach; ?>
93
+ </div>
94
+ <?php else : ?>
95
+ <div class="fl-builder-blocks-section-content fl-builder-modules">
96
+ <?php foreach($modules as $module) : ?>
97
+ <span class="fl-builder-block fl-builder-block-module" data-type="<?php echo $module->slug; ?>"><?php echo $module->name; ?></span>
98
+ <?php endforeach; ?>
99
+ </div>
100
+ <?php endif; ?>
101
+ </div>
102
+ <?php endforeach; ?>
103
+ </div>
104
+ </div>
105
+ </div>
106
  </div>
107
  <div class="fl-builder-loading"></div>
108
  <div class="fl-builder-hidden-editor">
109
+ <?php wp_editor(' ', 'flhiddeneditor', array('wpautop' => true)); ?>
110
  </div>
111
  <input type="hidden" id="fl-post-id" value="<?php echo $post_id; ?>" />
112
  <input type="hidden" id="fl-admin-url" value="<?php echo admin_url(); ?>" />
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.5.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.5.6',
7
+ 'slug' => 'bb-plugin',
8
+ 'type' => 'plugin'
9
+ ));
10
  }
includes/updater/classes/class-fl-updater.php CHANGED
@@ -1,39 +1,54 @@
1
  <?php
2
 
3
  /**
4
- * @class FLUpdater
 
 
5
  */
6
  final class FLUpdater {
7
 
8
  /**
9
- * @property $_store_api_url
10
- * @static
11
- * @private
 
 
12
  */
13
  static private $_store_api_url = 'https://www.wpbeaverbuilder.com/';
14
 
15
  /**
16
- * @property $_updates_api_url
17
- * @static
18
- * @private
 
 
19
  */
20
  static private $_updates_api_url = 'http://updates.wpbeaverbuilder.com/';
21
 
22
  /**
23
- * @property $_products
24
- * @static
25
- * @private
 
 
26
  */
27
  static private $_products = array();
28
 
29
  /**
30
- * @property $settings
31
- * @private
 
 
 
32
  */
33
  private $settings = array();
34
 
35
  /**
36
- * @method __construct
 
 
 
 
37
  */
38
  public function __construct( $settings = array() )
39
  {
@@ -50,157 +65,184 @@ final class FLUpdater {
50
  }
51
 
52
  /**
53
- * @method update_check
 
 
 
 
54
  */
55
  public function update_check($transient)
56
  {
57
- if(empty($transient->checked)) {
58
- return $transient;
59
- }
60
-
61
- $response = FLUpdater::api_request(self::$_updates_api_url, array(
62
- 'fl-api-method' => 'update_check',
63
- 'email' => FLUpdater::get_subscription_email(),
64
- 'domain' => network_home_url(),
65
- 'product' => $this->settings['name'],
66
- 'slug' => $this->settings['slug'],
67
- 'version' => $this->settings['version']
68
- ));
69
-
70
- if(isset($response) && $response !== false && is_object($response) && !isset($response->errors)) {
71
-
72
- if($this->settings['type'] == 'plugin') {
73
-
74
- $plugin = self::get_plugin_file($this->settings['slug']);
75
- $new_ver = $response->new_version;
76
- $curr_ver = $this->settings['version'];
77
-
78
- if(version_compare($new_ver, $curr_ver, '>')) {
79
- $transient->response[$plugin] = $response;
80
- }
81
- }
82
- else if($this->settings['type'] == 'theme') {
83
-
84
- $new_ver = $response->new_version;
85
- $curr_ver = $this->settings['version'];
86
-
87
- if(version_compare($new_ver, $curr_ver, '>')) {
88
- $transient->response[$this->settings['slug']] = array(
89
- 'new_version' => $response->new_version,
90
- 'url' => $response->url,
91
- 'package' => $response->package
92
  );
93
- }
94
- }
95
- }
96
 
97
  return $transient;
98
  }
99
 
100
  /**
101
- * @method update_message
 
 
 
 
 
 
102
  */
103
  public function update_message( $plugin_data, $response )
104
  {
105
- if ( empty( $response->package ) ) {
106
- echo '<p style="padding:10px 20px; margin-top: 10px; background: #d54e21; color: #fff;">';
107
- echo __( '<strong>UPDATE UNAVAILABLE!</strong>', 'fl-builder' );
108
- echo '&nbsp;&nbsp;&nbsp;';
109
- echo __('Please subscribe to enable automatic updates for this plugin.', 'fl-builder');
110
- echo ' <a href="' . $plugin_data['PluginURI'] . '" target="_blank" style="color: #fff; text-decoration: underline;">';
111
- echo __('Subscribe Now', 'fl-builder');
112
- echo ' &raquo;</a>';
113
- echo '</p>';
114
- }
115
- }
116
 
117
  /**
118
- * @method plugin_info
 
 
 
 
 
 
119
  */
120
  public function plugin_info($false, $action, $args)
121
  {
122
  if(!isset($args->slug) || $args->slug != $this->settings['slug']) {
123
- return $false;
124
  }
125
 
126
  $response = FLUpdater::api_request(self::$_updates_api_url, array(
127
- 'fl-api-method' => 'plugin_info',
128
- 'email' => FLUpdater::get_subscription_email(),
129
- 'domain' => network_home_url(),
130
- 'product' => $this->settings['name'],
131
- 'slug' => $this->settings['slug'],
132
- 'version' => $this->settings['version']
133
- ));
134
-
135
- if(isset($response) && is_object($response) && $response !== false) {
136
- $response->name = $this->settings['name'];
137
- $response->sections = (array)$response->sections;
138
- return $response;
139
- }
140
-
141
- return $false;
142
  }
143
 
144
  /**
145
- * @method init
146
- * @static
 
 
 
147
  */
148
  static public function init()
149
  {
150
- include FL_UPDATER_DIR . 'includes/config.php';
151
 
152
- foreach($config as $path) {
153
- if(file_exists($path)) {
154
- require_once $path;
155
- }
156
- }
157
  }
158
 
159
  /**
160
- * @method add_product
161
- * @static
 
 
 
 
162
  */
163
  static public function add_product($args = array())
164
  {
165
  if(is_array($args) && isset($args['slug'])) {
166
 
167
- if($args['type'] == 'plugin') {
168
- if(file_exists(WP_CONTENT_DIR . '/plugins/' . $args['slug'])) {
169
- self::$_products[$args['name']] = $args;
170
- new FLUpdater(self::$_products[$args['name']]);
171
- }
172
- }
173
- if($args['type'] == 'theme') {
174
- if(file_exists(WP_CONTENT_DIR . '/themes/' . $args['slug'])) {
175
- self::$_products[$args['name']] = $args;
176
- new FLUpdater(self::$_products[$args['name']]);
177
- }
178
- }
179
  }
180
  }
181
 
182
  /**
183
- * @method render_form
184
- * @static
185
- */
 
 
186
  static public function render_form()
187
  {
188
  // Activate a subscription?
189
- if(isset($_POST['fl-updater-nonce'])) {
190
- if(wp_verify_nonce($_POST['fl-updater-nonce'], 'updater-nonce')) {
191
  self::save_subscription_email($_POST['email']);
192
  }
193
- }
194
 
195
- $status = self::get_subscription_status();
196
 
197
- // Include the form ui.
198
  include FL_UPDATER_DIR . 'includes/form.php';
199
  }
200
 
201
  /**
202
- * @method get_subscription_email
203
- * @static
 
 
204
  */
205
  static public function get_subscription_email()
206
  {
@@ -210,8 +252,11 @@ final class FLUpdater {
210
  }
211
 
212
  /**
213
- * @method save_subscription_email
214
- * @static
 
 
 
215
  */
216
  static public function save_subscription_email($email)
217
  {
@@ -219,83 +264,97 @@ final class FLUpdater {
219
  }
220
 
221
  /**
222
- * @method key_status
223
- * @static
 
 
224
  */
225
  static public function get_subscription_status()
226
  {
227
- $status = self::api_request(self::$_store_api_url, array(
228
- 'fl-api-method' => 'subscription_status',
229
- 'email' => FLUpdater::get_subscription_email()
230
- ));
231
 
232
- if(isset($status->active) && $status->active) {
233
- return $status;
234
- }
235
 
236
- return false;
237
  }
238
 
239
  /**
240
- * @method get_plugin_file
241
- * @static
242
- * @private
 
 
 
 
243
  */
244
  static private function get_plugin_file( $slug )
245
  {
246
- if ( 'bb-plugin' == $slug ) {
247
- $file = $slug . '/fl-builder.php';
248
- }
249
- else {
250
- $file = $slug . '/' . $slug . '.php';
251
- }
252
-
253
- return $file;
254
  }
255
 
256
  /**
257
- * @method api_request
258
- * @static
259
- * @private
 
 
 
 
 
260
  */
261
  static private function api_request($api_url = false, $args = array())
262
  {
263
  if($api_url) {
264
 
265
- $params = array();
266
 
267
- foreach($args as $key => $val) {
268
- $params[] = $key . '=' . urlencode($val);
269
- }
270
 
271
- return self::remote_get($api_url . '?' . implode('&', $params));
272
  }
273
 
274
  return false;
275
  }
276
 
277
  /**
278
- * @method remote_get
279
- * @static
280
- * @private
 
 
 
281
  */
282
  static private function remote_get($url)
283
  {
284
  $request = wp_remote_get($url);
285
 
286
  if(is_wp_error($request)) {
287
- return false;
288
  }
289
  if(wp_remote_retrieve_response_code($request) != 200) {
290
- return false;
291
- }
292
 
293
- $response = json_decode(wp_remote_retrieve_body($request));
294
 
295
  if(isset($response->error)) {
296
  return false;
297
  }
298
 
299
  return $response;
300
- }
301
  }
1
  <?php
2
 
3
  /**
4
+ * Manages remote updates for all Beaver Builder products.
5
+ *
6
+ * @since 1.0
7
  */
8
  final class FLUpdater {
9
 
10
  /**
11
+ * The API URL for the Beaver Builder store.
12
+ *
13
+ * @since 1.0
14
+ * @access private
15
+ * @var string $_store_api_url
16
  */
17
  static private $_store_api_url = 'https://www.wpbeaverbuilder.com/';
18
 
19
  /**
20
+ * The API URL for the Beaver Builder update server.
21
+ *
22
+ * @since 1.0
23
+ * @access private
24
+ * @var string $_updates_api_url
25
  */
26
  static private $_updates_api_url = 'http://updates.wpbeaverbuilder.com/';
27
 
28
  /**
29
+ * An internal array of data for each product.
30
+ *
31
+ * @since 1.0
32
+ * @access private
33
+ * @var array $_products
34
  */
35
  static private $_products = array();
36
 
37
  /**
38
+ * An internal array of settings for the updater instance.
39
+ *
40
+ * @since 1.0
41
+ * @access private
42
+ * @var array $settings
43
  */
44
  private $settings = array();
45
 
46
  /**
47
+ * Updater constructor method.
48
+ *
49
+ * @since 1.0
50
+ * @param array $settings An array of settings for this instance.
51
+ * @return void
52
  */
53
  public function __construct( $settings = array() )
54
  {
65
  }
66
 
67
  /**
68
+ * Checks to see if an update is available for the current product.
69
+ *
70
+ * @since 1.0
71
+ * @param object $transient A WordPress transient object with update data.
72
+ * @return object
73
  */
74
  public function update_check($transient)
75
  {
76
+ if(empty($transient->checked)) {
77
+ return $transient;
78
+ }
79
+
80
+ $response = FLUpdater::api_request(self::$_updates_api_url, array(
81
+ 'fl-api-method' => 'update_check',
82
+ 'email' => FLUpdater::get_subscription_email(),
83
+ 'domain' => network_home_url(),
84
+ 'product' => $this->settings['name'],
85
+ 'slug' => $this->settings['slug'],
86
+ 'version' => $this->settings['version']
87
+ ));
88
+
89
+ if(isset($response) && $response !== false && is_object($response) && !isset($response->errors)) {
90
+
91
+ if($this->settings['type'] == 'plugin') {
92
+
93
+ $plugin = self::get_plugin_file($this->settings['slug']);
94
+ $new_ver = $response->new_version;
95
+ $curr_ver = $this->settings['version'];
96
+
97
+ if(version_compare($new_ver, $curr_ver, '>')) {
98
+ $transient->response[$plugin] = $response;
99
+ }
100
+ }
101
+ else if($this->settings['type'] == 'theme') {
102
+
103
+ $new_ver = $response->new_version;
104
+ $curr_ver = $this->settings['version'];
105
+
106
+ if(version_compare($new_ver, $curr_ver, '>')) {
107
+ $transient->response[$this->settings['slug']] = array(
108
+ 'new_version' => $response->new_version,
109
+ 'url' => $response->url,
110
+ 'package' => $response->package
111
  );
112
+ }
113
+ }
114
+ }
115
 
116
  return $transient;
117
  }
118
 
119
  /**
120
+ * Shows an update message on the plugins page if an update
121
+ * is available but there is no active subscription.
122
+ *
123
+ * @since 1.0
124
+ * @param array $plugin_data An array of data for this plugin.
125
+ * @param object $response An object with update data for this plugin.
126
+ * @return void
127
  */
128
  public function update_message( $plugin_data, $response )
129
  {
130
+ if ( empty( $response->package ) ) {
131
+ echo '<p style="padding:10px 20px; margin-top: 10px; background: #d54e21; color: #fff;">';
132
+ echo __( '<strong>UPDATE UNAVAILABLE!</strong>', 'fl-builder' );
133
+ echo '&nbsp;&nbsp;&nbsp;';
134
+ echo __('Please subscribe to enable automatic updates for this plugin.', 'fl-builder');
135
+ echo ' <a href="' . $plugin_data['PluginURI'] . '" target="_blank" style="color: #fff; text-decoration: underline;">';
136
+ echo __('Subscribe Now', 'fl-builder');
137
+ echo ' &raquo;</a>';
138
+ echo '</p>';
139
+ }
140
+ }
141
 
142
  /**
143
+ * Retrives the data for the plugin info lightbox.
144
+ *
145
+ * @since 1.0
146
+ * @param bool $false
147
+ * @param string $action
148
+ * @param object $args
149
+ * @return object|bool
150
  */
151
  public function plugin_info($false, $action, $args)
152
  {
153
  if(!isset($args->slug) || $args->slug != $this->settings['slug']) {
154
+ return $false;
155
  }
156
 
157
  $response = FLUpdater::api_request(self::$_updates_api_url, array(
158
+ 'fl-api-method' => 'plugin_info',
159
+ 'email' => FLUpdater::get_subscription_email(),
160
+ 'domain' => network_home_url(),
161
+ 'product' => $this->settings['name'],
162
+ 'slug' => $this->settings['slug'],
163
+ 'version' => $this->settings['version']
164
+ ));
165
+
166
+ if(isset($response) && is_object($response) && $response !== false) {
167
+ $response->name = $this->settings['name'];
168
+ $response->sections = (array)$response->sections;
169
+ return $response;
170
+ }
171
+
172
+ return $false;
173
  }
174
 
175
  /**
176
+ * Static method for initializing an instance of the updater
177
+ * for each active product.
178
+ *
179
+ * @since 1.0
180
+ * @return void
181
  */
182
  static public function init()
183
  {
184
+ include FL_UPDATER_DIR . 'includes/config.php';
185
 
186
+ foreach($config as $path) {
187
+ if(file_exists($path)) {
188
+ require_once $path;
189
+ }
190
+ }
191
  }
192
 
193
  /**
194
+ * Static method for adding a product to the updater and
195
+ * creating the new instance.
196
+ *
197
+ * @since 1.0
198
+ * @param array $args An array of settings for the product.
199
+ * @return void
200
  */
201
  static public function add_product($args = array())
202
  {
203
  if(is_array($args) && isset($args['slug'])) {
204
 
205
+ if($args['type'] == 'plugin') {
206
+ if(file_exists(WP_CONTENT_DIR . '/plugins/' . $args['slug'])) {
207
+ self::$_products[$args['name']] = $args;
208
+ new FLUpdater(self::$_products[$args['name']]);
209
+ }
210
+ }
211
+ if($args['type'] == 'theme') {
212
+ if(file_exists(WP_CONTENT_DIR . '/themes/' . $args['slug'])) {
213
+ self::$_products[$args['name']] = $args;
214
+ new FLUpdater(self::$_products[$args['name']]);
215
+ }
216
+ }
217
  }
218
  }
219
 
220
  /**
221
+ * Static method for rendering the license form.
222
+ *
223
+ * @since 1.0
224
+ * @return void
225
+ */
226
  static public function render_form()
227
  {
228
  // Activate a subscription?
229
+ if(isset($_POST['fl-updater-nonce'])) {
230
+ if(wp_verify_nonce($_POST['fl-updater-nonce'], 'updater-nonce')) {
231
  self::save_subscription_email($_POST['email']);
232
  }
233
+ }
234
 
235
+ $status = self::get_subscription_status();
236
 
237
+ // Include the form ui.
238
  include FL_UPDATER_DIR . 'includes/form.php';
239
  }
240
 
241
  /**
242
+ * Static method for getting the subscription email or license key.
243
+ *
244
+ * @since 1.0
245
+ * @return string
246
  */
247
  static public function get_subscription_email()
248
  {
252
  }
253
 
254
  /**
255
+ * Static method for updating the subscription email.
256
+ *
257
+ * @since 1.0
258
+ * @param string $email The new email address or license key.
259
+ * @return void
260
  */
261
  static public function save_subscription_email($email)
262
  {
264
  }
265
 
266
  /**
267
+ * Static method for retrieving the subscription status.
268
+ *
269
+ * @since 1.0
270
+ * @return bool
271
  */
272
  static public function get_subscription_status()
273
  {
274
+ $status = self::api_request(self::$_store_api_url, array(
275
+ 'fl-api-method' => 'subscription_status',
276
+ 'email' => FLUpdater::get_subscription_email()
277
+ ));
278
 
279
+ if(isset($status->active) && $status->active) {
280
+ return $status;
281
+ }
282
 
283
+ return false;
284
  }
285
 
286
  /**
287
+ * Static method for retrieving the plugin file path for a
288
+ * product relative to the plugins directory.
289
+ *
290
+ * @since 1.0
291
+ * @access private
292
+ * @param string $slug The product slug.
293
+ * @return string
294
  */
295
  static private function get_plugin_file( $slug )
296
  {
297
+ if ( 'bb-plugin' == $slug ) {
298
+ $file = $slug . '/fl-builder.php';
299
+ }
300
+ else {
301
+ $file = $slug . '/' . $slug . '.php';
302
+ }
303
+
304
+ return $file;
305
  }
306
 
307
  /**
308
+ * Static method for sending a request to the store
309
+ * or update API.
310
+ *
311
+ * @since 1.0
312
+ * @access private
313
+ * @param string $api_url The API URL to use.
314
+ * @param array $args An array of args to send along with the request.
315
+ * @return mixed The response or false if there is an error.
316
  */
317
  static private function api_request($api_url = false, $args = array())
318
  {
319
  if($api_url) {
320
 
321
+ $params = array();
322
 
323
+ foreach($args as $key => $val) {
324
+ $params[] = $key . '=' . urlencode($val);
325
+ }
326
 
327
+ return self::remote_get($api_url . '?' . implode('&', $params));
328
  }
329
 
330
  return false;
331
  }
332
 
333
  /**
334
+ * Get a remote response.
335
+ *
336
+ * @since 1.0
337
+ * @access private
338
+ * @param string $url The URL to get.
339
+ * @return mixed The response or false if there is an error.
340
  */
341
  static private function remote_get($url)
342
  {
343
  $request = wp_remote_get($url);
344
 
345
  if(is_wp_error($request)) {
346
+ return false;
347
  }
348
  if(wp_remote_retrieve_response_code($request) != 200) {
349
+ return false;
350
+ }
351
 
352
+ $response = json_decode(wp_remote_retrieve_body($request));
353
 
354
  if(isset($response->error)) {
355
  return false;
356
  }
357
 
358
  return $response;
359
+ }
360
  }
includes/updater/includes/config.php CHANGED
@@ -1,8 +1,8 @@
1
  <?php
2
 
3
  $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
  );
1
  <?php
2
 
3
  $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
  );
includes/updater/includes/form.php CHANGED
@@ -1,44 +1,44 @@
1
  <div class="wrap">
2
 
3
- <?php if(!$status) : ?>
4
- <p style="padding:10px 20px; background: #d54e21; color: #fff;">
5
- <?php _e('UPDATES UNAVAILABLE! Please subscribe or enter your licence key below to enable automatic updates.', 'fl-builder'); ?>
6
- &nbsp;<a style="color: #fff;" href="<?php echo FLBuilderModel::get_upgrade_url( array( 'utm_source' => 'external', 'utm_medium' => 'builder', 'utm_campaign' => 'settings-page' ) ); ?>" target="_blank"><?php _e('Subscribe Now', 'fl-builder'); ?> &raquo;</a>
7
- </p>
8
- <?php endif; ?>
9
 
10
- <h3 class="fl-settings-form-header">
11
- <?php _e('Updates &amp; Support Subscription', 'fl-builder'); ?>
12
- <span> &mdash; </span>
13
  <?php if($status) : ?>
14
  <i style="color:#3cb341;"><?php _e('Active!', 'fl-builder'); ?></i>
15
  <?php else : ?>
16
  <i style="color:#ae5842;"><?php _e('Not Active!', 'fl-builder'); ?></i>
17
  <?php endif; ?>
18
- </h3>
19
 
20
- <?php if(isset($_POST['fl-updater-nonce'])) : ?>
21
- <div class="updated">
22
- <p><?php _e('Email address saved!', 'fl-builder'); ?></p>
23
- </div>
24
- <?php endif; ?>
25
 
26
  <p>
27
  <?php echo sprintf( __( 'Enter your <a%s>licence key</a> to enable remote updates and support.', 'fl-builder' ), ' href="https://www.wpbeaverbuilder.com/my-account/?utm_source=external&utm_medium=builder&utm_campaign=settings-page" target="_blank"' ) ?>
28
  </p>
29
  <?php if(is_multisite()) : ?>
30
- <p>
31
- <strong><?php _e( 'NOTE:', 'fl-builder' ); ?></strong> <?php _e('This applies to all sites on the network.', 'fl-builder'); ?>
32
- </p>
33
- <?php endif; ?>
34
- <form action="" method="post">
35
 
36
  <input type="password" name="email" value="<?php echo self::get_subscription_email(); ?>" class="regular-text" />
37
 
38
- <p class="submit">
39
  <input type="submit" name="submit" class="button button-primary" value="<?php esc_attr_e( 'Save Subscription Settings', 'fl-builder' ); ?>">
40
  <?php wp_nonce_field('updater-nonce', 'fl-updater-nonce'); ?>
41
- </p>
42
- </form>
43
 
44
  </div>
1
  <div class="wrap">
2
 
3
+ <?php if(!$status) : ?>
4
+ <p style="padding:10px 20px; background: #d54e21; color: #fff;">
5
+ <?php _e('UPDATES UNAVAILABLE! Please subscribe or enter your licence key below to enable automatic updates.', 'fl-builder'); ?>
6
+ &nbsp;<a style="color: #fff;" href="<?php echo FLBuilderModel::get_upgrade_url( array( 'utm_source' => 'external', 'utm_medium' => 'builder', 'utm_campaign' => 'settings-page' ) ); ?>" target="_blank"><?php _e('Subscribe Now', 'fl-builder'); ?> &raquo;</a>
7
+ </p>
8
+ <?php endif; ?>
9
 
10
+ <h3 class="fl-settings-form-header">
11
+ <?php _e('Updates &amp; Support Subscription', 'fl-builder'); ?>
12
+ <span> &mdash; </span>
13
  <?php if($status) : ?>
14
  <i style="color:#3cb341;"><?php _e('Active!', 'fl-builder'); ?></i>
15
  <?php else : ?>
16
  <i style="color:#ae5842;"><?php _e('Not Active!', 'fl-builder'); ?></i>
17
  <?php endif; ?>
18
+ </h3>
19
 
20
+ <?php if(isset($_POST['fl-updater-nonce'])) : ?>
21
+ <div class="updated">
22
+ <p><?php _e('Email address saved!', 'fl-builder'); ?></p>
23
+ </div>
24
+ <?php endif; ?>
25
 
26
  <p>
27
  <?php echo sprintf( __( 'Enter your <a%s>licence key</a> to enable remote updates and support.', 'fl-builder' ), ' href="https://www.wpbeaverbuilder.com/my-account/?utm_source=external&utm_medium=builder&utm_campaign=settings-page" target="_blank"' ) ?>
28
  </p>
29
  <?php if(is_multisite()) : ?>
30
+ <p>
31
+ <strong><?php _e( 'NOTE:', 'fl-builder' ); ?></strong> <?php _e('This applies to all sites on the network.', 'fl-builder'); ?>
32
+ </p>
33
+ <?php endif; ?>
34
+ <form action="" method="post">
35
 
36
  <input type="password" name="email" value="<?php echo self::get_subscription_email(); ?>" class="regular-text" />
37
 
38
+ <p class="submit">
39
  <input type="submit" name="submit" class="button button-primary" value="<?php esc_attr_e( 'Save Subscription Settings', 'fl-builder' ); ?>">
40
  <?php wp_nonce_field('updater-nonce', 'fl-updater-nonce'); ?>
41
+ </p>
42
+ </form>
43
 
44
  </div>
includes/user-template-settings.php CHANGED
@@ -1,22 +1,22 @@
1
  <?php
2
 
3
  FLBuilder::register_settings_form('user_template', array(
4
- 'title' => __('Save Template', 'fl-builder'),
5
- 'tabs' => array(
6
- 'general' => array(
7
- 'title' => __('General', 'fl-builder'),
8
- 'description' => __('Save the current layout as a template that can be reused under <strong>Templates &rarr; Your Templates</strong>.', 'fl-builder'),
9
- 'sections' => array(
10
- 'general' => array(
11
- 'title' => '',
12
- 'fields' => array(
13
- 'name' => array(
14
- 'type' => 'text',
15
- 'label' => _x( 'Name', 'Template name.', 'fl-builder' )
16
- )
17
- )
18
- )
19
- )
20
- )
21
- )
22
  ));
1
  <?php
2
 
3
  FLBuilder::register_settings_form('user_template', array(
4
+ 'title' => __('Save Template', 'fl-builder'),
5
+ 'tabs' => array(
6
+ 'general' => array(
7
+ 'title' => __('General', 'fl-builder'),
8
+ 'description' => __('Save the current layout as a template that can be reused under <strong>Templates &rarr; Your Templates</strong>.', 'fl-builder'),
9
+ 'sections' => array(
10
+ 'general' => array(
11
+ 'title' => '',
12
+ 'fields' => array(
13
+ 'name' => array(
14
+ 'type' => 'text',
15
+ 'label' => _x( 'Name', 'Template name.', 'fl-builder' )
16
+ )
17
+ )
18
+ )
19
+ )
20
+ )
21
+ )
22
  ));
includes/vendor/sendinblue/Mailin.php ADDED
@@ -0,0 +1,324 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Mailin REST client
5
+ */
6
+ class Mailin
7
+ {
8
+ public $api_key;
9
+ public $base_url;
10
+ public $curl_opts = array();
11
+ public function __construct($base_url,$api_key)
12
+ {
13
+ if(!function_exists('curl_init'))
14
+ {
15
+ throw new Exception('Mailin requires CURL module');
16
+ }
17
+ $this->base_url = $base_url;
18
+ $this->api_key = $api_key;
19
+ }
20
+ /**
21
+ * Do CURL request with authorization
22
+ */
23
+ private function do_request($resource,$method,$input)
24
+ {
25
+ $called_url = $this->base_url."/".$resource;
26
+ $ch = curl_init($called_url);
27
+ $auth_header = 'api-key:'.$this->api_key;
28
+ $content_header = "Content-Type:application/json";
29
+ if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
30
+ // Windows only over-ride
31
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
32
+ }
33
+ curl_setopt($ch, CURLOPT_HTTPHEADER, array($auth_header,$content_header));
34
+ curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
35
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
36
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
37
+ curl_setopt($ch, CURLOPT_HEADER, 0);
38
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $input);
39
+ $data = curl_exec($ch);
40
+ if(curl_errno($ch))
41
+ {
42
+ echo 'Curl error: ' . curl_error($ch). '\n';
43
+ }
44
+ curl_close($ch);
45
+ return json_decode($data,true);
46
+ }
47
+ public function get($resource,$input)
48
+ {
49
+ return $this->do_request($resource,"GET",$input);
50
+ }
51
+ public function put($resource,$input)
52
+ {
53
+ return $this->do_request($resource,"PUT",$input);
54
+ }
55
+ public function post($resource,$input)
56
+ {
57
+ return $this->do_request($resource,"POST",$input);
58
+ }
59
+ public function delete($resource,$input)
60
+ {
61
+ return $this->do_request($resource,"DELETE",$input);
62
+ }
63
+ public function get_account()
64
+ {
65
+ return $this->get("account","");
66
+ }
67
+ public function get_smtp_details()
68
+ {
69
+ return $this->get("account/smtpdetail","");
70
+ }
71
+ public function create_child_account($email,$password,$company_org,$first_name,$last_name,$credits,$associate_ip)
72
+ {
73
+ return $this->post("account",json_encode(array("child_email"=>$email,"password"=>$password,"company_org"=>$company_org,"first_name"=>$first_name,"last_name"=>$last_name,"credits"=>$credits,"associate_ip"=>$associate_ip)));
74
+ }
75
+ public function update_child_account($child_authkey,$company_org,$first_name,$last_name,$password,$associate_ip,$disassociate_ip)
76
+ {
77
+ return $this->put("account",json_encode(array("auth_key"=>$child_authkey,"company_org"=>$company_org,"first_name"=>$first_name,"last_name"=>$last_name,"password"=>$password,"associate_ip"=>$associate_ip,"disassociate_ip"=>$disassociate_ip)));
78
+ }
79
+ public function delete_child_account($child_authkey)
80
+ {
81
+ return $this->delete("account/".$child_authkey,"");
82
+ }
83
+ public function get_reseller_child($child_authkey)
84
+ {
85
+ return $this->post("account/getchildv2",json_encode(array("auth_key"=>$child_authkey)));
86
+ }
87
+ public function add_remove_child_credits($child_authkey,$add_credits,$remove_credits)
88
+ {
89
+ return $this->post("account/addrmvcredit",json_encode(array("auth_key"=>$child_authkey,"add_credit"=>$add_credits,"rmv_credit"=>$remove_credits)));
90
+ }
91
+ public function send_sms($to,$from,$text,$web_url,$tag,$type)
92
+ {
93
+ return $this->post("sms",json_encode(array("text"=>$text,"tag"=>$tag,"web_url"=>$web_url,"from"=>$from,"to"=>$to,"type"=>$type)));
94
+ }
95
+ public function create_sms_campaign($camp_name,$sender,$content,$bat_sent,$listids,$exclude_list,$scheduled_date)
96
+ {
97
+ return $this->post("sms",json_encode(array("name"=>$camp_name,"sender"=>$sender,"content"=>$content,"bat"=>$bat_sent,"listid"=>$listids,"exclude_list"=>$exclude_list, "scheduled_date"=>$scheduled_date)));
98
+ }
99
+ public function update_sms_campaign($id,$camp_name,$sender,$content,$bat_sent,$listids,$exclude_list,$scheduled_date)
100
+ {
101
+ return $this->put("sms/".$id,json_encode(array("name"=>$camp_name,"sender"=>$sender,"content"=>$content,"bat"=>$bat_sent,"listid"=>$listids,"exclude_list"=>$exclude_list, "scheduled_date"=>$scheduled_date)));
102
+ }
103
+ public function send_bat_sms($campid,$mobilephone)
104
+ {
105
+ return $this->get("sms/".$campid,json_encode(array("to"=>$mobilephone)));
106
+ }
107
+ public function get_campaigns_v2($type,$status,$page,$page_limit)
108
+ {
109
+ return $this->get("campaign/detailsv2",json_encode(array("type"=>$type,"status"=>$status,"page"=>$page,"page_limit"=>$page_limit)));
110
+ }
111
+ public function get_campaign_v2($id)
112
+ {
113
+ return $this->get("campaign/".$id."/detailsv2","");
114
+ }
115
+ public function create_campaign($category,$from_name,$name,$bat_sent,$html_content,$html_url,$listid,$scheduled_date,$subject,$from_email,$reply_to,$to_field,$exclude_list,$attachmentUrl,$inline_image)
116
+ {
117
+ return $this->post("campaign",json_encode(array("category"=>$category,"from_name"=>$from_name,"name"=>$name,"bat"=>$bat_sent,"html_content"=>$html_content,"html_url"=>$html_url,"listid"=>$listid,"scheduled_date"=>$scheduled_date,"subject"=>$subject,"from_email"=>$from_email,"reply_to"=>$reply_to,"to_field"=>$to_field,"exclude_list"=>$exclude_list,"attachment_url"=>$attachmentUrl,"inline_image"=>$inline_image)));
118
+ }
119
+ public function delete_campaign($id)
120
+ {
121
+ return $this->delete("campaign/".$id,"");
122
+ }
123
+ public function update_campaign($id,$category,$from_name,$name,$bat_sent,$html_content,$html_url,$listid,$scheduled_date,$subject,$from_email,$reply_to,$to_field,$exclude_list,$attachmentUrl,$inline_image)
124
+ {
125
+ return $this->put("campaign/".$id,json_encode(array("category"=>$category,"from_name"=>$from_name,"name"=>$name,"bat"=>$bat_sent,"html_content"=>$html_content,"html_url"=>$html_url,"listid"=>$listid,"scheduled_date"=>$scheduled_date,"subject"=>$subject,"from_email"=>$from_email,"reply_to"=>$reply_to,"to_field"=>$to_field,"exclude_list"=>$exclude_list,"attachment_url"=>$attachmentUrl,"inline_image"=>$inline_image)));
126
+ }
127
+ public function campaign_report_email($id,$lang,$email_subject,$email_to,$email_content_type,$email_bcc,$email_cc,$email_body)
128
+ {
129
+ return $this->post("campaign/".$id."/report",json_encode(array("lang"=>$lang,"email_subject"=>$email_subject,"email_to"=>$email_to,"email_content_type"=>$email_content_type,"email_bcc"=>$email_bcc,"email_cc"=>$email_cc,"email_body"=>$email_body)));
130
+ }
131
+ public function campaign_recipients_export($id,$notify_url,$type)
132
+ {
133
+ return $this->post("campaign/".$id."/recipients",json_encode(array("notify_url"=>$notify_url,"type"=>$type)));
134
+ }
135
+ public function send_bat_email($campid,$email_to)
136
+ {
137
+ return $this->post("campaign/".$campid."/test",json_encode(array("emails"=>$email_to)));
138
+ }
139
+ public function create_trigger_campaign($category,$from_name,$name,$bat_sent,$html_content,$html_url,$listid,$scheduled_date,$subject,$from_email,$reply_to,$to_field,$exclude_list,$recurring,$attachmentUrl,$inline_image)
140
+ {
141
+ return $this->post("campaign",json_encode(array("category"=>$category,"from_name"=>$from_name,"trigger_name"=>$name,"bat"=>$bat_sent,"html_content"=>$html_content,"html_url"=>$html_url,"listid"=>$listid,"scheduled_date"=>$scheduled_date,"subject"=>$subject,"from_email"=>$from_email,"reply_to"=>$reply_to,"to_field"=>$to_field,"exclude_list"=>$exclude_list,"recurring"=>$recurring,"attachment_url"=>$attachmentUrl,"inline_image"=>$inline_image)));
142
+ }
143
+ public function update_trigger_campaign($id,$category,$from_name,$name,$bat_sent,$html_content,$html_url,$listid,$scheduled_date,$subject,$from_email,$reply_to,$to_field,$exclude_list,$recurring,$attachmentUrl,$inline_image)
144
+ {
145
+ return $this->put("campaign/".$id,json_encode(array("category"=>$category,"from_name"=>$from_name,"trigger_name"=>$name,"bat"=>$bat_sent,"html_content"=>$html_content,"html_url"=>$html_url,"listid"=>$listid,"scheduled_date"=>$scheduled_date,"subject"=>$subject,"from_email"=>$from_email,"reply_to"=>$reply_to,"to_field"=>$to_field,"exclude_list"=>$exclude_list,"recurring"=>$recurring,"attachment_url"=>$attachmentUrl,"inline_image"=>$inline_image)));
146
+ }
147
+ public function share_campaign($campaign_ids)
148
+ {
149
+ return $this->post("campaign/sharelinkv2",json_encode(array("camp_ids"=>$campaign_ids)));
150
+ }
151
+ public function update_campaign_status($id,$status)
152
+ {
153
+ return $this->put("campaign/".$id."/updatecampstatus",json_encode(array("status"=>$status)));
154
+ }
155
+ public function get_processes($page,$page_limit)
156
+ {
157
+ return $this->get("process",json_encode(array("page"=>$page,"page_limit"=>$page_limit)));
158
+ }
159
+ public function get_process($id)
160
+ {
161
+ return $this->get("process/".$id,"");
162
+ }
163
+ public function get_lists($page,$page_limit)
164
+ {
165
+ return $this->get("list",json_encode(array("page"=>$page,"page_limit"=>$page_limit)));
166
+ }
167
+ public function get_list($id)
168
+ {
169
+ return $this->get("list/".$id,"");
170
+ }
171
+ public function create_list($list_name,$list_parent)
172
+ {
173
+ return $this->post("lis