WordPress Page Builder – Beaver Builder - Version 2.6.0.3

Version Description

Download this release

Release Info

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

Code changes from version 2.5.5.5 to 2.6.0.3

Files changed (38) hide show
  1. changelog.txt +107 -3
  2. classes/class-fl-builder-admin-advanced.php +300 -0
  3. classes/class-fl-builder-admin-posts.php +5 -2
  4. classes/class-fl-builder-admin-settings.php +66 -9
  5. classes/class-fl-builder-art.php +130 -9
  6. classes/class-fl-builder-color.php +4 -1
  7. classes/class-fl-builder-compatibility.php +43 -2
  8. classes/class-fl-builder-css.php +11 -9
  9. classes/class-fl-builder-debug.php +18 -2
  10. classes/class-fl-builder-font-awesome.php +0 -1
  11. classes/class-fl-builder-fonts.php +3 -1
  12. classes/class-fl-builder-global-import-export.php +108 -0
  13. classes/class-fl-builder-loader.php +3 -1
  14. classes/class-fl-builder-loop.php +104 -70
  15. classes/class-fl-builder-model.php +238 -22
  16. classes/class-fl-builder-module.php +13 -0
  17. classes/class-fl-builder-service-mailjet.php +72 -39
  18. classes/class-fl-builder-settings-compat-helper.php +1 -1
  19. classes/class-fl-builder-settings-compat.php +6 -0
  20. classes/class-fl-builder-ui-settings-forms.php +2 -2
  21. classes/class-fl-builder-user-settings.php +50 -5
  22. classes/class-fl-builder-utils.php +35 -1
  23. classes/class-fl-builder.php +212 -69
  24. css/build/builder.bundle.css +65 -4
  25. css/build/builder.bundle.min.css +1 -1
  26. css/fl-builder-admin-settings.css +120 -0
  27. css/fl-builder-layout-large.css +32 -0
  28. css/fl-builder-layout-medium.css +12 -1
  29. css/fl-builder-layout-responsive.css +22 -92
  30. css/fl-builder-layout.css +3 -0
  31. css/fl-builder-ui-skin-dark.css +18 -7
  32. css/fl-builder.css +289 -187
  33. css/fl-builder.min.css +1 -1
  34. css/fl-color-picker.css +0 -1
  35. css/fl-lightbox.css +2 -2
  36. css/simple-notify.min.css +1 -0
  37. data/layout-05-Maintenance-lite.dat +0 -1
  38. data/{layout-37-About-lite.dat → layout-36-About-lite.dat} +1 -1
changelog.txt CHANGED
@@ -1,5 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  <h4>2.5.5.5 - 09/06/2022</h4>
2
- <p>strong>Hot Fix</strong></p>
3
  <ul>
4
  <li>Fix JS error with Photo module captions when new lines are used in the caption</li>
5
  <li>Add new filter <code>fl_photocaptionregex</code> so users can adjust the regex for allowed characters in captions when displayed in the lightbox</li>
@@ -7,7 +111,7 @@
7
  </ul>
8
 
9
  <h4>2.5.5.4 - 08/23/2022</h4>
10
- <p>strong>Hot Fix</strong></p>
11
  <ul>
12
  <li>Gallery Module: Fix caption now showing with the below photo position</li>
13
  <li>Fix live preview not working with Row Shapes height</li>
@@ -67,7 +171,7 @@
67
  <li>Video Module: Fix error when embedding a Facebook video and using the lightbox</li>
68
  </ul>
69
 
70
- <h4>2.5.4.3 - 05/25/2022</h4>
71
  <p><strong>Hot Fix</strong></p>
72
  <ul>
73
  <li>Fix alignment issue with the launch Beaver Builder box in WP Admin when using WordPress 6.0</li>
1
+ <h4>2.6.0.3 - 10/19/2022</h4>
2
+ <p><strong>Hot Fix</strong></p>
3
+ <ul>
4
+ <li>Fix row margin and padding being incorrect in some cases when upgrading from 2.5 to 2.6</li>
5
+ <li>Fix filtering being missing from Accordion and Tab modules when displaying dynamic content</li>
6
+ <li>Number Counter: Fix separator missing and remove separate number size field that is no longer needed or used</li>
7
+ <li>Button Module: Fix custom width not working if using a gradient background</li>
8
+ <li>Fix slashes being stripped from captions</li>
9
+ </ul>
10
+
11
+ <h4>2.6.0.2 - 09/29/2022</h4>
12
+ <p><strong>Hot Fix</strong></p>
13
+ <ul>
14
+ <li>Slideshow Module: Fix fatal error in PHP 8 if the Overlay Hide Delay settings is empty</li>
15
+ <li>Subscribe Form Module: Fix fatal error in PHP 8 if settings are not arrays & fix CSS error if input gap is left empty</li>
16
+ <li>Fix system-ui fonts being removed for UI by mistake</li>
17
+ <li>Fix live preview loading spinner not being removed after preview loads</li>
18
+ <li>Posts Module: Fix Column Count being wrong for Large breakpoint on upgrade</li>
19
+ <li>Posts Module: Make sure Filters that show in content tab are only relevant to the Post Types selected</li>
20
+ <li>Fix preview CSS not clearing properly</li>
21
+ <li>Move Duplicate link action showing Admin Bar to bottom if there are other items that show up in the dropdown</li>
22
+ <li>FontAwesome compatibility: Remove notice about a possible conflict with Beaver Builder as it is no longer needed with FontAwesome 6</li>
23
+ </ul>
24
+
25
+ <h4>2.6.0.1 - 09/22/2022</h4>
26
+ <p><strong>Hot Fix</strong></p>
27
+ <ul>
28
+ <li>UI: Fix Templates dropdown showing duplicate items when set to some languages</li>
29
+ <li>TEC: Fix pagination in Post Module not showing when it should</li>
30
+ <li>Fix PHP notices when using Phone App Micro Landing Page Template</li>
31
+ <li>Fix some JS notices when moving the mouse while refreshing</li>
32
+ <li>Prevent some unneeded debug info from outputting in the browser console</li>
33
+ <li>Subscribe Module: Fix Mailjet integration if using the Mailjet plugin and update the tooltip for the API key link</li>
34
+ <li>Fix issue with saving modules with the Advanced Settings Mod Security toggle enabled</li>
35
+ <li>Fix Post Module Post Spacing not rendering 0 when List Layout is used</li>
36
+ </ul>
37
+
38
+ <h4>2.6 "Calero" - 09/13/2022</h4>
39
+ <p>Beaver Builder 2.6 is here! This is a major update and will be released as the official download on the My Account page first. Remote updates to all existing sites will begin soon.</p>
40
+
41
+ <p>Please check out the <a href="https://www.wpbeaverbuilder.com/beaver-builder-2-6" target="_blank" rel="noopener">Release Post</a> for highlights of what's new or the <a href="https://docs.wpbeaverbuilder.com/beaver-builder/about-this-release" target="_blank" rel="noopener">"About this Release"</a> doc for all of the details.</p>
42
+
43
+ <p><strong>Enhancements</strong></p>
44
+ <ul>
45
+ <li>NEW Add a new breakpoint option to Global Settings</li>
46
+ <li>NEW: 4 New Micro Landing Page templates</li>
47
+ <li>Add new tabs to BB Settings Page in WP Admin: Advanced Settings & Import/Export</li>
48
+ <li>NEW Add UI for adding row shapes in global settings</li>
49
+ <li>NEW Add search to saved item tab in content panel</li>
50
+ <li>NEW You can now use WordPress reusable blocks in Beaver Builder layouts</li>
51
+ <li>Copy and Paste Improvements: Hover over the wrench for rows and modules and the columns icon for columns to see the new copy option. Paste only appears if there is data to paste</li>
52
+ <li>Outline Panel: Add keyboard shortcuts</li>
53
+ <li>Outline Panel: collapse/expand all items and persistent storage were added so that the panel remembers what sections you have expanded and collapsed</li>
54
+ <li>Outline Panel: Will now highlight the node that is open for editing</li>
55
+ <li>When hovering over a Google Font in font selector, show a preview of the font</li>
56
+ <li>Update Icons admin page to show FontAwesome Kit deprecation notice and recommendation to use Official FontAwesome plugin</li>
57
+ <li>Add Headings to the AJAX Crash Modal</li>
58
+ <li>Display value of Label field in Advanced section of node settings in a tooltip on the node settings icon, in the Settings modal and in the hover overlay</li>
59
+ <li>Add min-width to Alert Modal Pop-up to fix display issues when translated</li>
60
+ <li>Refine the feel of the overlay and highlight features in the canvas area</li>
61
+ <li>Global margins/paddings: now use a dimension field so you can control all 4 sides separately</li>
62
+ <li>UI Dark Mode/Light Mode can now be set to Auto so it changes with your OS</li>
63
+ <li>Accordion Module: Add support to display dynamic data or to select saved items for display in the content area</li>
64
+ <li>Tabs Module: Add support to display dynamic data or to select saved items for display in the content area</li>
65
+ <li>Columns: Add aspect ratio option</li>
66
+ <li>Add Advanced Gradient BG option for buttons in the Button, Button Group, Call to Action, Callout and Content Slider modules</li>
67
+ <li>Post Module: Add option to filter by custom fields</li>
68
+ <li>Post Module: Add ability to select multiple post types</li>
69
+ <li>Post Module: Add option to show/hide author link</li>
70
+ <li>Content Slider: Add typography for slides</li>
71
+ <li>Login Form Module: Add icon options for the fields and buttons & change cursor to pointer for Remember Me checkbox</li>
72
+ <li>Pricing Table: Add icon color options for individual features</li>
73
+ <li>Pricing Table: Add typography for the Ribbon option, add color option for the Price</li>
74
+ <li>Tabs Module: Add a setting for which tab is active on load</li>
75
+ <li>Add Pressidium support to the Cache Clearing Tool</li>
76
+ <li>Debug Mode: Show values of Advanced settings in debug output</li>
77
+ </ul>
78
+
79
+ <p><strong>Bug Fixes</strong></p>
80
+ <ul>
81
+ <li>Fix Video Module select button being unclickable when Yith WooCommerce Affiliate plugin is active</li>
82
+ <li>Fix JS error with Photo module captions when new lines are used in the caption</li>
83
+ <li>Heading Module: Fixed letter spacing set to 0 was not rendering properly with the BB Theme</li>
84
+ <li>Pricing Table: Fix Button Hover Color not working if its rgba</li>
85
+ <li>Menu Module: Fix Undefined property PHP Warning</li>
86
+ <li>Fix resizing rows setting an invalid value with pixel unit and not being able to go back to the original width when resizing with drag handles</li>
87
+ <li>Fix shortcodes not working in Advanced tab class and ID fields if there are quotes used in attributes</li>
88
+ <li>Photo Module: Fix image going out of container on mobile</li>
89
+ <li>Fix <code>:empty</code> selector not working with columns</li>
90
+ <li>WooCommerce: Fix Posts module overriding margin-bottom css for post spacing</li>
91
+ <li>WooCommerce: Fix notices overlapping the content panel</li>
92
+ <li>Fix Settings modal not working if using a RTL language</li>
93
+ <li>Fix "Add menu item" displaying in menu module when it shouldn't if using one of the Header Themer layouts</li>
94
+ <li>Fix an issue where a button module is run through autop when it shouldn't be</li>
95
+ <li>Remove duplicative Row CSS</li>
96
+ <li>Fix reverse stacking not working with all container tags</li>
97
+ <li>Fix responsive editing not showing inherited values in some cases</li>
98
+ <li>Pricing Table: Fix Title color not rendering Title is highlighted</li>
99
+ <li>Pricing Table: Make sure Box Top Margin is only available when using Legacy settings</li>
100
+ <li>Pricing Table: Fix button border hover color not working</li>
101
+ <li>Pricing Table: Fix some colors not working if the Row text color is set</li>
102
+ <li>Posts Module: Fix fatal error in PHP 8 if 0 or blank value is saved for column option</li>
103
+ </ul>
104
+
105
  <h4>2.5.5.5 - 09/06/2022</h4>
