WordPress Page Builder – Beaver Builder - Version 1.5.9

Version Description

Download this release

Release Info

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

Code changes from version 1.5.6 to 1.5.9

Files changed (46) hide show
  1. changelog.txt +66 -0
  2. classes/class-fl-builder-admin-posts.php +3 -1
  3. classes/class-fl-builder-admin-settings.php +23 -67
  4. classes/class-fl-builder-admin.php +6 -2
  5. classes/class-fl-builder-model.php +271 -176
  6. classes/class-fl-builder-service-hatchbuck.php +256 -0
  7. classes/class-fl-builder-service-infusionsoft.php +300 -0
  8. classes/class-fl-builder-service-sendinblue.php +2 -2
  9. classes/class-fl-builder-services.php +15 -0
  10. classes/class-fl-builder.php +98 -36
  11. css/fl-builder-admin-posts.css +24 -1
  12. css/fl-builder-admin-settings.css +1 -0
  13. css/fl-builder-layout.css +48 -11
  14. css/fl-builder.css +62 -35
  15. fl-builder.php +2 -2
  16. includes/admin-posts.php +1 -1
  17. includes/column-css.php +18 -1
  18. includes/column-settings.php +124 -0
  19. includes/js-config.php +2 -2
  20. includes/row-settings.php +4 -4
  21. includes/ui.php +13 -2
  22. includes/updater-config.php +1 -1
  23. includes/user-template-settings.php +0 -22
  24. includes/vendor/infusionsoft/infusionsoft.pem +3894 -0
  25. includes/vendor/infusionsoft/isdk.php +2632 -0
  26. includes/vendor/infusionsoft/xmlrpc-3.0/Changelog +1573 -0
  27. includes/vendor/infusionsoft/xmlrpc-3.0/Makefile +123 -0
  28. includes/vendor/infusionsoft/xmlrpc-3.0/NEWS +333 -0
  29. includes/vendor/infusionsoft/xmlrpc-3.0/README +13 -0
  30. includes/vendor/infusionsoft/xmlrpc-3.0/extras/rsakey.pem +9 -0
  31. includes/vendor/infusionsoft/xmlrpc-3.0/extras/test.pl +52 -0
  32. includes/vendor/infusionsoft/xmlrpc-3.0/extras/test.py +37 -0
  33. includes/vendor/infusionsoft/xmlrpc-3.0/extras/workspace.testPhpServer.fttb +1 -1
  34. includes/vendor/infusionsoft/xmlrpc-3.0/lib/xmlrpc.inc +3326 -0
  35. includes/vendor/infusionsoft/xmlrpc-3.0/lib/xmlrpc_wrappers.inc +955 -0
  36. includes/vendor/infusionsoft/xmlrpc-3.0/lib/xmlrpcs.inc +1246 -0
  37. js/fl-builder-layout.js +76 -7
  38. js/fl-builder-preview.js +11 -2
  39. js/fl-builder-tour.js +7 -1
  40. js/fl-builder.js +219 -202
  41. languages/es_ES.mo +0 -0
  42. languages/es_ES.po +1324 -844
  43. languages/fr_FR.mo +0 -0
  44. languages/fr_FR.po +1609 -646
  45. languages/it_IT.mo +0 -0
  46. languages/it_IT.po +441 -477
changelog.txt CHANGED
@@ -1,3 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  <h4>1.5.6 - 04/26/2015</h4>
2
  <p><strong>Enhancements</strong></p>
3
  <ul>
1
+ <h4>1.5.9 - 06/01/2015</h4>
2
+ <p><strong>Enhancements</strong></p>
3
+ <ul>
4
+ <li>Accordion and tab items can now be linked to. Please see this <a href="https://www.wpbeaverbuilder.com/knowledge-base/linking-to-tabs-and-accordions/">knowledge base entry</a> for more info.</li>
5
+ <li>Button icons can now be added after the button text.</li>
6
+ <li>Added background color overlay for columns.</li>
7
+ <li>Added Dutch translation.</li>
8
+ </ul>
9
+ <p><strong>Bug Fixes</strong></p>
10
+ <ul>
11
+ <li>Fixed issues with modules, widgets and shortcodes that create secondary loops causing the page to become unresponsive.</li>
12
+ <li>Fixed a bug with widgets that use checkbox groups.</li>
13
+ <li>Fixed a bug with the pricing table module that caused some styling not to show.</li>
14
+ <li>The map module no longer scrolls as you scroll the page.</li>
15
+ <li>CSS tweak to prevent the text editor from breaking when the body's position is set to relative.</li>
16
+ <li>CSS tweak for photos to prevent extra space below them.</li>
17
+ <li>CSS tweak to make fixed background photos scroll on iOS to prevent them from getting blown up too big.</li>
18
+ <li>CSS tweak to fix a FireFox bug with callouts.</li>
19
+ <li>Added jQuery as a dependency for fl-builder-layout-(POST_ID).js so it's included after jquery.js if jquery.js is moved to wp_footer.</li>
20
+ </ul>
21
+
22
+ <h4>1.5.8 - 05/17/2015</h4>
23
+ <p>Please see <a href="https://www.wpbeaverbuilder.com/?p=14686" target="_blank">the blog post</a> for more info on this release.</p>
24
+ <p><strong>Enhancements</strong></p>
25
+ <ul>
26
+ <li>User defined templates can now be categorized and ordered.</li>
27
+ <li>Revisions are now enabled for user defined templates.</li>
28
+ <li>Added a setting to enable the templates admin interface for editing templates in the WordPress admin.</li>
29
+ <li>Added a setting for Agency members to override core templates.</li>
30
+ <li>Added Hatchbuck integration to the Subscribe Form module.</li>
31
+ <li>Photo backgrounds can now be added to columns.</li>
32
+ </ul>
33
+ <p><strong>Bug Fixes</strong></p>
34
+ <ul>
35
+ <li>Fixed a CSS z-index bug with the Content Slider module's next/prev buttons.</li>
36
+ </ul>
37
+
38
+ <h4>1.5.7.2 - 05/12/2015</h4>
39
+ <p><strong>Bug Fixes</strong></p>
40
+ <ul>
41
+ <li>Fixed a bug with shortcodes not being rendered when the Posts module is present on a page.</li>
42
+ </ul>
43
+
44
+ <h4>1.5.7.1 - 05/10/2015</h4>
45
+ <p><strong>Bug Fixes</strong></p>
46
+ <ul>
47
+ <li>Fixed a FireFox and IE bug with the Photo module introduced in 1.5.7.</li>
48
+ <li>Fixed a CSS bug with the height of the Content Slider module when multiple sliders are on the same page.</li>
49
+ <li>Fixed a bug that prevented shortcodes from being escaped with double brackets.</li>
50
+ <li>Fixed a bug that caused the Video module to freeze the builder with videos that are uploaded to WordPress.</li>
51
+ </ul>
52
+
53
+ <h4>1.5.7 - 05/04/2015</h4>
54
+ <p><strong>Enhancements</strong></p>
55
+ <ul>
56
+ <li>Added Infusionsoft integration.</li>
57
+ </ul>
58
+ <p><strong>Bug Fixes</strong></p>
59
+ <ul>
60
+ <li>Fixed a bug causing MailPoet to be unavailable in the Subscribe Form module.</li>
61
+ <li>Fixed a bug causing the builder's admin settings to be unavailable when DISALLOW_FILE_MODS is set to true.</li>
62
+ <li>Fixed a bug with new lines in photo captions breaking the Slideshow module.</li>
63
+ <li>Fixed a CSS bug with photo captions that are shown on hover.</li>
64
+ <li>Fixed floating content issues with the Accordion module.</li>
65
+ </ul>
66
+
67
  <h4>1.5.6 - 04/26/2015</h4>