106
+ <p><strong>Hot Fix</strong></p>
107
  <ul>
108
  <li>Fix JS error with Photo module captions when new lines are used in the caption</li>
109
  <li>Add new filter <code>fl_photocaptionregex</code> so users can adjust the regex for allowed characters in captions when displayed in the lightbox</li>
111
  </ul>
112
 
113
  <h4>2.5.5.4 - 08/23/2022</h4>
114
+ <p><strong>Hot Fix</strong></p>
115
  <ul>
116
  <li>Gallery Module: Fix caption now showing with the below photo position</li>
117
  <li>Fix live preview not working with Row Shapes height</li>
171
  <li>Video Module: Fix error when embedding a Facebook video and using the lightbox</li>
172
  </ul>
173
 
174
+ <h4>2.5.4.3- 05/25/2022</h4>
175
  <p><strong>Hot Fix</strong></p>
176
  <ul>
177
  <li>Fix alignment issue with the launch Beaver Builder box in WP Admin when using WordPress 6.0</li>
classes/class-fl-builder-admin-advanced.php ADDED
@@ -0,0 +1,300 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class that handles showing admin advanced options.
5
+ *
6
+ * @since 2.6
7
+ */
8
+ final class FLBuilderAdminAdvanced {
9
+
10
+ /**
11
+ * The advanced settings default groups
12
+ * @since 2.6
13
+ */
14
+ public static function get_groups() {
15
+ return array(
16
+ 'ui' => array(
17
+ 'label' => __( 'Builder UI', 'fl-builder' ),
18
+ ),
19
+ 'admin' => array(
20
+ 'label' => __( 'WP Admin', 'fl-builder' ),
21
+ ),
22
+ 'assets' => array(
23
+ 'label' => __( 'Assets', 'fl-builder' ),
24
+ ),
25
+ 'frontend' => array(
26
+ 'label' => __( 'Frontend', 'fl-builder' ),
27
+ ),
28
+ );
29
+ }
30
+
31
+ /**
32
+ * Return all advanced settings as an array
33
+ * @since 2.6
34
+ */
35
+ static public function get_settings() {
36
+ $settings = array(
37
+ 'outline_enabled' => array(
38
+ 'label' => __( 'Outline Panel', 'fl-builder' ),
39
+ 'default' => 1,
40
+ 'callback' => array( __CLASS__, 'disable_outline' ),
41
+ 'group' => 'ui',
42
+ 'link' => 'https://docs.wpbeaverbuilder.com/beaver-builder/getting-started/bb-editor-basics/outline-panel/',
43
+ ),
44
+ 'inline_editing_enabled' => array(
45
+ 'label' => __( 'Inline Editing', 'fl-builder' ),
46
+ 'default' => 1,
47
+ 'callback' => array( __CLASS__, 'disable_inline_edit' ),
48
+ 'group' => 'ui',
49
+ 'link' => 'https://docs.wpbeaverbuilder.com/beaver-builder/getting-started/bb-editor-basics/inline-editing/',
50
+ ),
51
+ 'notifications_enabled' => array(
52
+ 'label' => __( 'Notification system', 'fl-builder' ),
53
+ 'default' => 1,
54
+ 'callback' => array( __CLASS__, 'disable_notifications' ),
55
+ 'group' => 'ui',
56
+ 'description' => __( 'When disabled you will not receive alerts for new posts on the blog', 'fl-builder' ),
57
+ ),
58
+ 'lasttab_enabled' => array(
59
+ 'label' => __( 'Remember last used tab', 'fl-builder' ),
60
+ 'default' => 1,
61
+ 'callback' => array( __CLASS__, 'disable_lastused' ),
62
+ 'group' => 'ui',
63
+ 'description' => __( 'The Builder remembers the last tab used in the row/column/module settings window.', 'fl-builder' ),
64
+ ),
65
+ 'rowshapes_enabled' => array(
66
+ 'label' => __( 'Custom Row Shapes', 'fl-builder' ),
67
+ 'default' => 1,
68
+ 'callback' => array( __CLASS__, 'disable_rowshapes' ),
69
+ 'group' => 'ui',
70
+ 'description' => __( 'When enabled a custom row shapes tab will be added to the Global Settings.', 'fl-builder' ),
71
+ ),
72
+ 'limitrevisions_enabled' => array(
73
+ 'label' => __( 'Limit WP revisions for layouts', 'fl-builder' ),
74
+ 'default' => 0,
75
+ 'callback' => array( __CLASS__, 'limit_revisions' ),
76
+ 'group' => 'ui',
77
+ 'description' => __( 'WP by default does not limit the amount of revisions. This setting will limit revisions to 10 for Layouts', 'fl-builder' ),
78
+ ),
79
+ 'modsec_enabled' => array(
80
+ 'label' => __( 'Mod Security fix', 'fl-builder' ),
81
+ 'default' => 0,
82
+ 'callback' => array( __CLASS__, 'enable_modsec' ),
83
+ 'group' => 'ui',
84
+ 'link' => 'https://docs.wpbeaverbuilder.com/beaver-builder/troubleshooting/common-issues/403-forbidden-or-blocked-error/',
85
+ ),
86
+ 'sort_enabled' => array(
87
+ 'label' => __( 'Allow pages to be sortable', 'fl-builder' ),
88
+ 'default' => 1,
89
+ 'callback' => array( __CLASS__, 'disable_sorting' ),
90
+ 'group' => 'admin',
91
+ 'description' => __( 'In WP admin lists of pages, posts, and custom post types in the back end, there is a Builder link in the list of post display filters, which limits the display to items that have Builder layouts.', 'fl-builder' ),
92
+ ),
93
+ 'duplicate_enabled' => array(
94
+ 'label' => __( 'Show duplicate action links in WP Admin', 'fl-builder' ),
95
+ 'default' => 1,
96
+ 'callback' => array( __CLASS__, 'disable_duplicate' ),
97
+ 'group' => 'admin',
98
+ ),
99
+ 'duplicatemenu_enabled' => array(
100
+ 'label' => __( 'Show duplicate action link in WP Admin Bar', 'fl-builder' ),
101
+ 'default' => 1,
102
+ 'callback' => array( __CLASS__, 'disable_duplicate_menu' ),
103
+ 'group' => 'admin',
104
+ ),
105
+ 'google_enabled' => array(
106
+ 'label' => 'Google Fonts',
107
+ 'description' => __( 'When disabled no Google Fonts will be enqueued or available in style options', 'fl-builder' ),
108
+ 'default' => 1,
109
+ 'callback' => array( __CLASS__, 'disable_google' ),
110
+ 'group' => 'assets',
111
+ ),
112
+ 'awesome_enabled' => array(
113
+ 'label' => __( 'Font Awesome', 'fl-builder' ),
114
+ 'description' => __( 'When disabled Font Awesome will NOT be enqueued, even if modules require it.', 'fl-builder' ),
115
+ 'default' => 1,
116
+ 'callback' => array( __CLASS__, 'disable_awesome' ),
117
+ 'group' => 'assets',
118
+ ),
119
+ 'gd_crop_enabled' => array(
120
+ 'label' => __( 'Prefer GD for image cropping', 'fl-builder' ),
121
+ 'default' => 0,
122
+ 'callback' => array( __CLASS__, 'enable_gd_crop' ),
123
+ 'group' => 'assets',
124
+ ),
125
+ 'inline_enabled' => array(
126
+ 'label' => 'Render CSS/JS assets inline',
127
+ 'default' => 0,
128
+ 'callback' => array( __CLASS__, 'render_inline' ),
129
+ 'group' => 'frontend',
130
+ 'description' => __( 'Instead of loading Builder CSS and JavaScript as an asset file, you can render the CSS inline.', 'fl-builder' ),
131
+ 'link' => 'https://docs.wpbeaverbuilder.com/beaver-builder/developer/how-to-tips/load-css-and-javascript-inline/',
132
+ ),
133
+ 'modules_enabled' => array(
134
+ 'label' => __( 'Show advanced module usage', 'fl-builder' ),
135
+ 'default' => 0,
136
+ 'callback' => array( __CLASS__, 'modules_enabled' ),
137
+ 'group' => 'admin',
138
+ 'description' => __( 'Show detailed module usage on modules tab.', 'fl-builder' ),
139
+ 'link' => 'https://docs.wpbeaverbuilder.com/beaver-builder/developer/tutorials-guides/common-beaver-builder-plugin-filter-examples/#show-which-modules-are-in-use-in-a-website',
140
+ ),
141
+
142
+ 'small_data_enabled' => array(
143
+ 'label' => __( 'Small Data Mode', 'fl-builder' ),
144
+ 'default' => 0,
145
+ 'callback' => array( __CLASS__, 'small_data_enabled' ),
146
+ 'group' => 'ui',
147
+ 'description' => __( 'When enabled, fields that are empty/blank will not be saved to the database.', 'fl-builder' ),
148
+ ),
149
+ 'node_labels_enabled' => array(
150
+ 'label' => __( 'Node Labels', 'fl-builder' ),
151
+ 'default' => 1,
152
+ 'callback' => array( __CLASS__, 'node_labels_enabled' ),
153
+ 'group' => 'ui',
154
+ 'description' => __( 'Show custom labels for Nodes.', 'fl-builder' ),
155
+ ),
156
+ );
157
+ if ( FLBuilderModel::is_white_labeled() ) {
158
+ unset( $settings['notifications_enabled'] );
159
+ }
160
+ return $settings;
161
+ }
162
+
163
+ static private function disable_sorting() {
164
+ add_filter( 'fl_builder_admin_edit_sort_bb_enabled', '__return_false', 11 );
165
+ }
166
+ static private function disable_outline() {
167
+ add_filter( 'fl_builder_outline_panel_enabled', '__return_false', 11 );
168
+ }
169
+ static private function disable_inline_edit() {
170
+ add_filter( 'fl_inline_editing_enabled', '__return_false', 11 );
171
+ }
172
+ static private function disable_notifications() {
173
+ add_filter( 'fl_disable_notifications', '__return_true', 11 );
174
+ }
175
+ static private function disable_lastused() {
176
+ add_filter( 'fl_remember_settings_tabs_enabled', '__return_false', 11 );
177
+ }
178
+ static private function disable_duplicate() {
179
+ add_filter( 'fl_builder_duplicate_enabled', '__return_false', 11 );
180
+ }
181
+ static private function disable_duplicate_menu() {
182
+ add_filter( 'fl_builder_duplicatemenu_enabled', '__return_false', 11 );
183
+ }
184
+ static private function disable_google() {
185
+ add_filter( 'fl_builder_font_families_google', '__return_empty_array', 11 );
186
+ add_filter( 'fl_enable_google_fonts_enqueue', '__return_false', 11 );
187
+ }
188
+ static private function disable_awesome() {
189
+ if ( ! isset( $_GET['fl_builder'] ) ) {
190
+ add_action( 'wp_enqueue_scripts', function() {
191
+ wp_dequeue_style( 'font-awesome' );
192
+ wp_dequeue_style( 'font-awesome-5' );
193
+ wp_deregister_style( 'font-awesome' );
194
+ wp_deregister_style( 'font-awesome-5' );
195
+ }, 10001 );
196
+ }
197
+ }
198
+ static private function render_inline() {
199
+ add_filter( 'fl_builder_render_assets_inline', '__return_true', 1000 );
200
+ }
201
+ static private function modules_enabled() {
202
+ add_filter( 'is_module_disable_enabled', '__return_true', 11 );
203
+ }
204
+
205
+ static private function small_data_enabled() {
206
+ add_filter( 'fl_builder_enable_small_data_mode', '__return_true', 12 );
207
+ }
208
+
209
+ static private function enable_gd_crop() {
210
+ add_filter( 'wp_image_editors', function() {
211
+ return array( 'WP_Image_Editor_GD', 'WP_Image_Editor_Imagick' );
212
+ }, 100 );
213
+ }
214
+ static private function disable_rowshapes() {
215
+ add_filter( 'fl_builder_register_settings_form', function( $form, $id ) {
216
+ if ( 'global' == $id && isset( $form['tabs']['shapes'] ) ) {
217
+ unset( $form['tabs']['shapes'] );
218
+ }
219
+ return $form;
220
+ }, 11, 2 );
221
+ }
222
+
223
+ static private function limit_revisions() {
224
+ add_filter( 'wp_revisions_to_keep', function( $num, $post ) {
225
+ $enabled = get_post_meta( $post->ID, '_fl_builder_enabled', true );
226
+ if ( $enabled ) {
227
+ return 11;
228
+ }
229
+ return $num;
230
+ }, 10, 2 );
231
+ }
232
+
233
+ static private function enable_modsec() {
234
+ add_filter( 'fl_is_modsec_fix_enabled', '__return_true', 11 );
235
+ }
236
+
237
+ static private function node_labels_enabled() {
238
+ add_filter( 'fl_node_labels_disabled', '__return_true' );
239
+ }
240
+
241
+ /**
242
+ * @since 2.6
243
+ */
244
+ static public function init() {
245
+ self::register_settings();
246
+ add_action( 'after_setup_theme', __CLASS__ . '::register_user_access_settings' );
247
+ add_action( 'wp_ajax_fl_advanced_submit', array( __CLASS__, 'advanced_submit' ) );
248
+ self::init_hooks();
249
+ }
250
+
251
+ static public function advanced_submit() {
252
+ if ( isset( $_POST['action'] ) && wp_verify_nonce( $_POST['_wpnonce'], 'advanced' ) ) {
253
+ $setting = $_POST['setting'];
254
+ $value = 'true' === $_POST['value'] ? '1' : '0';
255
+ update_option( "_fl_builder_{$setting}", $value );
256
+ wp_send_json_success();
257
+ } else {
258
+ wp_send_json_error();
259
+ }
260
+ }
261
+
262
+ /**
263
+ * Register the new user level to view options
264
+ * @since 2.6
265
+ */
266
+ static public function register_user_access_settings() {
267
+ FLBuilderUserAccess::register_setting( 'fl_builder_advanced_options', array(
268
+ 'default' => array( 'administrator' ),
269
+ 'group' => __( 'Admin', 'fl-builder' ),
270
+ 'label' => __( 'Advanced Settings', 'fl-builder' ),
271
+ 'description' => __( 'The selected roles will be able to access the Advanced Settings. Note: user roles without the <code>manage_options</code> capability cannot access these settings.', 'fl-builder' ),
272
+ 'order' => '110',
273
+ ) );
274
+ }
275
+
276
+ /**
277
+ * @since 2.6
278
+ */
279
+ static private function init_hooks() {
280
+ foreach ( self::get_settings() as $key => $setting ) {
281
+ $option = get_option( "_fl_builder_{$key}", $setting['default'] );
282
+ if ( $option != $setting['default'] ) {
283
+ call_user_func( $setting['callback'] );
284
+ }
285
+ }
286
+ }
287
+
288
+ /**
289
+ * Register the new settings
290
+ * @since 2.6
291
+ */
292
+ static private function register_settings() {
293
+ foreach ( self::get_settings() as $key => $setting ) {
294
+ FLBuilderAdminSettings::register_setting( '_fl_builder_' . $key );
295
+ }
296
+ }
297
+
298
+ }
299
+
300
+ FLBuilderAdminAdvanced::init();
classes/class-fl-builder-admin-posts.php CHANGED
@@ -350,7 +350,7 @@ final class FLBuilderAdminPosts {
350
  $enabled = get_post_meta( $post->ID, '_fl_builder_enabled', true );
351
  $dot = '&nbsp;<span style="color:' . ( $enabled ? '#6bc373' : '#d9d9d9' ) . '; font-size:18px;">&bull;</span>';
352
  $actions['fl-builder'] = '<a href="' . FLBuilderModel::get_edit_url() . '">' . FLBuilderModel::get_branding() . $dot . '</a>';
353
- if ( $enabled ) {
354
  $url = add_query_arg( array(
355
  'post_type' => $post->post_type,
356
  'post_id' => $post->ID,
@@ -376,7 +376,10 @@ final class FLBuilderAdminPosts {
376
 
377
  if ( wp_verify_nonce( $nonce, 'duplicate_nonce' ) ) {
378
  $post_id = FLBuilderModel::duplicate_post( $id );
379
- $url = FLBuilderModel::get_edit_url( $post_id );
 
 
 
380
  wp_redirect( $url );
381
  exit;
382
  } else {
350
  $enabled = get_post_meta( $post->ID, '_fl_builder_enabled', true );
351
  $dot = '&nbsp;<span style="color:' . ( $enabled ? '#6bc373' : '#d9d9d9' ) . '; font-size:18px;">&bull;</span>';
352
  $actions['fl-builder'] = '<a href="' . FLBuilderModel::get_edit_url() . '">' . FLBuilderModel::get_branding() . $dot . '</a>';
353
+ if ( $enabled && true === apply_filters( 'fl_builder_duplicate_enabled', true ) ) {
354
  $url = add_query_arg( array(
355
  'post_type' => $post->post_type,
356
  'post_id' => $post->ID,
376
 
377
  if ( wp_verify_nonce( $nonce, 'duplicate_nonce' ) ) {
378
  $post_id = FLBuilderModel::duplicate_post( $id );
379
+ $url = add_query_arg( array(
380
+ 'post' => $post_id,
381
+ 'action' => 'edit',
382
+ ), admin_url( 'post.php' ) );
383
  wp_redirect( $url );
384
  exit;
385
  } else {
classes/class-fl-builder-admin-settings.php CHANGED
@@ -16,6 +16,23 @@ final class FLBuilderAdminSettings {
16
  */
17
  static public $errors = array();
18
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  /**
20
  * Initializes the admin settings.
21
  *
@@ -25,6 +42,31 @@ final class FLBuilderAdminSettings {
25
  static public function init() {
26
  add_action( 'init', __CLASS__ . '::init_hooks', 11 );
27
  add_action( 'wp_ajax_fl_welcome_submit', array( 'FLBuilderAdminSettings', 'welcome_submit' ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  }
29
 
30
  /**
@@ -91,6 +133,7 @@ final class FLBuilderAdminSettings {
91
  wp_enqueue_style( 'fl-builder-admin-settings', FL_BUILDER_URL . 'css/fl-builder-admin-settings.css', array(), FL_BUILDER_VERSION );
92
  wp_enqueue_style( 'jquery-multiselect', FL_BUILDER_URL . 'css/jquery.multiselect.css', array(), FL_BUILDER_VERSION );
93
  wp_enqueue_style( 'fl-jquery-tiptip', FL_BUILDER_URL . 'css/jquery.tiptip.css', array(), FL_BUILDER_VERSION );
 
94
 
95
  if ( FLBuilder::fa5_pro_enabled() ) {
96
  if ( '' !== get_option( '_fl_builder_kit_fa_pro' ) ) {
@@ -105,7 +148,7 @@ final class FLBuilderAdminSettings {
105
  wp_enqueue_script( 'jquery-actual', FL_BUILDER_URL . 'js/jquery.actual.min.js', array( 'jquery' ), FL_BUILDER_VERSION );
106
  wp_enqueue_script( 'jquery-multiselect', FL_BUILDER_URL . 'js/jquery.multiselect.js', array( 'jquery' ), FL_BUILDER_VERSION );
107
  wp_enqueue_script( 'fl-jquery-tiptip', FL_BUILDER_URL . 'js/jquery.tiptip.min.js', array( 'jquery' ), FL_BUILDER_VERSION, true );
108
-
109
  // Media Uploader
110
  wp_enqueue_media();
111
  }
@@ -198,46 +241,56 @@ final class FLBuilderAdminSettings {
198
  * @see fl_builder_admin_settings_nav_items
199
  */
200
  $item_data = apply_filters( 'fl_builder_admin_settings_nav_items', array(
201
- 'welcome' => array(
202
  'title' => __( 'Welcome', 'fl-builder' ),
203
  'show' => ! FLBuilderModel::is_white_labeled() && ( is_network_admin() || ! self::multisite_support() ),
204
  'priority' => 50,
205
  ),
206
- 'license' => array(
207
  'title' => __( 'License', 'fl-builder' ),
208
  'show' => ( is_network_admin() || ! self::multisite_support() ),
209
  'priority' => 100,
210
  ),
211
- 'upgrade' => array(
212
  'title' => __( 'Upgrade', 'fl-builder' ),
213
  'show' => FL_BUILDER_LITE === true,
214
  'priority' => 200,
215
  ),
216
- 'modules' => array(
217
  'title' => __( 'Modules', 'fl-builder' ),
218
  'show' => true,
219
  'priority' => 300,
220
  ),
221
- 'post-types' => array(
222
  'title' => __( 'Post Types', 'fl-builder' ),
223
  'show' => true,
224
  'priority' => 400,
225
  ),
226
- 'user-access' => array(
227
  'title' => __( 'User Access', 'fl-builder' ),
228
  'show' => true,
229
  'priority' => 500,
230
  ),
231
- 'icons' => array(
232
  'title' => __( 'Icons', 'fl-builder' ),
233
  'show' => FL_BUILDER_LITE !== true,
234
  'priority' => 600,
235
  ),
236
- 'tools' => array(
237
  'title' => __( 'Tools', 'fl-builder' ),
238
  'show' => true,
239
  'priority' => 700,
240
  ),
 
 
 
 
 
 
 
 
 
 
241
  ) );
242
 
243
  $sorted_data = array();
@@ -293,6 +346,10 @@ final class FLBuilderAdminSettings {
293
  // Tools
294
  self::render_form( 'tools' );
295
 
 
 
 
 
296
  /**
297
  * Let extensions hook into form rendering.
298
  * @see fl_builder_admin_settings_render_forms
16
  */
17
  static public $errors = array();
18
 
19
+ private static $registered_settings = array();
20
+
21
+ private static $global_settings = array(
22
+ '_fl_builder_post_types',
23
+ '_fl_builder_enabled_modules',
24
+ '_fl_builder_enabled_templates',
25
+ '_fl_builder_enabled_icons',
26
+ '_fl_builder_user_access',
27
+ '_fl_builder_enable_fa_pro',
28
+ '_fl_builder_kit_fa_pro',
29
+ '_fl_builder_cache_plugins',
30
+ '_fl_builder_branding',
31
+ '_fl_builder_branding_icon',
32
+ '_fl_builder_theme_branding',
33
+ '_fl_builder_help_button',
34
+ );
35
+
36
  /**
37
  * Initializes the admin settings.
38
  *
42
  static public function init() {
43
  add_action( 'init', __CLASS__ . '::init_hooks', 11 );
44
  add_action( 'wp_ajax_fl_welcome_submit', array( 'FLBuilderAdminSettings', 'welcome_submit' ) );
45
+ // register global settings
46
+ self::register_settings();
47
+ }
48
+
49
+ /**
50
+ * @since 2.6
51
+ */
52
+ private static function register_settings() {
53
+ foreach ( self::$global_settings as $setting ) {
54
+ self::register_setting( $setting );
55
+ }
56
+ }
57
+
58
+ /**
59
+ * @since 2.6
60
+ */
61
+ public static function register_setting( $key ) {
62
+ self::$registered_settings[] = $key;
63
+ }
64
+
65
+ /**
66
+ * @since 2.6
67
+ */
68
+ public static function registered_settings() {
69
+ return self::$registered_settings;
70
  }
71
 
72
  /**
133
  wp_enqueue_style( 'fl-builder-admin-settings', FL_BUILDER_URL . 'css/fl-builder-admin-settings.css', array(), FL_BUILDER_VERSION );
134
  wp_enqueue_style( 'jquery-multiselect', FL_BUILDER_URL . 'css/jquery.multiselect.css', array(), FL_BUILDER_VERSION );
135
  wp_enqueue_style( 'fl-jquery-tiptip', FL_BUILDER_URL . 'css/jquery.tiptip.css', array(), FL_BUILDER_VERSION );
136
+ wp_enqueue_style( 'fl-admin-notify', FL_BUILDER_URL . 'css/simple-notify.min.css', array(), FL_BUILDER_VERSION );
137
 
138
  if ( FLBuilder::fa5_pro_enabled() ) {
139
  if ( '' !== get_option( '_fl_builder_kit_fa_pro' ) ) {
148
  wp_enqueue_script( 'jquery-actual', FL_BUILDER_URL . 'js/jquery.actual.min.js', array( 'jquery' ), FL_BUILDER_VERSION );
149
  wp_enqueue_script( 'jquery-multiselect', FL_BUILDER_URL . 'js/jquery.multiselect.js', array( 'jquery' ), FL_BUILDER_VERSION );
150
  wp_enqueue_script( 'fl-jquery-tiptip', FL_BUILDER_URL . 'js/jquery.tiptip.min.js', array( 'jquery' ), FL_BUILDER_VERSION, true );
151
+ wp_enqueue_script( 'fl-admin-notify', FL_BUILDER_URL . 'js/simple-notify.min.js', array(), FL_BUILDER_VERSION );
152
  // Media Uploader
153
  wp_enqueue_media();
154
  }
241
  * @see fl_builder_admin_settings_nav_items
242
  */
243
  $item_data = apply_filters( 'fl_builder_admin_settings_nav_items', array(
244
+ 'welcome' => array(
245
  'title' => __( 'Welcome', 'fl-builder' ),
246
  'show' => ! FLBuilderModel::is_white_labeled() && ( is_network_admin() || ! self::multisite_support() ),
247
  'priority' => 50,
248
  ),
249
+ 'license' => array(
250
  'title' => __( 'License', 'fl-builder' ),
251
  'show' => ( is_network_admin() || ! self::multisite_support() ),
252
  'priority' => 100,
253
  ),
254
+ 'upgrade' => array(
255
  'title' => __( 'Upgrade', 'fl-builder' ),
256
  'show' => FL_BUILDER_LITE === true,
257
  'priority' => 200,
258
  ),
259
+ 'modules' => array(
260
  'title' => __( 'Modules', 'fl-builder' ),
261
  'show' => true,
262
  'priority' => 300,
263
  ),
264
+ 'post-types' => array(
265
  'title' => __( 'Post Types', 'fl-builder' ),
266
  'show' => true,
267
  'priority' => 400,
268
  ),
269
+ 'user-access' => array(
270
  'title' => __( 'User Access', 'fl-builder' ),
271
  'show' => true,
272
  'priority' => 500,
273
  ),
274
+ 'icons' => array(
275
  'title' => __( 'Icons', 'fl-builder' ),
276
  'show' => FL_BUILDER_LITE !== true,
277
  'priority' => 600,
278
  ),
279
+ 'tools' => array(
280
  'title' => __( 'Tools', 'fl-builder' ),
281
  'show' => true,
282
  'priority' => 700,
283
  ),
284
+ 'advanced' => array(
285
+ 'title' => __( 'Advanced', 'fl-builder' ),
286
+ 'show' => true,
287
+ 'priority' => 750,
288
+ ),
289
+ 'import-export' => array(
290
+ 'title' => __( 'Import / Export', 'fl-builder' ),
291
+ 'show' => true,
292
+ 'priority' => 800,
293
+ ),
294
  ) );
295
 
296
  $sorted_data = array();
346
  // Tools
347
  self::render_form( 'tools' );
348
 
349
+ self::render_form( 'advanced' );
350
+
351
+ self::render_form( 'import-export' );
352
+
353
  /**
354
  * Let extensions hook into form rendering.
355
  * @see fl_builder_admin_settings_render_forms
classes/class-fl-builder-art.php CHANGED
@@ -29,6 +29,12 @@ class FLBuilderArt {
29
 
30
  // Add special <option> sets for js output
31
  add_filter( 'fl_builder_shared_option_sets', 'FLBuilderArt::filter_shared_option_sets' );
 
 
 
 
 
 
32
  }
33
 
34
  /**
@@ -132,6 +138,7 @@ class FLBuilderArt {
132
  'preserve_aspect_ratio' => 'none',
133
  'render' => '',
134
  'preset_settings' => array(),
 
135
  );
136
 
137
  $args = wp_parse_args( $args, $defaults );
@@ -148,10 +155,11 @@ class FLBuilderArt {
148
  * This is so when you choose a shape, we can also setup other fields for the optimal initial appearance.
149
  */
150
  FLBuilderSettingsPresets::register( 'shape', array(
151
- 'name' => $args['name'],
152
- 'label' => $args['label'],
153
- 'settings' => $args['preset_settings'],
154
- 'data' => array(
 
155
  'viewBox' => array(
156
  'x' => $args['x'],
157
  'y' => $args['y'],
@@ -177,10 +185,13 @@ class FLBuilderArt {
177
  */
178
  $art = apply_filters( 'fl_shape_artwork', self::$artwork );
179
 
180
- if ( $key && isset( $art[ $key ] ) ) {
181
- return $art[ $key ];
 
 
 
 
182
  }
183
-
184
  return $art;
185
  }
186
 
@@ -213,6 +224,7 @@ class FLBuilderArt {
213
  */
214
  static public function render_art( $shape, $settings ) {
215
 
 
216
  // Render artwork into a buffer
217
  if ( $shape && isset( $shape['render'] ) ) {
218
  ob_start();
@@ -220,10 +232,12 @@ class FLBuilderArt {
220
 
221
  if ( is_string( $render ) && file_exists( $render ) ) {
222
  include $render;
 
 
223
  }
224
  $output = ob_get_clean();
225
- return $output;
226
  }
 
227
  }
228
 
229
  /**
@@ -316,7 +330,7 @@ class FLBuilderArt {
316
  $shape_args = self::get_art( $shape_name );
317
  $content = self::render_art( $shape_args, $settings );
318
 
319
- if ( ! isset( $shape_args['x'] ) ) {
320
  return false;
321
  }
322
 
@@ -818,5 +832,112 @@ class FLBuilderArt {
818
  return null;
819
  }
820
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
821
  }
822
  FLBuilderArt::init();
29
 
30
  // Add special <option> sets for js output
31
  add_filter( 'fl_builder_shared_option_sets', 'FLBuilderArt::filter_shared_option_sets' );
32
+
33
+ add_filter( 'fl_builder_register_settings_form', 'FLBuilderArt::global_options', 10, 2 );
34
+
35
+ add_action( 'init', 'FLBuilderArt::register_global_form' );
36
+
37
+ add_action( 'init', 'FLBuilderArt::register_global_shapes' );
38
  }
39
 
40
  /**
138
  'preserve_aspect_ratio' => 'none',
139
  'render' => '',
140
  'preset_settings' => array(),
141
+ 'shape_original' => '',
142
  );
143
 
144
  $args = wp_parse_args( $args, $defaults );
155
  * This is so when you choose a shape, we can also setup other fields for the optimal initial appearance.
156
  */
157
  FLBuilderSettingsPresets::register( 'shape', array(
158
+ 'name' => $args['name'],
159
+ 'label' => $args['label'],
160
+ 'settings' => $args['preset_settings'],
161
+ 'shape_original' => $args['shape_original'],
162
+ 'data' => array(
163
  'viewBox' => array(
164
  'x' => $args['x'],
165
  'y' => $args['y'],
185
  */
186
  $art = apply_filters( 'fl_shape_artwork', self::$artwork );
187
 
188
+ if ( $key ) {
189
+ if ( isset( $art[ $key ] ) ) {
190
+ return $art[ $key ];
191
+ } else {
192
+ return false;
193
+ }
194
  }
 
195
  return $art;
196
  }
197
 
224
  */
225
  static public function render_art( $shape, $settings ) {
226
 
227
+ $output = '';
228
  // Render artwork into a buffer
229
  if ( $shape && isset( $shape['render'] ) ) {
230
  ob_start();
232
 
233
  if ( is_string( $render ) && file_exists( $render ) ) {
234
  include $render;
235
+ } else {
236
+ echo $render;
237
  }
238
  $output = ob_get_clean();
 
239
  }
240
+ return $output;
241
  }
242
 
243
  /**
330
  $shape_args = self::get_art( $shape_name );
331
  $content = self::render_art( $shape_args, $settings );
332
 
333
+ if ( ! $shape_args ) {
334
  return false;
335
  }
336
 
832
  return null;
833
  }
834
  }
835
+
836
+ static public function register_global_shapes( $global_settings = false ) {
837
+
838
+ $width = '800';
839
+ $height = '100';
840
+
841
+ if ( FLBuilderAJAX::doing_ajax() ) {
842
+ return false;
843
+ }
844
+
845
+ if ( ! $global_settings ) {
846
+ $global_settings = FLBuilderModel::get_global_settings();
847
+ }
848
+
849
+ if ( isset( $global_settings->shape_form ) && ! empty( $global_settings->shape_form ) ) {
850
+ foreach ( (array) $global_settings->shape_form as $i => $shape ) {
851
+
852
+ if ( ! isset( $shape->shape ) || '' == $shape->shape_name || '' == $shape->shape ) {
853
+ continue;
854
+ }
855
+
856
+ $svg = $shape->shape;
857
+ $name = $shape->shape_name;
858
+
859
+ // find width/height
860
+ $sizes = preg_match( '/viewBox="[0-9]+\s[0-9]+\s([0-9]+)\s([0-9]+)/', $svg, $matches );
861
+
862
+ if ( isset( $matches[1] ) && isset( $matches[2] ) ) {
863
+ $width = $matches[1];
864
+ $height = $matches[2];
865
+ }
866
+
867
+ // here we just want the internals of the svg everything else is stripped.
868
+ $svg = preg_replace( '/^<\?xml[^>]*>/', '', $svg );
869
+ $svg = preg_replace( '/<svg[^>]*>/', '', $svg );
870
+ $svg = preg_replace( '/(<[a-z]+)/', '$1 class="fl-shape" ', ltrim( $svg ) );
871
+ $svg = str_replace( '</svg>', '', $svg );
872
+
873
+ $args = array(
874
+ 'render' => $svg,
875
+ 'width' => $width,
876
+ 'height' => $height,
877
+ 'name' => '' !== $shape->shape_original ? $shape->shape_original : 'global-shapes-' . sanitize_title( $name ),
878
+ 'label' => $name,
879
+ 'shape_original' => '' !== $shape->shape_original ? $shape->shape_original : 'global-shapes-' . sanitize_title( $name ),
880
+ );
881
+ self::register_shape( $args );
882
+ }
883
+ }
884
+ }
885
+
886
+ static public function global_options( $form, $id ) {
887
+
888
+ if ( 'global' == $id ) {
889
+ $form['tabs']['shapes'] = array(
890
+ 'title' => 'Shapes',
891
+ 'description' => 'Paste your SVG code to add new row shapes to the shape dropdown.',
892
+ 'sections' => array(
893
+ 'shapes' => array(
894
+ 'title' => 'Row SVG Shapes',
895
+ 'fields' => array(
896
+ 'shape_form' => array(
897
+ 'type' => 'form',
898
+ 'label' => 'Shape',
899
+ 'form' => 'global_shapes_form',
900
+ 'preview_text' => 'shape_name',
901
+ 'multiple' => true,
902
+ ),
903
+ ),
904
+ ),
905
+ ),
906
+ );
907
+ }
908
+ return $form;
909
+ }
910
+
911
+ public static function register_global_form() {
912
+ FLBuilder::register_settings_form('global_shapes_form', array(
913
+ 'title' => __( 'Add Shape', 'fl-builder' ),
914
+ 'tabs' => array(
915
+ 'general' => array(
916
+ 'title' => __( 'General', 'fl-builder' ), // Tab title
917
+ 'sections' => array(
918
+ 'general' => array(
919
+ 'title' => '',
920
+ 'fields' => array(
921
+ 'shape_name' => array(
922
+ 'type' => 'text',
923
+ 'label' => 'Name',
924
+ 'required' => true,
925
+ ),
926
+ 'shape' => array(
927
+ 'label' => 'SVG Code',
928
+ 'type' => 'textarea',
929
+ 'rows' => 10,
930
+ 'required' => true,
931
+ ),
932
+ 'shape_original' => array(
933
+ 'type' => 'text',
934
+ ),
935
+ ),
936
+ ),
937
+ ),
938
+ ),
939
+ ),
940
+ ));
941
+ }
942
  }
943
  FLBuilderArt::init();
classes/class-fl-builder-color.php CHANGED
@@ -123,7 +123,7 @@ final class FLBuilderColor {
123
  * @param array $setting
124
  * @return string
125
  */
126
- static public function gradient( $setting ) {
127
  $gradient = '';
128
  $values = array();
129
 
@@ -145,6 +145,9 @@ final class FLBuilderColor {
145
  $stop = $setting['stops'][ $i ];
146
 
147
  if ( empty( $color ) ) {
 
 
 
148
  $color = 'rgba(255,255,255,0)';
149
  }
150
  if ( ! strstr( $color, 'rgb' ) ) {
123
  * @param array $setting
124
  * @return string
125
  */
126
+ static public function gradient( $setting, $test = false ) {
127
  $gradient = '';
128
  $values = array();
129
 
145
  $stop = $setting['stops'][ $i ];
146
 
147
  if ( empty( $color ) ) {
148
+ if ( $test ) {
149
+ return false;
150
+ }
151
  $color = 'rgba(255,255,255,0)';
152
  }
153
  if ( ! strstr( $color, 'rgb' ) ) {
classes/class-fl-builder-compatibility.php CHANGED
@@ -56,6 +56,7 @@ final class FLBuilderCompatibility {
56
  add_action( 'wp_enqueue_scripts', array( __CLASS__, 'fix_signify_theme_media' ), 11 );
57
  add_action( 'pre_get_posts', array( __CLASS__, 'hide_tribe_child_recurring_events' ) );
58
  add_action( 'wp_print_scripts', array( __CLASS__, 'convert_box_bb' ), 20 );
 
59
 
60
  // Filters
61
  add_filter( 'fl_builder_is_post_editable', array( __CLASS__, 'bp_pages_support' ), 11, 2 );
@@ -91,8 +92,9 @@ final class FLBuilderCompatibility {
91
  add_filter( 'get_the_excerpt', array( __CLASS__, 'fix_rest_excerpt_filter' ), 10, 2 );
92
  add_filter( 'woocommerce_tab_manager_tab_panel_content', array( __CLASS__, 'fix_woo_tab_manager_missing_content' ), 10, 3 );
93
  add_filter( 'fl_builder_loop_query_args', array( __CLASS__, 'hide_tribe_child_recurring_events_custom_query' ) );
94
- add_filter( 'fl_builder_render_assets_inline', array( __CLASS__, 'fix_ultimate_dashboard_pro' ), 11 );
95
  add_filter( 'the_content', __CLASS__ . '::render_tribe_event_template', 11 );
 
96
  }
97
 
98
  /**
@@ -1225,7 +1227,7 @@ final class FLBuilderCompatibility {
1225
  return $args;
1226
  }
1227
 
1228
- if ( 'tribe_events' !== $args['settings']->post_type || 'custom_query' !== $args['settings']->data_source ) {
1229
  return $args;
1230
  }
1231
 
@@ -1257,5 +1259,44 @@ final class FLBuilderCompatibility {
1257
  remove_action( 'wp_head', 'convbox_head_script' );
1258
  }
1259
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1260
  }
1261
  FLBuilderCompatibility::init();
56
  add_action( 'wp_enqueue_scripts', array( __CLASS__, 'fix_signify_theme_media' ), 11 );
57
  add_action( 'pre_get_posts', array( __CLASS__, 'hide_tribe_child_recurring_events' ) );
58
  add_action( 'wp_print_scripts', array( __CLASS__, 'convert_box_bb' ), 20 );
59
+ add_action( 'wp_enqueue_scripts', array( __CLASS__, 'yith_woocommerce_affiliates' ), 20 );
60
 
61
  // Filters
62
  add_filter( 'fl_builder_is_post_editable', array( __CLASS__, 'bp_pages_support' ), 11, 2 );
92
  add_filter( 'get_the_excerpt', array( __CLASS__, 'fix_rest_excerpt_filter' ), 10, 2 );
93
  add_filter( 'woocommerce_tab_manager_tab_panel_content', array( __CLASS__, 'fix_woo_tab_manager_missing_content' ), 10, 3 );
94
  add_filter( 'fl_builder_loop_query_args', array( __CLASS__, 'hide_tribe_child_recurring_events_custom_query' ) );
95
+ add_filter( 'fl_builder_render_assets_inline', array( __CLASS__, 'fix_ultimate_dashboard_pro' ), 1001 );
96
  add_filter( 'the_content', __CLASS__ . '::render_tribe_event_template', 11 );
97
+ add_filter( 'fl_builder_loop_query', array( __CLASS__, 'fix_tribe_events_pagination' ), 20, 2 );
98
  }
99
 
100
  /**
1227
  return $args;
1228
  }
1229
 
1230
+ if ( ! FLBuilderUtils::post_type_contains( 'tribe_events', $args['settings']->post_type ) || 'custom_query' !== $args['settings']->data_source ) {
1231
  return $args;
1232
  }
1233
 
1259
  remove_action( 'wp_head', 'convbox_head_script' );
1260
  }
1261
  }
1262
+
1263
+ /**
1264
+ * @since 2.6
1265
+ */
1266
+
1267
+ public static function yith_woocommerce_affiliates() {
1268
+ if ( class_exists( 'FLBuilderModel' ) && ( FLBuilderModel::is_builder_active() ) ) {
1269
+ wp_dequeue_script( 'yith-wcaf-shortcodes' );
1270
+ }
1271
+ }
1272
+
1273
+ /**
1274
+ * Fixes TEC 6 pagination.
1275
+ *
1276
+ * @since 2.6
1277
+ */
1278
+ public static function fix_tribe_events_pagination( $query, $settings ) {
1279
+ if ( ! class_exists( 'TEC\Events\Custom_Tables\V1\WP_Query\Modifiers\Events_Only_Modifier' ) ) {
1280
+ return $query;
1281
+ }
1282
+
1283
+ if ( empty( $settings->data_source ) || $query->post_count < 1 ) {
1284
+ return $query;
1285
+ }
1286
+
1287
+ if ( 'main_query' === $settings->data_source && ! is_post_type_archive( 'tribe_events' ) ) {
1288
+ return $query;
1289
+ }
1290
+
1291
+ if ( 'custom_query' === $settings->data_source && ! FLBuilderUtils::post_type_contains( 'tribe_events', $settings->post_type ) ) {
1292
+ return $query;
1293
+ }
1294
+
1295
+ $query->max_num_pages = ceil( $query->found_posts / $query->query_vars['posts_per_page'] );
1296
+
1297
+ return $query;
1298
+ }
1299
+
1300
+
1301
  }
1302
  FLBuilderCompatibility::init();
classes/class-fl-builder-css.php CHANGED
@@ -56,7 +56,7 @@ final class FLBuilderCSS {
56
  $props = $args['props'];
57
  $default_unit = $args['unit'];
58
  $enabled = $args['enabled'];
59
- $breakpoints = array( '', 'medium', 'responsive' );
60
  $ignore = $args['ignore'];
61
 
62
  if ( ! $settings || empty( $setting_name ) || empty( $selector ) ) {
@@ -156,7 +156,7 @@ final class FLBuilderCSS {
156
  $selector = $args['selector'];
157
  $settings = $args['settings'];
158
  $setting_name = $args['setting_name'];
159
- $breakpoints = array( '', 'medium', 'responsive' );
160
 
161
  if ( empty( $type ) || empty( $selector ) || ! $settings || empty( $setting_name ) ) {
162
  return;
@@ -229,16 +229,16 @@ final class FLBuilderCSS {
229
  $props['border-color'] = $setting['color'];
230
  }
231
  if ( isset( $setting['width'] ) && is_array( $setting['width'] ) ) {
232
- if ( '' !== $setting['width']['top'] ) {
233
  $props['border-top-width'] = $setting['width']['top'] . 'px';
234
  }
235
- if ( '' !== $setting['width']['right'] ) {
236
  $props['border-right-width'] = $setting['width']['right'] . 'px';
237
  }
238
- if ( '' !== $setting['width']['bottom'] ) {
239
  $props['border-bottom-width'] = $setting['width']['bottom'] . 'px';
240
  }
241
- if ( '' !== $setting['width']['left'] ) {
242
  $props['border-left-width'] = $setting['width']['left'] . 'px';
243
  }
244
  }
@@ -313,8 +313,8 @@ final class FLBuilderCSS {
313
  $props['line-height'] .= $setting['line_height']['unit'];
314
  }
315
  }
316
- if ( isset( $setting['letter_spacing'] ) && ! empty( $setting['letter_spacing']['length'] ) ) {
317
- $props['letter-spacing'] = $setting['letter_spacing']['length'] . 'px';
318
  }
319
  if ( isset( $setting['text_align'] ) ) {
320
  $props['text-align'] = $setting['text_align'];
@@ -347,7 +347,7 @@ final class FLBuilderCSS {
347
  */
348
  static public function render() {
349
  $rendered = array();
350
- $breakpoints = array( 'default', 'medium', 'responsive' );
351
  $css = '';
352
 
353
  // Setup system breakpoints here to ensure proper order.
@@ -519,6 +519,8 @@ final class FLBuilderCSS {
519
 
520
  if ( 'default' === $media ) {
521
  $media = '';
 
 
522
  } elseif ( 'medium' === $media ) {
523
  $media = "max-width: {$settings->medium_breakpoint}px";
524
  } elseif ( 'responsive' === $media ) {
56
  $props = $args['props'];
57
  $default_unit = $args['unit'];
58
  $enabled = $args['enabled'];
59
+ $breakpoints = array( '', 'large', 'medium', 'responsive' );
60
  $ignore = $args['ignore'];
61
 
62
  if ( ! $settings || empty( $setting_name ) || empty( $selector ) ) {
156
  $selector = $args['selector'];
157
  $settings = $args['settings'];
158
  $setting_name = $args['setting_name'];
159
+ $breakpoints = array( '', 'large', 'medium', 'responsive' );
160
 
161
  if ( empty( $type ) || empty( $selector ) || ! $settings || empty( $setting_name ) ) {
162
  return;
229
  $props['border-color'] = $setting['color'];
230
  }
231
  if ( isset( $setting['width'] ) && is_array( $setting['width'] ) ) {
232
+ if ( ! empty( $setting['width']['top'] ) ) {
233
  $props['border-top-width'] = $setting['width']['top'] . 'px';
234
  }
235
+ if ( ! empty( $setting['width']['right'] ) ) {
236
  $props['border-right-width'] = $setting['width']['right'] . 'px';
237
  }
238
+ if ( ! empty( $setting['width']['bottom'] ) ) {
239
  $props['border-bottom-width'] = $setting['width']['bottom'] . 'px';
240
  }
241
+ if ( ! empty( $setting['width']['left'] ) ) {
242
  $props['border-left-width'] = $setting['width']['left'] . 'px';
243
  }
244
  }
313
  $props['line-height'] .= $setting['line_height']['unit'];
314
  }
315
  }
316
+ if ( isset( $setting['letter_spacing'] ) && '' !== strval( $setting['letter_spacing']['length'] ) ) {
317
+ $props['letter-spacing'] = floatval( $setting['letter_spacing']['length'] ) . 'px';
318
  }
319
  if ( isset( $setting['text_align'] ) ) {
320
  $props['text-align'] = $setting['text_align'];
347
  */
348
  static public function render() {
349
  $rendered = array();
350
+ $breakpoints = array( 'default', 'large', 'medium', 'responsive' );
351
  $css = '';
352
 
353
  // Setup system breakpoints here to ensure proper order.
519
 
520
  if ( 'default' === $media ) {
521
  $media = '';
522
+ } elseif ( 'large' === $media ) {
523
+ $media = "max-width: {$settings->large_breakpoint}px";
524
  } elseif ( 'medium' === $media ) {
525
  $media = "max-width: {$settings->medium_breakpoint}px";
526
  } elseif ( 'responsive' === $media ) {
classes/class-fl-builder-debug.php CHANGED
@@ -45,7 +45,7 @@ final class FL_Debug {
45
  if ( is_array( $test['data'] ) ) {
46
  $test['data'] = implode( "\n", $test['data'] );
47
  }
48
- return sprintf( "%s\n%s\n\n", $test['name'], $test['data'] );
49
  }
50
 
51
  private static function register( $slug, $args ) {
@@ -144,7 +144,7 @@ final class FL_Debug {
144
 
145
  $args = array(
146
  'name' => 'FL Modsec Fix',
147
- 'data' => defined( 'FL_BUILDER_MODSEC_FIX' ) && FL_BUILDER_MODSEC_FIX ? 'Yes' : 'No',
148
  );
149
  self::register( 'fl_modsec', $args );
150
 
@@ -502,6 +502,22 @@ final class FL_Debug {
502
  }
503
  }
504
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
505
  $args = array(
506
  'name' => 'Server',
507
  'data' => self::divider(),
45
  if ( is_array( $test['data'] ) ) {
46
  $test['data'] = implode( "\n", $test['data'] );
47
  }
48
+ return isset( $test['name'] ) ? sprintf( "%s\n%s\n\n", $test['name'], $test['data'] ) : sprintf( "%s\n\n", $test['data'] );
49
  }
50
 
51
  private static function register( $slug, $args ) {
144
 
145
  $args = array(
146
  'name' => 'FL Modsec Fix',
147
+ 'data' => FLBuilderUtils::is_modsec_fix_enabled() ? 'Yes' : 'No',
148
  );
149
  self::register( 'fl_modsec', $args );
150
 
502
  }
503
  }
504
 
505
+ self::register( 'adv', array(
506
+ 'name' => 'Advanced Options',
507
+ 'data' => self::divider(),
508
+ ) );
509
+
510
+ $adv_opts = FLBuilderAdminAdvanced::get_settings();
511
+ $opts = array();
512
+ foreach ( $adv_opts as $key => $opt ) {
513
+ $option = get_option( "_fl_builder_{$key}", $opt['default'] ) ? 'Enabled' : 'Disabled';
514
+ $opts[] = sprintf( '%s: %s', $opt['label'], $option );
515
+ }
516
+ $args = array(
517
+ 'data' => $opts,
518
+ );
519
+ self::register( 'adv_settings', $args );
520
+
521
  $args = array(
522
  'name' => 'Server',
523
  'data' => self::divider(),
classes/class-fl-builder-font-awesome.php CHANGED
@@ -145,7 +145,6 @@ final class FLBuilderFontAwesome {
145
  public static function register_plugin() {
146
  $args = apply_filters( 'fl_builder_font_awesome_register_args', array(
147
  'name' => __( 'Beaver Builder', 'fl-builder' ),
148
- 'v4Compat' => false,
149
  'technology' => 'webfont',
150
  ) );
151
  fa()->register( $args );
145
  public static function register_plugin() {
146
  $args = apply_filters( 'fl_builder_font_awesome_register_args', array(
147
  'name' => __( 'Beaver Builder', 'fl-builder' ),
 
148
  'technology' => 'webfont',
149
  ) );
150
  fa()->register( $args );
classes/class-fl-builder-fonts.php CHANGED
@@ -384,7 +384,9 @@ final class FLBuilderFonts {
384
 
385
  $google_url = substr( $google_url, 0, -1 );
386
 
387
- wp_enqueue_style( 'fl-builder-google-fonts-' . md5( $google_url ), $google_url, array() );
 
 
388
 
389
  self::$fonts = array();
390
  }
384
 
385
  $google_url = substr( $google_url, 0, -1 );
386
 
387
+ if ( true === apply_filters( 'fl_enable_google_fonts_enqueue', true ) ) {
388
+ wp_enqueue_style( 'fl-builder-google-fonts-' . md5( $google_url ), $google_url, array() );
389
+ }
390
 
391
  self::$fonts = array();
392
  }
classes/class-fl-builder-global-import-export.php ADDED
@@ -0,0 +1,108 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class FLBuilderGlobalImportExport {
3
+
4
+ function __construct() {
5
+ add_action( 'wp_ajax_export_global_settings', array( $this, 'export_data' ) );
6
+ add_action( 'wp_ajax_import_global_settings', array( $this, 'import_data' ) );
7
+ add_action( 'wp_ajax_reset_global_settings', array( $this, 'reset_data' ) );
8
+ add_filter( 'wp_check_filetype_and_ext', array( $this, 'allow_import' ), 10, 4 );
9
+
10
+ add_action( 'admin_enqueue_scripts', function() {
11
+ wp_enqueue_script( 'fl-builder-global-import-export', FL_BUILDER_URL . 'js/fl-builder-global-import-export.js', array( 'jquery' ), FL_BUILDER_VERSION );
12
+ wp_localize_script( 'fl-builder-global-import-export', 'FLBuilderAdminImportExportConfig', array(
13
+ 'select' => __( 'Import Settings', 'fl-builder' ),
14
+ ));
15
+ });
16
+ }
17
+
18
+ /**
19
+ * @since 2.6
20
+ */
21
+ static public function export_data() {
22
+
23
+ check_admin_referer( 'fl_builder_import_export' );
24
+
25
+ if ( current_user_can( 'manage_options' ) ) {
26
+
27
+ $settings = array();
28
+ $admin_settings = array();
29
+
30
+ $settings['builder_global_settings'] = FLBuilderModel::get_global_settings();
31
+
32
+ foreach ( FLBuilderAdminSettings::registered_settings() as $setting ) {
33
+ $admin_settings[ $setting ] = get_option( $setting );
34
+ }
35
+
36
+ $settings['admin_settings'] = $admin_settings;
37
+
38
+ if ( ! $settings ) {
39
+ wp_send_json_error( 'No settings found' );
40
+ }
41
+ wp_send_json_success( wp_json_encode( $settings ) );
42
+ } else {
43
+ wp_send_json_error();
44
+ }
45
+ }
46
+
47
+ public function import_data() {
48
+
49
+ check_admin_referer( 'fl_builder_import_export' );
50
+
51
+ if ( current_user_can( 'manage_options' ) ) {
52
+
53
+ $id = $_POST['importid'];
54
+ $path = get_attached_file( $id );
55
+
56
+ if ( ! $path ) {
57
+ wp_send_json_error( 'Could not find file!' );
58
+ }
59
+
60
+ $data = file_get_contents( $path );
61
+
62
+ if ( ! is_object( json_decode( $data ) ) ) {
63
+ wp_send_json_error( 'Could not parse file!' );
64
+ }
65
+
66
+ $data = json_decode( $data );
67
+
68
+ update_option( '_fl_builder_settings', $data->builder_global_settings );
69
+
70
+ // loop through admin settings
71
+ $settings = $data->admin_settings;
72
+
73
+ foreach ( $settings as $key => $setting ) {
74
+ update_option( $key, $setting );
75
+ }
76
+ wp_send_json_success( $data );
77
+ } else {
78
+ wp_send_json_error();
79
+ }
80
+ }
81
+
82
+ public function reset_data() {
83
+
84
+ check_admin_referer( 'fl_builder_import_export' );
85
+
86
+ if ( current_user_can( 'manage_options' ) ) {
87
+ delete_option( '_fl_builder_settings' );
88
+ foreach ( FLBuilderAdminSettings::registered_settings() as $setting ) {
89
+ delete_option( $setting );
90
+ }
91
+ wp_send_json_success();
92
+ } else {
93
+ wp_send_json_error();
94
+ }
95
+ }
96
+
97
+ public function allow_import( $data, $file, $filename, $mimes ) {
98
+ if ( isset( $_POST['fl_global_import'] ) && current_user_can( 'manage_options' ) ) {
99
+ $wp_filetype = wp_check_filetype( $filename, $mimes );
100
+ $ext = $wp_filetype['ext'];
101
+ $type = $wp_filetype['type'];
102
+ $proper_filename = $data['proper_filename'];
103
+ return compact( 'ext', 'type', 'proper_filename' );
104
+ }
105
+ return $data;
106
+ }
107
+ }
108
+ new FLBuilderGlobalImportExport;
classes/class-fl-builder-loader.php CHANGED
@@ -48,7 +48,7 @@ if ( ! class_exists( 'FLBuilderLoader' ) ) {
48
  * @return void
49
  */
50
  static private function define_constants() {
51
- define( 'FL_BUILDER_VERSION', '2.5.5.5' );
52
  define( 'FL_BUILDER_FILE', trailingslashit( dirname( dirname( __FILE__ ) ) ) . 'fl-builder.php' );
53
  define( 'FL_BUILDER_DIR', plugin_dir_path( FL_BUILDER_FILE ) );
54
  define( 'FL_BUILDER_URL', esc_url( plugins_url( '/', FL_BUILDER_FILE ) ) );
@@ -94,6 +94,7 @@ if ( ! class_exists( 'FLBuilderLoader' ) ) {
94
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-import.php';
95
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-loop.php';
96
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-model.php';
 
97
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-module.php';
98
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-photo.php';
99
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-revisions.php';
@@ -114,6 +115,7 @@ if ( ! class_exists( 'FLBuilderLoader' ) ) {
114
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-settings-presets.php';
115
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-compatibility.php';
116
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-font-awesome.php';
 
117
 
118
  /* WP CLI Commands */
119
  if ( defined( 'WP_CLI' ) ) {
48
  * @return void
49
  */
50
  static private function define_constants() {
51
+ define( 'FL_BUILDER_VERSION', '2.6.0.3' );
52
  define( 'FL_BUILDER_FILE', trailingslashit( dirname( dirname( __FILE__ ) ) ) . 'fl-builder.php' );
53
  define( 'FL_BUILDER_DIR', plugin_dir_path( FL_BUILDER_FILE ) );
54
  define( 'FL_BUILDER_URL', esc_url( plugins_url( '/', FL_BUILDER_FILE ) ) );
94
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-import.php';
95
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-loop.php';
96
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-model.php';
97
+ require_once FL_BUILDER_DIR . 'classes/class-fl-builder-admin-advanced.php';
98
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-module.php';
99
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-photo.php';
100
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-revisions.php';
115
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-settings-presets.php';
116
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-compatibility.php';
117
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-font-awesome.php';
118
+ require_once FL_BUILDER_DIR . 'classes/class-fl-builder-global-import-export.php';
119
 
120
  /* WP CLI Commands */
121
  if ( defined( 'WP_CLI' ) ) {
classes/class-fl-builder-loop.php CHANGED
@@ -245,6 +245,37 @@ final class FLBuilderLoop {
245
  );
246
  }
247
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
248
  // Build the author query.
249
  if ( ! empty( $users ) ) {
250
 
@@ -261,96 +292,99 @@ final class FLBuilderLoop {
261
 
262
  $args[ $arg ] = $users;
263
  }
 
 
 
264
 
265
- // Build the taxonomy query.
266
- $taxonomies = self::taxonomies( $post_type );
267
-
268
- foreach ( $taxonomies as $tax_slug => $tax ) {
269
 
270
- $tax_value = '';
271
- $term_ids = array();
272
- $operator = 'IN';
273
-
274
- // Get the value of the suggest field.
275
- if ( isset( $settings->{'tax_' . $post_type . '_' . $tax_slug} ) ) {
276
- // New style slug.
277
- $tax_value = $settings->{'tax_' . $post_type . '_' . $tax_slug};
278
- } elseif ( isset( $settings->{'tax_' . $tax_slug} ) ) {
279
- // Old style slug for backwards compat.
280
- $tax_value = $settings->{'tax_' . $tax_slug};
281
- }
282
 
283
- // Get the term IDs array.
284
- if ( ! empty( $tax_value ) ) {
285
- $term_ids = explode( ',', $tax_value );
286
- }
 
 
 
 
287
 
288
- // Handle matching settings.
289
- if ( isset( $settings->{'tax_' . $post_type . '_' . $tax_slug . '_matching'} ) ) {
 
 
290
 
291
- $tax_matching = $settings->{'tax_' . $post_type . '_' . $tax_slug . '_matching'};
 
292
 
293
- if ( ! $tax_matching ) {
294
- // Do not match these terms.
295
- $operator = 'NOT IN';
296
- } elseif ( 'related' === $tax_matching ) {
297
- // Match posts by related terms from the global post.
298
- global $post;
299
- $terms = wp_get_post_terms( $post->ID, $tax_slug );
300
- $related = array();
301
 
302
- foreach ( $terms as $term ) {
303
- if ( ! in_array( $term->term_id, $term_ids ) ) {
304
- $related[] = $term->term_id;
 
 
 
 
 
 
 
 
 
 
305
  }
306
- }
307
 
308
- if ( empty( $related ) ) {
309
- // If no related terms, match all except those in the suggest field.
310
- $operator = 'NOT IN';
311
- } else {
312
-
313
- // Don't include posts with terms selected in the suggest field.
314
- $args['tax_query'][] = array(
315
- 'taxonomy' => $tax_slug,
316
- 'field' => 'id',
317
- 'terms' => $term_ids,
318
- 'operator' => 'NOT IN',
319
- );
320
-
321
- // Set the term IDs to the related terms.
322
- $term_ids = $related;
 
323
  }
324
  }
325
- }
326
 
327
- if ( ! empty( $term_ids ) ) {
328
 
329
- $args['tax_query'][] = array(
330
- 'taxonomy' => $tax_slug,
331
- 'field' => 'id',
332
- 'terms' => $term_ids,
333
- 'operator' => $operator,
334
- );
 
335
  }
336
  }
337
 
338
- // Post in/not in query.
339
- if ( isset( $settings->{'posts_' . $post_type} ) ) {
 
340
 
341
- $ids = $settings->{'posts_' . $post_type};
342
- $arg = 'post__in';
343
 
344
- // Set to NOT IN if matching is present and set to 0.
345
- if ( isset( $settings->{'posts_' . $post_type . '_matching'} ) ) {
346
- if ( ! $settings->{'posts_' . $post_type . '_matching'} ) {
347
- $arg = 'post__not_in';
 
348
  }
349
- }
350
 
351
- // Add the args if we have IDs.
352
- if ( ! empty( $ids ) ) {
353
- $args[ $arg ] = explode( ',', $settings->{'posts_' . $post_type} );
 
354
  }
355
  }
356
 
245
  );
246
  }
247
 
248
+ // Filter by meta key
249
+ if ( ( isset( $settings->custom_field ) && is_array( $settings->custom_field ) && count( $settings->custom_field ) > 0 ) && ( isset( $settings->data_source ) && 'custom_query' == $settings->data_source ) ) {
250
+ if ( count( $settings->custom_field ) == 1 ) {
251
+
252
+ if ( isset( $settings->custom_field[0]->filter_meta_key ) && ! empty( $settings->custom_field[0]->filter_meta_key ) ) {
253
+ $args['meta_key'] = untrailingslashit( $settings->custom_field[0]->filter_meta_key );
254
+ if ( 'EXISTS' != $settings->custom_field[0]->filter_meta_compare && 'NOT EXISTS' != $settings->custom_field[0]->filter_meta_compare ) {
255
+ $args['meta_value'] = untrailingslashit( $settings->custom_field[0]->filter_meta_value );
256
+ }
257
+ $args['meta_type'] = $settings->custom_field[0]->filter_meta_type;
258
+ $args['meta_compare'] = $settings->custom_field[0]->filter_meta_compare;
259
+ }
260
+ } else {
261
+ if ( isset( $settings->custom_field_relation ) ) {
262
+ $args['meta_query']['relation'] = $settings->custom_field_relation;
263
+ foreach ( $settings->custom_field as $fields ) {
264
+ if ( ! empty( $fields ) ) {
265
+ $filter_arr = array();
266
+ $filter_arr['key'] = untrailingslashit( $fields->filter_meta_key );
267
+ if ( 'EXISTS' != $fields->filter_meta_compare && 'NOT EXISTS' != $fields->filter_meta_compare ) {
268
+ $filter_arr['value'] = untrailingslashit( $fields->filter_meta_value );
269
+ }
270
+ $filter_arr['type'] = $fields->filter_meta_type;
271
+ $filter_arr['compare'] = $fields->filter_meta_compare;
272
+ $args['meta_query'][] = $filter_arr;
273
+ }
274
+ }
275
+ }
276
+ }
277
+ }
278
+
279
  // Build the author query.
280
  if ( ! empty( $users ) ) {
281
 
292
 
293
  $args[ $arg ] = $users;
294
  }
295
+ foreach ( (array) $post_type as $type ) {
296
+ // Build the taxonomy query.
297
+ $taxonomies = self::taxonomies( $type );
298
 
299
+ foreach ( $taxonomies as $tax_slug => $tax ) {
 
 
 
300
 
301
+ $tax_value = '';
302
+ $term_ids = array();
303
+ $operator = 'IN';
 
 
 
 
 
 
 
 
 
304
 
305
+ // Get the value of the suggest field.
306
+ if ( isset( $settings->{'tax_' . $type . '_' . $tax_slug} ) ) {
307
+ // New style slug.
308
+ $tax_value = $settings->{'tax_' . $type . '_' . $tax_slug};
309
+ } elseif ( isset( $settings->{'tax_' . $tax_slug} ) ) {
310
+ // Old style slug for backwards compat.
311
+ $tax_value = $settings->{'tax_' . $tax_slug};
312
+ }
313
 
314
+ // Get the term IDs array.
315
+ if ( ! empty( $tax_value ) ) {
316
+ $term_ids = explode( ',', $tax_value );
317
+ }
318
 
319
+ // Handle matching settings.
320
+ if ( isset( $settings->{'tax_' . $type . '_' . $tax_slug . '_matching'} ) ) {
321
 
322
+ $tax_matching = $settings->{'tax_' . $type . '_' . $tax_slug . '_matching'};
 
 
 
 
 
 
 
323
 
324
+ if ( ! $tax_matching ) {
325
+ // Do not match these terms.
326
+ $operator = 'NOT IN';
327
+ } elseif ( 'related' === $tax_matching ) {
328
+ // Match posts by related terms from the global post.
329
+ global $post;
330
+ $terms = wp_get_post_terms( $post->ID, $tax_slug );
331
+ $related = array();
332
+
333
+ foreach ( $terms as $term ) {
334
+ if ( ! in_array( $term->term_id, $term_ids ) ) {
335
+ $related[] = $term->term_id;
336
+ }
337
  }
 
338
 
339
+ if ( empty( $related ) ) {
340
+ // If no related terms, match all except those in the suggest field.
341
+ $operator = 'NOT IN';
342
+ } else {
343
+
344
+ // Don't include posts with terms selected in the suggest field.
345
+ $args['tax_query'][] = array(
346
+ 'taxonomy' => $tax_slug,
347
+ 'field' => 'id',
348
+ 'terms' => $term_ids,
349
+ 'operator' => 'NOT IN',
350
+ );
351
+
352
+ // Set the term IDs to the related terms.
353
+ $term_ids = $related;
354
+ }
355
  }
356
  }
 
357
 
358
+ if ( ! empty( $term_ids ) ) {
359
 
360
+ $args['tax_query'][] = array(
361
+ 'taxonomy' => $tax_slug,
362
+ 'field' => 'id',
363
+ 'terms' => $term_ids,
364
+ 'operator' => $operator,
365
+ );
366
+ }
367
  }
368
  }
369
 
370
+ foreach ( (array) $post_type as $type ) {
371
+ // Post in/not in query.
372
+ if ( isset( $settings->{'posts_' . $type} ) ) {
373
 
374
+ $ids = $settings->{'posts_' . $type};
375
+ $arg = 'post__in';
376
 
377
+ // Set to NOT IN if matching is present and set to 0.
378
+ if ( isset( $settings->{'posts_' . $type . '_matching'} ) ) {
379
+ if ( ! $settings->{'posts_' . $type . '_matching'} ) {
380
+ $arg = 'post__not_in';
381
+ }
382
  }
 
383
 
384
+ // Add the args if we have IDs.
385
+ if ( ! empty( $ids ) ) {
386
+ $args[ $arg ] = explode( ',', $settings->{'posts_' . $type} );
387
+ }
388
  }
389
  }
390
 
classes/class-fl-builder-model.php CHANGED
@@ -191,6 +191,7 @@ final class FLBuilderModel {
191
  add_action( 'fl_builder_after_save_user_template', __CLASS__ . '::save_layout_revision' );
192
 
193
  /* Filters */
 
194
  add_filter( 'heartbeat_received', __CLASS__ . '::lock_post', 10, 2 );
195
  add_filter( 'fl_builder_register_settings_form', __CLASS__ . '::filter_row_settings_for_resize', 10, 2 );
196
  add_filter( 'wp_revisions_to_keep', __CLASS__ . '::limit_revisions', 10, 2 );
@@ -500,6 +501,155 @@ final class FLBuilderModel {
500
  return (bool) apply_filters( 'fl_builder_is_post_editable', $editable );
501
  }
502
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
503
  /**
504
  * Called by the heartbeat API. Lock the current post
505
  * so only the current user can edit it.
@@ -1519,6 +1669,43 @@ final class FLBuilderModel {
1519
  return $defaults;
1520
  }
1521