68
  <p><strong>Enhancements</strong></p>
69
  <ul>
classes/class-fl-builder-admin-posts.php CHANGED
@@ -88,7 +88,9 @@ final class FLBuilderAdminPosts {
88
  {
89
  global $post;
90
 
91
- $enabled = FLBuilderModel::is_builder_enabled();
 
 
92
 
93
  include FL_BUILDER_DIR . 'includes/admin-posts.php';
94
  }
88
  {
89
  global $post;
90
 
91
+ $post_type_obj = get_post_type_object ( $post->post_type );
92
+ $post_type_name = strtolower( $post_type_obj->labels->singular_name );
93
+ $enabled = FLBuilderModel::is_builder_enabled();
94
 
95
  include FL_BUILDER_DIR . 'includes/admin-posts.php';
96
  }
classes/class-fl-builder-admin-settings.php CHANGED
@@ -59,10 +59,10 @@ final class FLBuilderAdminSettings {
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
 
@@ -334,7 +334,7 @@ final class FLBuilderAdminSettings {
334
  static public function save()
335
  {
336
  // Only admins can save settings.
337
- if(!current_user_can('delete_plugins')) {
338
  return;
339
  }
340
 
@@ -365,16 +365,8 @@ final class FLBuilderAdminSettings {
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
 
@@ -382,6 +374,7 @@ final class FLBuilderAdminSettings {
382
  * Saves the enabled templates.
383
  *
384
  * @since 1.0
 
385
  * @access private
386
  * @return void
387
  */
@@ -389,16 +382,14 @@ final class FLBuilderAdminSettings {
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
  }
@@ -415,26 +406,20 @@ final class FLBuilderAdminSettings {
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
 
@@ -552,16 +537,7 @@ final class FLBuilderAdminSettings {
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
  /**
@@ -577,15 +553,7 @@ final class FLBuilderAdminSettings {
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
 
@@ -603,14 +571,8 @@ final class FLBuilderAdminSettings {
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
 
@@ -675,13 +637,7 @@ final class FLBuilderAdminSettings {
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
 
@@ -694,7 +650,7 @@ final class FLBuilderAdminSettings {
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' ) ) {
59
  */
60
  static public function menu()
61
  {
62
+ if ( current_user_can( 'delete_users' ) ) {
63
 
64
  $title = FLBuilderModel::get_branding();
65
+ $cap = 'delete_users';
66
  $slug = 'fl-builder-settings';
67
  $func = 'FLBuilderAdminSettings::render';
68
 
334
  static public function save()
335
  {
336
  // Only admins can save settings.
337
+ if(!current_user_can('delete_users')) {
338
  return;
339
  }
340
 
365
  if ( is_array( $_POST['fl-modules'] ) ) {
366
  $modules = array_map( 'sanitize_text_field', $_POST['fl-modules'] );
367
  }
368
+
369
+ FLBuilderModel::update_admin_settings_option( '_fl_builder_enabled_modules', $modules, true );
 
 
 
 
 
 
 
 
370
  }
371
  }
372
 
374
  * Saves the enabled templates.
375
  *
376
  * @since 1.0
377
+ * @since 1.5.7 Added the ability to enable the templates admin UI.
378
  * @access private
379
  * @return void
380
  */
382
  {
383
  if ( isset( $_POST['fl-templates-nonce'] ) && wp_verify_nonce( $_POST['fl-templates-nonce'], 'templates' ) ) {
384
 
385
+ $enabled_templates = sanitize_text_field( $_POST['fl-template-settings'] );
386
+ $admin_ui_enabled = isset( $_POST['fl-template-admin-ui'] ) ? 1 : 0;
387
+
388
+ FLBuilderModel::update_admin_settings_option( '_fl_builder_enabled_templates', $enabled_templates, true );
389
+ FLBuilderModel::update_admin_settings_option( '_fl_builder_user_templates_admin', $admin_ui_enabled, true );
390
+
391
+ if ( class_exists( 'FLBuilderTemplatesOverride' ) ) {
392
+ FLBuilderTemplatesOverride::save_admin_settings();
 
 
393
  }
394
  }
395
  }
406
  if ( isset( $_POST['fl-post-types-nonce'] ) && wp_verify_nonce( $_POST['fl-post-types-nonce'], 'post-types' ) ) {
407
 
408
  if ( is_network_admin() ) {
 
409
  $post_types = sanitize_text_field( $_POST['fl-post-types'] );
410
  $post_types = str_replace( ' ', '', $post_types );
411
  $post_types = explode( ',', $post_types );
 
 
 
 
 
412
  }
413
  else {
414
 
415
  $post_types = array();
416
 
417
+ if ( isset( $_POST['fl-post-types'] ) && is_array( $_POST['fl-post-types'] ) ) {
418
  $post_types = array_map( 'sanitize_text_field', $_POST['fl-post-types'] );
419
  }
 
 
420
  }
421
+
422
+ FLBuilderModel::update_admin_settings_option( '_fl_builder_post_types', $post_types, true );
423
  }
424
  }
425
 
537
  */
538
  static private function update_enabled_icons( $enabled_icons = array() )
539
  {
540
+ FLBuilderModel::update_admin_settings_option( '_fl_builder_enabled_icons', $enabled_icons, true );
 
 
 
 
 
 
 
 
 
541
  }
542
 
543
  /**
553
 
554
  $capability = sanitize_text_field( $_POST['fl-editing-capability'] );
555
 
556
+ FLBuilderModel::update_admin_settings_option( '_fl_builder_editing_capability', $capability, true );
 
 
 
 
 
 
 
 
557
  }
558
  }
559
 
571
  $branding = wp_kses_post( $_POST['fl-branding'] );
572
  $branding_icon = sanitize_text_field( $_POST['fl-branding-icon'] );
573
 
574
+ FLBuilderModel::update_admin_settings_option( '_fl_builder_branding', $branding, false );
575
+ FLBuilderModel::update_admin_settings_option( '_fl_builder_branding_icon', $branding_icon, false );
 
 
 
 
 
 
576
  }
577
  }
578
 
637
  return;
638
  }
639
 
640
+ FLBuilderModel::update_admin_settings_option( '_fl_builder_help_button', $settings, false );
 
 
 
 
 
 
641
  }
642
  }
643
 
650
  */
651
  static private function clear_cache()
652
  {
653
+ if ( ! current_user_can( 'delete_users' ) ) {
654
  return;
655
  }
656
  else if ( isset( $_POST['fl-cache-nonce'] ) && wp_verify_nonce( $_POST['fl-cache-nonce'], 'cache' ) ) {
classes/class-fl-builder-admin.php CHANGED
@@ -149,20 +149,24 @@ final class FLBuilderAdmin {
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)) {
149
  }
150
 
151
  /**
152
+ * Loads builder classes if they exist.
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-template-settings.php';
160
+ $overrides_class = FL_BUILDER_DIR . 'classes/class-fl-builder-templates-override.php';
161
  $ms_class = FL_BUILDER_DIR . 'classes/class-fl-builder-multisite.php';
162
  $ms_settings_class = FL_BUILDER_DIR . 'classes/class-fl-builder-multisite-settings.php';
163
 
164
  if(file_exists($templates_class)) {
165
  require_once $templates_class;
166
  }
167
+ if(file_exists($overrides_class)) {
168
+ require_once $overrides_class;
169
+ }
170
  if(is_multisite()) {
171
 
172
  if(file_exists($ms_class)) {
classes/class-fl-builder-model.php CHANGED
@@ -148,19 +148,21 @@ final class FLBuilderModel {
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
  /**
@@ -235,24 +237,10 @@ final class FLBuilderModel {
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';
@@ -277,20 +265,29 @@ final class FLBuilderModel {
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
  }
@@ -1644,29 +1641,11 @@ final class FLBuilderModel {
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
  /**
@@ -2061,7 +2040,12 @@ final class FLBuilderModel {
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
  /**
@@ -2678,28 +2662,22 @@ final class FLBuilderModel {
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
  /**
@@ -2711,9 +2689,10 @@ final class FLBuilderModel {
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',
@@ -2728,17 +2707,87 @@ final class FLBuilderModel {
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
  /**
@@ -2762,11 +2811,13 @@ final class FLBuilderModel {
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;
@@ -2784,7 +2835,9 @@ final class FLBuilderModel {
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);
@@ -2894,15 +2947,28 @@ final class FLBuilderModel {
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
 
@@ -2992,6 +3058,59 @@ final class FLBuilderModel {
2992
  file_put_contents(FL_BUILDER_DIR . 'data/templates.dat', serialize($updated));
2993
  }
2994
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2995
  /**
2996
  * Returns the custom branding string.
2997
  *
@@ -3000,24 +3119,9 @@ final class FLBuilderModel {
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
  /**
@@ -3028,24 +3132,9 @@ final class FLBuilderModel {
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
  /**
@@ -3056,28 +3145,9 @@ final class FLBuilderModel {
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
  /**
@@ -3089,28 +3159,9 @@ final class FLBuilderModel {
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
  /**
@@ -3143,24 +3194,9 @@ final class FLBuilderModel {
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
  /**
@@ -3219,6 +3255,63 @@ final class FLBuilderModel {
3219
  update_option( '_fl_builder_services', $services );
3220
  }
3221
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3222
  /**
3223
  * Returns the plugin basename for Beaver Builder.
3224
  *
@@ -3246,9 +3339,11 @@ final class FLBuilderModel {
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
 
148
  */
149
  static public function get_edit_url( $post_id = false )
150
  {
 
 
151
  if ( false === $post_id ) {
152
+ global $post;
153
+ }
154
+ else {
155
+ $post = get_post( $post_id );
156
  }
157
 
158
+ $url = add_query_arg( 'fl_builder', '', get_permalink( $post->ID ) );
159
 
160
+ if ( 'draft' == $post->post_status ) {
161
+ return set_url_scheme( $url );
162
+ }
163
+ else {
164
+ return $url;
165
  }
 
 
166
  }
167
 
168
  /**
237
  */
238
  static public function get_post_types()
239
  {
240
+ $value = self::get_admin_settings_option( '_fl_builder_post_types', true );
 
 
 
 
 
 
 
 
 
 
 
 
 
241
 
242
+ if ( ! $value ) {
243
+ return array( 'page', 'fl-builder-template' );
 
244
  }
245
  else {
246
  $value[] = 'fl-builder-template';
265
  * is being worked on.
266
  *
267
  * @since 1.0
268
+ * @since 1.5.9 Trying to use the global $wp_the_query instead of $post to get the post id.
269
  * @return int|bool The post id or false.
270
  */
271
  static public function get_post_id()
272
  {
273
+ global $wp_the_query;
274
  global $post;
275
 
276
  $post_data = self::get_post_data();
277
 
278
+ // Get a post ID sent in an AJAX request.
279
+ if ( isset( $post_data['post_id'] ) ) {
280
  return $post_data['post_id'];
281
  }
282
+ // Get a post ID from the main query.
283
+ else if ( in_the_loop() && isset( $wp_the_query ) && isset( $wp_the_query->post ) ) {
284
+ return $wp_the_query->post->ID;
285
+ }
286
+ // Get a post ID in a query outside of the main loop.
287
+ else if ( isset( $post ) ) {
288
  return $post->ID;
289
  }
290
+ // No post ID found.
291
  else {
292
  return false;
293
  }
1641
  */
1642
  static public function get_enabled_modules()
1643
  {
1644
+ $default = array_keys( self::$modules );
 
1645
  $default[] = 'all';
1646
+ $value = self::get_admin_settings_option( '_fl_builder_enabled_modules', true );
1647
+
1648
+ return ( ! $value || in_array( 'all', $value ) ) ? $default : $value;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1649
  }
1650
 
1651
  /**
2040
  require_once FL_BUILDER_DIR . 'includes/row-settings.php';
2041
  require_once FL_BUILDER_DIR . 'includes/column-settings.php';
2042
  require_once FL_BUILDER_DIR . 'includes/module-settings.php';
2043
+
2044
+ $user_templates = FL_BUILDER_DIR . 'includes/user-template-settings.php';
2045
+
2046
+ if ( file_exists( $user_templates ) ) {
2047
+ require_once $user_templates;
2048
+ }
2049
  }
2050
 
2051
  /**
2662
  */
2663
  static public function get_enabled_templates()
2664
  {
2665
+ $value = self::get_admin_settings_option( '_fl_builder_enabled_templates', true );
2666
+
2667
+ return ! $value ? 'enabled' : $value;
2668
+ }
 
 
 
 
 
 
 
 
 
 
2669
 
2670
+ /**
2671
+ * Returns whether the user templates admin UI is enabled.
2672
+ *
2673
+ * @since 1.5.7
2674
+ * @return string
2675
+ */
2676
+ static public function is_user_templates_admin_enabled()
2677
+ {
2678
+ $value = self::get_admin_settings_option( '_fl_builder_user_templates_admin', true );
2679
+
2680
+ return ! $value ? 0 : $value;
2681
  }
2682
 
2683
  /**
2689
  static public function save_user_template()
2690
  {
2691
  $post_data = self::get_post_data();
2692
+ $settings = $post_data['settings'];
2693
 
2694
  $post_id = wp_insert_post(array(
2695
+ 'post_title' => $settings['name'],
2696
  'post_type' => 'fl-builder-template',
2697
  'post_status' => 'publish',
2698
  'ping_status' => 'closed',
2707
 
2708
  // Save the template layout data.
2709
  self::update_layout_data($data, 'published', $post_id);
2710
+
2711
+ // Enable the builder for this template.
2712
+ update_post_meta($post_id, '_fl_builder_enabled', true);
2713
  }
2714
 
2715
  /**
2716
  * Returns data for all user defined templates.
2717
  *
2718
  * @since 1.1.3
2719
+ * @since 1.5.7 Added support for template categories.
2720
  * @return array
2721
  */
2722
  static public function get_user_templates()
2723
  {
2724
+ $categorized = array(
2725
+ 'uncategorized' => array(
2726
+ 'name' => _x( 'Uncategorized', 'Default user template category.', 'fl-builder' ),
2727
+ 'templates' => array()
2728
+ )
2729
+ );
2730
+
2731
+ $posts = get_posts( array(
2732
+ 'post_type' => 'fl-builder-template',
2733
+ 'orderby' => 'menu_order title',
2734
+ 'order' => 'ASC',
2735
+ 'posts_per_page' => '-1',
2736
+ ) );
2737
+
2738
+ $templates = array();
2739
+
2740
+ // Loop through templates posts and build the templates array.
2741
+ foreach( $posts as $post ) {
2742
+
2743
+ if ( has_post_thumbnail( $post->ID ) ) {
2744
+ $image_data = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), 'medium' );
2745
+ $image = $image_data[0];
2746
+ }
2747
+ else {
2748
+ $image = FL_BUILDER_URL . 'img/templates/blank.jpg';
2749
+ }
2750
+
2751
+ $templates[] = array(
2752
+ 'id' => $post->ID,
2753
+ 'name' => $post->post_title,
2754
+ 'image' => $image
2755
+ );
2756
+ }
2757
+
2758
+ // Loop through templates and build the categorized array.
2759
+ foreach ( $templates as $template ) {
2760
+
2761
+ $cats = wp_get_post_terms( $template['id'], 'fl-builder-template-category' );
2762
+
2763
+ if ( 0 === count( $cats ) || is_wp_error( $cats ) ) {
2764
+ $categorized['uncategorized']['templates'][] = $template;
2765
+ }
2766
+ else {
2767
+
2768
+ foreach ( $cats as $cat ) {
2769
+
2770
+ if ( ! isset( $categorized[ $cat->slug ] ) ) {
2771
+ $categorized[ $cat->slug ] = array(
2772
+ 'name' => $cat->name,
2773
+ 'templates' => array()
2774
+ );
2775
+ }
2776
+
2777
+ $categorized[ $cat->slug ]['templates'][] = $template;
2778
+ }
2779
+ }
2780
+ }
2781
+
2782
+ // Unset the uncategorized cat if no templates.
2783
+ if ( 0 === count( $categorized['uncategorized']['templates'] ) ) {
2784
+ unset( $categorized['uncategorized'] );
2785
+ }
2786
+
2787
+ return array(
2788
+ 'templates' => $templates,
2789
+ 'categorized' => $categorized
2790
+ );
2791
  }
2792
 
2793
  /**
2811
  * Apply a user defined template to the current layout.
2812
  *
2813
  * @since 1.1.3
2814
+ * @since 1.5.7 Added param for passing template data.
2815
  * @param int $template_id The post ID of the template to apply.
2816
  * @param bool $append Whether to append the new template or replacing the existing layout.
2817
+ * @param string $template_data Template data to use instead of data for the passed id.
2818
  * @return void
2819
  */
2820
+ static public function apply_user_template($template_id = null, $append = false, $template_data = null)
2821
  {
2822
  $post_data = self::get_post_data();
2823
  $template_id = isset($post_data['template_id']) ? $post_data['template_id'] : $template_id;
2835
  if($template_id != 'blank') {
2836
 
2837
  // Get the template data.
2838
+ if ( ! $template_data ) {
2839
+ $template_data = self::get_layout_data('published', $template_id);
2840
+ }
2841
 
2842
  // Get new ids for the template nodes.
2843
  $template_data = self::generate_new_node_ids($template_data);
2947
  * Apply a core template.
2948
  *
2949
  * @since 1.0
2950
+ * @since 1.5.7. Added logic for overriding core templates.
2951
  * @param int $index The index of the template to apply.
2952
  * @param bool $append Whether to append the new template or replacing the existing layout.
2953
  * @return void
2954
  */
2955
  static public function apply_template($index = 0, $append = false)
2956
  {
2957
+ $post_data = self::get_post_data();
2958
+ $index = isset($post_data['template_id']) ? $post_data['template_id'] : $index;
2959
+ $append = isset($post_data['append']) ? $post_data['append'] : $append;
2960
+
2961
+ // Apply a user defined template if core templates are overriden.
2962
+ if ( class_exists( 'FLBuilderTemplatesOverride' ) ) {
2963
+
2964
+ $success = FLBuilderTemplatesOverride::apply( $index, $append );
2965
+
2966
+ if ( $success ) {
2967
+ return;
2968
+ }
2969
+ }
2970
+
2971
+ // Apply a core template.
2972
  $template = self::get_template($index);
2973
  $row_position = self::next_node_position('row');
2974
 
3058
  file_put_contents(FL_BUILDER_DIR . 'data/templates.dat', serialize($updated));
3059
  }
3060
 
3061
+ /**
3062
+ * Returns template data needed for the template selector.
3063
+ *
3064
+ * @since 1.5.7
3065
+ * @return array
3066
+ */
3067
+ static public function get_template_selector_data()
3068
+ {
3069
+ // Return data for overriding core templates?
3070
+ if ( class_exists( 'FLBuilderTemplatesOverride' ) ) {
3071
+
3072
+ $data = FLBuilderTemplatesOverride::get_selector_data();
3073
+
3074
+ if ( $data ) {
3075
+ return $data;
3076
+ }
3077
+ }
3078
+
3079
+ // Return data for core templates.
3080
+ $category_labels = array(
3081
+ 'landing' => __( 'Home Pages', 'fl-builder' ),
3082
+ 'company' => __( 'Content Pages', 'fl-builder' )
3083
+ );
3084
+ $categorized = array();
3085
+ $templates = array();
3086
+
3087
+ foreach( self::get_templates() as $key => $template ) {
3088
+ $templates[] = array(
3089
+ 'id' => $key,
3090
+ 'name' => $template->name,
3091
+ 'image' => FL_BUILDER_URL . 'img/templates/' . $template->image,
3092
+ 'category' => $template->category
3093
+ );
3094
+ }
3095
+
3096
+ foreach( $templates as $template ) {
3097
+
3098
+ if ( ! isset( $categorized[ $template['category'] ] ) ) {
3099
+ $categorized[ $template['category'] ] = array(
3100
+ 'name' => $category_labels[ $template['category'] ],
3101
+ 'templates' => array()
3102
+ );
3103
+ }
3104
+
3105
+ $categorized[ $template['category'] ]['templates'][] = $template;
3106
+ }
3107
+
3108
+ return array(
3109
+ 'templates' => $templates,
3110
+ 'categorized' => $categorized
3111
+ );
3112
+ }
3113
+
3114
  /**
3115
  * Returns the custom branding string.
3116
  *
3119
  */
3120
  static public function get_branding()
3121
  {
3122
+ $value = self::get_admin_settings_option( '_fl_builder_branding', false );
3123
+
3124
+ return ! $value ? __( 'Page Builder', 'fl-builder' ) : stripcslashes( $value );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3125
  }
3126
 
3127
  /**
3132
  */
3133
  static public function get_branding_icon()
3134
  {
3135
+ $value = self::get_admin_settings_option( '_fl_builder_branding_icon', false );
3136
+
3137
+ return false === $value ? FL_BUILDER_URL . 'img/beaver.png' : $value;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3138
  }
3139
 
3140
  /**
3145
  */
3146
  static public function get_enabled_icons()
3147
  {
3148
+ $value = self::get_admin_settings_option( '_fl_builder_enabled_icons', true );
3149
+
3150
+ return ! $value ? array( 'font-awesome', 'foundation-icons', 'dashicons' ) : $value;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3151
  }
3152
 
3153
  /**
3159
  */
3160
  static public function get_editing_capability()
3161
  {
3162
+ $value = self::get_admin_settings_option( '_fl_builder_editing_capability', true );
3163
+
3164
+ return ! $value ? 'edit_posts' : $value;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3165
  }
3166
 
3167
  /**
3194
  */
3195
  static public function get_help_button_settings()
3196
  {
3197
+ $value = self::get_admin_settings_option( '_fl_builder_help_button', false );
3198
+
3199
+ return false === $value ? self::get_help_button_defaults() : $value;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3200
  }
3201
 
3202
  /**
3255
  update_option( '_fl_builder_services', $services );
3256
  }
3257
 
3258
+ /**
3259
+ * Returns an option from the database for
3260
+ * the admin settings page.
3261
+ *
3262
+ * @since 1.5.7
3263
+ * @param string $key The option key.
3264
+ * @param bool $network_override Whether to allow the network admin setting to be overridden on subsites.
3265
+ * @return mixed
3266
+ */
3267
+ static public function get_admin_settings_option( $key, $network_override = true )
3268
+ {
3269
+ // Get the site-wide option if we're in the network admin.
3270
+ if ( is_network_admin() ) {
3271
+ $value = get_site_option( $key );
3272
+ }
3273
+ // Get the site-wide option if network overrides aren't allowed.
3274
+ else if ( ! $network_override && class_exists( 'FLBuilderMultisiteSettings' ) ) {
3275
+ $value = get_site_option( $key );
3276
+ }
3277
+ // Network overrides are allowed. Return the subsite option if it exists.
3278
+ else if ( class_exists( 'FLBuilderMultisiteSettings' ) ) {
3279
+ $value = get_option( $key );
3280
+ $value = false === $value ? get_site_option( $key ) : $value;
3281
+ }
3282
+ // This must be a single site install. Get the single site option.
3283
+ else {
3284
+ $value = get_option( $key );
3285
+ }
3286
+
3287
+ return $value;
3288
+ }
3289
+
3290
+ /**
3291
+ * Updates an option from the admin settings page.
3292
+ *
3293
+ * @since 1.5.7
3294
+ * @param string $key The option key.
3295
+ * @param mixed $value The value to update.
3296
+ * @param bool $network_override Whether to allow the network admin setting to be overridden on subsites.
3297
+ * @return mixed
3298
+ */
3299
+ static public function update_admin_settings_option( $key, $value, $network_override = true )
3300
+ {
3301
+ // Update the site-wide option since we're in the network admin.
3302
+ if ( is_network_admin() ) {
3303
+ update_site_option( $key, $value );
3304
+ }
3305
+ // Delete the option if network overrides are allowed and the override checkbox isn't checked.
3306
+ else if ( $network_override && FLBuilderAdminSettings::multisite_support() && ! isset( $_POST['fl-override-ms'] ) ) {
3307
+ delete_option( $key );
3308
+ }
3309
+ // Update the option for single install or subsite.
3310
+ else {
3311
+ update_option( $key, $value );
3312
+ }
3313
+ }
3314
+
3315
  /**
3316
  * Returns the plugin basename for Beaver Builder.
3317
  *
3339
  delete_option('_fl_builder_settings');
3340
  delete_option('_fl_builder_enabled_modules');
3341
  delete_option('_fl_builder_enabled_templates');
3342
+ delete_option('_fl_builder_user_templates_admin');
3343
  delete_option('_fl_builder_post_types');
3344
  delete_option('_fl_builder_enabled_icons');
3345
  delete_option('_fl_builder_branding');
3346
+ delete_option('_fl_builder_branding_icon');
3347
  delete_option('_fl_builder_editing_capability');
3348
  delete_option('_fl_builder_help_button');
3349
 
classes/class-fl-builder-service-hatchbuck.php ADDED
@@ -0,0 +1,256 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Helper class for the Hatchbuck API.
5
+ *
6
+ * @since 1.5.8
7
+ */
8
+ final class FLBuilderServiceHatchbuck extends FLBuilderService {
9
+
10
+ /**
11
+ * The ID for this service.
12
+ *
13
+ * @since 1.5.8
14
+ * @var string $id
15
+ */
16
+ public $id = 'hatchbuck';
17
+
18
+ /**
19
+ * The API url for this service.
20
+ *
21
+ * @since 1.5.8
22
+ * @access private
23
+ * @var string $api_url
24
+ */
25
+ private $api_url = 'https://api.hatchbuck.com/api/v1/contact/';
26
+
27
+ /**
28
+ * Test the API connection.
29
+ *
30
+ * @since 1.5.8
31
+ * @param array $fields {
32
+ * @type string $api_key A valid API key.
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
+ // Try to connect and store the connection data.
51
+ else {
52
+
53
+ $result = wp_remote_post( $this->api_url . 'search?api_key=' . $fields['api_key'], array(
54
+ 'method' => 'POST',
55
+ 'timeout' => 60,
56
+ 'headers' => array(
57
+ 'Content-Type' => 'application/json'
58
+ ),
59
+ 'body' => array(),
60
+ ) );
61
+
62
+ if ( 401 == $result['response']['code'] ) {
63
+ $response['error'] = __( 'Error: Please check your API key.', 'fl-builder' );
64
+ }
65
+ else {
66
+ $response['data'] = array( 'api_key' => $fields['api_key'] );
67
+ }
68
+ }
69
+
70
+ return $response;
71
+ }
72
+
73
+ /**
74
+ * Renders the markup for the connection settings.
75
+ *
76
+ * @since 1.5.8
77
+ * @return string The connection settings markup.
78
+ */
79
+ public function render_connect_settings()
80
+ {
81
+ ob_start();
82
+
83
+ FLBuilder::render_settings_field( 'api_key', array(
84
+ 'row_class' => 'fl-builder-service-connect-row',
85
+ 'class' => 'fl-builder-service-connect-input',
86
+ 'type' => 'text',
87
+ 'label' => __( 'API Key', 'fl-builder' ),
88
+ 'help' => __( 'Your API key can be found in your Hatchbuck account under Account Settings > Web API.', 'fl-builder' ),
89
+ 'preview' => array(
90
+ 'type' => 'none'
91
+ )
92
+ ));
93
+
94
+ return ob_get_clean();
95
+ }
96
+
97
+ /**
98
+ * Render the markup for service specific fields.
99
+ *
100
+ * @since 1.5.8
101
+ * @param string $account The name of the saved account.
102
+ * @param object $settings Saved module settings.
103
+ * @return array {
104
+ * @type bool|string $error The error message or false if no error.
105
+ * @type string $html The field markup.
106
+ * }
107
+ */
108
+ public function render_fields( $account, $settings )
109
+ {
110
+ $response = array(
111
+ 'error' => false,
112
+ 'html' => $this->render_tag_field( $settings )
113
+ );
114
+
115
+ return $response;
116
+ }
117
+
118
+ /**
119
+ * Render markup for the tag field.
120
+ *
121
+ * @since 1.5.8
122
+ * @param object $settings Saved module settings.
123
+ * @return string The markup for the tag field.
124
+ * @access private
125
+ */
126
+ private function render_tag_field( $settings )
127
+ {
128
+ ob_start();
129
+
130
+ FLBuilder::render_settings_field( 'list_id', array(
131
+ 'row_class' => 'fl-builder-service-field-row',
132
+ 'class' => 'fl-builder-service-list-select',
133
+ 'type' => 'text',
134
+ 'label' => _x( 'Tag', 'A tag to add to contacts in Hatchbuck when they subscribe.', 'fl-builder' ),
135
+ 'preview' => array(
136
+ 'type' => 'none'
137
+ )
138
+ ), $settings);
139
+
140
+ return ob_get_clean();
141
+ }
142
+
143
+ /**
144
+ * Subscribe an email address to Hatchbuck.
145
+ *
146
+ * @since 1.5.8
147
+ * @param object $settings A module settings object.
148
+ * @param string $email The email to subscribe.
149
+ * @param string $name Optional. The full name of the person subscribing.
150
+ * @return array {
151
+ * @type bool|string $error The error message or false if no error.
152
+ * }
153
+ */
154
+ public function subscribe( $settings, $email, $name = false )
155
+ {
156
+ $contact_id = null;
157
+ $account_data = $this->get_account_data( $settings->service_account );
158
+ $response = array( 'error' => false );
159
+
160
+ if ( ! $account_data ) {
161
+ $response['error'] = __( 'There was an error subscribing to Hatchbuck. The account is no longer connected.', 'fl-builder' );
162
+ }
163
+ else {
164
+
165
+ // Build the data array.
166
+ $data = array(
167
+ 'emails' => array(
168
+ array(
169
+ 'address' => $email,
170
+ 'type' => 'Work'
171
+ )
172
+ ),
173
+ 'status' => array(
174
+ 'name' => 'Lead'
175
+ )
176
+ );
177
+
178
+ // Check if the contact exists.
179
+ $result = wp_remote_post( $this->api_url . 'search?api_key=' . $account_data['api_key'], array(
180
+ 'method' => 'POST',
181
+ 'timeout' => 60,
182
+ 'headers' => array(
183
+ 'Content-Type' => 'application/json'
184
+ ),
185
+ 'body' => json_encode( $data ),
186
+ ) );
187
+
188
+ // Return if we have an API key error.
189
+ if ( 401 == $result['response']['code'] ) {
190
+ $response['error'] = __( 'There was an error subscribing to Hatchbuck. The API key is invalid.', 'fl-builder' );
191
+ return $response; // Invalid API key.
192
+ }
193
+ // Contact already exists.
194
+ else if ( 200 == $result['response']['code'] ) {
195
+ $result_data = json_decode( $result['body'] );
196
+ $contact_id = $result_data[0]->contactId;
197
+ }
198
+ // Generic error. Contact not found should be 400.
199
+ else if ( 400 != $result['response']['code'] ) {
200
+ $response['error'] = __( 'There was an error subscribing to Hatchbuck.', 'fl-builder' );
201
+ return $response;
202
+ }
203
+
204
+ // Add the contact if it doesn't exist.
205
+ if ( ! $contact_id ) {
206
+
207
+ // Add the name to the data array if we have one.
208
+ if ( $name ) {
209
+
210
+ $names = explode( ' ', $name );
211
+
212
+ if ( isset( $names[0] ) ) {
213
+ $data['firstName'] = $names[0];
214
+ }
215
+ if ( isset( $names[1] ) ) {
216
+ $data['lastName'] = $names[1];
217
+ }
218
+ }
219
+
220
+ // Add the contact to Hatchbuck.
221
+ $result = wp_remote_post( $this->api_url . '?api_key=' . $account_data['api_key'], array(
222
+ 'method' => 'POST',
223
+ 'timeout' => 60,
224
+ 'headers' => array(
225
+ 'Content-Type' => 'application/json'
226
+ ),
227
+ 'body' => json_encode( $data ),
228
+ ) );
229
+
230
+ // Return if we have an error.
231
+ if ( 200 != $result['response']['code'] ) {
232
+ $response['error'] = __( 'There was an error subscribing to Hatchbuck.', 'fl-builder' );
233
+ return $response;
234
+ }
235
+
236
+ // Get the result data that contains the new contact ID.
237
+ $result_data = json_decode( $result['body'] );
238
+ $contact_id = $result_data->contactId;
239
+ }
240
+
241
+ // Add the tag to the contact.
242
+ $result = wp_remote_post( $this->api_url . $contact_id . '/Tags?api_key=' . $account_data['api_key'], array(
243
+ 'method' => 'POST',
244
+ 'timeout' => 60,
245
+ 'headers' => array(
246
+ 'Content-Type' => 'application/json'
247
+ ),
248
+ 'body' => json_encode( array(
249
+ array( 'name' => $settings->list_id )
250
+ ) ),
251
+ ) );
252
+ }
253
+
254
+ return $response;
255
+ }
256
+ }
classes/class-fl-builder-service-infusionsoft.php ADDED
@@ -0,0 +1,300 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Helper class for the Infusionsoft API.
5
+ *
6
+ * @since 1.5.7
7
+ */
8
+ final class FLBuilderServiceInfusionsoft extends FLBuilderService {
9
+
10
+ /**
11
+ * The ID for this service.
12
+ *
13
+ * @since 1.5.7
14
+ * @var string $id
15
+ */
16
+ public $id = 'infusionsoft';
17
+
18
+ /**
19
+ * @since 1.5.7
20
+ * @var object $api_instance
21
+ * @access private
22
+ */
23
+ private $api_instance = null;
24
+
25
+ /**
26
+ * Get an instance of the API.
27
+ *
28
+ * @since 1.5.7
29
+ * @param string $app_id A valid app ID.
30
+ * @param string $api_key A valid API key.
31
+ * @return object The API instance.
32
+ */
33
+ public function get_api( $app_id, $api_key )
34
+ {
35
+ if ( $this->api_instance ) {
36
+ return $this->api_instance;
37
+ }
38
+ if ( ! class_exists( 'iSDK' ) ) {
39
+ require_once FL_BUILDER_DIR . 'includes/vendor/infusionsoft/isdk.php';
40
+ }
41
+
42
+ try {
43
+ $this->api_instance = new iSDK();
44
+ $this->api_instance->cfgCon( $app_id, $api_key, 'throw' );
45
+ }
46
+ catch ( iSDKException $e ) {
47
+ $this->api_instance = new stdClass();
48
+ $this->api_instance->error = sprintf(
49
+ __( 'There was an error connecting to Infusionsoft. %s', 'fl-builder' ),
50
+ $e->getMessage()
51
+ );
52
+ }
53
+
54
+ return $this->api_instance;
55
+ }
56
+
57
+ /**
58
+ * Test the API connection.
59
+ *
60
+ * @since 1.5.7
61
+ * @param array $fields {
62
+ * @type string $app_id A valid app ID.
63
+ * @type string $api_key A valid API key.
64
+ * }
65
+ * @return array{
66
+ * @type bool|string $error The error message or false if no error.
67
+ * @type array $data An array of data used to make the connection.
68
+ * }
69
+ */
70
+ public function connect( $fields = array() )
71
+ {
72
+ $response = array(
73
+ 'error' => false,
74
+ 'data' => array()
75
+ );
76
+
77
+ // Make sure we have an API key.
78
+ if ( ! isset( $fields['api_key'] ) || empty( $fields['api_key'] ) ) {
79
+ $response['error'] = __( 'Error: You must provide an API key.', 'fl-builder' );
80
+ }
81
+ // Make sure we have an app ID.
82
+ else if ( ! isset( $fields['app_id'] ) || empty( $fields['app_id'] ) ) {
83
+ $response['error'] = __( 'Error: You must provide an app ID.', 'fl-builder' );
84
+ }
85
+ // Try to connect and store the connection data.
86
+ else {
87
+
88
+ $api = $this->get_api( $fields['app_id'], $fields['api_key'] );
89
+
90
+ if ( isset( $api->error ) ) {
91
+ $response['error'] = $api->error;
92
+ }
93
+ else {
94
+ $response['data'] = array(
95
+ 'app_id' => $fields['app_id'],
96
+ 'api_key' => $fields['api_key']
97
+ );
98
+ }
99
+ }
100
+
101
+ return $response;
102
+ }
103
+
104
+ /**
105
+ * Renders the markup for the connection settings.
106
+ *
107
+ * @since 1.5.7
108
+ * @return string The connection settings markup.
109
+ */
110
+ public function render_connect_settings()
111
+ {
112
+ ob_start();
113
+
114
+ FLBuilder::render_settings_field( 'app_id', array(
115
+ 'row_class' => 'fl-builder-service-connect-row',
116
+ 'class' => 'fl-builder-service-connect-input',
117
+ 'type' => 'text',
118
+ 'label' => __( 'App ID', 'fl-builder' ),
119
+ 'help' => __( 'Your App ID can be found in the URL for your account. For example, if the URL for your account is myaccount.infusionsoft.com, your App ID would be <strong>myaccount</strong>.', 'fl-builder' ),
120
+ 'preview' => array(
121
+ 'type' => 'none'
122
+ )
123
+ ));
124
+
125
+ FLBuilder::render_settings_field( 'api_key', array(
126
+ 'row_class' => 'fl-builder-service-connect-row',
127
+ 'class' => 'fl-builder-service-connect-input',
128
+ 'type' => 'text',
129
+ 'label' => __( 'API Key', 'fl-builder' ),
130
+ 'help' => __( 'Your API key can be found in your Infusionsoft account under Admin > Settings > Application > API > Encrypted Key.', 'fl-builder' ),
131
+ 'preview' => array(
132
+ 'type' => 'none'
133
+ )
134
+ ));
135
+
136
+ return ob_get_clean();
137
+ }
138
+
139
+ /**
140
+ * Render the markup for service specific fields.
141
+ *
142
+ * @since 1.5.7
143
+ * @param string $account The name of the saved account.
144
+ * @param object $settings Saved module settings.
145
+ * @return array {
146
+ * @type bool|string $error The error message or false if no error.
147
+ * @type string $html The field markup.
148
+ * }
149
+ */
150
+ public function render_fields( $account, $settings )
151
+ {
152
+ $account_data = $this->get_account_data( $account );
153
+ $api = $this->get_api( $account_data['app_id'], $account_data['api_key'] );
154
+ $page = 0;
155
+ $lists = array();
156
+ $response = array(
157
+ 'error' => false,
158
+ 'html' => ''
159
+ );
160
+
161
+ if ( isset( $api->error ) ) {
162
+ $response['error'] = $api->error;
163
+ }
164
+ else {
165
+
166
+ while ( true ) {
167
+
168
+ $result = $api->dsQuery(
169
+ 'ContactGroup',
170
+ 1000,
171
+ $page,
172
+ array( 'Id' => '%' ),
173
+ array( 'Id', 'GroupName' )
174
+ );
175
+
176
+ $lists = array_merge( $lists, $result );
177
+
178
+ if ( count( $result ) < 1000 ) {
179
+ break;
180
+ }
181
+
182
+ $page ++;
183
+ }
184
+
185
+ $response['html'] = $this->render_list_field( $lists, $settings );
186
+ }
187
+
188
+ return $response;
189
+ }
190
+
191
+ /**
192
+ * Render markup for the list field.
193
+ *
194
+ * @since 1.5.7
195
+ * @param array $lists List data from the API.
196
+ * @param object $settings Saved module settings.
197
+ * @return string The markup for the list field.
198
+ * @access private
199
+ */
200
+ private function render_list_field( $lists, $settings )
201
+ {
202
+ ob_start();
203
+
204
+ $options = array( '' => __( 'Choose...', 'fl-builder' ) );
205
+
206
+ foreach ( $lists as $list ) {
207
+ $options[ $list['Id'] ] = $list['GroupName'];
208
+ }
209
+
210
+ FLBuilder::render_settings_field( 'list_id', array(
211
+ 'row_class' => 'fl-builder-service-field-row',
212
+ 'class' => 'fl-builder-service-list-select',
213
+ 'type' => 'select',
214
+ 'label' => _x( 'List', 'An email list from a third party provider.', 'fl-builder' ),
215
+ 'options' => $options,
216
+ 'preview' => array(
217
+ 'type' => 'none'
218
+ )
219
+ ), $settings);
220
+
221
+ return ob_get_clean();
222
+ }
223
+
224
+ /**
225
+ * Subscribe an email address to Infusionsoft.
226
+ *
227
+ * @since 1.5.7
228
+ * @param object $settings A module settings object.
229
+ * @param string $email The email to subscribe.
230
+ * @param string $name Optional. The full name of the person subscribing.
231
+ * @return array {
232
+ * @type bool|string $error The error message or false if no error.
233
+ * }
234
+ */
235
+ public function subscribe( $settings, $email, $name = false )
236
+ {
237
+ $account_data = $this->get_account_data( $settings->service_account );
238
+ $response = array( 'error' => false );
239
+ $data = array();
240
+
241
+ if ( ! $account_data ) {
242
+ $response['error'] = __( 'There was an error subscribing to Infusionsoft. The account is no longer connected.', 'fl-builder' );
243
+ }
244
+ else {
245
+
246
+ $api = $this->get_api( $account_data['app_id'], $account_data['api_key'] );
247
+
248
+ if ( isset( $api->error ) ) {
249
+ $response['error'] = $api->error;
250
+ }
251
+ else {
252
+
253
+ if ( $name ) {
254
+
255
+ $names = explode( ' ', $name );
256
+
257
+ if ( isset( $names[0] ) && isset( $names[1] ) ) {
258
+ $data = array(
259
+ 'FirstName' => $names[0],
260
+ 'LastName' => $names[1],
261
+ 'Email' => $email
262
+ );
263
+ }
264
+ else {
265
+ $data = array(
266
+ 'FirstName' => $name,
267
+ 'Email' => $email
268
+ );
269
+ }
270
+ }
271
+ else {
272
+ $data = array( 'Email' => $email );
273
+ }
274
+
275
+ try {
276
+
277
+ $contact = $api->findByEmail( $email, array( 'Id' ) );
278
+
279
+ if ( isset( $contact[0] ) && ! empty( $contact[0]['Id'] ) ) {
280
+ $contact_id = $contact[0]['Id'];
281
+ $api->updateCon( $contact_id, $data );
282
+