Funnel Builder by CartFlows – Create High Converting Sales Funnels For WordPress - Version 1.5.10

Version Description

Download this release

Release Info

Developer sandesh055
Plugin Icon Funnel Builder by CartFlows – Create High Converting Sales Funnels For WordPress
Version 1.5.10
Comparing to
See all releases

Code changes from version 1.5.9 to 1.5.10

Files changed (32) hide show
  1. assets/js/import.js +29 -40
  2. assets/min-js/import.min.js +1 -1
  3. cartflows.php +2 -2
  4. changelog.txt +5 -0
  5. classes/batch-process/class-cartflows-batch-process.php +295 -270
  6. classes/batch-process/class-cartflows-importer-elementor.php +86 -69
  7. classes/batch-process/class-cartflows-importer-gutenberg-batch.php +63 -0
  8. classes/batch-process/class-cartflows-importer-gutenberg.php +90 -0
  9. classes/batch-process/helpers/class-cartflows-importer-image.php +53 -43
  10. classes/class-cartflows-admin-fields.php +271 -267
  11. classes/class-cartflows-admin.php +657 -653
  12. classes/class-cartflows-api.php +382 -381
  13. classes/class-cartflows-cloning.php +465 -465
  14. classes/class-cartflows-helper.php +787 -777
  15. classes/class-cartflows-importer.php +1739 -1692
  16. classes/class-cartflows-loader.php +1 -1
  17. classes/class-cartflows-meta-fields.php +6 -6
  18. classes/class-cartflows-utils.php +591 -591
  19. classes/class-cartflows-wizard.php +698 -688
  20. includes/admin/cartflows-admin.php +35 -35
  21. includes/admin/cartflows-general.php +525 -522
  22. includes/meta-fields/generate-product-repeater.php +99 -99
  23. includes/meta-fields/get-field.php +42 -42
  24. includes/meta-fields/get-product-selection-repeater.php +117 -117
  25. languages/cartflows.pot +2050 -2045
  26. modules/checkout/classes/class-cartflows-checkout-markup.php +1260 -1260
  27. modules/checkout/classes/class-cartflows-checkout-meta.php +959 -959
  28. modules/flow/classes/class-cartflows-flow-post-type.php +383 -383
  29. modules/flow/classes/class-cartflows-permalink.php +158 -159
  30. modules/flow/classes/class-cartflows-step-post-type.php +496 -496
  31. readme.txt +9 -2
  32. theme-support/astra/class-cartflows-astra-compatibility.php +113 -113
assets/js/import.js CHANGED
@@ -110,7 +110,8 @@ var CartFlowsAjaxQueue = (function() {
110
  * Init
111
  */
112
  init: function()
113
- {
 
114
  this._bind();
115
 
116
  if( 'other' !== CartFlowsImportVars.default_page_builder ) {
@@ -660,32 +661,25 @@ var CartFlowsAjaxQueue = (function() {
660
 
661
  _process_cache_remote_flows: function() {
662
 
 
663
 
664
- if( 'gutenberg' == CartFlowsImportVars.default_page_builder ) {
665
- CartFlowsImport._cache_remote_flows();
666
- } else {
667
- var page_builder_plugins = CartFlowsImportVars.required_plugins[ CartFlowsImportVars.default_page_builder ]['plugins'];
668
-
669
- var anyInactive = true;
670
 
671
- $.each( page_builder_plugins, function( index, plugin ) {
672
 
673
- if( anyInactive ) {
674
- if( 'install' === plugin.status || 'activate' === plugin.status ) {
675
- anyInactive = false;
676
- }
677
  }
678
- });
679
-
680
- if( false === anyInactive ) {
681
- $('.wcf-page-builder-notice').html( wp.template('cartflows-page-builder-notice') );
682
- $('#wcf-remote-flow-list').find( '.spinner' ).remove();
683
- } else {
684
- CartFlowsImport._cache_remote_flows();
685
  }
686
- }
687
-
688
 
 
 
 
 
 
 
689
  },
690
 
691
  _cache_remote_flows: function() {
@@ -755,30 +749,25 @@ var CartFlowsAjaxQueue = (function() {
755
 
756
  _process_cache_remote_steps: function() {
757
 
758
- if( 'gutenberg' == CartFlowsImportVars.default_page_builder ) {
759
- CartFlowsImport._cache_remote_steps();
760
- } else {
761
-
762
- var page_builder_plugins = CartFlowsImportVars.required_plugins[ CartFlowsImportVars.default_page_builder ]['plugins'];
763
-
764
 
765
- var anyInactive = true;
766
 
767
- $.each( page_builder_plugins, function( index, plugin ) {
768
 
769
- if( anyInactive ) {
770
- if( 'install' === plugin.status || 'activate' === plugin.status ) {
771
- anyInactive = false;
772
- }
773
  }
774
- });
775
-
776
- if( false === anyInactive ) {
777
- $('.wcf-page-builder-notice').html( wp.template('cartflows-page-builder-notice') );
778
- $('#wcf-remote-step-list').find( '.spinner' ).remove();
779
- } else {
780
- CartFlowsImport._cache_remote_steps();
781
  }
 
 
 
 
 
 
 
782
  }
783
 
784
  },
110
  * Init
111
  */
112
  init: function()
113
+ {
114
+
115
  this._bind();
116
 
117
  if( 'other' !== CartFlowsImportVars.default_page_builder ) {
661
 
662
  _process_cache_remote_flows: function() {
663
 
664
+ var page_builder_plugins = CartFlowsImportVars.required_plugins[ CartFlowsImportVars.default_page_builder ]['plugins'];
665
 
666
+ var anyInactive = true;
 
 
 
 
 
667
 
668
+ $.each( page_builder_plugins, function( index, plugin ) {
669
 
670
+ if( anyInactive ) {
671
+ if( 'install' === plugin.status || 'activate' === plugin.status ) {
672
+ anyInactive = false;
 
673
  }
 
 
 
 
 
 
 
674
  }
675
+ });
 
676
 
677
+ if( false === anyInactive ) {
678
+ $('.wcf-page-builder-notice').html( wp.template('cartflows-page-builder-notice') );
679
+ $('#wcf-remote-flow-list').find( '.spinner' ).remove();
680
+ } else {
681
+ CartFlowsImport._cache_remote_flows();
682
+ }
683
  },
684
 
685
  _cache_remote_flows: function() {
749
 
750
  _process_cache_remote_steps: function() {
751
 
752
+ var page_builder_plugins = CartFlowsImportVars.required_plugins[ CartFlowsImportVars.default_page_builder ]['plugins'];
753
+
 
 
 
 
754
 
755
+ var anyInactive = true;
756
 
757
+ $.each( page_builder_plugins, function( index, plugin ) {
758
 
759
+ if( anyInactive ) {
760
+ if( 'install' === plugin.status || 'activate' === plugin.status ) {
761
+ anyInactive = false;
 
762
  }
 
 
 
 
 
 
 
763
  }
764
+ });
765
+
766
+ if( false === anyInactive ) {
767
+ $('.wcf-page-builder-notice').html( wp.template('cartflows-page-builder-notice') );
768
+ $('#wcf-remote-step-list').find( '.spinner' ).remove();
769
+ } else {
770
+ CartFlowsImport._cache_remote_steps();
771
  }
772
 
773
  },
assets/min-js/import.min.js CHANGED
@@ -1 +1 @@
1
- var CartFlowsAjaxQueue=function(){var a=[];return{add:function(t){a.push(t)},remove:function(t){-1<jQuery.inArray(t,a)&&a.splice($.inArray(t,a),1)},run:function(){var t,e=this;a.length?(t=a[0].complete,a[0].complete=function(){"function"==typeof t&&t(),a.shift(),e.run.apply(e,[])},jQuery.ajax(a[0])):e.tid=setTimeout(function(){e.run.apply(e,[])},1e3)},stop:function(){a=[],clearTimeout(this.tid)}}}();!function(c){CartFlowsImport={doc:c(document),wrap:c(".wcf-flow-steps-data-wrap"),inner:c(".wcf-flow-steps-data-wrap-importer"),post_id:c("#post_ID").val(),_ref:null,_api_step_type:{},_api_params:{},all_steps:0,remaining_steps:0,remaining_install_plugins:0,remaining_active_plugins:0,woo_required_steps:["checkout","upsell","downsell","thankyou","optin"],step_order:["landing","checkout","upsell","downsell","thankyou","optin"],new_step_names:{landing:"Landing",checkout:"Checkout (Woo)",upsell:"Upsell (Woo)",downsell:"Downsell (Woo)",thankyou:"Thank You (Woo)",optin:"Optin (Woo)"},init:function(){if(this._bind(),"other"!==CartFlowsImportVars.default_page_builder&&(c(".post-type-cartflows_flow").hasClass("edit-php")&&this._process_cache_remote_flows(),c(".post-type-cartflows_flow").hasClass("post-php")&&this._process_cache_remote_steps()),c(".post-type-cartflows_flow").hasClass("edit-php")&&null!==this._getParamFromURL("add-new-flow")&&this._render_remote_flows(),c(".post-type-cartflows_flow").hasClass("post-php")&&null!==this._getParamFromURL("add-new-step")&&this._render_remote_steps(),this._getParamFromURL("highlight-step-id")){var t=c('.wcf-step-wrap[data-id="'+this._getParamFromURL("highlight-step-id")+'"]');t.length&&c("html, body").animate({scrollTop:t.offset().top},1500)}if(c(".post-type-cartflows_flow").hasClass("edit-php")){var e=c(".edit-php.post-type-cartflows_flow").find(".page-title-action:first");e.after('<a href="'+CartFlowsImportVars.export_url+'" class="page-title-action">Export</a>'),e.after('<a href="'+CartFlowsImportVars.import_url+'" class="page-title-action">Import</a>')}},_getParamFromURL:function(t,e){e=e||window.location.href,t=t.replace(/[\[\]]/g,"\\$&");var a=new RegExp("[?&]"+t+"(=([^&#]*)|&|#|$)").exec(e);return a?a[2]?decodeURIComponent(a[2].replace(/\+/g," ")):"":null},_bind:function(){var t=CartFlowsImport;t.doc.on("click",".wcf-install-plugin",t._install_plugin),t.doc.on("cartflows-api-request-fail",t._api_request_failed),t.doc.on("click","#wcf-get-started-steps a, .wcf-create-from-scratch-link",t._toggle_ready_templates),t.doc.on("click",".cartflows-flow-import-blank",t._create_default_flow),t.doc.on("click","#wcf-remote-flow-importer .wcf-page-builder-links a",t._filterFlowPageBuilderClick),t.doc.on("click","#wcf-remote-step-importer #wcf-categories .step-type-filter-links a",t._filterBlankStepCategoryClick),t.doc.on("change","#wcf-remote-step-importer #wcf-scratch-steps-categories .step-type-filter-links",t._filterBlankStepCategoryChange),t.doc.on("click","#wcf-get-started-steps",t._filterBlankStepCategoryChange),t.doc.on("click","#wcf-remote-step-importer .wcf-page-builder-links a",t._filterStepPageBuilderClick),t.doc.on("click",".cartflows-step-import-blank:not(.get-pro)",t._create_blank_step),t.doc.on("click","#wcf-remote-step-importer .cartflows-step-import",t._process_import_step),t.doc.on("click","#wcf-remote-flow-importer .cartflows-step-import",t._process_import_flow),t.doc.on("click",".cartflows-preview-flow-step",t._preview_individual),t.doc.on("add_template_to_page-fail",t._add_template_to_page_fail),c("body").on("thickbox:iframe:loaded",t._previewLoaded),c(document).on("keyup input","#wcf-remote-step-importer .wcf-flow-search-input",t._remote_step_search),c(document).on("click",".actions a",t._previewResponsive),c(document).on("click",".page-title-action:first",t._render_remote_flows),c(document).on("click",".wcf-trigger-popup",t._render_remote_steps),c(document).on("click",".wcf-templates-popup-overlay",t._close_template_popup),c(document).on("click",".wcf-popup-close-wrap .close-icon",t._close_template_popup),c(document).on("wp-plugin-install-success",t._installSuccess),c(document).on("click",".wcf-activate-wc",t._installWc)},_install_plugin:function(t){t.preventDefault();var e=c(this);if(!e.hasClass("updating-message")){c("#wcf-remote-flow-importer").addClass("request-process"),c("#wcf-remote-step-importer").addClass("request-process"),e.addClass("updating-message button");var a=CartFlowsImportVars.required_plugins[CartFlowsImportVars.default_page_builder].plugins;c.each(a,function(t,e){"install"===e.status&&CartFlowsImport.remaining_install_plugins++,"activate"===e.status&&CartFlowsImport.remaining_active_plugins++}),CartFlowsImport.remaining_install_plugins?CartFlowsImport._install_all_plugins():CartFlowsImport.remaining_active_plugins?CartFlowsImport._activate_all_plugins():c("#wcf-remote-flow-importer").length?CartFlowsImport._cache_remote_flows():c("#wcf-remote-step-importer").length&&CartFlowsImport._cache_remote_steps()}},_install_all_plugins:function(){var t=CartFlowsImportVars.required_plugins[CartFlowsImportVars.default_page_builder].plugins;c.each(t,function(t,e){"install"===e.status&&wp.updates.queue.push({action:"install-plugin",data:{slug:e.slug}})}),wp.updates.queueChecker()},_activate_all_plugins:function(){if(CartFlowsImport.remaining_active_plugins||CartFlowsImport.remaining_install_plugins){var t=CartFlowsImportVars.required_plugins[CartFlowsImportVars.default_page_builder].plugins;CartFlowsAjaxQueue.stop(),CartFlowsAjaxQueue.run(),c.each(t,function(t,e){"activate"===e.status&&CartFlowsAjaxQueue.add({url:CartFlowsImportVars.ajaxurl,type:"POST",data:{action:"cartflows_activate_plugin",plugin_init:e.init,security:CartFlowsImportVars.cartflows_activate_plugin_nonce},success:function(t){CartFlowsImport.remaining_active_plugins--,CartFlowsImport.remaining_active_plugins||CartFlowsImport.remaining_install_plugins||(c("#wcf-remote-flow-importer").length?CartFlowsImport._cache_remote_flows():c("#wcf-remote-step-importer").length&&CartFlowsImport._cache_remote_steps())}})})}else c("#wcf-remote-flow-importer").length?CartFlowsImport._cache_remote_flows():c("#wcf-remote-step-importer").length&&CartFlowsImport._cache_remote_steps()},_installSuccess:function(t,a){t.preventDefault(),"no"===CartFlowsImportVars.is_wc_activated&&CartFlowsImport._activateWc();var e=CartFlowsImportVars.required_plugins[CartFlowsImportVars.default_page_builder].plugins;c.each(e,function(t,e){"install"===e.status&&a.slug===e.slug&&c.ajax({url:ajaxurl,type:"POST",data:{action:"cartflows_activate_plugin",plugin_init:e.init,security:CartFlowsImportVars.cartflows_activate_plugin_nonce}}).done(function(t,e,a){CartFlowsImport.remaining_install_plugins--,CartFlowsImport.remaining_install_plugins||CartFlowsImport._activate_all_plugins()})})},_api_request_failed:function(t,e,a,s){"error"==s&&(c("#wcf-remote-content-failed").length||c("#wcf-ready-templates").html(wp.template("cartflows-website-unreachable")))},_toggle_ready_templates:function(t){t.preventDefault();var e=c(this).data("slug")||"";c("#wcf-get-started-steps").find("a").removeClass("current"),c("#wcf-get-started-steps").find('a[data-slug="'+e+'"]').addClass("current"),"canvas"==e?(c("#wcf-ready-templates").hide(),c("#wcf-start-from-scratch").show()):(c("#wcf-ready-templates").show(),c("#wcf-start-from-scratch").hide()),!c(".wcf-page-builder-notice").length&&c("#wcf-remote-step-importer").length&&CartFlowsImport._showSteps()},_switch_step_tab:function(t){t.preventDefault();var e=c(".wcf-tab > li.active > a").attr("href");c(".wcf-tab > li.active").removeClass("active"),c(this).parents("li").addClass("active"),c(e).removeClass("active"),c(e).addClass("hide");var a=c(this).attr("href");c(a).removeClass("hide"),c(a).addClass("active")},_remote_step_search:function(t){t.preventDefault(),c(".step-type-filter-links").find("option").removeClass("current"),c(".step-type-filter-links").find("option:first-child").addClass("current"),window.clearTimeout(CartFlowsImport._ref),CartFlowsImport._ref=window.setTimeout(function(){CartFlowsImport._ref=null,CartFlowsImport._showSteps()},500)},_previewResponsive:function(t){t.preventDefault();var e=c(this).find(".dashicons"),a=e.attr("data-view")||"";c("#TB_window").removeClass("desktop tablet mobile"),c("#TB_window").addClass(a),c(".actions .dashicons").removeClass("active"),e.addClass("active"),c("#TB_iframeContent").removeClass(),c("#TB_iframeContent").addClass(a)},_filterStepPageBuilderClick:function(t){t.preventDefault(),c(this).parents("ul").find("a").removeClass("current"),c(this).addClass("current");var e=c(".step-type-filter-links .current").data("slug")||"";"upsell"===e||"downsell"===e?c(".wcf-template-notice").show():c(".wcf-template-notice").hide(),c(".wcf-page-builder-notice").html(""),c("#wcf-remote-step-list").html('<span class="spinner is-active"></span>'),CartFlowsImport._showSteps()},_filterBlankStepCategoryClick:function(t){t.preventDefault(),c(".wcf-page-builder-notice").html("");var e=c(this).data("group")||"";e&&(c("#wcf-scratch-steps-categories .step-type-filter-links").val(e),c("#wcf-scratch-steps-categories .step-type-filter-links option").removeClass("current"),c('#wcf-scratch-steps-categories .step-type-filter-links option[data-group="'+e+'"]').addClass("current")),c(".step-type-filter-links").find("a").removeClass("current"),c(this).addClass("current"),$step_type=c(this).data("slug"),"upsell"===$step_type||"downsell"===$step_type?c(".wcf-template-notice").show():c(".wcf-template-notice").hide(),""!=CartFlowsImportVars._is_pro_active||"upsell"!=$step_type&&"downsell"!=$step_type?(c(".cartflows-step-import-blank").text("Create Step"),c(".cartflows-step-import-blank").removeClass("get-pro"),c(".cartflows-step-import-blank").removeAttr("target")):(c(".cartflows-step-import-blank").text("Get Pro"),c(".cartflows-step-import-blank").attr("href",CartFlowsImportVars.domain_url),c(".cartflows-step-import-blank").attr("target","_blank"),c(".cartflows-step-import-blank").addClass("get-pro")),c("#wcf-remote-step-list").html('<span class="spinner is-active"></span>'),CartFlowsImport._showSteps()},_filterBlankStepCategoryChange:function(t){t.preventDefault(),c(".wcf-notice-wrap").remove(),c(".cartflows-step-import-blank").css("pointer-events","auto").removeClass("disabled");var e=c(".step-type-filter-links").find("option:selected").val()||"";if(e&&(c(".step-type-filter-links").val(e),c(".step-type-filter-links").find("a").removeClass("current"),c(".step-type-filter-links").find('a[data-group="'+e+'"]').addClass("current")),c(".step-type-filter-links").find("option").removeClass("current"),c(".step-type-filter-links").find("option:selected").addClass("current"),$step_type=c(".step-type-filter-links").find("option:selected").data("slug"),!("no"!==CartFlowsImportVars.is_wc_installed&&"no"!==CartFlowsImportVars.is_wc_activated||"upsell"!==$step_type&&"downsell"!==$step_type&&"checkout"!==$step_type&&"thankyou"!==$step_type))return c(".cartflows-step-import-blank").after("<p class='wcf-notice-wrap' style='text-align: center'>You need WooCommerce plugin installed and actived to use this product flow. <br/><br/> <a href='#' class='wcf-activate-wc button-secondary'> Click here to install and activate WooCommerce </a> </p>"),void c(".cartflows-step-import-blank").addClass("disabled").css("pointer-events","none");"upsell"===$step_type||"downsell"===$step_type?c(".wcf-template-notice").show():c(".wcf-template-notice").hide(),""!=CartFlowsImportVars._is_pro_active||"upsell"!=$step_type&&"downsell"!=$step_type?(c(".cartflows-step-import-blank").text("Create Step"),c(".cartflows-step-import-blank").removeClass("get-pro"),c(".cartflows-step-import-blank").removeAttr("target")):(c(".cartflows-step-import-blank").text("Get Pro"),c(".cartflows-step-import-blank").attr("href",CartFlowsImportVars.domain_url),c(".cartflows-step-import-blank").attr("target","_blank"),c(".cartflows-step-import-blank").addClass("get-pro")),!c(".wcf-page-builder-notice").length&&c("#wcf-remote-step-importer").length&&(c("#wcf-remote-step-list").html('<span class="spinner is-active"></span>'),CartFlowsImport._showSteps())},_showSteps:function(){var t={licence_args:CartFlowsImportVars.licence_args,per_page:100,_fields:CartFlowsImportVars.step_fields.toString()},e=c("#wcf-categories .step-type-filter-links").find(".current").data("group")||"",s=c("#wcf-categories .step-type-filter-links").find(".current").data("slug");""!==e&&"all"!==e&&(t[CartFlowsImportVars.step_type]=e);e=c("#wcf-page-builders .wcf-page-builder-links").find(".current").data("group")||"",s=c("#wcf-page-builders .wcf-page-builder-links").find(".current").data("slug")||"";var r=c("#wcf-page-builders .wcf-page-builder-links").find(".current").data("title")||"Page Builder";""!==e&&"all"!==e&&(t[CartFlowsImportVars.step_page_builder]=e);var a={remote_slug:CartFlowsImportVars.step,slug:CartFlowsImportVars.step+"?"+decodeURIComponent(c.param(t))};CartFlowsAPI._api_request(a,function(a){a.current_step_type=s,"yes"!==CartFlowsImportVars.is_wc_activated&&c.each(a.items,function(t,e){a.items[t].woo_required=!1,0<=c.inArray(e.step_type.slug,CartFlowsImport.woo_required_steps)&&(a.items[t].woo_required=!0)});var t=wp.template("cartflows-steps-list");parseInt(a.items_count)?c("#wcf-remote-step-list").html(t(a)):(c("#wcf-remote-step-list").html(wp.template("cartflows-no-steps")),c(".cartflows-no-steps").find(".description").html("We are working on ready templates designed with "+r+'.<br/>Meanwhile you can <a href="#" data-slug="canvas" class="wcf-create-from-scratch-link">create your own designs</a> easily.')),c(".wcf-page-builder-notice").remove(),c("#wcf-remote-step-importer").removeClass("request-process")})},_apiAddParam_per_page:function(){CartFlowsImport._api_params.per_page=100},_apiAddParam_licence_args:function(){CartFlowsImport._api_params.licence_args=CartFlowsImportVars.licence_args},_apiAddParam_search:function(){var t=c(".wcf-flow-search-input").val()||"";""!==t&&(CartFlowsImport._api_params.search=t)},_close_popup:function(){c("#cartflows-steps").fadeOut(),c("body").removeClass("cartflows-popup-is-open")},_post_auto_save:function(){var t=c("#title"),e=c("#title-prompt-text"),a=CartFlowsImport;t.val()||(t.val("CartFlows #"+a.post_id),e.length&&e.remove()),wp.autosave&&wp.autosave.server.triggerSave()},_process_cache_remote_flows:function(){if("gutenberg"==CartFlowsImportVars.default_page_builder)CartFlowsImport._cache_remote_flows();else{var t=CartFlowsImportVars.required_plugins[CartFlowsImportVars.default_page_builder].plugins,a=!0;c.each(t,function(t,e){a&&("install"!==e.status&&"activate"!==e.status||(a=!1))}),!1===a?(c(".wcf-page-builder-notice").html(wp.template("cartflows-page-builder-notice")),c("#wcf-remote-flow-list").find(".spinner").remove()):CartFlowsImport._cache_remote_flows()}},_cache_remote_flows:function(){CartFlowsImport;var t={search:CartFlowsImportVars.default_page_builder,licence_args:CartFlowsImportVars.licence_args,hide_empty:!1,_fields:CartFlowsImportVars.flow_page_builder_fields.toString()},e={remote_slug:CartFlowsImportVars.flow_page_builder,slug:CartFlowsImportVars.flow_page_builder+"?"+decodeURIComponent(c.param(t)),wrapper_class:"wcf-page-builder-links filter-links",show_all:!1};CartFlowsAPI._api_request(e,function(t){var e=wp.template("cartflows-term-filters");c("#wcf-page-builders").html(e(t)),c("#wcf-page-builders").find("li:first a").addClass("current");var a={licence_args:CartFlowsImportVars.licence_args,hide_empty:!0,_fields:CartFlowsImportVars.flow_type_fields.toString()},s={remote_slug:CartFlowsImportVars.flow_type,slug:CartFlowsImportVars.flow_type+"?"+decodeURIComponent(c.param(a)),wrapper_class:"flow-type-filter-links filter-links",show_all:!1};CartFlowsAPI._api_request(s,function(t){var e=wp.template("cartflows-term-filters");c("#wcf-categories").html(e(t)),c("#wcf-categories").find("li:first a").addClass("current"),CartFlowsImport._showFlows()})})},_render_remote_flows:function(t){t&&t.preventDefault(),c("#wcf-remote-flow-importer").addClass("open"),c("html").addClass("wcf-popup-open")},_process_cache_remote_steps:function(){if("gutenberg"==CartFlowsImportVars.default_page_builder)CartFlowsImport._cache_remote_steps();else{var t=CartFlowsImportVars.required_plugins[CartFlowsImportVars.default_page_builder].plugins,a=!0;c.each(t,function(t,e){a&&("install"!==e.status&&"activate"!==e.status||(a=!1))}),!1===a?(c(".wcf-page-builder-notice").html(wp.template("cartflows-page-builder-notice")),c("#wcf-remote-step-list").find(".spinner").remove()):CartFlowsImport._cache_remote_steps()}},mapOrder:function(t,r,o){return t.sort(function(t,e){var a=t[o],s=e[o];return-1===r.indexOf(a)?0:r.indexOf(a)>r.indexOf(s)?1:-1}),t},_cache_remote_steps:function(){CartFlowsImport;c("html").addClass("wcf-steps-loading");var t={search:CartFlowsImportVars.default_page_builder,licence_args:CartFlowsImportVars.licence_args,hide_empty:!1,_fields:CartFlowsImportVars.step_page_builder_fields.toString()},e={remote_slug:CartFlowsImportVars.step_page_builder,slug:CartFlowsImportVars.step_page_builder+"?"+decodeURIComponent(c.param(t)),wrapper_class:"wcf-page-builder-links filter-links",show_all:!1};CartFlowsAPI._api_request(e,function(t){var e=wp.template("cartflows-term-filters");c("#wcf-page-builders").html(e(t)),c("#wcf-page-builders").find("li:first a").addClass("current")});t={licence_args:CartFlowsImportVars.licence_args,_fields:CartFlowsImportVars.step_type_fields.toString()},e={remote_slug:CartFlowsImportVars.step_type,slug:CartFlowsImportVars.step_type+"?"+decodeURIComponent(c.param(t)),wrapper_class:"step-type-filter-links filter-links",show_all:!1};CartFlowsAPI._api_request(e,function(t){t.items=CartFlowsImport.mapOrder(t.items,CartFlowsImport.step_order,"slug");var s=t,r=t.items_count;if(t.items)for(key in t.items){t.items[key].name=CartFlowsImport.new_step_names[t.items[key].slug];var e={licence_args:CartFlowsImportVars.licence_args,per_page:100,_fields:CartFlowsImportVars.step_fields.toString()};e[CartFlowsImportVars.step_type]=t.items[key].id;var a={remote_slug:CartFlowsImportVars.step,slug:CartFlowsImportVars.step+"?"+decodeURIComponent(c.param(e))};CartFlowsAPI._api_request(a,function(t){var e=wp.template("cartflows-steps-list");if(parseInt(t.items_count)?c("#wcf-remote-step-list").html(e(t)):c("#wcf-remote-step-list").html(wp.template("cartflows-no-steps")),0==--r){var a=wp.template("cartflows-term-filters-dropdown");e=wp.template("cartflows-term-filters");c("#wcf-categories").html(e(s)),c("#wcf-scratch-steps-categories").html(a(s)),c("#wcf-scratch-steps-categories").find("option:first").addClass("current"),c("#wcf-categories").find("li a[data-slug=landing]").addClass("current"),c(".wcf-page-builder-notice").remove(),c("#wcf-remote-content").find(".spinner").remove(),CartFlowsImport._showSteps(),c("html").removeClass("wcf-steps-loading")}})}})},_render_remote_steps:function(t){t&&t.preventDefault(),c("#wcf-remote-step-importer").addClass("open"),c("html").addClass("wcf-popup-open")},_categorize_data:function(t){var s=[];return c.each(t,function(t,e){var a=e.step_type.slug;void 0===s[a]&&(s[a]=[]),s[a].push(e)}),s},_close_template_popup:function(t){(c(t.target).hasClass("wcf-templates-popup-overlay")||c(t.target).hasClass("close-icon"))&&(c(".wcf-templates-popup-overlay").hasClass("request-process")||(c("html").removeClass("wcf-popup-open"),c(".wcf-templates-popup-overlay").removeClass("open")))},_ajax:function(t,s,r){var o=CartFlowsImport;c.ajax({url:ajaxurl,type:"POST",data:t}).done(function(t,e,a){s&&"function"==typeof s&&s({request:t,status:e,XHR:a}),o.doc.trigger(r+"-done",[t,e,a])}).fail(function(t,e){o.doc.trigger(r+"-fail",[t,e])}).always(function(){o.doc.trigger(r+"-always")})},_empty:function(t){if("number"==typeof t||"boolean"==typeof t)return!1;if(null==t)return!0;if(void 0!==t.length)return 0==t.length;var e=0;for(var a in t)t.hasOwnProperty(a)&&e++;return 0==e},_preview_individual:function(){var t=c(this).data("id")||"",e=c(this).data("href")||"";c(".cartflows-preview-flow-step").removeClass("active"),c('.cartflows-preview-flow-step[data-id="'+t+'"]').addClass("active"),c("#TB_window").addClass("cartflows-thickbox-loading"),c("#TB_iframeContent").removeAttr("onload"),c("#TB_iframeContent").removeAttr("src"),c("#TB_iframeContent").attr("src",e),c("#TB_iframeContent").attr("onload","CartFlowsImport.showIframe()")},showIframe:function(){c("#TB_load").remove(),c("#TB_window").css({visibility:"visible"}),c("#TB_window").removeClass("cartflows-thickbox-loading")},_previewLoaded:function(t){t.preventDefault(),c("#TB_window").removeClass("cartflows-thickbox-loading")},_filterFlowPageBuilderClick:function(t){t.preventDefault(),c(this).parents("ul").find("a").removeClass("current"),c(this).addClass("current"),c(".wcf-page-builder-notice").html(""),c("#wcf-remote-flow-list").html('<span class="spinner is-active"></span>'),CartFlowsImport._showFlows()},_showFlows:function(){var t={licence_args:CartFlowsImportVars.licence_args,_fields:CartFlowsImportVars.flow_fields.toString(),per_page:100},e=c("#wcf-page-builders .wcf-page-builder-links").find(".current").data("group")||"";c("#wcf-page-builders .wcf-page-builder-links").find(".current").data("slug"),c("#wcf-page-builders .wcf-page-builder-links").find(".current").data("title");""!==e&&"all"!==e&&(t[CartFlowsImportVars.flow_page_builder]=e);var a={remote_slug:CartFlowsImportVars.flow,slug:CartFlowsImportVars.flow+"?"+decodeURIComponent(c.param(t))};CartFlowsAPI._api_request(a,function(s){"yes"!==CartFlowsImportVars.is_wc_activated&&c.each(s.items,function(a,t){s.items[a].woo_required=!1,c.each(t.flow_steps,function(t,e){0<=c.inArray(e.type,CartFlowsImport.woo_required_steps)&&(s.items[a].woo_required=!0)})});var t=wp.template("cartflows-flows-list");parseInt(s.items_count)?c("#wcf-remote-flow-list").html(t(s)):c("#wcf-remote-flow-list").html(wp.template("cartflows-no-flows")),c(".wcf-page-builder-notice").remove(),c("#wcf-remote-flow-importer").removeClass("request-process")})},_create_default_flow:function(t){t.preventDefault();var e=CartFlowsImport,a=c(this);if(!a.hasClass("updating-message")){c("#wcf-remote-flow-importer").addClass("request-process"),a.addClass("updating-message").text("Creating Flow.."),a.parents(".template").addClass("importing");var s={action:"cartflows_default_flow",security:cartflows_admin.cf_default_flow_nonce};e._ajax(s,function(t){if(t.request.success){var e=t.request.data;setTimeout(function(){a.removeClass("updating-message").text("Flow Created! Redirecting.."),window.location=CartFlowsImportVars.admin_url+"post.php?post="+e+"&action=edit"},3e3)}})}},_activate_plugin:function(t){var e=CartFlowsImport,a={action:"cartflows_activate_plugin",plugin_init:t,security:CartFlowsImportVars.cartflows_activate_plugin_nonce};e._ajax(a,function(t){})},_process_import_flow:function(t){t.preventDefault();var s=c(this);if(!s.hasClass("updating-message")){c("#wcf-remote-flow-importer").addClass("request-process");var e=CartFlowsImport;s.text("Creating Flow.."),s.addClass("updating-message"),s.parents(".template").addClass("importing");var a=s.data("flow-steps")||"",r=""!==a?JSON.parse("["+a+"]"):[],o={action:"cartflows_create_flow",security:cartflows_admin.cf_create_flow_nonce};e._ajax(o,function(t){if(t.request.success){var a=t.request.data;r&&(CartFlowsAjaxQueue.stop(),CartFlowsAjaxQueue.run(),CartFlowsImport.all_steps=r.length,s.addClass("updating-message").text("Importing Step 1 of "+CartFlowsImport.all_steps),c.each(r,function(t,e){CartFlowsAjaxQueue.add({url:CartFlowsImportVars.ajaxurl,type:"POST",data:{action:"cartflows_import_flow_step",flow_id:a,template_id:e,security:cartflows_admin.cf_import_flow_step_nonce},success:function(t){CartFlowsImport.remaining_steps=CartFlowsImport.remaining_steps+1,CartFlowsImport.remaining_steps===CartFlowsImport.all_steps?(s.addClass("updating-message").text("Imported Step "+CartFlowsImport.remaining_steps+" of "+CartFlowsImport.all_steps),setTimeout(function(){s.removeClass("updating-message").text("All Imported! Redirecting.."),window.location=CartFlowsImportVars.admin_url+"post.php?post="+a+"&action=edit"},3e3)):s.addClass("updating-message").text("Importing Step "+CartFlowsImport.remaining_steps+" of "+CartFlowsImport.all_steps)},error:function(t){CartFlowsImport.remaining_steps=CartFlowsImport.remaining_steps+1,template=s.parents(".template.importing"),template.find(".preview").addClass("notice notice-warning").removeClass("preview").text(t.statusText),CartFlowsImport.remaining_steps===CartFlowsImport.all_steps?(s.addClass("updating-message").text("Failed "+CartFlowsImport.remaining_steps+" of "+CartFlowsImport.all_steps),setTimeout(function(){s.removeClass("updating-message button-primary").addClass("disabled")},3e3)):s.addClass("updating-message").text("Failed "+CartFlowsImport.remaining_steps+" of "+CartFlowsImport.all_steps)},fail:function(t){CartFlowsImport.remaining_steps=CartFlowsImport.remaining_steps+1,CartFlowsImport.remaining_steps===CartFlowsImport.all_steps?(s.addClass("updating-message").text("Imported "+CartFlowsImport.remaining_steps+" of "+CartFlowsImport.all_steps),setTimeout(function(){s.removeClass("updating-message").text("All Step Imported! Reloading.."),location.reload()},3e3)):s.addClass("updating-message").text("Importing "+CartFlowsImport.remaining_steps+" of "+CartFlowsImport.all_steps)}})}))}})}},_handle_error:function(t){c(".cartflows-step-import.updating-message").addClass("updating-message").text(t.errorMessage)},_create_blank_step:function(t){t.preventDefault();var a=c(this),e=CartFlowsImport,s=c("#post_ID").val(),r=c("#wcf-scratch-steps-categories .step-type-filter-links .current").data("slug")||"",o=c("#wcf-scratch-steps-categories .step-type-filter-links .current").data("title")||"",l=r,i=c('.wcf-step-wrap[data-term-slug="'+r+'"]').length||1,p=o+" "+(parseInt(i)+1);if(all_step_type=["landing","checkout","thankyou"],c("#wcf-start-from-scratch .wcf-notice-wrap ").remove(),""!==l){if(CartFlowsImportVars._is_pro_active||"upsell"!==l&&"downsell"!==l){if(a.parents(".template").addClass("importing"),!CartFlowsImportVars._is_pro_active)if("-1"!=jQuery.inArray(l,all_step_type))if(0<c('.wcf-step-wrap[data-term-slug="'+l+'"]').length){a.parents(".template.importing");return a.removeClass("importing updating-message").text("Import Failed!"),void c("#wcf-start-from-scratch .inner").append('<div class="wcf-notice-wrap"><div class="notice notice-warning"><p>Upgrade to Pro for adding more than one '+l.charAt(0).toUpperCase()+l.slice(1)+" step.</p></div></div>")}if(c("#wcf-remote-step-importer").addClass("request-process"),c(".cartflows-step-import").addClass("disabled"),a.addClass("importing updating-message").text("Creating.."),c("body").hasClass("post-type-cartflows_flow")){var n={action:"cartflows_step_create_blank",flow_id:s,step_type:l,step_title:p,security:cartflows_admin.cf_step_create_blank_nonce};e._ajax(n,function(t){CartFlowsImport;var e=a.parents(".template.importing");t.request.success?(a.text("Created. Reloading.."),setTimeout(function(){window.location.href=window.location.href+"&highlight-step-id="+t.request.data},3e3)):(a.removeClass("importing updating-message").text("Creating Failed!"),c("#wcf-remote-step-importer").removeClass("request-process"),e.find(".cartflows-step-preview").append("<div class='preview'></div>"),e.find(".preview").addClass("notice notice-warning").removeClass("preview").text(t.request.data))})}}}else c("#wcf-start-from-scratch .inner").append('<div class="wcf-notice-wrap"><div class="notice notice-info"><p>Please select the step type.</p></div></div>')},_process_import_step:function(t){t.preventDefault();var a=c(this),e=a.data("slug")||"",s=c('.wcf-step-wrap[data-term-slug="'+e+'"]').length||1;if((step_title=a.data("title")||"",step_custom_title=step_title+" "+(parseInt(s)+1),o=CartFlowsImport,all_step_slug=["landing","checkout","thankyou"],!CartFlowsImportVars._is_pro_active)&&("-1"!=jQuery.inArray(e,all_step_slug)&&0<c('.wcf-step-wrap[data-term-slug="'+e+'"]').length)){var r=a.parents(".template");return a.removeClass("importing updating-message").text("Import Failed!"),r.find(".preview").hide(),r.find("#wcf_create_notice").show().find("a").addClass("notice notice-warning ").text("Upgrade to Pro for adding more than one "+e.charAt(0).toUpperCase()+e.slice(1)+" step"),void c("#wcf-remote-step-importer").removeClass("request-process")}if(!a.hasClass("updating-message")){c("#wcf-remote-step-importer").addClass("request-process");var o=CartFlowsImport;a.addClass("updating-message"),a.parents(".template").addClass("importing");var l=a.data("template-id")||"",i=c("#post_ID").val(),p=e;o=CartFlowsImport;if(c(".cartflows-step-import-blank").addClass("disabled"),c(".cartflows-step-import").addClass("disabled"),a.addClass("importing updating-message").text("Importing.."),c("body").hasClass("post-type-cartflows_flow")){var n={action:"cartflows_step_import",flow_id:i,template_id:l,step_title:step_custom_title,step_type:p,security:cartflows_admin.cf_step_import_nonce};o._ajax(n,function(t){CartFlowsImport;var e=a.parents(".template.importing");t.request.success?(a.text("Imported. Reloading.."),setTimeout(function(){window.location.href=window.location.href+"&highlight-step-id="+t.request.data},3e3)):(c(".wcf-templates-popup-overlay").removeClass("request-process"),a.removeClass("importing updating-message").text("Import Failed!"),e.find(".preview").addClass("notice notice-warning").removeClass("preview").text(t.request.data))},"add_template_to_page")}}},_add_template_to_page_fail:function(t,e,a){t.preventDefault();CartFlowsImport;var s=c(".wcf-flow-steps-data-wrap-importer .template.importing");s.find(".cartflows-step-import").removeClass("importing updating-message").text("Import Failed!"),s.find(".preview").addClass("notice notice-warning").removeClass("preview").text(e.responseText)},_activateWc:function(t){c.ajax({url:ajaxurl,type:"POST",data:{action:"cartflows_activate_plugin",plugin_init:"woocommerce/woocommerce.php",security:CartFlowsImportVars.cartflows_activate_plugin_nonce}}).done(function(t,e,a){c(".wcf-notice-wrap").addClass("wcf-hidden"),c(".cartflows-template-selector").removeAttr("disabled"),CartFlowsImport.wc_installed=!0,CartFlowsImportVars.is_wc_installed="yes",CartFlowsImportVars.is_wc_activated="yes",location.reload(!0),window.location.search+="&add-new-flow"})},_installWc:function(t){c(this).addClass("updating-message button"),c(this).text(cartflows_admin.wc_activating_message),0==cartflows_admin.wc_status.installed?(wp.updates.shouldRequestFilesystemCredentials&&!wp.updates.ajaxLocked&&(wp.updates.requestFilesystemCredentials(t),$document.on("credential-modal-cancel",function(){c(".install-now.updating-message").removeClass("updating-message").text(wp.updates.l10n.installNow),wp.a11y.speak(wp.updates.l10n.updateCancel,"polite")})),wp.updates.installPlugin({slug:"woocommerce"})):CartFlowsImport._activateWc()}},c(function(){CartFlowsImport.init()})}(jQuery);
1
+ var CartFlowsAjaxQueue=function(){var a=[];return{add:function(t){a.push(t)},remove:function(t){-1<jQuery.inArray(t,a)&&a.splice($.inArray(t,a),1)},run:function(){var t,e=this;a.length?(t=a[0].complete,a[0].complete=function(){"function"==typeof t&&t(),a.shift(),e.run.apply(e,[])},jQuery.ajax(a[0])):e.tid=setTimeout(function(){e.run.apply(e,[])},1e3)},stop:function(){a=[],clearTimeout(this.tid)}}}();!function(c){CartFlowsImport={doc:c(document),wrap:c(".wcf-flow-steps-data-wrap"),inner:c(".wcf-flow-steps-data-wrap-importer"),post_id:c("#post_ID").val(),_ref:null,_api_step_type:{},_api_params:{},all_steps:0,remaining_steps:0,remaining_install_plugins:0,remaining_active_plugins:0,woo_required_steps:["checkout","upsell","downsell","thankyou","optin"],step_order:["landing","checkout","upsell","downsell","thankyou","optin"],new_step_names:{landing:"Landing",checkout:"Checkout (Woo)",upsell:"Upsell (Woo)",downsell:"Downsell (Woo)",thankyou:"Thank You (Woo)",optin:"Optin (Woo)"},init:function(){if(this._bind(),"other"!==CartFlowsImportVars.default_page_builder&&(c(".post-type-cartflows_flow").hasClass("edit-php")&&this._process_cache_remote_flows(),c(".post-type-cartflows_flow").hasClass("post-php")&&this._process_cache_remote_steps()),c(".post-type-cartflows_flow").hasClass("edit-php")&&null!==this._getParamFromURL("add-new-flow")&&this._render_remote_flows(),c(".post-type-cartflows_flow").hasClass("post-php")&&null!==this._getParamFromURL("add-new-step")&&this._render_remote_steps(),this._getParamFromURL("highlight-step-id")){var t=c('.wcf-step-wrap[data-id="'+this._getParamFromURL("highlight-step-id")+'"]');t.length&&c("html, body").animate({scrollTop:t.offset().top},1500)}if(c(".post-type-cartflows_flow").hasClass("edit-php")){var e=c(".edit-php.post-type-cartflows_flow").find(".page-title-action:first");e.after('<a href="'+CartFlowsImportVars.export_url+'" class="page-title-action">Export</a>'),e.after('<a href="'+CartFlowsImportVars.import_url+'" class="page-title-action">Import</a>')}},_getParamFromURL:function(t,e){e=e||window.location.href,t=t.replace(/[\[\]]/g,"\\$&");var a=new RegExp("[?&]"+t+"(=([^&#]*)|&|#|$)").exec(e);return a?a[2]?decodeURIComponent(a[2].replace(/\+/g," ")):"":null},_bind:function(){var t=CartFlowsImport;t.doc.on("click",".wcf-install-plugin",t._install_plugin),t.doc.on("cartflows-api-request-fail",t._api_request_failed),t.doc.on("click","#wcf-get-started-steps a, .wcf-create-from-scratch-link",t._toggle_ready_templates),t.doc.on("click",".cartflows-flow-import-blank",t._create_default_flow),t.doc.on("click","#wcf-remote-flow-importer .wcf-page-builder-links a",t._filterFlowPageBuilderClick),t.doc.on("click","#wcf-remote-step-importer #wcf-categories .step-type-filter-links a",t._filterBlankStepCategoryClick),t.doc.on("change","#wcf-remote-step-importer #wcf-scratch-steps-categories .step-type-filter-links",t._filterBlankStepCategoryChange),t.doc.on("click","#wcf-get-started-steps",t._filterBlankStepCategoryChange),t.doc.on("click","#wcf-remote-step-importer .wcf-page-builder-links a",t._filterStepPageBuilderClick),t.doc.on("click",".cartflows-step-import-blank:not(.get-pro)",t._create_blank_step),t.doc.on("click","#wcf-remote-step-importer .cartflows-step-import",t._process_import_step),t.doc.on("click","#wcf-remote-flow-importer .cartflows-step-import",t._process_import_flow),t.doc.on("click",".cartflows-preview-flow-step",t._preview_individual),t.doc.on("add_template_to_page-fail",t._add_template_to_page_fail),c("body").on("thickbox:iframe:loaded",t._previewLoaded),c(document).on("keyup input","#wcf-remote-step-importer .wcf-flow-search-input",t._remote_step_search),c(document).on("click",".actions a",t._previewResponsive),c(document).on("click",".page-title-action:first",t._render_remote_flows),c(document).on("click",".wcf-trigger-popup",t._render_remote_steps),c(document).on("click",".wcf-templates-popup-overlay",t._close_template_popup),c(document).on("click",".wcf-popup-close-wrap .close-icon",t._close_template_popup),c(document).on("wp-plugin-install-success",t._installSuccess),c(document).on("click",".wcf-activate-wc",t._installWc)},_install_plugin:function(t){t.preventDefault();var e=c(this);if(!e.hasClass("updating-message")){c("#wcf-remote-flow-importer").addClass("request-process"),c("#wcf-remote-step-importer").addClass("request-process"),e.addClass("updating-message button");var a=CartFlowsImportVars.required_plugins[CartFlowsImportVars.default_page_builder].plugins;c.each(a,function(t,e){"install"===e.status&&CartFlowsImport.remaining_install_plugins++,"activate"===e.status&&CartFlowsImport.remaining_active_plugins++}),CartFlowsImport.remaining_install_plugins?CartFlowsImport._install_all_plugins():CartFlowsImport.remaining_active_plugins?CartFlowsImport._activate_all_plugins():c("#wcf-remote-flow-importer").length?CartFlowsImport._cache_remote_flows():c("#wcf-remote-step-importer").length&&CartFlowsImport._cache_remote_steps()}},_install_all_plugins:function(){var t=CartFlowsImportVars.required_plugins[CartFlowsImportVars.default_page_builder].plugins;c.each(t,function(t,e){"install"===e.status&&wp.updates.queue.push({action:"install-plugin",data:{slug:e.slug}})}),wp.updates.queueChecker()},_activate_all_plugins:function(){if(CartFlowsImport.remaining_active_plugins||CartFlowsImport.remaining_install_plugins){var t=CartFlowsImportVars.required_plugins[CartFlowsImportVars.default_page_builder].plugins;CartFlowsAjaxQueue.stop(),CartFlowsAjaxQueue.run(),c.each(t,function(t,e){"activate"===e.status&&CartFlowsAjaxQueue.add({url:CartFlowsImportVars.ajaxurl,type:"POST",data:{action:"cartflows_activate_plugin",plugin_init:e.init,security:CartFlowsImportVars.cartflows_activate_plugin_nonce},success:function(t){CartFlowsImport.remaining_active_plugins--,CartFlowsImport.remaining_active_plugins||CartFlowsImport.remaining_install_plugins||(c("#wcf-remote-flow-importer").length?CartFlowsImport._cache_remote_flows():c("#wcf-remote-step-importer").length&&CartFlowsImport._cache_remote_steps())}})})}else c("#wcf-remote-flow-importer").length?CartFlowsImport._cache_remote_flows():c("#wcf-remote-step-importer").length&&CartFlowsImport._cache_remote_steps()},_installSuccess:function(t,a){t.preventDefault(),"no"===CartFlowsImportVars.is_wc_activated&&CartFlowsImport._activateWc();var e=CartFlowsImportVars.required_plugins[CartFlowsImportVars.default_page_builder].plugins;c.each(e,function(t,e){"install"===e.status&&a.slug===e.slug&&c.ajax({url:ajaxurl,type:"POST",data:{action:"cartflows_activate_plugin",plugin_init:e.init,security:CartFlowsImportVars.cartflows_activate_plugin_nonce}}).done(function(t,e,a){CartFlowsImport.remaining_install_plugins--,CartFlowsImport.remaining_install_plugins||CartFlowsImport._activate_all_plugins()})})},_api_request_failed:function(t,e,a,s){"error"==s&&(c("#wcf-remote-content-failed").length||c("#wcf-ready-templates").html(wp.template("cartflows-website-unreachable")))},_toggle_ready_templates:function(t){t.preventDefault();var e=c(this).data("slug")||"";c("#wcf-get-started-steps").find("a").removeClass("current"),c("#wcf-get-started-steps").find('a[data-slug="'+e+'"]').addClass("current"),"canvas"==e?(c("#wcf-ready-templates").hide(),c("#wcf-start-from-scratch").show()):(c("#wcf-ready-templates").show(),c("#wcf-start-from-scratch").hide()),!c(".wcf-page-builder-notice").length&&c("#wcf-remote-step-importer").length&&CartFlowsImport._showSteps()},_switch_step_tab:function(t){t.preventDefault();var e=c(".wcf-tab > li.active > a").attr("href");c(".wcf-tab > li.active").removeClass("active"),c(this).parents("li").addClass("active"),c(e).removeClass("active"),c(e).addClass("hide");var a=c(this).attr("href");c(a).removeClass("hide"),c(a).addClass("active")},_remote_step_search:function(t){t.preventDefault(),c(".step-type-filter-links").find("option").removeClass("current"),c(".step-type-filter-links").find("option:first-child").addClass("current"),window.clearTimeout(CartFlowsImport._ref),CartFlowsImport._ref=window.setTimeout(function(){CartFlowsImport._ref=null,CartFlowsImport._showSteps()},500)},_previewResponsive:function(t){t.preventDefault();var e=c(this).find(".dashicons"),a=e.attr("data-view")||"";c("#TB_window").removeClass("desktop tablet mobile"),c("#TB_window").addClass(a),c(".actions .dashicons").removeClass("active"),e.addClass("active"),c("#TB_iframeContent").removeClass(),c("#TB_iframeContent").addClass(a)},_filterStepPageBuilderClick:function(t){t.preventDefault(),c(this).parents("ul").find("a").removeClass("current"),c(this).addClass("current");var e=c(".step-type-filter-links .current").data("slug")||"";"upsell"===e||"downsell"===e?c(".wcf-template-notice").show():c(".wcf-template-notice").hide(),c(".wcf-page-builder-notice").html(""),c("#wcf-remote-step-list").html('<span class="spinner is-active"></span>'),CartFlowsImport._showSteps()},_filterBlankStepCategoryClick:function(t){t.preventDefault(),c(".wcf-page-builder-notice").html("");var e=c(this).data("group")||"";e&&(c("#wcf-scratch-steps-categories .step-type-filter-links").val(e),c("#wcf-scratch-steps-categories .step-type-filter-links option").removeClass("current"),c('#wcf-scratch-steps-categories .step-type-filter-links option[data-group="'+e+'"]').addClass("current")),c(".step-type-filter-links").find("a").removeClass("current"),c(this).addClass("current"),$step_type=c(this).data("slug"),"upsell"===$step_type||"downsell"===$step_type?c(".wcf-template-notice").show():c(".wcf-template-notice").hide(),""!=CartFlowsImportVars._is_pro_active||"upsell"!=$step_type&&"downsell"!=$step_type?(c(".cartflows-step-import-blank").text("Create Step"),c(".cartflows-step-import-blank").removeClass("get-pro"),c(".cartflows-step-import-blank").removeAttr("target")):(c(".cartflows-step-import-blank").text("Get Pro"),c(".cartflows-step-import-blank").attr("href",CartFlowsImportVars.domain_url),c(".cartflows-step-import-blank").attr("target","_blank"),c(".cartflows-step-import-blank").addClass("get-pro")),c("#wcf-remote-step-list").html('<span class="spinner is-active"></span>'),CartFlowsImport._showSteps()},_filterBlankStepCategoryChange:function(t){t.preventDefault(),c(".wcf-notice-wrap").remove(),c(".cartflows-step-import-blank").css("pointer-events","auto").removeClass("disabled");var e=c(".step-type-filter-links").find("option:selected").val()||"";if(e&&(c(".step-type-filter-links").val(e),c(".step-type-filter-links").find("a").removeClass("current"),c(".step-type-filter-links").find('a[data-group="'+e+'"]').addClass("current")),c(".step-type-filter-links").find("option").removeClass("current"),c(".step-type-filter-links").find("option:selected").addClass("current"),$step_type=c(".step-type-filter-links").find("option:selected").data("slug"),!("no"!==CartFlowsImportVars.is_wc_installed&&"no"!==CartFlowsImportVars.is_wc_activated||"upsell"!==$step_type&&"downsell"!==$step_type&&"checkout"!==$step_type&&"thankyou"!==$step_type))return c(".cartflows-step-import-blank").after("<p class='wcf-notice-wrap' style='text-align: center'>You need WooCommerce plugin installed and actived to use this product flow. <br/><br/> <a href='#' class='wcf-activate-wc button-secondary'> Click here to install and activate WooCommerce </a> </p>"),void c(".cartflows-step-import-blank").addClass("disabled").css("pointer-events","none");"upsell"===$step_type||"downsell"===$step_type?c(".wcf-template-notice").show():c(".wcf-template-notice").hide(),""!=CartFlowsImportVars._is_pro_active||"upsell"!=$step_type&&"downsell"!=$step_type?(c(".cartflows-step-import-blank").text("Create Step"),c(".cartflows-step-import-blank").removeClass("get-pro"),c(".cartflows-step-import-blank").removeAttr("target")):(c(".cartflows-step-import-blank").text("Get Pro"),c(".cartflows-step-import-blank").attr("href",CartFlowsImportVars.domain_url),c(".cartflows-step-import-blank").attr("target","_blank"),c(".cartflows-step-import-blank").addClass("get-pro")),!c(".wcf-page-builder-notice").length&&c("#wcf-remote-step-importer").length&&(c("#wcf-remote-step-list").html('<span class="spinner is-active"></span>'),CartFlowsImport._showSteps())},_showSteps:function(){var t={licence_args:CartFlowsImportVars.licence_args,per_page:100,_fields:CartFlowsImportVars.step_fields.toString()},e=c("#wcf-categories .step-type-filter-links").find(".current").data("group")||"",s=c("#wcf-categories .step-type-filter-links").find(".current").data("slug");""!==e&&"all"!==e&&(t[CartFlowsImportVars.step_type]=e);e=c("#wcf-page-builders .wcf-page-builder-links").find(".current").data("group")||"",s=c("#wcf-page-builders .wcf-page-builder-links").find(".current").data("slug")||"";var r=c("#wcf-page-builders .wcf-page-builder-links").find(".current").data("title")||"Page Builder";""!==e&&"all"!==e&&(t[CartFlowsImportVars.step_page_builder]=e);var a={remote_slug:CartFlowsImportVars.step,slug:CartFlowsImportVars.step+"?"+decodeURIComponent(c.param(t))};CartFlowsAPI._api_request(a,function(a){a.current_step_type=s,"yes"!==CartFlowsImportVars.is_wc_activated&&c.each(a.items,function(t,e){a.items[t].woo_required=!1,0<=c.inArray(e.step_type.slug,CartFlowsImport.woo_required_steps)&&(a.items[t].woo_required=!0)});var t=wp.template("cartflows-steps-list");parseInt(a.items_count)?c("#wcf-remote-step-list").html(t(a)):(c("#wcf-remote-step-list").html(wp.template("cartflows-no-steps")),c(".cartflows-no-steps").find(".description").html("We are working on ready templates designed with "+r+'.<br/>Meanwhile you can <a href="#" data-slug="canvas" class="wcf-create-from-scratch-link">create your own designs</a> easily.')),c(".wcf-page-builder-notice").remove(),c("#wcf-remote-step-importer").removeClass("request-process")})},_apiAddParam_per_page:function(){CartFlowsImport._api_params.per_page=100},_apiAddParam_licence_args:function(){CartFlowsImport._api_params.licence_args=CartFlowsImportVars.licence_args},_apiAddParam_search:function(){var t=c(".wcf-flow-search-input").val()||"";""!==t&&(CartFlowsImport._api_params.search=t)},_close_popup:function(){c("#cartflows-steps").fadeOut(),c("body").removeClass("cartflows-popup-is-open")},_post_auto_save:function(){var t=c("#title"),e=c("#title-prompt-text"),a=CartFlowsImport;t.val()||(t.val("CartFlows #"+a.post_id),e.length&&e.remove()),wp.autosave&&wp.autosave.server.triggerSave()},_process_cache_remote_flows:function(){var t=CartFlowsImportVars.required_plugins[CartFlowsImportVars.default_page_builder].plugins,a=!0;c.each(t,function(t,e){a&&("install"!==e.status&&"activate"!==e.status||(a=!1))}),!1===a?(c(".wcf-page-builder-notice").html(wp.template("cartflows-page-builder-notice")),c("#wcf-remote-flow-list").find(".spinner").remove()):CartFlowsImport._cache_remote_flows()},_cache_remote_flows:function(){CartFlowsImport;var t={search:CartFlowsImportVars.default_page_builder,licence_args:CartFlowsImportVars.licence_args,hide_empty:!1,_fields:CartFlowsImportVars.flow_page_builder_fields.toString()},e={remote_slug:CartFlowsImportVars.flow_page_builder,slug:CartFlowsImportVars.flow_page_builder+"?"+decodeURIComponent(c.param(t)),wrapper_class:"wcf-page-builder-links filter-links",show_all:!1};CartFlowsAPI._api_request(e,function(t){var e=wp.template("cartflows-term-filters");c("#wcf-page-builders").html(e(t)),c("#wcf-page-builders").find("li:first a").addClass("current");var a={licence_args:CartFlowsImportVars.licence_args,hide_empty:!0,_fields:CartFlowsImportVars.flow_type_fields.toString()},s={remote_slug:CartFlowsImportVars.flow_type,slug:CartFlowsImportVars.flow_type+"?"+decodeURIComponent(c.param(a)),wrapper_class:"flow-type-filter-links filter-links",show_all:!1};CartFlowsAPI._api_request(s,function(t){var e=wp.template("cartflows-term-filters");c("#wcf-categories").html(e(t)),c("#wcf-categories").find("li:first a").addClass("current"),CartFlowsImport._showFlows()})})},_render_remote_flows:function(t){t&&t.preventDefault(),c("#wcf-remote-flow-importer").addClass("open"),c("html").addClass("wcf-popup-open")},_process_cache_remote_steps:function(){var t=CartFlowsImportVars.required_plugins[CartFlowsImportVars.default_page_builder].plugins,a=!0;c.each(t,function(t,e){a&&("install"!==e.status&&"activate"!==e.status||(a=!1))}),!1===a?(c(".wcf-page-builder-notice").html(wp.template("cartflows-page-builder-notice")),c("#wcf-remote-step-list").find(".spinner").remove()):CartFlowsImport._cache_remote_steps()},mapOrder:function(t,r,o){return t.sort(function(t,e){var a=t[o],s=e[o];return-1===r.indexOf(a)?0:r.indexOf(a)>r.indexOf(s)?1:-1}),t},_cache_remote_steps:function(){CartFlowsImport;c("html").addClass("wcf-steps-loading");var t={search:CartFlowsImportVars.default_page_builder,licence_args:CartFlowsImportVars.licence_args,hide_empty:!1,_fields:CartFlowsImportVars.step_page_builder_fields.toString()},e={remote_slug:CartFlowsImportVars.step_page_builder,slug:CartFlowsImportVars.step_page_builder+"?"+decodeURIComponent(c.param(t)),wrapper_class:"wcf-page-builder-links filter-links",show_all:!1};CartFlowsAPI._api_request(e,function(t){var e=wp.template("cartflows-term-filters");c("#wcf-page-builders").html(e(t)),c("#wcf-page-builders").find("li:first a").addClass("current")});t={licence_args:CartFlowsImportVars.licence_args,_fields:CartFlowsImportVars.step_type_fields.toString()},e={remote_slug:CartFlowsImportVars.step_type,slug:CartFlowsImportVars.step_type+"?"+decodeURIComponent(c.param(t)),wrapper_class:"step-type-filter-links filter-links",show_all:!1};CartFlowsAPI._api_request(e,function(t){t.items=CartFlowsImport.mapOrder(t.items,CartFlowsImport.step_order,"slug");var s=t,r=t.items_count;if(t.items)for(key in t.items){t.items[key].name=CartFlowsImport.new_step_names[t.items[key].slug];var e={licence_args:CartFlowsImportVars.licence_args,per_page:100,_fields:CartFlowsImportVars.step_fields.toString()};e[CartFlowsImportVars.step_type]=t.items[key].id;var a={remote_slug:CartFlowsImportVars.step,slug:CartFlowsImportVars.step+"?"+decodeURIComponent(c.param(e))};CartFlowsAPI._api_request(a,function(t){var e=wp.template("cartflows-steps-list");if(parseInt(t.items_count)?c("#wcf-remote-step-list").html(e(t)):c("#wcf-remote-step-list").html(wp.template("cartflows-no-steps")),0==--r){var a=wp.template("cartflows-term-filters-dropdown");e=wp.template("cartflows-term-filters");c("#wcf-categories").html(e(s)),c("#wcf-scratch-steps-categories").html(a(s)),c("#wcf-scratch-steps-categories").find("option:first").addClass("current"),c("#wcf-categories").find("li a[data-slug=landing]").addClass("current"),c(".wcf-page-builder-notice").remove(),c("#wcf-remote-content").find(".spinner").remove(),CartFlowsImport._showSteps(),c("html").removeClass("wcf-steps-loading")}})}})},_render_remote_steps:function(t){t&&t.preventDefault(),c("#wcf-remote-step-importer").addClass("open"),c("html").addClass("wcf-popup-open")},_categorize_data:function(t){var s=[];return c.each(t,function(t,e){var a=e.step_type.slug;void 0===s[a]&&(s[a]=[]),s[a].push(e)}),s},_close_template_popup:function(t){(c(t.target).hasClass("wcf-templates-popup-overlay")||c(t.target).hasClass("close-icon"))&&(c(".wcf-templates-popup-overlay").hasClass("request-process")||(c("html").removeClass("wcf-popup-open"),c(".wcf-templates-popup-overlay").removeClass("open")))},_ajax:function(t,s,r){var o=CartFlowsImport;c.ajax({url:ajaxurl,type:"POST",data:t}).done(function(t,e,a){s&&"function"==typeof s&&s({request:t,status:e,XHR:a}),o.doc.trigger(r+"-done",[t,e,a])}).fail(function(t,e){o.doc.trigger(r+"-fail",[t,e])}).always(function(){o.doc.trigger(r+"-always")})},_empty:function(t){if("number"==typeof t||"boolean"==typeof t)return!1;if(null==t)return!0;if(void 0!==t.length)return 0==t.length;var e=0;for(var a in t)t.hasOwnProperty(a)&&e++;return 0==e},_preview_individual:function(){var t=c(this).data("id")||"",e=c(this).data("href")||"";c(".cartflows-preview-flow-step").removeClass("active"),c('.cartflows-preview-flow-step[data-id="'+t+'"]').addClass("active"),c("#TB_window").addClass("cartflows-thickbox-loading"),c("#TB_iframeContent").removeAttr("onload"),c("#TB_iframeContent").removeAttr("src"),c("#TB_iframeContent").attr("src",e),c("#TB_iframeContent").attr("onload","CartFlowsImport.showIframe()")},showIframe:function(){c("#TB_load").remove(),c("#TB_window").css({visibility:"visible"}),c("#TB_window").removeClass("cartflows-thickbox-loading")},_previewLoaded:function(t){t.preventDefault(),c("#TB_window").removeClass("cartflows-thickbox-loading")},_filterFlowPageBuilderClick:function(t){t.preventDefault(),c(this).parents("ul").find("a").removeClass("current"),c(this).addClass("current"),c(".wcf-page-builder-notice").html(""),c("#wcf-remote-flow-list").html('<span class="spinner is-active"></span>'),CartFlowsImport._showFlows()},_showFlows:function(){var t={licence_args:CartFlowsImportVars.licence_args,_fields:CartFlowsImportVars.flow_fields.toString(),per_page:100},e=c("#wcf-page-builders .wcf-page-builder-links").find(".current").data("group")||"";c("#wcf-page-builders .wcf-page-builder-links").find(".current").data("slug"),c("#wcf-page-builders .wcf-page-builder-links").find(".current").data("title");""!==e&&"all"!==e&&(t[CartFlowsImportVars.flow_page_builder]=e);var a={remote_slug:CartFlowsImportVars.flow,slug:CartFlowsImportVars.flow+"?"+decodeURIComponent(c.param(t))};CartFlowsAPI._api_request(a,function(s){"yes"!==CartFlowsImportVars.is_wc_activated&&c.each(s.items,function(a,t){s.items[a].woo_required=!1,c.each(t.flow_steps,function(t,e){0<=c.inArray(e.type,CartFlowsImport.woo_required_steps)&&(s.items[a].woo_required=!0)})});var t=wp.template("cartflows-flows-list");parseInt(s.items_count)?c("#wcf-remote-flow-list").html(t(s)):c("#wcf-remote-flow-list").html(wp.template("cartflows-no-flows")),c(".wcf-page-builder-notice").remove(),c("#wcf-remote-flow-importer").removeClass("request-process")})},_create_default_flow:function(t){t.preventDefault();var e=CartFlowsImport,a=c(this);if(!a.hasClass("updating-message")){c("#wcf-remote-flow-importer").addClass("request-process"),a.addClass("updating-message").text("Creating Flow.."),a.parents(".template").addClass("importing");var s={action:"cartflows_default_flow",security:cartflows_admin.cf_default_flow_nonce};e._ajax(s,function(t){if(t.request.success){var e=t.request.data;setTimeout(function(){a.removeClass("updating-message").text("Flow Created! Redirecting.."),window.location=CartFlowsImportVars.admin_url+"post.php?post="+e+"&action=edit"},3e3)}})}},_activate_plugin:function(t){var e=CartFlowsImport,a={action:"cartflows_activate_plugin",plugin_init:t,security:CartFlowsImportVars.cartflows_activate_plugin_nonce};e._ajax(a,function(t){})},_process_import_flow:function(t){t.preventDefault();var s=c(this);if(!s.hasClass("updating-message")){c("#wcf-remote-flow-importer").addClass("request-process");var e=CartFlowsImport;s.text("Creating Flow.."),s.addClass("updating-message"),s.parents(".template").addClass("importing");var a=s.data("flow-steps")||"",r=""!==a?JSON.parse("["+a+"]"):[],o={action:"cartflows_create_flow",security:cartflows_admin.cf_create_flow_nonce};e._ajax(o,function(t){if(t.request.success){var a=t.request.data;r&&(CartFlowsAjaxQueue.stop(),CartFlowsAjaxQueue.run(),CartFlowsImport.all_steps=r.length,s.addClass("updating-message").text("Importing Step 1 of "+CartFlowsImport.all_steps),c.each(r,function(t,e){CartFlowsAjaxQueue.add({url:CartFlowsImportVars.ajaxurl,type:"POST",data:{action:"cartflows_import_flow_step",flow_id:a,template_id:e,security:cartflows_admin.cf_import_flow_step_nonce},success:function(t){CartFlowsImport.remaining_steps=CartFlowsImport.remaining_steps+1,CartFlowsImport.remaining_steps===CartFlowsImport.all_steps?(s.addClass("updating-message").text("Imported Step "+CartFlowsImport.remaining_steps+" of "+CartFlowsImport.all_steps),setTimeout(function(){s.removeClass("updating-message").text("All Imported! Redirecting.."),window.location=CartFlowsImportVars.admin_url+"post.php?post="+a+"&action=edit"},3e3)):s.addClass("updating-message").text("Importing Step "+CartFlowsImport.remaining_steps+" of "+CartFlowsImport.all_steps)},error:function(t){CartFlowsImport.remaining_steps=CartFlowsImport.remaining_steps+1,template=s.parents(".template.importing"),template.find(".preview").addClass("notice notice-warning").removeClass("preview").text(t.statusText),CartFlowsImport.remaining_steps===CartFlowsImport.all_steps?(s.addClass("updating-message").text("Failed "+CartFlowsImport.remaining_steps+" of "+CartFlowsImport.all_steps),setTimeout(function(){s.removeClass("updating-message button-primary").addClass("disabled")},3e3)):s.addClass("updating-message").text("Failed "+CartFlowsImport.remaining_steps+" of "+CartFlowsImport.all_steps)},fail:function(t){CartFlowsImport.remaining_steps=CartFlowsImport.remaining_steps+1,CartFlowsImport.remaining_steps===CartFlowsImport.all_steps?(s.addClass("updating-message").text("Imported "+CartFlowsImport.remaining_steps+" of "+CartFlowsImport.all_steps),setTimeout(function(){s.removeClass("updating-message").text("All Step Imported! Reloading.."),location.reload()},3e3)):s.addClass("updating-message").text("Importing "+CartFlowsImport.remaining_steps+" of "+CartFlowsImport.all_steps)}})}))}})}},_handle_error:function(t){c(".cartflows-step-import.updating-message").addClass("updating-message").text(t.errorMessage)},_create_blank_step:function(t){t.preventDefault();var a=c(this),e=CartFlowsImport,s=c("#post_ID").val(),r=c("#wcf-scratch-steps-categories .step-type-filter-links .current").data("slug")||"",o=c("#wcf-scratch-steps-categories .step-type-filter-links .current").data("title")||"",l=r,i=c('.wcf-step-wrap[data-term-slug="'+r+'"]').length||1,p=o+" "+(parseInt(i)+1);if(all_step_type=["landing","checkout","thankyou"],c("#wcf-start-from-scratch .wcf-notice-wrap ").remove(),""!==l){if(CartFlowsImportVars._is_pro_active||"upsell"!==l&&"downsell"!==l){if(a.parents(".template").addClass("importing"),!CartFlowsImportVars._is_pro_active)if("-1"!=jQuery.inArray(l,all_step_type))if(0<c('.wcf-step-wrap[data-term-slug="'+l+'"]').length){a.parents(".template.importing");return a.removeClass("importing updating-message").text("Import Failed!"),void c("#wcf-start-from-scratch .inner").append('<div class="wcf-notice-wrap"><div class="notice notice-warning"><p>Upgrade to Pro for adding more than one '+l.charAt(0).toUpperCase()+l.slice(1)+" step.</p></div></div>")}if(c("#wcf-remote-step-importer").addClass("request-process"),c(".cartflows-step-import").addClass("disabled"),a.addClass("importing updating-message").text("Creating.."),c("body").hasClass("post-type-cartflows_flow")){var n={action:"cartflows_step_create_blank",flow_id:s,step_type:l,step_title:p,security:cartflows_admin.cf_step_create_blank_nonce};e._ajax(n,function(t){CartFlowsImport;var e=a.parents(".template.importing");t.request.success?(a.text("Created. Reloading.."),setTimeout(function(){window.location.href=window.location.href+"&highlight-step-id="+t.request.data},3e3)):(a.removeClass("importing updating-message").text("Creating Failed!"),c("#wcf-remote-step-importer").removeClass("request-process"),e.find(".cartflows-step-preview").append("<div class='preview'></div>"),e.find(".preview").addClass("notice notice-warning").removeClass("preview").text(t.request.data))})}}}else c("#wcf-start-from-scratch .inner").append('<div class="wcf-notice-wrap"><div class="notice notice-info"><p>Please select the step type.</p></div></div>')},_process_import_step:function(t){t.preventDefault();var a=c(this),e=a.data("slug")||"",s=c('.wcf-step-wrap[data-term-slug="'+e+'"]').length||1;if((step_title=a.data("title")||"",step_custom_title=step_title+" "+(parseInt(s)+1),o=CartFlowsImport,all_step_slug=["landing","checkout","thankyou"],!CartFlowsImportVars._is_pro_active)&&("-1"!=jQuery.inArray(e,all_step_slug)&&0<c('.wcf-step-wrap[data-term-slug="'+e+'"]').length)){var r=a.parents(".template");return a.removeClass("importing updating-message").text("Import Failed!"),r.find(".preview").hide(),r.find("#wcf_create_notice").show().find("a").addClass("notice notice-warning ").text("Upgrade to Pro for adding more than one "+e.charAt(0).toUpperCase()+e.slice(1)+" step"),void c("#wcf-remote-step-importer").removeClass("request-process")}if(!a.hasClass("updating-message")){c("#wcf-remote-step-importer").addClass("request-process");var o=CartFlowsImport;a.addClass("updating-message"),a.parents(".template").addClass("importing");var l=a.data("template-id")||"",i=c("#post_ID").val(),p=e;o=CartFlowsImport;if(c(".cartflows-step-import-blank").addClass("disabled"),c(".cartflows-step-import").addClass("disabled"),a.addClass("importing updating-message").text("Importing.."),c("body").hasClass("post-type-cartflows_flow")){var n={action:"cartflows_step_import",flow_id:i,template_id:l,step_title:step_custom_title,step_type:p,security:cartflows_admin.cf_step_import_nonce};o._ajax(n,function(t){CartFlowsImport;var e=a.parents(".template.importing");t.request.success?(a.text("Imported. Reloading.."),setTimeout(function(){window.location.href=window.location.href+"&highlight-step-id="+t.request.data},3e3)):(c(".wcf-templates-popup-overlay").removeClass("request-process"),a.removeClass("importing updating-message").text("Import Failed!"),e.find(".preview").addClass("notice notice-warning").removeClass("preview").text(t.request.data))},"add_template_to_page")}}},_add_template_to_page_fail:function(t,e,a){t.preventDefault();CartFlowsImport;var s=c(".wcf-flow-steps-data-wrap-importer .template.importing");s.find(".cartflows-step-import").removeClass("importing updating-message").text("Import Failed!"),s.find(".preview").addClass("notice notice-warning").removeClass("preview").text(e.responseText)},_activateWc:function(t){c.ajax({url:ajaxurl,type:"POST",data:{action:"cartflows_activate_plugin",plugin_init:"woocommerce/woocommerce.php",security:CartFlowsImportVars.cartflows_activate_plugin_nonce}}).done(function(t,e,a){c(".wcf-notice-wrap").addClass("wcf-hidden"),c(".cartflows-template-selector").removeAttr("disabled"),CartFlowsImport.wc_installed=!0,CartFlowsImportVars.is_wc_installed="yes",CartFlowsImportVars.is_wc_activated="yes",location.reload(!0),window.location.search+="&add-new-flow"})},_installWc:function(t){c(this).addClass("updating-message button"),c(this).text(cartflows_admin.wc_activating_message),0==cartflows_admin.wc_status.installed?(wp.updates.shouldRequestFilesystemCredentials&&!wp.updates.ajaxLocked&&(wp.updates.requestFilesystemCredentials(t),$document.on("credential-modal-cancel",function(){c(".install-now.updating-message").removeClass("updating-message").text(wp.updates.l10n.installNow),wp.a11y.speak(wp.updates.l10n.updateCancel,"polite")})),wp.updates.installPlugin({slug:"woocommerce"})):CartFlowsImport._activateWc()}},c(function(){CartFlowsImport.init()})}(jQuery);
cartflows.php CHANGED
@@ -3,12 +3,12 @@
3
  * Plugin Name: CartFlows
4
  * Plugin URI: https://cartflows.com/
5
  * Description: Create beautiful checkout pages & sales flows for WooCommerce.
6
- * Version: 1.5.9
7
  * Author: CartFlows Inc
8
  * Author URI: https://cartflows.com/
9
  * Text Domain: cartflows
10
  * WC requires at least: 3.0
11
- * WC tested up to: 4.1.0
12
  *
13
  * @package CartFlows
14
  */
3
  * Plugin Name: CartFlows
4
  * Plugin URI: https://cartflows.com/
5
  * Description: Create beautiful checkout pages & sales flows for WooCommerce.
6
+ * Version: 1.5.10
7
  * Author: CartFlows Inc
8
  * Author URI: https://cartflows.com/
9
  * Text Domain: cartflows
10
  * WC requires at least: 3.0
11
+ * WC tested up to: 4.2
12
  *
13
  * @package CartFlows
14
  */
changelog.txt CHANGED
@@ -1,3 +1,8 @@
 
 
 
 
 
1
  Version 1.5.9 - Thursday, 14th May 2020
2
  - New: Added quantity and discount options for the product.
3
  - Fix: Google Analytics JS error.
1
+ Version 1.5.10 - Wednesday, 3rd June 2020
2
+ - New: Gutenberg templates added.
3
+ - New: Import/Export content support added.
4
+ - Fix: Step slug was not editable in some permalink cases.
5
+
6
  Version 1.5.9 - Thursday, 14th May 2020
7
  - New: Added quantity and discount options for the product.
8
  - Fix: Google Analytics JS error.
classes/batch-process/class-cartflows-batch-process.php CHANGED
@@ -1,270 +1,295 @@
1
- <?php
2
- /**
3
- * Batch Processing
4
- *
5
- * @package CartFlows
6
- * @since 1.0.0
7
- */
8
-
9
- if ( ! class_exists( 'CartFlows_Batch_Process' ) ) :
10
-
11
- /**
12
- * CartFlows_Batch_Process
13
- *
14
- * @since 1.0.0
15
- */
16
- class CartFlows_Batch_Process {
17
-
18
- /**
19
- * Instance
20
- *
21
- * @since 1.0.0
22
- * @var object Class object.
23
- * @access private
24
- */
25
- private static $instance;
26
-
27
- /**
28
- * Elementor Batch Instance
29
- *
30
- * @since 1.1.1 Updated instance name with elementor specific.
31
- *
32
- * @since 1.0.0
33
- * @var object Class object.
34
- * @access public
35
- */
36
- public static $batch_instance_elementor;
37
-
38
- /**
39
- * Beaver Builder Batch Instance
40
- *
41
- * @since 1.1.1
42
- * @var object Class object.
43
- * @access public
44
- */
45
- public static $batch_instance_bb;
46
-
47
- /**
48
- * Divi Batch Instance
49
- *
50
- * @since 1.1.1
51
- * @var object Class object.
52
- * @access public
53
- */
54
- public static $batch_instance_divi;
55
-
56
- /**
57
- * Initiator
58
- *
59
- * @since 1.0.0
60
- * @return object initialized object of class.
61
- */
62
- public static function get_instance() {
63
- if ( ! isset( self::$instance ) ) {
64
- self::$instance = new self();
65
- }
66
- return self::$instance;
67
- }
68
-
69
- /**
70
- * Constructor
71
- *
72
- * @since 1.0.0
73
- */
74
- public function __construct() {
75
-
76
- // Not BB or Elementor then avoid importer.
77
- // if ( ! class_exists( '\Elementor\Plugin' ) && ! class_exists( 'FLBuilder' ) ) {
78
- // return;
79
- // }
80
- // Core Helpers - Image.
81
- require_once ABSPATH . 'wp-admin/includes/image.php';
82
-
83
- // Core Helpers - Batch Processing.
84
- require_once CARTFLOWS_DIR . 'classes/batch-process/helpers/class-cartflows-importer-image.php';
85
- require_once CARTFLOWS_DIR . 'classes/batch-process/helpers/class-wp-async-request.php';
86
- require_once CARTFLOWS_DIR . 'classes/batch-process/helpers/class-wp-background-process.php';
87
-
88
- $default_page_builder = Cartflows_Helper::get_common_setting( 'default_page_builder' );
89
-
90
- // Elementor.
91
- if ( ( 'elementor' === $default_page_builder ) && class_exists( '\Elementor\Plugin' ) ) {
92
- // Add "elementor" in import [queue].
93
- // @todo Remove required `allow_url_fopen` support.
94
- if ( ini_get( 'allow_url_fopen' ) ) {
95
- require_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-importer-elementor.php';
96
- require_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-importer-elementor-batch.php';
97
- self::$batch_instance_elementor = new Cartflows_Importer_Elementor_Batch();
98
- }
99
- }
100
-
101
- // Beaver Builder.
102
- if ( ( 'beaver-builder' === $default_page_builder ) && class_exists( 'FLBuilder' ) ) {
103
- require_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-importer-beaver-builder.php';
104
- require_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-importer-beaver-builder-batch.php';
105
- self::$batch_instance_bb = new Cartflows_Importer_Beaver_Builder_Batch();
106
- }
107
-
108
- // Divi.
109
- if ( ( 'divi' === $default_page_builder ) && ( class_exists( 'ET_Builder_Plugin' ) || Cartflows_Compatibility::get_instance()->is_divi_enabled() ) ) {
110
- require_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-importer-divi.php';
111
- require_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-importer-divi-batch.php';
112
- self::$batch_instance_divi = new Cartflows_Importer_Divi_Batch();
113
- }
114
-
115
- // Start image importing after site import complete.
116
- add_action( 'cartflows_after_template_import', array( $this, 'start_batch_process' ) );
117
- add_action( 'cartflows_import_complete', array( $this, 'complete_batch_import' ) );
118
- add_filter( 'upload_mimes', array( $this, 'custom_upload_mimes' ) );
119
- add_filter( 'wp_prepare_attachment_for_js', array( $this, 'add_svg_image_support' ), 10, 3 );
120
- }
121
-
122
- /**
123
- * Added .svg files as supported format in the uploader.
124
- *
125
- * @since 1.1.4
126
- *
127
- * @param array $mimes Already supported mime types.
128
- */
129
- public function custom_upload_mimes( $mimes ) {
130
-
131
- // Allow SVG files.
132
- $mimes['svg'] = 'image/svg+xml';
133
- $mimes['svgz'] = 'image/svg+xml';
134
-
135
- // Allow XML files.
136
- $mimes['xml'] = 'text/xml';
137
-
138
- return $mimes;
139
- }
140
-
141
- /**
142
- * Add SVG image support
143
- *
144
- * @since 1.1.4
145
- *
146
- * @param array $response Attachment response.
147
- * @param object $attachment Attachment object.
148
- * @param array $meta Attachment meta data.
149
- */
150
- public function add_svg_image_support( $response, $attachment, $meta ) {
151
- if ( ! function_exists( 'simplexml_load_file' ) ) {
152
- return $response;
153
- }
154
-
155
- if ( ! empty( $response['sizes'] ) ) {
156
- return $response;
157
- }
158
-
159
- if ( 'image/svg+xml' !== $response['mime'] ) {
160
- return $response;
161
- }
162
-
163
- $svg_path = get_attached_file( $attachment->ID );
164
-
165
- $dimensions = self::get_svg_dimensions( $svg_path );
166
-
167
- $response['sizes'] = array(
168
- 'full' => array(
169
- 'url' => $response['url'],
170
- 'width' => $dimensions->width,
171
- 'height' => $dimensions->height,
172
- 'orientation' => $dimensions->width > $dimensions->height ? 'landscape' : 'portrait',
173
- ),
174
- );
175
-
176
- return $response;
177
- }
178
-
179
- /**
180
- * Get SVG Dimensions
181
- *
182
- * @since 1.1.4.
183
- *
184
- * @param string $svg SVG file path.
185
- * @return array Return SVG file height & width for valid SVG file.
186
- */
187
- public static function get_svg_dimensions( $svg ) {
188
-
189
- $svg = simplexml_load_file( $svg );
190
-
191
- if ( false === $svg ) {
192
- $width = '0';
193
- $height = '0';
194
- } else {
195
- $attributes = $svg->attributes();
196
- $width = (string) $attributes->width;
197
- $height = (string) $attributes->height;
198
- }
199
-
200
- return (object) array(
201
- 'width' => $width,
202
- 'height' => $height,
203
- );
204
- }
205
-
206
- /**
207
- * Batch Process Complete.
208
- *
209
- * @return void
210
- */
211
- public function complete_batch_import() {
212
- wcf()->logger->import_log( '() BATCH Process Complete!' );
213
- }
214
-
215
- /**
216
- * Start Image Import
217
- *
218
- * @param integer $post_id Post Id.
219
- *
220
- * @return void
221
- */
222
- public function start_batch_process( $post_id = '' ) {
223
-
224
- $default_page_builder = Cartflows_Helper::get_common_setting( 'default_page_builder' );
225
-
226
- wcf()->logger->import_log( '(✓) BATCH Started!' );
227
- wcf()->logger->import_log( '() Step ID ' . $post_id );
228
-
229
- // Add "elementor" in import [queue].
230
- if ( 'beaver-builder' === $default_page_builder && self::$batch_instance_bb ) {
231
-
232
- // Add to queue.
233
- self::$batch_instance_bb->push_to_queue( $post_id );
234
-
235
- // Dispatch Queue.
236
- self::$batch_instance_bb->save()->dispatch();
237
-
238
- wcf()->logger->import_log( '(✓) Dispatch "Beaver Builder" Request..' );
239
-
240
- } elseif ( 'elementor' === $default_page_builder && self::$batch_instance_elementor ) {
241
-
242
- // Add to queue.
243
- self::$batch_instance_elementor->push_to_queue( $post_id );
244
-
245
- // Dispatch Queue.
246
- self::$batch_instance_elementor->save()->dispatch();
247
-
248
- wcf()->logger->import_log( '(✓) Dispatch "Elementor" Request..' );
249
- } elseif ( 'divi' === $default_page_builder && self::$batch_instance_divi ) {
250
-
251
- // Add to queue.
252
- self::$batch_instance_divi->push_to_queue( $post_id );
253
-
254
- // Dispatch Queue.
255
- self::$batch_instance_divi->save()->dispatch();
256
-
257
- wcf()->logger->import_log( '(✓) Dispatch "Divi" Request..' );
258
- } else {
259
- wcf()->logger->import_log( '(✕) Could not import image due to allow_url_fopen() is disabled!' );
260
- }
261
- }
262
-
263
- }
264
-
265
- /**
266
- * Kicking this off by calling 'get_instance()' method
267
- */
268
- CartFlows_Batch_Process::get_instance();
269
-
270
- endif;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Batch Processing
4
+ *
5
+ * @package CartFlows
6
+ * @since 1.0.0
7
+ */
8
+
9
+ if ( ! class_exists( 'CartFlows_Batch_Process' ) ) :
10
+
11
+ /**
12
+ * CartFlows_Batch_Process
13
+ *
14
+ * @since 1.0.0
15
+ */
16
+ class CartFlows_Batch_Process {
17
+
18
+ /**
19
+ * Instance
20
+ *
21
+ * @since 1.0.0
22
+ * @var object Class object.
23
+ * @access private
24
+ */
25
+ private static $instance;
26
+
27
+ /**
28
+ * Elementor Batch Instance
29
+ *
30
+ * @since 1.1.1 Updated instance name with elementor specific.
31
+ *
32
+ * @since 1.0.0
33
+ * @var object Class object.
34
+ * @access public
35
+ */
36
+ public static $batch_instance_elementor;
37
+
38
+ /**
39
+ * Beaver Builder Batch Instance
40
+ *
41
+ * @since 1.1.1
42
+ * @var object Class object.
43
+ * @access public
44
+ */
45
+ public static $batch_instance_bb;
46
+
47
+ /**
48
+ * Divi Batch Instance
49
+ *
50
+ * @since 1.1.1
51
+ * @var object Class object.
52
+ * @access public
53
+ */
54
+ public static $batch_instance_divi;
55
+
56
+ /**
57
+ * Gutenberg Batch Instance
58
+ *
59
+ * @since 1.5.9
60
+ * @var object Class object.
61
+ * @access public
62
+ */
63
+ public static $batch_instance_gb;
64
+
65
+ /**
66
+ * Initiator
67
+ *
68
+ * @since 1.0.0
69
+ * @return object initialized object of class.
70
+ */
71
+ public static function get_instance() {
72
+ if ( ! isset( self::$instance ) ) {
73
+ self::$instance = new self();
74
+ }
75
+ return self::$instance;
76
+ }
77
+
78
+ /**
79
+ * Constructor
80
+ *
81
+ * @since 1.0.0
82
+ */
83
+ public function __construct() {
84
+
85
+ // Not BB or Elementor then avoid importer.
86
+ // if ( ! class_exists( '\Elementor\Plugin' ) && ! class_exists( 'FLBuilder' ) ) {
87
+ // return;
88
+ // }
89
+ // Core Helpers - Image.
90
+ require_once ABSPATH . 'wp-admin/includes/image.php';
91
+
92
+ // Core Helpers - Batch Processing.
93
+ require_once CARTFLOWS_DIR . 'classes/batch-process/helpers/class-cartflows-importer-image.php';
94
+ require_once CARTFLOWS_DIR . 'classes/batch-process/helpers/class-wp-async-request.php';
95
+ require_once CARTFLOWS_DIR . 'classes/batch-process/helpers/class-wp-background-process.php';
96
+
97
+ $default_page_builder = Cartflows_Helper::get_common_setting( 'default_page_builder' );
98
+
99
+ // Elementor.
100
+ if ( ( 'elementor' === $default_page_builder ) && class_exists( '\Elementor\Plugin' ) ) {
101
+ // Add "elementor" in import [queue].
102
+ // @todo Remove required `allow_url_fopen` support.
103
+ if ( ini_get( 'allow_url_fopen' ) ) {
104
+ require_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-importer-elementor.php';
105
+ require_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-importer-elementor-batch.php';
106
+ self::$batch_instance_elementor = new Cartflows_Importer_Elementor_Batch();
107
+ }
108
+ }
109
+
110
+ // Beaver Builder.
111
+ if ( ( 'beaver-builder' === $default_page_builder ) && class_exists( 'FLBuilder' ) ) {
112
+ require_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-importer-beaver-builder.php';
113
+ require_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-importer-beaver-builder-batch.php';
114
+ self::$batch_instance_bb = new Cartflows_Importer_Beaver_Builder_Batch();
115
+ }
116
+
117
+ // Divi.
118
+ if ( ( 'divi' === $default_page_builder ) && ( class_exists( 'ET_Builder_Plugin' ) || Cartflows_Compatibility::get_instance()->is_divi_enabled() ) ) {
119
+ require_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-importer-divi.php';
120
+ require_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-importer-divi-batch.php';
121
+ self::$batch_instance_divi = new Cartflows_Importer_Divi_Batch();
122
+ }
123
+
124
+ // Gutenberg.
125
+ if ( ( 'gutenberg' === $default_page_builder ) ) {
126
+ require_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-importer-gutenberg.php';
127
+ require_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-importer-gutenberg-batch.php';
128
+ self::$batch_instance_gb = new Cartflows_Importer_Gutenberg_Batch();
129
+ }
130
+
131
+ // Start image importing after site import complete.
132
+ add_action( 'cartflows_after_template_import', array( $this, 'start_batch_process' ) );
133
+ add_action( 'cartflows_import_complete', array( $this, 'complete_batch_import' ) );
134
+ add_filter( 'upload_mimes', array( $this, 'custom_upload_mimes' ) );
135
+ add_filter( 'wp_prepare_attachment_for_js', array( $this, 'add_svg_image_support' ), 10, 3 );
136
+ }
137
+
138
+ /**
139
+ * Added .svg files as supported format in the uploader.
140
+ *
141
+ * @since 1.1.4
142
+ *
143
+ * @param array $mimes Already supported mime types.
144
+ */
145
+ public function custom_upload_mimes( $mimes ) {
146
+
147
+ // Allow SVG files.
148
+ $mimes['svg'] = 'image/svg+xml';
149
+ $mimes['svgz'] = 'image/svg+xml';
150
+
151
+ // Allow XML files.
152
+ $mimes['xml'] = 'text/xml';
153
+
154
+ return $mimes;
155
+ }
156
+
157
+ /**
158
+ * Add SVG image support
159
+ *
160
+ * @since 1.1.4
161
+ *
162
+ * @param array $response Attachment response.
163
+ * @param object $attachment Attachment object.
164
+ * @param array $meta Attachment meta data.
165
+ */
166
+ public function add_svg_image_support( $response, $attachment, $meta ) {
167
+ if ( ! function_exists( 'simplexml_load_file' ) ) {
168
+ return $response;
169
+ }
170
+
171
+ if ( ! empty( $response['sizes'] ) ) {
172
+ return $response;
173
+ }
174
+
175
+ if ( 'image/svg+xml' !== $response['mime'] ) {
176
+ return $response;
177
+ }
178
+
179
+ $svg_path = get_attached_file( $attachment->ID );
180
+
181
+ $dimensions = self::get_svg_dimensions( $svg_path );
182
+
183
+ $response['sizes'] = array(
184
+ 'full' => array(
185
+ 'url' => $response['url'],
186
+ 'width' => $dimensions->width,
187
+ 'height' => $dimensions->height,
188
+ 'orientation' => $dimensions->width > $dimensions->height ? 'landscape' : 'portrait',
189
+ ),
190
+ );
191
+
192
+ return $response;
193
+ }
194
+
195
+ /**
196
+ * Get SVG Dimensions
197
+ *
198
+ * @since 1.1.4.
199
+ *
200
+ * @param string $svg SVG file path.
201
+ * @return array Return SVG file height & width for valid SVG file.
202
+ */
203
+ public static function get_svg_dimensions( $svg ) {
204
+
205
+ $svg = simplexml_load_file( $svg );
206
+
207
+ if ( false === $svg ) {
208
+ $width = '0';
209
+ $height = '0';
210
+ } else {
211
+ $attributes = $svg->attributes();
212
+ $width = (string) $attributes->width;
213
+ $height = (string) $attributes->height;
214
+ }
215
+
216
+ return (object) array(
217
+ 'width' => $width,
218
+ 'height' => $height,
219
+ );
220
+ }
221
+
222
+ /**
223
+ * Batch Process Complete.
224
+ *
225
+ * @return void
226
+ */
227
+ public function complete_batch_import() {
228
+ wcf()->logger->import_log( '(✓) BATCH Process Complete!' );
229
+ }
230
+
231
+ /**
232
+ * Start Image Import
233
+ *
234
+ * @param integer $post_id Post Id.
235
+ *
236
+ * @return void
237
+ */
238
+ public function start_batch_process( $post_id = '' ) {
239
+
240
+ $default_page_builder = Cartflows_Helper::get_common_setting( 'default_page_builder' );
241
+
242
+ wcf()->logger->import_log( '(✓) BATCH Started!' );
243
+ wcf()->logger->import_log( '(✓) Step ID ' . $post_id );
244
+
245
+ // Add "elementor" in import [queue].
246
+ if ( 'beaver-builder' === $default_page_builder && self::$batch_instance_bb ) {
247
+
248
+ // Add to queue.
249
+ self::$batch_instance_bb->push_to_queue( $post_id );
250
+
251
+ // Dispatch Queue.
252
+ self::$batch_instance_bb->save()->dispatch();
253
+
254
+ wcf()->logger->import_log( '(✓) Dispatch "Beaver Builder" Request..' );
255
+
256
+ } elseif ( 'elementor' === $default_page_builder && self::$batch_instance_elementor ) {
257
+
258
+ // Add to queue.
259
+ self::$batch_instance_elementor->push_to_queue( $post_id );
260
+
261
+ // Dispatch Queue.
262
+ self::$batch_instance_elementor->save()->dispatch();
263
+
264
+ wcf()->logger->import_log( '(✓) Dispatch "Elementor" Request..' );
265
+ } elseif ( 'divi' === $default_page_builder && self::$batch_instance_divi ) {
266
+
267
+ // Add to queue.
268
+ self::$batch_instance_divi->push_to_queue( $post_id );
269
+
270
+ // Dispatch Queue.
271
+ self::$batch_instance_divi->save()->dispatch();
272
+
273
+ wcf()->logger->import_log( '(✓) Dispatch "Divi" Request..' );
274
+ } elseif ( 'gutenberg' === $default_page_builder && self::$batch_instance_gb ) {
275
+
276
+ // Add to queue.
277
+ self::$batch_instance_gb->push_to_queue( $post_id );
278
+
279
+ // Dispatch Queue.
280
+ self::$batch_instance_gb->save()->dispatch();
281
+
282
+ wcf()->logger->import_log( '(✓) Dispatch "Gutenberg" Request..' );
283
+ } else {
284
+ wcf()->logger->import_log( '(✕) Could not import image due to allow_url_fopen() is disabled!' );
285
+ }
286
+ }
287
+
288
+ }
289
+
290
+ /**
291
+ * Kicking this off by calling 'get_instance()' method
292
+ */
293
+ CartFlows_Batch_Process::get_instance();
294
+
295
+ endif;
classes/batch-process/class-cartflows-importer-elementor.php CHANGED
@@ -1,69 +1,86 @@
1
- <?php
2
- /**
3
- * Elementor Importer
4
- *
5
- * @package CARTFLOWS
6
- */
7
-
8
- namespace Elementor\TemplateLibrary;
9
-
10
- use Elementor\Core\Base\Document;
11
- use Elementor\DB;
12
- use Elementor\Core\Settings\Page\Manager as PageSettingsManager;
13
- use Elementor\Core\Settings\Manager as SettingsManager;
14
- use Elementor\Core\Settings\Page\Model;
15
- use Elementor\Editor;
16
- use Elementor\Plugin;
17
- use Elementor\Settings;
18
- use Elementor\Utils;
19
-
20
- if ( ! defined( 'ABSPATH' ) ) {
21
- exit; // Exit if accessed directly.
22
- }
23
-
24
- /**
25
- * Elementor template library local source.
26
- *
27
- * Elementor template library local source handler class is responsible for
28
- * handling local Elementor templates saved by the user locally on his site.
29
- *
30
- * @since 1.0.0
31
- */
32
- class CartFlows_Importer_Elementor extends Source_Local {
33
-
34
- /**
35
- * Import single template
36
- *
37
- * @param int $post_id post ID.
38
- */
39
- public function import_single_template( $post_id ) {
40
-
41
- $rest_content = get_post_meta( $post_id, '_elementor_data', true );
42
-
43
- if ( empty( $rest_content ) ) {
44
- $data = __( 'Invalid content.', 'cartflows' );
45
- wcf()->logger->import_log( '(✕) ' . $data );
46
- }
47
-
48
- $rest_content = add_magic_quotes( $rest_content );
49
- $content = json_decode( $rest_content, true );
50
-
51
- if ( ! is_array( $content ) ) {
52
- $data = __( 'Invalid content. Expected an array.', 'cartflows' );
53
- wcf()->logger->import_log( '(✕) ' . $data );
54
- wcf()->logger->import_log( $content );
55
- } else {
56
-
57
- wcf()->logger->import_log( '() Processing Request..' );
58
-
59
- // Import the data.
60
- $content = $this->process_export_import_content( $content, 'on_import' );
61
-
62
- // Update content.
63
- update_metadata( 'post', $post_id, '_elementor_data', $content );
64
-
65
- wcf()->logger->import_log( '(✓) Process Complete' );
66
- }
67
-
68
- }
69
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Elementor Importer
4
+ *
5
+ * @package CARTFLOWS
6
+ */
7
+
8
+ namespace Elementor\TemplateLibrary;
9
+
10
+ use Elementor\Core\Base\Document;
11
+ use Elementor\DB;
12
+ use Elementor\Core\Settings\Page\Manager as PageSettingsManager;
13
+ use Elementor\Core\Settings\Manager as SettingsManager;
14
+ use Elementor\Core\Settings\Page\Model;
15
+ use Elementor\Editor;
16
+ use Elementor\Plugin;
17
+ use Elementor\Settings;
18
+ use Elementor\Utils;
19
+
20
+ if ( ! defined( 'ABSPATH' ) ) {
21
+ exit; // Exit if accessed directly.
22
+ }
23
+
24
+ /**
25
+ * Elementor template library local source.
26
+ *
27
+ * Elementor template library local source handler class is responsible for
28
+ * handling local Elementor templates saved by the user locally on his site.
29
+ *
30
+ * @since 1.0.0
31
+ */
32
+ class CartFlows_Importer_Elementor extends Source_Local {
33
+
34
+ /**
35
+ * Import single template
36
+ *
37
+ * @param int $post_id post ID.
38
+ */
39
+ public function import_single_template( $post_id ) {
40
+
41
+ $rest_content = get_post_meta( $post_id, '_elementor_data', true );
42
+
43
+ if ( empty( $rest_content ) ) {
44
+ $data = __( 'Invalid content.', 'cartflows' );
45
+ wcf()->logger->import_log( '(✕) ' . $data );
46
+ }
47
+
48
+ if ( is_array( $rest_content ) ) {
49
+ $content = $rest_content;
50
+ } else {
51
+ $rest_content = add_magic_quotes( $rest_content );
52
+ $content = json_decode( $rest_content, true );
53
+ }
54
+
55
+ if ( ! is_array( $content ) ) {
56
+ $data = __( 'Invalid content. Expected an array.', 'cartflows' );
57
+ wcf()->logger->import_log( '() ' . $data );
58
+ wcf()->logger->import_log( $content );
59
+ } else {
60
+
61
+ wcf()->logger->import_log( '(✓) Processing Request..' );
62
+
63
+ // Import the data.
64
+ $content = $this->process_export_import_content( $content, 'on_import' );
65
+
66
+ // Update content.
67
+ update_metadata( 'post', $post_id, '_elementor_data', $content );
68
+
69
+ $this->clear_cache();
70
+
71
+ wcf()->logger->import_log( '(✓) Process Complete' );
72
+ }
73
+ }
74
+
75
+ /**
76
+ * Clear Cache.
77
+ *
78
+ * @since 1.0.0
79
+ */
80
+ public function clear_cache() {
81
+ // Clear 'Elementor' file cache.
82
+ if ( class_exists( '\Elementor\Plugin' ) ) {
83
+ \Elementor\Plugin::$instance->files_manager->clear_cache();
84
+ }
85
+ }
86
+ }
classes/batch-process/class-cartflows-importer-gutenberg-batch.php ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Gutenberg Batch Process
4
+ *
5
+ * @package CartFlows
6
+ * @since x.x.x
7
+ */
8
+
9
+ if ( ! class_exists( 'Cartflows_Importer_Gutenberg_Batch' ) && class_exists( 'WP_Background_Process' ) ) :
10
+
11
+ /**
12
+ * Image Background Process
13
+ *
14
+ * @since x.x.x
15
+ */
16
+ class Cartflows_Importer_Gutenberg_Batch extends WP_Background_Process {
17
+
18
+ /**
19
+ * Image Process
20
+ *
21
+ * @var string
22
+ */
23
+ protected $action = 'cartflows_gutenberg_image_process';
24
+
25
+ /**
26
+ * Task
27
+ *
28
+ * Override this method to perform any actions required on each
29
+ * queue item. Return the modified item for further processing
30
+ * in the next pass through. Or, return false to remove the
31
+ * item from the queue.
32
+ *
33
+ * @since x.x.x
34
+ *
35
+ * @param integer $post_id Post Id.
36
+ * @return mixed
37
+ */
38
+ protected function task( $post_id ) {
39
+
40
+ CartFlows_Importer_Gutenberg::get_instance()->import_single_post( $post_id );
41
+
42
+ return false;
43
+ }
44
+
45
+ /**
46
+ * Complete
47
+ *
48
+ * Override if applicable, but ensure that the below actions are
49
+ * performed, or, call parent::complete().
50
+ *
51
+ * @since x.x.x
52
+ */
53
+ protected function complete() {
54
+
55
+ parent::complete();
56
+
57
+ do_action( 'cartflows_import_complete' );
58
+
59
+ }
60
+
61
+ }
62
+
63
+ endif;
classes/batch-process/class-cartflows-importer-gutenberg.php ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Gutenberg Importer
4
+ *
5
+ * @package CartFlows
6
+ * @since x.x.x
7
+ */
8
+
9
+ if ( ! class_exists( 'CartFlows_Importer_Gutenberg' ) ) :
10
+
11
+ /**
12
+ * CartFlows Import Gutenberg
13
+ *
14
+ * @since x.x.x
15
+ */
16
+ class CartFlows_Importer_Gutenberg {
17
+
18
+ /**
19
+ * Instance
20
+ *
21
+ * @since x.x.x
22
+ * @access private
23
+ * @var object Class object.
24
+ */
25
+ private static $instance;
26
+
27
+ /**
28
+ * Initiator
29
+ *
30
+ * @since x.x.x
31
+ * @return object initialized object of class.
32
+ */
33
+ public static function get_instance() {
34
+
35
+ if ( ! isset( self::$instance ) ) {
36
+ self::$instance = new self();
37
+ }
38
+ return self::$instance;
39
+ }
40
+
41
+ /**
42
+ * Constructor
43
+ *
44
+ * @since x.x.x
45
+ */
46
+ public function __construct() {}
47
+
48
+ /**
49
+ * Update post meta.
50
+ *
51
+ * @param integer $post_id Post ID.
52
+ * @return void
53
+ */
54
+ public function import_single_post( $post_id = 0 ) {
55
+
56
+ // Download and replace images.
57
+ $content = get_post_field( 'post_content', $post_id );
58
+
59
+ if ( empty( $content ) ) {
60
+ wcf()->logger->import_log( '(✕) Not have "Gutenberg" Data. Post content is empty!' );
61
+ } else {
62
+
63
+ wcf()->logger->import_log( '(✓) Processing Request..' );
64
+
65
+ // Update hotlink images.
66
+ $content = CartFlows_Importer::get_instance()->get_content( $content );
67
+
68
+ // Fix for gutenberg invalid html due & -> &amp -> \u0026amp.
69
+ $content = str_replace( '&amp;', "\u0026amp;", $content );
70
+
71
+ // Update post content.
72
+ wp_update_post(
73
+ array(
74
+ 'ID' => $post_id,
75
+ 'post_content' => $content,
76
+ )
77
+ );
78
+
79
+ wcf()->logger->import_log( '(✓) Process Complete' );
80
+ }
81
+ }
82
+
83
+ }
84
+
85
+ /**
86
+ * Initialize class object with 'get_instance()' method
87
+ */
88
+ CartFlows_Importer_Gutenberg::get_instance();
89
+
90
+ endif;
classes/batch-process/helpers/class-cartflows-importer-image.php CHANGED
@@ -12,7 +12,6 @@
12
  * $downloaded_image = CartFlows_Import_Image::get_instance()->import( $image );
13
  *
14
  * @package CartFlows
15
- *
16
  * @since 1.1.1
17
  */
18
 
@@ -50,7 +49,7 @@ if ( ! class_exists( 'CartFlows_Import_Image' ) ) :
50
  */
51
  public static function get_instance() {
52
  if ( ! isset( self::$instance ) ) {
53
- self::$instance = new self;
54
  }
55
  return self::$instance;
56
  }
@@ -107,33 +106,23 @@ if ( ! class_exists( 'CartFlows_Import_Image' ) ) :
107
  */
108
  private function get_saved_image( $attachment ) {
109
 
110
- wcf()->logger->import_log( 'importer-image.php File' );
111
-
112
  if ( apply_filters( 'cartflows_image_importer_skip_image', false, $attachment ) ) {
113
-
114
- wcf()->logger->import_log( 'Download (✕) Replace (✕) - ' . $attachment['url'] );
115
-
116
- return $attachment;
 
117
  }
118
 
119
  global $wpdb;
120
 
121
- // Already imported? Then return!
122
- if ( isset( $this->already_imported_ids[ $attachment['id'] ] ) ) {
123
-
124
- wcf()->logger->import_log( 'Download (✓) Replace (✓) - ' . $attachment['url'] );
125
-
126
- return $this->already_imported_ids[ $attachment['id'] ];
127
- }
128
-
129
  // 1. Is already imported in Batch Import Process?
130
  $post_id = $wpdb->get_var(
131
  $wpdb->prepare(
132
- "
133
- SELECT post_id FROM {$wpdb->postmeta}
134
- WHERE meta_key = '_cartflows_image_hash'
135
- AND meta_value = %s
136
- ",
137
  $this->get_hash_image( $attachment['url'] )
138
  )
139
  );
@@ -145,28 +134,35 @@ if ( ! class_exists( 'CartFlows_Import_Image' ) ) :
145
  // To check it exist in attachment.
146
  $filename = basename( $attachment['url'] );
147
 
148
- wcf()->logger->import_log( 'File Basename - ' . $filename );
149
-
150
- $post_id = $wpdb->get_var( $wpdb->prepare( "
151
- SELECT post_id FROM {$wpdb->postmeta}
152
- WHERE meta_key = '_wp_attached_file'
153
- AND meta_value LIKE %s
154
- ", '%/' . $filename . '%' ) );
 
155
 
156
- wcf()->logger->import_log( 'Download (✓) Replace (✓) - ' . $attachment['url'] );
157
  }
158
 
159
  if ( $post_id ) {
160
- $new_attachment = array(
161
  'id' => $post_id,
162
  'url' => wp_get_attachment_url( $post_id ),
163
  );
164
- $this->already_imported_ids[ $attachment['id'] ] = $new_attachment;
165
 
166
- return $new_attachment;
 
 
 
167
  }
168
 
169
- return false;
 
 
 
170
  }
171
 
172
  /**
@@ -178,36 +174,50 @@ if ( ! class_exists( 'CartFlows_Import_Image' ) ) :
178
  */
179
  public function import( $attachment ) {
180
 
 
181
  $saved_image = $this->get_saved_image( $attachment );
 
182
 
183
- if ( $saved_image ) {
184
- return $saved_image;
185
  }
186
 
187
- $file_content = wp_remote_retrieve_body( wp_safe_remote_get( $attachment['url'], array( 'timeout' => '60', 'sslverify' => false) ) );
 
 
 
 
 
 
 
 
188
 
189
  // Empty file content?
190
  if ( empty( $file_content ) ) {
191
 
192
- wcf()->logger->import_log( 'Download (✕) Replace (✕) - ' . $attachment['url'] );
193
- wcf()->logger->import_log( 'Error: Failed wp_remote_retrieve_body().' );
194
-
195
  return $attachment;
196
  }
197
 
198
  // Extract the file name and extension from the URL.
199
  $filename = basename( $attachment['url'] );
200
 
 
201
  $upload = wp_upload_bits(
202
  $filename,
203
  null,
204
  $file_content
205
  );
 
 
 
 
206
 
207
  $post = array(
208
  'post_title' => $filename,
209
  'guid' => $upload['url'],
210
  );
 
211
 
212
  $info = wp_check_filetype( $upload['file'] );
213
  if ( $info ) {
@@ -229,9 +239,9 @@ if ( ! class_exists( 'CartFlows_Import_Image' ) ) :
229
  'url' => $upload['url'],
230
  );
231
 
232
- wcf()->logger->import_log( 'Download (✓) Replace (✓) - ' . $attachment['url'] );
233
 
234
- $this->already_imported_ids[ $attachment['id'] ] = $new_attachment;
235
 
236
  return $new_attachment;
237
  }
@@ -239,8 +249,8 @@ if ( ! class_exists( 'CartFlows_Import_Image' ) ) :
239
  }
240
 
241
  /**
242
- * Initialize class object with 'get_instance()' method
243
  */
244
  CartFlows_Import_Image::get_instance();
245
 
246
- endif;
12
  * $downloaded_image = CartFlows_Import_Image::get_instance()->import( $image );
13
  *
14
  * @package CartFlows
 
15
  * @since 1.1.1
16
  */
17
 
49
  */
50
  public static function get_instance() {
51
  if ( ! isset( self::$instance ) ) {
52
+ self::$instance = new self();
53
  }
54
  return self::$instance;
55
  }
106
  */
107
  private function get_saved_image( $attachment ) {
108
 
 
 
109
  if ( apply_filters( 'cartflows_image_importer_skip_image', false, $attachment ) ) {
110
+ wcf()->logger->import_log( 'IMAGE - SKIP Image - {from filter} - ' . $attachment['url'] . ' - Filter name `cartflows_image_importer_skip_image`.' );
111
+ return array(
112
+ 'status' => true,
113
+ 'attachment' => $attachment,
114
+ );
115
  }
116
 
117
  global $wpdb;
118
 
 
 
 
 
 
 
 
 
119
  // 1. Is already imported in Batch Import Process?
120
  $post_id = $wpdb->get_var(
121
  $wpdb->prepare(
122
+ 'SELECT `post_id` FROM `' . $wpdb->postmeta . '`
123
+ WHERE `meta_key` = \'_cartflows_image_hash\'
124
+ AND `meta_value` = %s
125
+ ;',
 
126
  $this->get_hash_image( $attachment['url'] )
127
  )
128
  );
134
  // To check it exist in attachment.
135
  $filename = basename( $attachment['url'] );
136
 
137
+ $post_id = $wpdb->get_var(
138
+ $wpdb->prepare(
139
+ "SELECT post_id FROM {$wpdb->postmeta}
140
+ WHERE meta_key = '_wp_attached_file'
141
+ AND meta_value LIKE %s",
142
+ '%/' . $filename . '%'
143
+ )
144
+ );
145
 
146
+ wcf()->logger->import_log( 'IMAGE - SKIP Image {already imported from xml} - ' . $attachment['url'] );
147
  }
148
 
149
  if ( $post_id ) {
150
+ $new_attachment = array(
151
  'id' => $post_id,
152
  'url' => wp_get_attachment_url( $post_id ),
153
  );
154
+ $this->already_imported_ids[] = $post_id;
155
 
156
+ return array(
157
+ 'status' => true,
158
+ 'attachment' => $new_attachment,
159
+ );
160
  }
161
 
162
+ return array(
163
+ 'status' => false,
164
+ 'attachment' => $attachment,
165
+ );
166
  }
167
 
168
  /**
174
  */
175
  public function import( $attachment ) {
176
 
177
+ wcf()->logger->import_log( 'Source - ' . $attachment['url'] );
178
  $saved_image = $this->get_saved_image( $attachment );
179
+ wcf()->logger->import_log( 'Log - ' . wp_json_encode( $saved_image['attachment'] ) );
180
 
181
+ if ( $saved_image['status'] ) {
182
+ return $saved_image['attachment'];
183
  }
184
 
185
+ $file_content = wp_remote_retrieve_body(
186
+ wp_safe_remote_get(
187
+ $attachment['url'],
188
+ array(
189
+ 'timeout' => '60',
190
+ 'sslverify' => false,
191
+ )
192
+ )
193
+ );
194
 
195
  // Empty file content?
196
  if ( empty( $file_content ) ) {
197
 
198
+ wcf()->logger->import_log( 'IMAGE - FAIL Image {Error: Failed wp_remote_retrieve_body} - ' . $attachment['url'] );
 
 
199
  return $attachment;
200
  }
201
 
202
  // Extract the file name and extension from the URL.
203
  $filename = basename( $attachment['url'] );
204
 
205
+ // @codingStandardsIgnoreStart
206
  $upload = wp_upload_bits(
207
  $filename,
208
  null,
209
  $file_content
210
  );
211
+ // @codingStandardsIgnoreEnd
212
+
213
+ wcf()->logger->import_log( $filename );
214
+ wcf()->logger->import_log( wp_json_encode( $upload ) );
215
 
216
  $post = array(
217
  'post_title' => $filename,
218
  'guid' => $upload['url'],
219
  );
220
+ wcf()->logger->import_log( wp_json_encode( $post ) );
221
 
222
  $info = wp_check_filetype( $upload['file'] );
223
  if ( $info ) {
239
  'url' => $upload['url'],
240
  );
241
 
242
+ wcf()->logger->import_log( 'IMAGE - SUCCESS Image {Imported} - ' . $new_attachment['url'] );
243
 
244
+ $this->already_imported_ids[] = $post_id;
245
 
246
  return $new_attachment;
247
  }
249
  }
250
 
251
  /**
252
+ * Kicking this off by calling 'get_instance()' method
253
  */
254
  CartFlows_Import_Image::get_instance();
255
 
256
+ endif;
classes/class-cartflows-admin-fields.php CHANGED
@@ -1,267 +1,271 @@
1
- <?php
2
- /**
3
- * CARTFLOWS Admin Fields.
4
- *
5
- * @package CARTFLOWS
6
- */
7
-
8
- /**
9
- * Class Cartflows_Admin_Fields.
10
- */
11
- class Cartflows_Admin_Fields {
12
-
13
- /**
14
- * Title Field
15
- *
16
- * @param array $args Args.
17
- * @return string
18
- */
19
- public static function title_field( $args ) {
20
-
21
- $title = $args['title'];
22
- $description = isset( $args['description'] ) ? $args['description'] : '';
23
-
24
- $output = '<h4 class="form-field wcf-title-field">';
25
- $output .= '<span>' . $title . '</span>';
26
- $output .= '</h4>';
27
-
28
- if ( ! empty( $description ) ) {
29
- $output .= '<div class="form-field-desc">';
30
- $output .= '<p>' . $description . '</p>';
31
- $output .= '</div>';
32
- }
33
-
34
- return $output;
35
- }
36
-
37
- /**
38
- * Text Field
39
- *
40
- * @param array $args Args.
41
- * @return string
42
- */
43
- public static function text_field( $args ) {
44
-
45
- $id = $args['id'];
46
- $name = $args['name'];
47
- $title = $args['title'];
48
- $value = $args['value'];
49
- $description = isset( $args['description'] ) ? $args['description'] : '';
50
- $placeholder = isset( $args['placeholder'] ) ? $args['placeholder'] : '';
51
-
52
- $output = '<div class="form-field" id="form-field-' . $id . '">';
53
- $output .= '<label for="' . $id . '">' . $title . '</label>';
54
- $output .= '<input placeholder="' . $placeholder . '" type="text" name="' . $name . '" id="' . $id . '" class="placeholder placeholder-active" value="' . esc_attr( $value ) . '">';
55
- $output .= '</div>';
56
-
57
- if ( ! empty( $description ) ) {
58
- $output .= '<div class="form-field-desc">';
59
- $output .= '<p>';
60
- $output .= $description;
61
- $output .= '</p>';
62
- $output .= '</div>';
63
- }
64
-
65
- return $output;
66
- }
67
-
68
- /**
69
- * URL Field
70
- *
71
- * @param array $args Args.
72
- * @return string
73
- */
74
- public static function url_field( $args ) {
75
-
76
- $id = $args['id'];
77
- $name = $args['name'];
78
- $title = $args['title'];
79
- $value = $args['value'];
80
-
81
- $output = '<div class="form-field">';
82
- $output .= '<label for="' . $id . '">' . $title . '</label>';
83
- $output .= '<input type="text" name="' . $name . '" id="' . $id . '" class="placeholder placeholder-active" value="' . esc_url( $value ) . '">';
84
- $output .= '</div>';
85
-
86
- return $output;
87
- }
88
-
89
- /**
90
- * Checkbox Field
91
- *
92
- * @param array $args Args.
93
- * @return string
94
- */
95
- public static function checkobox_field( $args ) {
96
-
97
- $id = $args['id'];
98
- $name = $args['name'];
99
- $title = $args['title'];
100
- $value = $args['value'];
101
-
102
- $output = '<div class="form-field" id="form-field-' . $id . '">';
103
- $output .= '<label for="' . $id . '">';
104
- $output .= '<input type="hidden" id="wcf_hid_' . $id . '" name="' . $name . '" value="disable">';
105
- $output .= '<input type="checkbox" id="wcf_' . $id . '" name="' . $name . '" value="enable" ' . checked( $value, 'enable', false ) . '>';
106
- $output .= $title;
107
- $output .= '</label>';
108
- $output .= '</div>';
109
-
110
- return $output;
111
- }
112
-
113
- /**
114
- * Radio Field
115
- *
116
- * @param array $args Args.
117
- * @return string
118
- */
119
- public static function radio_field( $args ) {
120
-
121
- $name = $args['name'];
122
- $id = $args['id'];
123
- $options = $args['options'];
124
- $value = $args['value'];
125
-
126
- $output = '';
127
- foreach ( $options as $type => $data ) {
128
-
129
- $output .= '<div class="form-field">';
130
- $output .= '<label for="' . $id . '">';
131
- $output .= '<input type="radio" class="wcf_permalink_structure" name="' . $name . '" value="' . $type . '" ' . checked( $value, $type, false ) . '>' . $data['label'] . '</label>';
132
- $output .= '<div class="form-field-desc">';
133
- $output .= '<p>';
134
- if ( empty( $type ) ) {
135
- $output .= $data['description'];
136
- } else {
137
- $output .= get_site_url() . $data['description'];
138
- }
139
-
140
- $output .= '</p>';
141
- $output .= '</div>';
142
- $output .= '</div>';
143
- }
144
-
145
- return $output;
146
- }
147
-
148
- /**
149
- * Select Field
150
- *
151
- * @since 1.1.4
152
- *
153
- * @param array $args Args.
154
- * @return string
155
- */
156
- public static function select_field( $args ) {
157
-
158
- $id = $args['id'];
159
- $name = $args['name'];
160
- $title = $args['title'];
161
- $description = $args['description'];
162
- $value = $args['value'];
163
- $options = $args['options'];
164
-
165
- $output = '<div class="form-field" id="form-field-' . $id . '">';
166
-
167
- $output .= '<div class="form-field-label">';
168
- $output .= $title;
169
- $output .= '</div>';
170
-
171
- $output .= '<div class="form-field-data">';
172
- $output .= '<select id="wcf_' . $id . '" name="' . $name . '">';
173
- foreach ( $options as $option_value => $option_title ) {
174
- $output .= '<option value="' . $option_value . '" ' . selected( $value, $option_value, false ) . '>' . $option_title . '</option>';
175
- }
176
- $output .= '</select>';
177
- $output .= '</div>';
178
-
179
- $output .= '<div class="form-field-desc">';
180
- $output .= '<p>';
181
- $output .= $description;
182
- $output .= '</p>';
183
- $output .= '</div>';
184
- $output .= '</div>';
185
-
186
- return $output;
187
- }
188
-
189
- /**
190
- * Checkout Selection Field
191
- *
192
- * @param array $args Args.
193
- * @return string
194
- */
195
- public static function flow_checkout_selection_field( $args ) {
196
-
197
- $id = $args['id'];
198
- $name = $args['name'];
199
- $title = $args['title'];
200
- $value = $args['value'];
201
-
202
- $checkout_steps = get_posts(
203
- array(
204
- 'posts_per_page' => -1,
205
- 'post_type' => CARTFLOWS_STEP_POST_TYPE,
206
- 'post_status' => 'publish',
207
- 'orderby' => 'ID',
208
- 'order' => 'ASC',
209
- 'tax_query' => array( //phpcs:ignore
210
- array(
211
- 'taxonomy' => CARTFLOWS_TAXONOMY_STEP_TYPE,
212
- 'field' => 'slug',
213
- 'terms' => 'checkout',
214
- ),
215
- ),
216
- )
217
- );
218
-
219
- $output = '<div class="form-field" id="form-field-' . $id . '">';
220
-
221
- $output .= '<div class="form-field-label">';
222
- $output .= '<label for="' . $id . '">';
223
- $output .= $title;
224
- $output .= '</label>';
225
- $output .= '</div>';
226
-
227
- $output .= '<div class="form-field-data">';
228
- $output .= '<select id="wcf_' . $id . '" name="' . $name . '">';
229
-
230
- if ( ! empty( $checkout_steps ) ) {
231
- $output .= '<option value="">' . __( 'Select', 'cartflows' ) . '</option>';
232
- } else {
233
-
234
- $output .= '<option value="">' . __( 'No Checkout Steps', 'cartflows' ) . '</option>';
235
- }
236
-
237
- foreach ( $checkout_steps as $index => $step_data ) {
238
-
239
- $output .= '<option value="' . $step_data->ID . '" ' . selected( $value, $step_data->ID, false ) . '>' . $step_data->post_title . ' (#' . $step_data->ID . ') </option>';
240
- }
241
-
242
- $output .= '</select>';
243
- $output .= '</div>';
244
-
245
- if ( '' !== $value ) {
246
- $output .= '<div class="form-field-actions">';
247
- $output .= '<a href="' . get_edit_post_link( $value ) . '" target="_blank" class="" title="Edit">';
248
- $output .= '<span class="dashicons dashicons-edit"></span>';
249
- $output .= '<span class="">Edit</span>';
250
- $output .= '</a>';
251
- $output .= '<a href="' . get_permalink( $value ) . '" target="_blank" class="" title="View">';
252
- $output .= '<span class="dashicons dashicons-visibility"></span>';
253
- $output .= '<span class="">View</span>';
254
- $output .= '</a>';
255
- $output .= '</div>';
256
- }
257
-
258
- $output .= '<div class="form-field-desc">';
259
- /* translators: %s: link */
260
- $output .= '<p>' . sprintf( __( 'Be sure not to add any product in above selected Global Checkout step. Please read information about how to set up Global Checkout %1$shere%2$s.', 'cartflows' ), '<a href="https://cartflows.com/docs/global-checkout/" target="_blank">', '</a>' ) . '</p>';
261
- $output .= '</div>';
262
-
263
- $output .= '</div>';
264
-
265
- return $output;
266
- }
267
- }
 
 
 
 
1
+ <?php
2
+ /**
3
+ * CARTFLOWS Admin Fields.
4
+ *
5
+ * @package CARTFLOWS
6
+ */
7
+
8
+ /**
9
+ * Class Cartflows_Admin_Fields.
10
+ */
11
+ class Cartflows_Admin_Fields {
12
+
13
+ /**
14
+ * Title Field
15
+ *
16
+ * @param array $args Args.
17
+ * @return string
18
+ */
19
+ public static function title_field( $args ) {
20
+
21
+ $title = $args['title'];
22
+ $description = isset( $args['description'] ) ? $args['description'] : '';
23
+
24
+ $output = '<h4 class="form-field wcf-title-field">';
25
+ $output .= '<span>' . $title . '</span>';
26
+ $output .= '</h4>';
27
+
28
+ if ( ! empty( $description ) ) {
29
+ $output .= '<div class="form-field-desc">';
30
+ $output .= '<p>' . $description . '</p>';
31
+ $output .= '</div>';
32
+ }
33
+
34
+ return $output;
35
+ }
36
+
37
+ /**
38
+ * Text Field
39
+ *
40
+ * @param array $args Args.
41
+ * @return string
42
+ */
43
+ public static function text_field( $args ) {
44
+
45
+ $id = $args['id'];
46
+ $name = $args['name'];
47
+ $title = $args['title'];
48
+ $value = $args['value'];
49
+ $description = isset( $args['description'] ) ? $args['description'] : '';
50
+ $placeholder = isset( $args['placeholder'] ) ? $args['placeholder'] : '';
51
+
52
+ $output = '<div class="form-field" id="form-field-' . $id . '">';
53
+ $output .= '<label for="' . $id . '">' . $title . '</label>';
54
+ $output .= '<input placeholder="' . $placeholder . '" type="text" name="' . $name . '" id="' . $id . '" class="placeholder placeholder-active" value="' . esc_attr( $value ) . '">';
55
+ $output .= '</div>';
56
+
57
+ if ( ! empty( $description ) ) {
58
+ $output .= '<div class="form-field-desc">';
59
+ $output .= '<p>';
60
+ $output .= $description;
61
+ $output .= '</p>';
62
+ $output .= '</div>';
63
+ }
64
+
65
+ return $output;
66
+ }
67
+
68
+ /**
69
+ * URL Field
70
+ *
71
+ * @param array $args Args.
72
+ * @return string
73
+ */
74
+ public static function url_field( $args ) {
75
+
76
+ $id = $args['id'];
77
+ $name = $args['name'];
78
+ $title = $args['title'];
79
+ $value = $args['value'];
80
+
81
+ $output = '<div class="form-field">';
82
+ $output .= '<label for="' . $id . '">' . $title . '</label>';
83
+ $output .= '<input type="text" name="' . $name . '" id="' . $id . '" class="placeholder placeholder-active" value="' . esc_url( $value ) . '">';
84
+ $output .= '</div>';
85
+
86
+ return $output;
87
+ }
88
+
89
+ /**
90
+ * Checkbox Field
91
+ *
92
+ * @param array $args Args.
93
+ * @return string
94
+ */
95
+ public static function checkobox_field( $args ) {
96
+
97
+ $id = $args['id'];
98
+ $name = $args['name'];
99
+ $title = $args['title'];
100
+ $value = $args['value'];
101
+
102
+ $output = '<div class="form-field" id="form-field-' . $id . '">';
103
+ $output .= '<label for="' . $id . '">';
104
+ $output .= '<input type="hidden" id="wcf_hid_' . $id . '" name="' . $name . '" value="disable">';
105
+ $output .= '<input type="checkbox" id="wcf_' . $id . '" name="' . $name . '" value="enable" ' . checked( $value, 'enable', false ) . '>';
106
+ $output .= $title;
107
+ $output .= '</label>';
108
+ $output .= '</div>';
109
+
110
+ return $output;
111
+ }
112
+
113
+ /**
114
+ * Radio Field
115
+ *
116
+ * @param array $args Args.
117
+ * @return string
118
+ */
119
+ public static function radio_field( $args ) {
120
+
121
+ $name = $args['name'];
122
+ $id = $args['id'];
123
+ $options = $args['options'];
124
+ $value = $args['value'];
125
+
126
+ $output = '';
127
+
128
+ if ( isset( $args['title'] ) ) {
129
+ $output .= '<h4 class="form-field-label">';
130
+ $output .= '<span>' . $args['title'] . '</span>';
131
+ $output .= '</h4>';
132
+ }
133
+
134
+ foreach ( $options as $type => $data ) {
135
+
136
+ $output .= '<div class="form-field">';
137
+ $output .= '<label for="' . $id . '">';
138
+ $output .= '<input type="radio" class="wcf_permalink_structure" name="' . $name . '" value="' . $type . '" ' . checked( $value, $type, false ) . '>' . $data['label'] . '</label>';
139
+ $output .= '<div class="form-field-desc">';
140
+ $output .= '<p>';
141
+
142
+ $output .= $data['description'];
143
+
144
+ $output .= '</p>';
145
+ $output .= '</div>';
146
+ $output .= '</div>';
147
+ }
148
+
149
+ return $output;
150
+ }
151
+
152
+ /**
153
+ * Select Field
154
+ *
155
+ * @since 1.1.4
156
+ *
157
+ * @param array $args Args.
158
+ * @return string
159
+ */
160
+ public static function select_field( $args ) {
161
+
162
+ $id = $args['id'];
163
+ $name = $args['name'];
164
+ $title = $args['title'];
165
+ $description = $args['description'];
166
+ $value = $args['value'];
167
+ $options = $args['options'];
168
+
169
+ $output = '<div class="form-field" id="form-field-' . $id . '">';
170
+
171
+ $output .= '<div class="form-field-label">';
172
+ $output .= $title;
173
+ $output .= '</div>';
174
+
175
+ $output .= '<div class="form-field-data">';
176
+ $output .= '<select id="wcf_' . $id . '" name="' . $name . '">';
177
+ foreach ( $options as $option_value => $option_title ) {
178
+ $output .= '<option value="' . $option_value . '" ' . selected( $value, $option_value, false ) . '>' . $option_title . '</option>';
179
+ }
180
+ $output .= '</select>';
181
+ $output .= '</div>';
182
+
183
+ $output .= '<div class="form-field-desc">';
184
+ $output .= '<p>';
185
+ $output .= $description;
186
+ $output .= '</p>';
187
+ $output .= '</div>';
188
+ $output .= '</div>';
189
+
190
+ return $output;
191
+ }
192
+
193
+ /**
194
+ * Checkout Selection Field
195
+ *
196
+ * @param array $args Args.
197
+ * @return string
198
+ */
199
+ public static function flow_checkout_selection_field( $args ) {
200
+
201
+ $id = $args['id'];
202
+ $name = $args['name'];
203
+ $title = $args['title'];
204
+ $value = $args['value'];
205
+
206
+ $checkout_steps = get_posts(
207
+ array(
208
+ 'posts_per_page' => -1,
209
+ 'post_type' => CARTFLOWS_STEP_POST_TYPE,
210
+ 'post_status' => 'publish',
211
+ 'orderby' => 'ID',
212
+ 'order' => 'ASC',
213
+ 'tax_query' => array( //phpcs:ignore
214
+ array(
215
+ 'taxonomy' => CARTFLOWS_TAXONOMY_STEP_TYPE,
216
+ 'field' => 'slug',
217
+ 'terms' => 'checkout',
218
+ ),
219
+ ),
220
+ )
221
+ );
222
+
223
+ $output = '<div class="form-field" id="form-field-' . $id . '">';
224
+
225
+ $output .= '<div class="form-field-label">';
226
+ $output .= '<label for="' . $id . '">';
227
+ $output .= $title;
228
+ $output .= '</label>';
229
+ $output .= '</div>';
230
+
231
+ $output .= '<div class="form-field-data">';
232
+ $output .= '<select id="wcf_' . $id . '" name="' . $name . '">';
233
+
234
+ if ( ! empty( $checkout_steps ) ) {
235
+ $output .= '<option value="">' . __( 'Select', 'cartflows' ) . '</option>';
236
+ } else {
237
+
238
+ $output .= '<option value="">' . __( 'No Checkout Steps', 'cartflows' ) . '</option>';
239
+ }
240
+
241
+ foreach ( $checkout_steps as $index => $step_data ) {
242
+
243
+ $output .= '<option value="' . $step_data->ID . '" ' . selected( $value, $step_data->ID, false ) . '>' . $step_data->post_title . ' (#' . $step_data->ID . ') </option>';
244
+ }
245
+
246
+ $output .= '</select>';
247
+ $output .= '</div>';
248
+
249
+ if ( '' !== $value ) {
250
+ $output .= '<div class="form-field-actions">';
251
+ $output .= '<a href="' . get_edit_post_link( $value ) . '" target="_blank" class="" title="Edit">';
252
+ $output .= '<span class="dashicons dashicons-edit"></span>';
253
+ $output .= '<span class="">Edit</span>';
254
+ $output .= '</a>';
255
+ $output .= '<a href="' . get_permalink( $value ) . '" target="_blank" class="" title="View">';
256
+ $output .= '<span class="dashicons dashicons-visibility"></span>';
257
+ $output .= '<span class="">View</span>';
258
+ $output .= '</a>';
259
+ $output .= '</div>';
260
+ }
261
+
262
+ $output .= '<div class="form-field-desc">';
263
+ /* translators: %s: link */
264
+ $output .= '<p>' . sprintf( __( 'Be sure not to add any product in above selected Global Checkout step. Please read information about how to set up Global Checkout %1$shere%2$s.', 'cartflows' ), '<a href="https://cartflows.com/docs/global-checkout/" target="_blank">', '</a>' ) . '</p>';
265
+ $output .= '</div>';
266
+
267
+ $output .= '</div>';
268
+
269
+ return $output;
270
+ }
271
+ }
classes/class-cartflows-admin.php CHANGED
@@ -1,653 +1,657 @@
1
- <?php
2
- /**
3
- * CartFlows Admin.
4
- *
5
- * @package CartFlows
6
- */
7
-
8
- /**
9
- * Class Cartflows_Admin.
10
- */
11
- class Cartflows_Admin {
12
-
13
- /**
14
- * Calls on initialization
15
- *
16
- * @since 1.0.0
17
- */
18
- public static function init() {
19
-
20
- self::initialise_plugin();
21
- self::init_hooks();
22
- }
23
-
24
- /**
25
- * Init Hooks.
26
- *
27
- * @since 1.0.0
28
- * @return void
29
- */
30
- public static function init_hooks() {
31
-
32
- if ( ! is_admin() ) {
33
- return;
34
- }
35
-
36
- include_once CARTFLOWS_DIR . 'classes/class-cartflows-admin-fields.php';
37
-
38
- /*
39
- Add CARTFLOWS menu option to admin.
40
- add_action( 'network_admin_menu', __CLASS__ . '::menu' );
41
- */
42
- add_action( 'admin_menu', __CLASS__ . '::menu' );
43
- add_action( 'admin_menu', __CLASS__ . '::submenu', 999 );
44
-
45
- add_action( 'cartflows_render_admin_content', __CLASS__ . '::render_content' );
46
-
47
- add_action( 'admin_init', __CLASS__ . '::settings_admin_scripts' );
48
-
49
- /* Global Addmin Script */
50
- add_action( 'admin_enqueue_scripts', __CLASS__ . '::global_admin_scripts', 20 );
51
-
52
- add_action( 'admin_footer', __CLASS__ . '::global_admin_data', 9555 );
53
-
54
- /* Add lite version class to body */
55
- add_action( 'admin_body_class', __CLASS__ . '::add_admin_body_class' );
56
-
57
- add_filter( 'plugin_action_links_' . CARTFLOWS_BASE, __CLASS__ . '::add_action_links' );
58
-
59
- add_action( 'admin_init', __CLASS__ . '::cartflows_after_save_permalinks' );
60
-
61
- }
62
-
63
- /**
64
- * After save of permalinks.
65
- */
66
- public static function cartflows_after_save_permalinks() {
67
-
68
- $has_saved_permalinks = get_option( 'cartflows_permalink_saved' );
69
- if ( $has_saved_permalinks ) {
70
- flush_rewrite_rules();
71
- delete_option( 'cartflows_permalink_saved' );
72
- }
73
- }
74
-
75
-
76
- /**
77
- * Initialize after Cartflows pro get loaded.
78
- */
79
- public static function settings_admin_scripts() {
80
- // Enqueue admin scripts.
81
- if ( isset( $_REQUEST['page'] ) && CARTFLOWS_SETTINGS === $_REQUEST['page'] ) { //phpcs:ignore
82
- add_action( 'admin_enqueue_scripts', __CLASS__ . '::styles_scripts' );
83
-
84
- self::save_settings();
85
- }
86
- }
87
- /**
88
- * Show action on plugin page.
89
- *
90
- * @param array $links links.
91
- * @return array
92
- */
93
- public static function add_action_links( $links ) {
94
- $mylinks = array(
95
- '<a href="' . admin_url( 'admin.php?page=' . CARTFLOWS_SETTINGS ) . '">Settings</a>',
96
- '<a target="_blank" href="' . esc_url( 'https://cartflows.com/docs' ) . '">Docs</a>',
97
- );
98
-
99
- if ( ! _is_cartflows_pro() ) {
100
- array_push( $mylinks, '<a style="color: #39b54a; font-weight: bold;" target="_blank" href="' . esc_url( 'https://cartflows.com/pricing/' ) . '"> Go Pro </a>' );
101
- }
102
-
103
- return array_merge( $links, $mylinks );
104
- }
105
-
106
- /**
107
- * Initialises the Plugin Name.
108
- *
109
- * @since 1.0.0
110
- * @return void
111
- */
112
- public static function initialise_plugin() {
113
-
114
- $name = 'Cartflows';
115
- $short_name = 'Cflows';
116
-
117
- define( 'CARTFLOWS_PLUGIN_NAME', $name );
118
- define( 'CARTFLOWS_PLUGIN_SHORT_NAME', $short_name );
119
- }
120
-
121
- /**
122
- * Renders the admin settings menu.
123
- *
124
- * @since 1.0.0
125
- * @return void
126
- */
127
- public static function menu() {
128
-
129
- if ( ! current_user_can( 'manage_options' ) ) {
130
- return;
131
- }
132
-
133
- add_menu_page(
134
- 'CartFlows',
135
- 'CartFlows',
136
- 'manage_options',
137
- CARTFLOWS_SLUG,
138
- __CLASS__ . '::render',
139
- 'data:image/svg+xml;base64,' . base64_encode( file_get_contents( CARTFLOWS_DIR . 'assets/images/cartflows-icon.svg' ) ),//phpcs:ignore
140
- 39.7
141
- );
142
-
143
- }
144
-
145
- /**
146
- * Add submenu to admin menu.
147
- *
148
- * @since 1.0.0
149
- */
150
- public static function submenu() {
151
-
152
- $parent_slug = CARTFLOWS_SLUG;
153
- $page_title = __( 'Settings', 'cartflows' );
154
- $menu_title = __( 'Settings', 'cartflows' );
155
- $capability = 'manage_options';
156
- $menu_slug = 'cartflows_settings';
157
- $callback = __CLASS__ . '::render';
158
-
159
- add_submenu_page(
160
- $parent_slug,
161
- $page_title,
162
- $menu_title,
163
- $capability,
164
- $menu_slug,
165
- $callback
166
- );
167
- }
168
-
169
- /**
170
- * Renders the admin settings.
171
- *
172
- * @since 1.0.0
173
- * @return void
174
- */
175
- public static function render() {
176
- $action = ( isset( $_GET['action'] ) ) ? sanitize_text_field( wp_unslash( $_GET['action'] ) ) : ''; //phpcs:ignore
177
- $action = ( ! empty( $action ) && '' != $action ) ? $action : 'general';
178
- $action = str_replace( '_', '-', $action );
179
-
180
- // Enable header icon filter below.
181
- $header_wrapper_class = apply_filters( 'cartflows_header_wrapper_class', array( $action ) );
182
-
183
- include_once CARTFLOWS_DIR . 'includes/admin/cartflows-admin.php';
184
- }
185
-
186
- /**
187
- * Renders the admin settings content.
188
- *
189
- * @since 1.0.0
190
- * @return void
191
- */
192
- public static function render_content() {
193
-
194
- $action = ( isset( $_GET['action'] ) ) ? sanitize_text_field( wp_unslash( $_GET['action'] ) ) : ''; //phpcs:ignore
195
- $action = ( ! empty( $action ) && '' != $action ) ? $action : 'general';
196
- $action = str_replace( '_', '-', $action );
197
- $action = 'general';
198
-
199
- $header_wrapper_class = apply_filters( 'cartflows_header_wrapper_class', array( $action ) );
200
-
201
- include_once CARTFLOWS_DIR . 'includes/admin/cartflows-general.php';
202
- }
203
-
204
- /**
205
- * Save Global Setting options.
206
- *
207
- * @since 1.0.0
208
- */
209
- public static function save_common_settings() {
210
-
211
- if ( isset( $_POST['cartflows-common-settings-nonce'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['cartflows-common-settings-nonce'] ) ), 'cartflows-common-settings' ) ) {
212
-
213
- $url = isset( $_SERVER['REQUEST_URI'] ) ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '';
214
- $new_settings = array();
215
-
216
- if ( isset( $_POST['_cartflows_common'] ) ) {
217
- // Loop through the input and sanitize each of the values.
218
- $new_settings = self::sanitize_form_inputs( wp_unslash( $_POST['_cartflows_common'] ) ); //phpcs:ignore
219
- }
220
-
221
- Cartflows_Helper::update_admin_settings_option( '_cartflows_common', $new_settings, false );
222
-
223
- $query = array(
224
- 'message' => 'saved',
225
- );
226
-
227
- $redirect_to = add_query_arg( $query, $url );
228
-
229
- wp_safe_redirect( $redirect_to );
230
- exit;
231
- } // End if statement.
232
- }
233
-
234
- /**
235
- * Save Debug Setting options.
236
- *
237
- * @since 1.1.14
238
- */
239
- public static function save_debug_settings() {
240
-
241
- if ( isset( $_POST['cartflows-debug-settings-nonce'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['cartflows-debug-settings-nonce'] ) ), 'cartflows-debug-settings' ) ) {
242
-
243
- $url = isset( $_SERVER['REQUEST_URI'] ) ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '';
244
- $new_settings = array();
245
-
246
- if ( isset( $_POST['_cartflows_debug_data'] ) ) {
247
- $new_settings = self::sanitize_form_inputs( wp_unslash( $_POST['_cartflows_debug_data'] ) ); //phpcs:ignore
248
- }
249
-
250
- Cartflows_Helper::update_admin_settings_option( '_cartflows_debug_data', $new_settings, false );
251
-
252
- $query = array(
253
- 'message' => 'saved',
254
- );
255
-
256
- $redirect_to = add_query_arg( $query, $url );
257
-
258
- wp_safe_redirect( $redirect_to );
259
- exit;
260
-
261
- }
262
- }
263
-
264
-
265
- /**
266
- * Save permalink Setting options.
267
- *
268
- * @since 1.1.14
269
- */
270
- public static function save_permalink_settings() {
271
-
272
- if ( isset( $_POST['cartflows-permalink-settings-nonce'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['cartflows-permalink-settings-nonce'] ) ), 'cartflows-permalink-settings' ) ) {
273
-
274
- $url = isset( $_SERVER['REQUEST_URI'] ) ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '';
275
- $new_settings = array();
276
-
277
- if ( isset( $_POST['reset'] ) ) {
278
- $_POST['_cartflows_permalink'] = array(
279
- 'permalink' => CARTFLOWS_STEP_POST_TYPE,
280
- 'permalink_flow_base' => CARTFLOWS_FLOW_POST_TYPE,
281
- 'permalink_structure' => '',
282
- );
283
-
284
- }
285
-
286
- if ( isset( $_POST['_cartflows_permalink'] ) ) {
287
- $cartflows_permalink_settings = self::sanitize_form_inputs( wp_unslash( $_POST['_cartflows_permalink'] ) ); //phpcs:ignore
288
-
289
- if ( empty( $cartflows_permalink_settings['permalink'] ) ) {
290
- $new_settings['permalink'] = CARTFLOWS_STEP_POST_TYPE;
291
- } else {
292
- $new_settings['permalink'] = $cartflows_permalink_settings['permalink'];
293
- }
294
-
295
- if ( empty( $cartflows_permalink_settings['permalink_flow_base'] ) ) {
296
- $new_settings['permalink_flow_base'] = CARTFLOWS_FLOW_POST_TYPE;
297
- } else {
298
- $new_settings['permalink_flow_base'] = $cartflows_permalink_settings['permalink_flow_base'];
299
- }
300
-
301
- $new_settings['permalink_structure'] = $cartflows_permalink_settings['permalink_structure'];
302
-
303
- }
304
-
305
- Cartflows_Helper::update_admin_settings_option( '_cartflows_permalink', $new_settings, false );
306
-
307
- $query = array(
308
- 'message' => 'saved',
309
- );
310
-
311
- $redirect_to = add_query_arg( $query, $url );
312
-
313
- update_option( 'cartflows_permalink_saved', true );
314
-
315
- wp_safe_redirect( $redirect_to );
316
- exit;
317
-
318
- }
319
- }
320
-
321
- /**
322
- * Save google analytics Setting options.
323
- *
324
- * @since 1.1.14
325
- */
326
- public static function save_google_analytics_settings() {
327
-
328
- if ( isset( $_POST['cartflows-google-analytics-settings-nonce'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['cartflows-google-analytics-settings-nonce'] ) ), 'cartflows-google-analytics-settings' ) ) {
329
-
330
- $url = isset( $_SERVER['REQUEST_URI'] ) ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '';
331
- $new_settings = array();
332
-
333
- if ( isset( $_POST['_cartflows_google_analytics'] ) ) {
334
- $new_settings = self::sanitize_form_inputs( $_POST['_cartflows_google_analytics'] ); //phpcs:ignore
335
-
336
- }
337
-
338
- Cartflows_Helper::update_admin_settings_option( '_cartflows_google_analytics', $new_settings, true );
339
-
340
- $query = array(
341
- 'message' => 'saved',
342
- );
343
-
344
- $redirect_to = add_query_arg( $query, $url );
345
-
346
- wp_safe_redirect( $redirect_to );
347
- exit;
348
-
349
- }
350
- }
351
-
352
- /**
353
- * Loop through the input and sanitize each of the values.
354
- *
355
- * @param array $input_settings input settings.
356
- * @return array
357
- */
358
- public static function sanitize_form_inputs( $input_settings = array() ) {
359
- $new_settings = array();
360
- foreach ( $input_settings as $key => $val ) {
361
-
362
- if ( is_array( $val ) ) {
363
- foreach ( $val as $k => $v ) {
364
- $new_settings[ $key ][ $k ] = ( isset( $val[ $k ] ) ) ? sanitize_text_field( $v ) : '';
365
- }
366
- } else {
367
- $new_settings[ $key ] = ( isset( $input_settings[ $key ] ) ) ? sanitize_text_field( $val ) : '';
368
- }
369
- }
370
- return $new_settings;
371
- }
372
-
373
- /**
374
- * Check is cartflows admin.
375
- *
376
- * @since 1.0.0
377
- * @return boolean
378
- */
379
- public static function is_global_admin() {
380
-
381
- $current_screen = get_current_screen();
382
-
383
- if (
384
- is_object( $current_screen ) &&
385
- isset( $current_screen->post_type ) &&
386
- ( CARTFLOWS_FLOW_POST_TYPE === $current_screen->post_type ||
387
- CARTFLOWS_STEP_POST_TYPE === $current_screen->post_type
388
- )
389
- ) {
390
- return true;
391
- }
392
- return false;
393
- }
394
-
395
- /**
396
- * Check is flow admin.
397
- *
398
- * @since 1.0.0
399
- * @return boolean
400
- */
401
- public static function is_flow_edit_admin() {
402
-
403
- $current_screen = get_current_screen();
404
-
405
- if (
406
- is_object( $current_screen ) &&
407
- isset( $current_screen->post_type ) &&
408
- ( CARTFLOWS_FLOW_POST_TYPE === $current_screen->post_type ) &&
409
- isset( $current_screen->base ) &&
410
- ( 'post' === $current_screen->base )
411
- ) {
412
- return true;
413
- }
414
- return false;
415
- }
416
-
417
- /**
418
- * Global Admin Scripts.
419
- *
420
- * @since 1.0.0
421
- */
422
- public static function global_admin_scripts() {
423
-
424
- $installed_plugins = get_plugins();
425
- $is_wc_installed = isset( $installed_plugins['woocommerce/woocommerce.php'] ) ? true : false;
426
- $edit_test_mode = filter_input( INPUT_GET, 'edit_test_mode', FILTER_SANITIZE_STRING );
427
- $edit_test_mode = 'yes' === $edit_test_mode ? true : false;
428
-
429
- $localize = array(
430
- 'ajaxurl' => admin_url( 'admin-ajax.php' ),
431
- 'ajax_nonce' => wp_create_nonce( 'cartflows-nonce' ),
432
- 'wc_status' => array(
433
- 'installed' => $is_wc_installed,
434
- 'active' => wcf()->is_woo_active,
435
- ),
436
- 'wc_activating_message' => __( 'Installing and activating..', 'cartflows' ),
437
- 'wc_install_error' => __( 'There was an error with the installation of plugin.', 'cartflows' ),
438
- 'wcf_edit_test_mode' => $edit_test_mode,
439
- );
440
-
441
- wp_localize_script( 'jquery', 'cartflows_admin', apply_filters( 'cartflows_admin_js_localize', $localize ) );
442
-
443
- if ( self::is_global_admin() ) {
444
-
445
- // Styles.
446
- wp_enqueue_style( 'cartflows-global-admin', CARTFLOWS_URL . 'admin/assets/css/global-admin.css', array(), CARTFLOWS_VER );
447
- wp_style_add_data( 'cartflows-global-admin', 'rtl', 'replace' );
448
-
449
- wp_enqueue_script(
450
- 'wcf-global-admin',
451
- CARTFLOWS_URL . 'admin/assets/js/global-admin.js',
452
- array( 'jquery' ),
453
- CARTFLOWS_VER,
454
- true
455
- );
456
-
457
- do_action( 'cartflows_global_admin_scripts' );
458
- }
459
- }
460
-
461
- /**
462
- * Global Admin Data.
463
- *
464
- * @since 1.0.0
465
- */
466
- public static function global_admin_data() {
467
-
468
- $current_screen = get_current_screen();
469
-
470
- if ( ! $current_screen ) {
471
- return;
472
- }
473
-
474
- if ( 'edit-' . CARTFLOWS_FLOW_POST_TYPE != $current_screen->id ) {
475
- return;
476
- }
477
-
478
- $default_page_builder = Cartflows_Helper::get_common_setting( 'default_page_builder' );
479
- ?>
480
-
481
- <div id="wcf-remote-flow-importer" class="wcf-templates-popup-overlay">
482
- <div class="wcf-templates-popup-content">
483
- <div class="spinner"></div>
484
- <div class="wcf-templates-wrap wcf-templates-wrap-flows">
485
-
486
- <div id="wcf-remote-flow-actions" class="wcf-template-header">
487
- <div class="wcf-template-logo-wrap">
488
- <span class="wcf-cartflows-logo-img">
489
- <span class="cartflows-logo-icon"></span>
490
- </span>
491
- <span class="wcf-cartflows-title"><?php esc_html_e( 'Flows Library', 'cartflows' ); ?></span>
492
- </div>
493
- <div class="wcf-tab-wrapper">
494
- <?php if ( 'other' !== $default_page_builder ) { ?>
495
- <div id="wcf-get-started-steps">
496
- <ul class="filter-links ">
497
- <li>
498
- <a href="#" class="current" data-slug="ready-templates" data-title="<?php esc_html_e( 'Ready Templates', 'cartflows' ); ?>"><?php esc_html_e( 'Ready Templates', 'cartflows' ); ?></a>
499
- </li>
500
- <li>
501
- <a href="#" data-slug="canvas" data-title="<?php esc_html_e( 'Create Your Own', 'cartflows' ); ?>"><?php esc_html_e( 'Create Your Own', 'cartflows' ); ?></a>
502
- </li>
503
- </ul>
504
- </div>
505
- <?php } ?>
506
- </div>
507
- <div class="wcf-popup-close-wrap">
508
- <span class="close-icon"><span class="wcf-cartflow-icons dashicons dashicons-no"></span></span>
509
- </div>
510
- </div>
511
- <!-- <div class="wcf-search-form">
512
- <label class="screen-reader-text" for="wp-filter-search-input"><?php esc_html_e( 'Search Sites', 'cartflows' ); ?> </label>
513
- <input placeholder="<?php esc_html_e( 'Search Flow...', 'cartflows' ); ?>" type="text" aria-describedby="live-search-desc" class="wcf-flow-search-input">
514
- </div> -->
515
-
516
- <div id="wcf-remote-content">
517
- <?php if ( 'other' !== $default_page_builder ) { ?>
518
- <div id="wcf-ready-templates">
519
- <div id="wcf-remote-filters">
520
- <div id="wcf-page-builders"></div>
521
- <div id="wcf-categories"></div>
522
- </div>
523
- <div class="wcf-page-builder-notice"></div>
524
- <div id="wcf-remote-flow-list" class="wcf-remote-list wcf-template-list-wrap"><span class="spinner is-active"></span></div>
525
- <div id="wcf-upcoming-page-builders" style="display: none;" class="wcf-remote-list wcf-template-list-wrap"></div>
526
- </div>
527
- <?php } ?>
528
- <div id="wcf-start-from-scratch" style="<?php echo ( 'other' !== $default_page_builder ) ? 'display: none;' : ''; ?>">
529
- <div class="inner">
530
- <a href="#" class="button button-hero button-primary cartflows-flow-import-blank"><?php esc_html_e( 'Design Your Flow', 'cartflows' ); ?></a>
531
- <p class="wcf-learn-how"><a href="https://cartflows.com/docs/cartflows-step-types/" target="_blank"><?php esc_html_e( 'Learn How', 'cartflows' ); ?> <i class="dashicons dashicons-external"></i></a></p>
532
- </div>
533
- </div>
534
- </div>
535
- </div>
536
- </div>
537
- </div>
538
-
539
- <?php
540
- }
541
-
542
- /**
543
- * Enqueues the needed CSS/JS for the builder's admin settings page.
544
- *
545
- * @since 1.0.0
546
- */
547
- public static function styles_scripts() {
548
-
549
- // Styles.
550
- wp_enqueue_style( 'cartflows-admin-settings', CARTFLOWS_URL . 'admin/assets/css/admin-menu-settings.css', array(), CARTFLOWS_VER );
551
- wp_style_add_data( 'cartflows-admin-settings', 'rtl', 'replace' );
552
-
553
- // Script.
554
- wp_enqueue_script( 'cartflows-admin-settings', CARTFLOWS_URL . 'admin/assets/js/admin-menu-settings.js', array( 'jquery', 'wp-util', 'updates' ), CARTFLOWS_VER, false );
555
-
556
- $localize = array(
557
- 'ajax_nonce' => wp_create_nonce( 'cartflows-widget-nonce' ),
558
- );
559
-
560
- wp_localize_script( 'cartflows-admin-settings', 'cartflows', apply_filters( 'cartflows_js_localize', $localize ) );
561
-
562
- do_action( 'cartflows_admin_settings_after_enqueue_scripts' );
563
- }
564
-
565
- /**
566
- * Save All admin settings here
567
- */
568
- public static function save_settings() {
569
-
570
- // Only admins can save settings.
571
- if ( ! current_user_can( 'manage_options' ) ) {
572
- return;
573
- }
574
-
575
- self::save_common_settings();
576
- self::save_debug_settings();
577
- self::save_permalink_settings();
578
-
579
- self::save_google_analytics_settings();
580
- self::save_facebook_settings();
581
-
582
- // Let extensions hook into saving.
583
- do_action( 'cartflows_admin_settings_save' );
584
- }
585
-
586
- /**
587
- * Get and return page URL
588
- *
589
- * @param string $menu_slug Menu name.
590
- * @since 1.0.0
591
- * @return string page url
592
- */
593
- public static function get_page_url( $menu_slug ) {
594
-
595
- $parent_page = self::$default_menu_position;
596
-
597
- if ( strpos( $parent_page, '?' ) !== false ) {
598
- $query_var = '&page=' . self::$plugin_slug;
599
- } else {
600
- $query_var = '?page=' . self::$plugin_slug;
601
- }
602
-
603
- $parent_page_url = admin_url( $parent_page . $query_var );
604
-
605
- $url = $parent_page_url . '&action=' . $menu_slug;
606
-
607
- return esc_url( $url );
608
- }
609
-
610
- /**
611
- * Admin body classes.
612
- *
613
- * Body classes to be added to <body> tag in admin page
614
- *
615
- * @param String $classes body classes returned from the filter.
616
- * @return String body classes to be added to <body> tag in admin page
617
- */
618
- public static function add_admin_body_class( $classes ) {
619
-
620
- $classes .= ' cartflows-' . CARTFLOWS_VER;
621
-
622
- return $classes;
623
- }
624
-
625
- /**
626
- * Save Global Setting options.
627
- *
628
- * @since 1.0.0
629
- */
630
- public static function save_facebook_settings() {
631
-
632
- if ( isset( $_POST['cartflows-facebook-settings-nonce'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['cartflows-facebook-settings-nonce'] ) ), 'cartflows-facebook-settings' ) ) {
633
-
634
- $url = isset( $_SERVER['REQUEST_URI'] ) ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '';
635
- $new_settings = array();
636
-
637
- if ( isset( $_POST['_cartflows_facebook'] ) ) {
638
- $new_settings = self::sanitize_form_inputs( wp_unslash( $_POST['_cartflows_facebook'] ) ); //phpcs:ignore
639
- }
640
-
641
- Cartflows_Helper::update_admin_settings_option( '_cartflows_facebook', $new_settings, false );
642
- $query = array(
643
- 'message' => 'saved',
644
- );
645
- $redirect_to = add_query_arg( $query, $url );
646
- wp_safe_redirect( $redirect_to );
647
- exit;
648
- }
649
- }
650
-
651
- }
652
-
653
- Cartflows_Admin::init();
 
 
 
 
1
+ <?php
2
+ /**
3
+ * CartFlows Admin.
4
+ *
5
+ * @package CartFlows
6
+ */
7
+
8
+ /**
9
+ * Class Cartflows_Admin.
10
+ */
11
+ class Cartflows_Admin {
12
+
13
+ /**
14
+ * Calls on initialization
15
+ *
16
+ * @since 1.0.0
17
+ */
18
+ public static function init() {
19
+
20
+ self::initialise_plugin();
21
+ self::init_hooks();
22
+ }
23
+
24
+ /**
25
+ * Init Hooks.
26
+ *
27
+ * @since 1.0.0
28
+ * @return void
29
+ */
30
+ public static function init_hooks() {
31
+
32
+ if ( ! is_admin() ) {
33
+ return;
34
+ }
35
+
36
+ include_once CARTFLOWS_DIR . 'classes/class-cartflows-admin-fields.php';
37
+
38
+ /*
39
+ Add CARTFLOWS menu option to admin.
40
+ add_action( 'network_admin_menu', __CLASS__ . '::menu' );
41
+ */
42
+ add_action( 'admin_menu', __CLASS__ . '::menu' );
43
+ add_action( 'admin_menu', __CLASS__ . '::submenu', 999 );
44
+
45
+ add_action( 'cartflows_render_admin_content', __CLASS__ . '::render_content' );
46
+
47
+ add_action( 'admin_init', __CLASS__ . '::settings_admin_scripts' );
48
+
49
+ /* Global Addmin Script */
50
+ add_action( 'admin_enqueue_scripts', __CLASS__ . '::global_admin_scripts', 20 );
51
+
52
+ add_action( 'admin_footer', __CLASS__ . '::global_admin_data', 9555 );
53
+
54
+ /* Add lite version class to body */
55
+ add_action( 'admin_body_class', __CLASS__ . '::add_admin_body_class' );
56
+
57
+ add_filter( 'plugin_action_links_' . CARTFLOWS_BASE, __CLASS__ . '::add_action_links' );
58
+
59
+ add_action( 'admin_init', __CLASS__ . '::cartflows_after_save_permalinks' );
60
+
61
+ }
62
+
63
+ /**
64
+ * After save of permalinks.
65
+ */
66
+ public static function cartflows_after_save_permalinks() {
67
+
68
+ $has_saved_permalinks = get_option( 'cartflows_permalink_saved' );
69
+ if ( $has_saved_permalinks ) {
70
+ flush_rewrite_rules();
71
+ delete_option( 'cartflows_permalink_saved' );
72
+ }
73
+ }
74
+
75
+
76
+ /**
77
+ * Initialize after Cartflows pro get loaded.
78
+ */
79
+ public static function settings_admin_scripts() {
80
+ // Enqueue admin scripts.
81
+ if ( isset( $_GET['page'] ) && false !== strpos( $_GET['page'], 'cartflows_' ) ) { //phpcs:ignore
82
+ add_action( 'admin_enqueue_scripts', __CLASS__ . '::styles_scripts' );
83
+
84
+ self::save_settings();
85
+ }
86
+ }
87
+ /**
88
+ * Show action on plugin page.
89
+ *
90
+ * @param array $links links.
91
+ * @return array
92
+ */
93
+ public static function add_action_links( $links ) {
94
+ $mylinks = array(
95
+ '<a href="' . admin_url( 'admin.php?page=' . CARTFLOWS_SETTINGS ) . '">Settings</a>',
96
+ '<a target="_blank" href="' . esc_url( 'https://cartflows.com/docs' ) . '">Docs</a>',
97
+ );
98
+
99
+ if ( ! _is_cartflows_pro() ) {
100
+ array_push( $mylinks, '<a style="color: #39b54a; font-weight: bold;" target="_blank" href="' . esc_url( 'https://cartflows.com/pricing/' ) . '"> Go Pro </a>' );
101
+ }
102
+
103
+ return array_merge( $links, $mylinks );
104
+ }
105
+
106
+ /**
107
+ * Initialises the Plugin Name.
108
+ *
109
+ * @since 1.0.0
110
+ * @return void
111
+ */
112
+ public static function initialise_plugin() {
113
+
114
+ $name = 'Cartflows';
115
+ $short_name = 'Cflows';
116
+
117
+ define( 'CARTFLOWS_PLUGIN_NAME', $name );
118
+ define( 'CARTFLOWS_PLUGIN_SHORT_NAME', $short_name );
119
+ }
120
+
121
+ /**
122
+ * Renders the admin settings menu.
123
+ *
124
+ * @since 1.0.0
125
+ * @return void
126
+ */
127
+ public static function menu() {
128
+
129
+ if ( ! current_user_can( 'manage_options' ) ) {
130
+ return;
131
+ }
132
+
133
+ add_menu_page(
134
+ 'CartFlows',
135
+ 'CartFlows',
136
+ 'manage_options',
137
+ CARTFLOWS_SLUG,
138
+ __CLASS__ . '::render',
139
+ 'data:image/svg+xml;base64,' . base64_encode( file_get_contents( CARTFLOWS_DIR . 'assets/images/cartflows-icon.svg' ) ),//phpcs:ignore
140
+ 39.7
141
+ );
142
+
143
+ }
144
+
145
+ /**
146
+ * Add submenu to admin menu.
147
+ *
148
+ * @since 1.0.0
149
+ */
150
+ public static function submenu() {
151
+
152
+ $parent_slug = CARTFLOWS_SLUG;
153
+ $page_title = __( 'Settings', 'cartflows' );
154
+ $menu_title = __( 'Settings', 'cartflows' );
155
+ $capability = 'manage_options';
156
+ $menu_slug = 'cartflows_settings';
157
+ $callback = __CLASS__ . '::render';
158
+
159
+ add_submenu_page(
160
+ $parent_slug,
161
+ $page_title,
162
+ $menu_title,
163
+ $capability,
164
+ $menu_slug,
165
+ $callback
166
+ );
167
+ }
168
+
169
+ /**
170
+ * Renders the admin settings.
171
+ *
172
+ * @since 1.0.0
173
+ * @return void
174
+ */
175
+ public static function render() {
176
+ $menu_page_slug = ( isset( $_GET['page'] ) ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : CARTFLOWS_SETTINGS; //phpcs:ignore
177
+ $action = ( isset( $_GET['action'] ) ) ? sanitize_text_field( wp_unslash( $_GET['action'] ) ) : ''; //phpcs:ignore
178
+ $action = ( ! empty( $action ) && '' != $action ) ? $action : 'general';
179
+ $action = str_replace( '_', '-', $action );
180
+
181
+ // Enable header icon filter below.
182
+ $header_wrapper_class = apply_filters( 'cartflows_admin_header_wrapper_class', array( $action, $menu_page_slug ) );
183
+
184
+ include_once CARTFLOWS_DIR . 'includes/admin/cartflows-admin.php';
185
+ }
186
+
187
+ /**
188
+ * Renders the admin settings content.
189
+ *
190
+ * @since 1.0.0
191
+ * @param sting $menu_page_slug current page name.
192
+ *
193
+ * @return void
194
+ */
195
+ public static function render_content( $menu_page_slug ) {
196
+
197
+ if ( CARTFLOWS_SETTINGS === $menu_page_slug ) {
198
+
199
+ $action = ( isset( $_GET['action'] ) ) ? sanitize_text_field( wp_unslash( $_GET['action'] ) ) : ''; //phpcs:ignore
200
+ $action = ( ! empty( $action ) && '' != $action ) ? $action : 'general';
201
+ $action = str_replace( '_', '-', $action );
202
+ $action = 'general';
203
+
204
+ include_once CARTFLOWS_DIR . 'includes/admin/cartflows-general.php';
205
+ }
206
+ }
207
+
208
+ /**
209
+ * Save Global Setting options.
210
+ *
211
+ * @since 1.0.0
212
+ */
213
+ public static function save_common_settings() {
214
+
215
+ if ( isset( $_POST['cartflows-common-settings-nonce'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['cartflows-common-settings-nonce'] ) ), 'cartflows-common-settings' ) ) {
216
+
217
+ $url = isset( $_SERVER['REQUEST_URI'] ) ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '';
218
+ $new_settings = array();
219
+
220
+ if ( isset( $_POST['_cartflows_common'] ) ) {
221
+ // Loop through the input and sanitize each of the values.
222
+ $new_settings = self::sanitize_form_inputs( wp_unslash( $_POST['_cartflows_common'] ) ); //phpcs:ignore
223
+ }
224
+
225
+ Cartflows_Helper::update_admin_settings_option( '_cartflows_common', $new_settings, false );
226
+
227
+ $query = array(
228
+ 'message' => 'saved',
229
+ );
230
+
231
+ $redirect_to = add_query_arg( $query, $url );
232
+
233
+ wp_safe_redirect( $redirect_to );
234
+ exit;
235
+ } // End if statement.
236
+ }
237
+
238
+ /**
239
+ * Save Debug Setting options.
240
+ *
241
+ * @since 1.1.14
242
+ */
243
+ public static function save_debug_settings() {
244
+
245
+ if ( isset( $_POST['cartflows-debug-settings-nonce'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['cartflows-debug-settings-nonce'] ) ), 'cartflows-debug-settings' ) ) {
246
+
247
+ $url = isset( $_SERVER['REQUEST_URI'] ) ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '';
248
+ $new_settings = array();
249
+
250
+ if ( isset( $_POST['_cartflows_debug_data'] ) ) {
251
+ $new_settings = self::sanitize_form_inputs( wp_unslash( $_POST['_cartflows_debug_data'] ) ); //phpcs:ignore
252
+ }
253
+
254
+ Cartflows_Helper::update_admin_settings_option( '_cartflows_debug_data', $new_settings, false );
255
+
256
+ $query = array(
257
+ 'message' => 'saved',
258
+ );
259
+
260
+ $redirect_to = add_query_arg( $query, $url );
261
+
262
+ wp_safe_redirect( $redirect_to );
263
+ exit;
264
+
265
+ }
266
+ }
267
+
268
+
269
+ /**
270
+ * Save permalink Setting options.
271
+ *
272
+ * @since 1.1.14
273
+ */
274
+ public static function save_permalink_settings() {
275
+
276
+ if ( isset( $_POST['cartflows-permalink-settings-nonce'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['cartflows-permalink-settings-nonce'] ) ), 'cartflows-permalink-settings' ) ) {
277
+
278
+ $url = isset( $_SERVER['REQUEST_URI'] ) ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '';
279
+ $new_settings = array();
280
+
281
+ if ( isset( $_POST['reset'] ) ) {
282
+ $_POST['_cartflows_permalink'] = array(
283
+ 'permalink' => CARTFLOWS_STEP_POST_TYPE,
284
+ 'permalink_flow_base' => CARTFLOWS_FLOW_POST_TYPE,
285
+ 'permalink_structure' => '',
286
+ );
287
+
288
+ }
289
+
290
+ if ( isset( $_POST['_cartflows_permalink'] ) ) {
291
+ $cartflows_permalink_settings = self::sanitize_form_inputs( wp_unslash( $_POST['_cartflows_permalink'] ) ); //phpcs:ignore
292
+
293
+ if ( empty( $cartflows_permalink_settings['permalink'] ) ) {
294
+ $new_settings['permalink'] = CARTFLOWS_STEP_POST_TYPE;
295
+ } else {
296
+ $new_settings['permalink'] = $cartflows_permalink_settings['permalink'];
297
+ }
298
+
299
+ if ( empty( $cartflows_permalink_settings['permalink_flow_base'] ) ) {
300
+ $new_settings['permalink_flow_base'] = CARTFLOWS_FLOW_POST_TYPE;
301
+ } else {
302
+ $new_settings['permalink_flow_base'] = $cartflows_permalink_settings['permalink_flow_base'];
303
+ }
304
+
305
+ $new_settings['permalink_structure'] = $cartflows_permalink_settings['permalink_structure'];
306
+
307
+ }
308
+
309
+ Cartflows_Helper::update_admin_settings_option( '_cartflows_permalink', $new_settings, false );
310
+
311
+ $query = array(
312
+ 'message' => 'saved',
313
+ );
314
+
315
+ $redirect_to = add_query_arg( $query, $url );
316
+
317
+ update_option( 'cartflows_permalink_saved', true );
318
+
319
+ wp_safe_redirect( $redirect_to );
320
+ exit;
321
+
322
+ }
323
+ }
324
+
325
+ /**
326
+ * Save google analytics Setting options.
327
+ *
328
+ * @since 1.1.14
329
+ */
330
+ public static function save_google_analytics_settings() {
331
+
332
+ if ( isset( $_POST['cartflows-google-analytics-settings-nonce'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['cartflows-google-analytics-settings-nonce'] ) ), 'cartflows-google-analytics-settings' ) ) {
333
+
334
+ $url = isset( $_SERVER['REQUEST_URI'] ) ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '';
335
+ $new_settings = array();
336
+
337
+ if ( isset( $_POST['_cartflows_google_analytics'] ) ) {
338
+ $new_settings = self::sanitize_form_inputs( $_POST['_cartflows_google_analytics'] ); //phpcs:ignore
339
+
340
+ }
341
+
342
+ Cartflows_Helper::update_admin_settings_option( '_cartflows_google_analytics', $new_settings, true );
343
+
344
+ $query = array(
345
+ 'message' => 'saved',
346
+ );
347
+
348
+ $redirect_to = add_query_arg( $query, $url );
349
+
350
+ wp_safe_redirect( $redirect_to );
351
+ exit;
352
+
353
+ }
354
+ }
355
+
356
+ /**
357
+ * Loop through the input and sanitize each of the values.
358
+ *
359
+ * @param array $input_settings input settings.
360
+ * @return array
361
+ */
362
+ public static function sanitize_form_inputs( $input_settings = array() ) {
363
+ $new_settings = array();
364
+ foreach ( $input_settings as $key => $val ) {
365
+
366
+ if ( is_array( $val ) ) {
367
+ foreach ( $val as $k => $v ) {
368
+ $new_settings[ $key ][ $k ] = ( isset( $val[ $k ] ) ) ? sanitize_text_field( $v ) : '';
369
+ }
370
+ } else {
371
+ $new_settings[ $key ] = ( isset( $input_settings[ $key ] ) ) ? sanitize_text_field( $val ) : '';
372
+ }
373
+ }
374
+ return $new_settings;
375
+ }
376
+
377
+ /**
378
+ * Check is cartflows admin.
379
+ *
380
+ * @since 1.0.0
381
+ * @return boolean
382
+ */
383
+ public static function is_global_admin() {
384
+
385
+ $current_screen = get_current_screen();
386
+
387
+ if (
388
+ is_object( $current_screen ) &&
389
+ isset( $current_screen->post_type ) &&
390
+ ( CARTFLOWS_FLOW_POST_TYPE === $current_screen->post_type ||
391
+ CARTFLOWS_STEP_POST_TYPE === $current_screen->post_type
392
+ )
393
+ ) {
394
+ return true;
395
+ }
396
+ return false;
397
+ }
398
+
399
+ /**
400
+ * Check is flow admin.
401
+ *
402
+ * @since 1.0.0
403
+ * @return boolean
404
+ */
405
+ public static function is_flow_edit_admin() {
406
+
407
+ $current_screen = get_current_screen();
408
+
409
+ if (
410
+ is_object( $current_screen ) &&
411
+ isset( $current_screen->post_type ) &&
412
+ ( CARTFLOWS_FLOW_POST_TYPE === $current_screen->post_type ) &&
413
+ isset( $current_screen->base ) &&
414
+ ( 'post' === $current_screen->base )
415
+ ) {
416
+ return true;
417
+ }
418
+ return false;
419
+ }
420
+
421
+ /**
422
+ * Global Admin Scripts.
423
+ *
424
+ * @since 1.0.0
425
+ */
426
+ public static function global_admin_scripts() {
427
+
428
+ $installed_plugins = get_plugins();
429
+ $is_wc_installed = isset( $installed_plugins['woocommerce/woocommerce.php'] ) ? true : false;
430
+ $edit_test_mode = filter_input( INPUT_GET, 'edit_test_mode', FILTER_SANITIZE_STRING );
431
+ $edit_test_mode = 'yes' === $edit_test_mode ? true : false;
432
+
433
+ $localize = array(
434
+ 'ajaxurl' => admin_url( 'admin-ajax.php' ),
435
+ 'ajax_nonce' => wp_create_nonce( 'cartflows-nonce' ),
436
+ 'wc_status' => array(
437
+ 'installed' => $is_wc_installed,
438
+ 'active' => wcf()->is_woo_active,
439
+ ),
440
+ 'wc_activating_message' => __( 'Installing and activating..', 'cartflows' ),
441
+ 'wc_install_error' => __( 'There was an error with the installation of plugin.', 'cartflows' ),
442
+ 'wcf_edit_test_mode' => $edit_test_mode,
443
+ );
444
+
445
+ wp_localize_script( 'jquery', 'cartflows_admin', apply_filters( 'cartflows_admin_js_localize', $localize ) );
446
+
447
+ if ( self::is_global_admin() ) {
448
+
449
+ // Styles.
450
+ wp_enqueue_style( 'cartflows-global-admin', CARTFLOWS_URL . 'admin/assets/css/global-admin.css', array(), CARTFLOWS_VER );
451
+ wp_style_add_data( 'cartflows-global-admin', 'rtl', 'replace' );
452
+
453
+ wp_enqueue_script(
454
+ 'wcf-global-admin',
455
+ CARTFLOWS_URL . 'admin/assets/js/global-admin.js',
456
+ array( 'jquery' ),
457
+ CARTFLOWS_VER,
458
+ true
459
+ );
460
+
461
+ do_action( 'cartflows_global_admin_scripts' );
462
+ }
463
+ }
464
+
465
+ /**
466
+ * Global Admin Data.
467
+ *
468
+ * @since 1.0.0
469
+ */
470
+ public static function global_admin_data() {
471
+
472
+ $current_screen = get_current_screen();
473
+
474
+ if ( ! $current_screen ) {
475
+ return;
476
+ }
477
+
478
+ if ( 'edit-' . CARTFLOWS_FLOW_POST_TYPE != $current_screen->id ) {
479
+ return;
480
+ }
481
+
482
+ $default_page_builder = Cartflows_Helper::get_common_setting( 'default_page_builder' );
483
+ ?>
484
+
485
+ <div id="wcf-remote-flow-importer" class="wcf-templates-popup-overlay">
486
+ <div class="wcf-templates-popup-content">
487
+ <div class="spinner"></div>
488
+ <div class="wcf-templates-wrap wcf-templates-wrap-flows">
489
+
490
+ <div id="wcf-remote-flow-actions" class="wcf-template-header">
491
+ <div class="wcf-template-logo-wrap">
492
+ <span class="wcf-cartflows-logo-img">
493
+ <span class="cartflows-logo-icon"></span>
494
+ </span>
495
+ <span class="wcf-cartflows-title"><?php esc_html_e( 'Flows Library', 'cartflows' ); ?></span>
496
+ </div>
497
+ <div class="wcf-tab-wrapper">
498
+ <?php if ( 'other' !== $default_page_builder ) { ?>
499
+ <div id="wcf-get-started-steps">
500
+ <ul class="filter-links ">
501
+ <li>
502
+ <a href="#" class="current" data-slug="ready-templates" data-title="<?php esc_html_e( 'Ready Templates', 'cartflows' ); ?>"><?php esc_html_e( 'Ready Templates', 'cartflows' ); ?></a>
503
+ </li>
504
+ <li>
505
+ <a href="#" data-slug="canvas" data-title="<?php esc_html_e( 'Create Your Own', 'cartflows' ); ?>"><?php esc_html_e( 'Create Your Own', 'cartflows' ); ?></a>
506
+ </li>
507
+ </ul>
508
+ </div>
509
+ <?php } ?>
510
+ </div>
511
+ <div class="wcf-popup-close-wrap">
512
+ <span class="close-icon"><span class="wcf-cartflow-icons dashicons dashicons-no"></span></span>
513
+ </div>
514
+ </div>
515
+ <!-- <div class="wcf-search-form">
516
+ <label class="screen-reader-text" for="wp-filter-search-input"><?php esc_html_e( 'Search Sites', 'cartflows' ); ?> </label>
517
+ <input placeholder="<?php esc_html_e( 'Search Flow...', 'cartflows' ); ?>" type="text" aria-describedby="live-search-desc" class="wcf-flow-search-input">
518
+ </div> -->
519
+
520
+ <div id="wcf-remote-content">
521
+ <?php if ( 'other' !== $default_page_builder ) { ?>
522
+ <div id="wcf-ready-templates">
523
+ <div id="wcf-remote-filters">
524
+ <div id="wcf-page-builders"></div>
525
+ <div id="wcf-categories"></div>
526
+ </div>
527
+ <div class="wcf-page-builder-notice"></div>
528
+ <div id="wcf-remote-flow-list" class="wcf-remote-list wcf-template-list-wrap"><span class="spinner is-active"></span></div>
529
+ <div id="wcf-upcoming-page-builders" style="display: none;" class="wcf-remote-list wcf-template-list-wrap"></div>
530
+ </div>
531
+ <?php } ?>
532
+ <div id="wcf-start-from-scratch" style="<?php echo ( 'other' !== $default_page_builder ) ? 'display: none;' : ''; ?>">
533
+ <div class="inner">
534
+ <a href="#" class="button button-hero button-primary cartflows-flow-import-blank"><?php esc_html_e( 'Design Your Flow', 'cartflows' ); ?></a>
535
+ <p class="wcf-learn-how"><a href="https://cartflows.com/docs/cartflows-step-types/" target="_blank"><?php esc_html_e( 'Learn How', 'cartflows' ); ?> <i class="dashicons dashicons-external"></i></a></p>
536
+ </div>
537
+ </div>
538
+ </div>
539
+ </div>
540
+ </div>
541
+ </div>
542
+
543
+ <?php
544
+ }
545
+
546
+ /**
547
+ * Enqueues the needed CSS/JS for the builder's admin settings page.
548
+ *
549
+ * @since 1.0.0
550
+ */
551
+ public static function styles_scripts() {
552
+
553
+ // Styles.
554
+ wp_enqueue_style( 'cartflows-admin-settings', CARTFLOWS_URL . 'admin/assets/css/admin-menu-settings.css', array(), CARTFLOWS_VER );
555
+ wp_style_add_data( 'cartflows-admin-settings', 'rtl', 'replace' );
556
+
557
+ // Script.
558
+ wp_enqueue_script( 'cartflows-admin-settings', CARTFLOWS_URL . 'admin/assets/js/admin-menu-settings.js', array( 'jquery', 'wp-util', 'updates' ), CARTFLOWS_VER, false );
559
+
560
+ $localize = array(
561
+ 'ajax_nonce' => wp_create_nonce( 'cartflows-widget-nonce' ),
562
+ );
563
+
564
+ wp_localize_script( 'cartflows-admin-settings', 'cartflows', apply_filters( 'cartflows_js_localize', $localize ) );
565
+
566
+ do_action( 'cartflows_admin_settings_after_enqueue_scripts' );
567
+ }
568
+
569
+ /**
570
+ * Save All admin settings here
571
+ */
572
+ public static function save_settings() {
573
+
574
+ // Only admins can save settings.
575
+ if ( ! current_user_can( 'manage_options' ) ) {
576
+ return;
577
+ }
578
+
579
+ self::save_common_settings();
580
+ self::save_debug_settings();
581
+ self::save_permalink_settings();
582
+
583
+ self::save_google_analytics_settings();
584
+ self::save_facebook_settings();
585
+
586
+ // Let extensions hook into saving.
587
+ do_action( 'cartflows_admin_settings_save' );
588
+ }
589
+
590
+ /**
591
+ * Get and return page URL
592
+ *
593
+ * @param string $menu_slug Menu name.
594
+ * @since 1.0.0
595
+ * @return string page url
596
+ */
597
+ public static function get_page_url( $menu_slug ) {
598
+
599
+ $parent_page = self::$default_menu_position;
600
+
601
+ if ( strpos( $parent_page, '?' ) !== false ) {
602
+ $query_var = '&page=' . self::$plugin_slug;
603
+ } else {
604
+ $query_var = '?page=' . self::$plugin_slug;
605
+ }
606
+
607
+ $parent_page_url = admin_url( $parent_page . $query_var );
608
+
609
+ $url = $parent_page_url . '&action=' . $menu_slug;
610
+
611
+ return esc_url( $url );
612
+ }
613
+
614
+ /**
615
+ * Admin body classes.
616
+ *
617
+ * Body classes to be added to <body> tag in admin page
618
+ *
619
+ * @param String $classes body classes returned from the filter.
620
+ * @return String body classes to be added to <body> tag in admin page
621
+ */
622
+ public static function add_admin_body_class( $classes ) {
623
+
624
+ $classes .= ' cartflows-' . CARTFLOWS_VER;
625
+
626
+ return $classes;
627
+ }
628
+
629
+ /**
630
+ * Save Global Setting options.
631
+ *
632
+ * @since 1.0.0
633
+ */
634
+ public static function save_facebook_settings() {
635
+
636
+ if ( isset( $_POST['cartflows-facebook-settings-nonce'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['cartflows-facebook-settings-nonce'] ) ), 'cartflows-facebook-settings' ) ) {
637
+
638
+ $url = isset( $_SERVER['REQUEST_URI'] ) ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '';
639
+ $new_settings = array();
640
+
641
+ if ( isset( $_POST['_cartflows_facebook'] ) ) {
642
+ $new_settings = self::sanitize_form_inputs( wp_unslash( $_POST['_cartflows_facebook'] ) ); //phpcs:ignore
643
+ }
644
+
645
+ Cartflows_Helper::update_admin_settings_option( '_cartflows_facebook', $new_settings, false );
646
+ $query = array(
647
+ 'message' => 'saved',
648
+ );
649
+ $redirect_to = add_query_arg( $query, $url );
650
+ wp_safe_redirect( $redirect_to );
651
+ exit;
652
+ }
653
+ }
654
+
655
+ }
656
+
657
+ Cartflows_Admin::init();
classes/class-cartflows-api.php CHANGED
@@ -1,381 +1,382 @@
1
- <?php
2
- /**
3
- * CartFlows API
4
- *
5
- * @package CartFlows
6
- * @since 1.0.0
7
- */
8
-
9
- if ( ! class_exists( 'CartFlows_API' ) ) :
10
-
11
- /**
12
- * CartFlows API
13
- *
14
- * @since 1.0.0
15
- */
16
- class CartFlows_API {
17
-
18
- /**
19
- * Instance
20
- *
21
- * @access private
22
- * @var object Class object.
23
- * @since 1.0.0
24
- */
25
- private static $instance;
26
-
27
- /**
28
- * Initiator
29
- *
30
- * @since 1.0.0
31
- * @return object initialized object of class.
32
- */
33
- public static function get_instance() {
34
- if ( ! isset( self::$instance ) ) {
35
- self::$instance = new self();
36
- }
37
- return self::$instance;
38
- }
39
-
40
- /**
41
- * Constructor
42
- *
43
- * @since 1.0.0
44
- */
45
- public function __construct() {
46
- }
47
-
48
- /**
49
- * Get site URL.
50
- *
51
- * @since 1.0.0
52
- *
53
- * @return string Site URL.
54
- */
55
- public static function get_site_url() {
56
- return apply_filters( 'cartflows_templates_url', CARTFLOWS_TEMPLATES_URL );
57
- }
58
-
59
- /**
60
- * Get Client Site Templates Rest API URL.
61
- *
62
- * @since 1.0.0
63
- *
64
- * @return string API site URL.
65
- */
66
- public static function get_step_endpoint_url() {
67
- return self::get_site_url() . 'wp-json/wp/v2/' . CARTFLOWS_STEP_POST_TYPE . '/';
68
- }
69
-
70
- /**
71
- * Get Client Site Category Rest API URL.
72
- *
73
- * @since 1.0.0
74
- *
75
- * @return string API site URL.
76
- */
77
- public static function get_category_endpoint_url() {
78
- return self::get_site_url() . 'wp-json/wp/v2/' . CARTFLOWS_TAXONOMY_STEP_PAGE_BUILDER . '/';
79
- }
80
-
81
- /**
82
- * Get API request URL.
83
- *
84
- * @since 1.0.0
85
- *
86
- * @param string $api_base base of api request.
87
- * @return string API site URL.
88
- */
89
- public static function get_request_api_url( $api_base = '' ) {
90
- return self::get_site_url() . 'wp-json/' . CARTFLOWS_STEP_POST_TYPE . '/v1/' . $api_base;
91
- }
92
-
93
- /**
94
- * License Args.
95
- *
96
- * @return array License arguments.
97
- */
98
- public static function get_licence_args() {
99
- return apply_filters( 'cartflows_licence_args', array() );
100
- }
101
-
102
- /**
103
- * Get single demo.
104
- *
105
- * @since 1.0.0
106
- *
107
- * @param string $site_id Template ID of the site.
108
- * @return array Template data.
109
- */
110
- public static function get_template( $site_id ) {
111
- // @codingStandardsIgnoreStart
112
- $request_params = array(
113
- 'licence_args' => self::get_licence_args(),
114
- '_fields' => 'id,slug,status,type,link,title,featured_media,template,cartflows_step_page_builder,cartflows_step_type,cartflows_step_flow,featured_image_url,licence_status,flow_type,step_type,page_builder,divi_content,post_meta',
115
- );
116
- // @codingStandardsIgnoreEnd
117
-
118
- $url = add_query_arg( $request_params, self::get_step_endpoint_url() . $site_id );
119
-
120
- $api_args = array(
121
- 'timeout' => 15,
122
- );
123
-
124
- $response = self::remote_get( $url, $api_args );
125
-
126
- if ( $response['success'] ) {
127
- $template = $response['data'];
128
- return array(
129
- 'title' => ( isset( $template['title']->rendered ) ) ? $template['title']->rendered : '',
130
- 'post_meta' => ( isset( $template['post_meta'] ) ) ? $template['post_meta'] : '',
131
- 'data' => $template,
132
- 'divi_content' => isset( $response['data']['divi_content'] ) ? $response['data']['divi_content'] : '',
133
- 'message' => $response['message'], // Your API Key is not valid. Please add valid API Key.
134
- 'success' => $response['success'],
135
- );
136
- }
137
-
138
- return array(
139
- 'title' => '',
140
- 'post_meta' => array(),
141
- 'message' => $response['message'],
142
- 'data' => $response['data'],
143
- 'divi_content' => '',
144
- 'success' => $response['success'],
145
- );
146
- }
147
-
148
- /**
149
- * Get Cloud Templates
150
- *
151
- * @since 1.0.0
152
- *
153
- * @param array $args For selecting the demos (Search terms, pagination etc).
154
- * @return array CartFlows list.
155
- */
156
- public static function get_templates( $args = array() ) {
157
-
158
- $request_params = wp_parse_args(
159
- $args,
160
- array(
161
- 'page' => '1',
162
- 'per_page' => '100',
163
- )
164
- );
165
-
166
- $url = add_query_arg( $request_params, self::get_step_endpoint_url() );
167
-
168
- $api_args = array(
169
- 'timeout' => 15,
170
- );
171
-
172
- $response = self::remote_get( $url, $api_args );
173
-
174
- if ( $response['success'] ) {
175
- $templates_data = $response['data'];
176
- $templates = array();
177
- foreach ( $templates_data as $key => $template ) {
178
-
179
- if ( ! isset( $template->id ) ) {
180
- continue;
181
- }
182
-
183
- $templates[ $key ]['id'] = isset( $template->id ) ? esc_attr( $template->id ) : '';
184
- $templates[ $key ]['slug'] = isset( $template->slug ) ? esc_attr( $template->slug ) : '';
185
- $templates[ $key ]['link'] = isset( $template->link ) ? esc_url( $template->link ) : '';
186
- $templates[ $key ]['date'] = isset( $template->date ) ? esc_attr( $template->date ) : '';
187
- $templates[ $key ]['title'] = isset( $template->title->rendered ) ? esc_attr( $template->title->rendered ) : '';
188
- $templates[ $key ]['featured_image_url'] = isset( $template->featured_image_url ) ? esc_url( $template->featured_image_url ) : '';
189
- $templates[ $key ]['content'] = isset( $template->content->rendered ) ? $template->content->rendered : '';
190
- $templates[ $key ]['divi_content'] = isset( $template->divi_content ) ? $template->divi_content : '';
191
- $templates[ $key ]['post_meta'] = isset( $template->post_meta ) ? $template->post_meta : '';
192
- }
193
-
194
- return array(
195
- 'templates' => $templates,
196
- 'templates_count' => $response['count'],
197
- 'data' => $response,
198
- );
199
- }
200
-
201
- return array(
202
- 'templates' => array(),
203
- 'templates_count' => 0,
204
- 'data' => $response,
205
- );
206
-
207
- }
208
-
209
- /**
210
- * Get categories.
211
- *
212
- * @since 1.0.0
213
- * @param array $args Arguments.
214
- * @return array Category data.
215
- */
216
- public static function get_categories( $args = array() ) {
217
-
218
- $request_params = apply_filters(
219
- 'cartflows_categories_api_params',
220
- wp_parse_args(
221
- $args,
222
- array(
223
- 'page' => '1',
224
- 'per_page' => '100',
225
- )
226
- )
227
- );
228
-
229
- $url = add_query_arg( $request_params, self::get_category_endpoint_url() );
230
-
231
- $api_args = apply_filters(
232
- 'cartflows_api_args',
233
- array(
234
- 'timeout' => 15,
235
- )
236
- );
237
-
238
- $response = self::remote_get( $url, $api_args );
239
-
240
- if ( $response['success'] ) {
241
- $categories_data = $response['data'];
242
- $categories = array();
243
-
244
- foreach ( $categories_data as $key => $category ) {
245
- if ( isset( $category->count ) && ! empty( $category->count ) ) {
246
- $categories[] = array(
247
- 'id' => isset( $category->id ) ? absint( $category->id ) : 0,
248
- 'count' => isset( $category->count ) ? absint( $category->count ) : 0,
249
- 'description' => isset( $category->description ) ? $category->description : '',
250
- 'link' => isset( $category->link ) ? esc_url( $category->link ) : '',
251
- 'name' => isset( $category->name ) ? $category->name : '',
252
- 'slug' => isset( $category->slug ) ? sanitize_text_field( $category->slug ) : '',
253
- 'taxonomy' => isset( $category->taxonomy ) ? $category->taxonomy : '',
254
- 'parent' => isset( $category->parent ) ? $category->parent : '',
255
- );
256
- }
257
- }
258
-
259
- return array(
260
- 'categories' => $categories,
261
- 'categories_count' => $response['count'],
262
- 'data' => $response,
263
- );
264
- }
265
-
266
- return array(
267
- 'categories' => array(),
268
- 'categories_count' => 0,
269
- 'data' => $response,
270
- );
271
- }
272
-
273
- /**
274
- * Remote GET API Request
275
- *
276
- * @since 1.0.0
277
- *
278
- * @param string $url Target server API URL.
279
- * @param array $args Array of arguments for the API request.
280
- * @return mixed Return the API request result.
281
- */
282
- public static function remote_get( $url = '', $args = array() ) {
283
- $request = wp_remote_get( $url, $args );
284
- return self::request( $request );
285
- }
286
-
287
- /**
288
- * Remote POST API Request
289
- *
290
- * @since 1.0.0
291
- *
292
- * @param string $url Target server API URL.
293
- * @param array $args Array of arguments for the API request.
294
- * @return mixed Return the API request result.
295
- */
296
- public static function remote_post( $url = '', $args = array() ) {
297
- $request = wp_remote_post( $url, $args );
298
-
299
- return self::request( $request );
300
- }
301
-
302
- /**
303
- * Site API Request
304
- *
305
- * @since 1.0.0
306
- *
307
- * @param boolean $api_base Target server API URL.
308
- * @param array $args Array of arguments for the API request.
309
- * @return mixed Return the API request result.
310
- */
311
- public static function site_request( $api_base = '', $args = array() ) {
312
-
313
- $api_url = self::get_request_api_url( $api_base );
314
-
315
- return self::remote_post( $api_url, $args );
316
- }
317
-
318
- /**
319
- * API Request
320
- *
321
- * Handle the API request and return the result.
322
- *
323
- * @since 1.0.0
324
- *
325
- * @param array $request Array of arguments for the API request.
326
- * @return mixed Return the API request result.
327
- */
328
- public static function request( $request ) {
329
-
330
- // Is WP Error?
331
- if ( is_wp_error( $request ) ) {
332
- return array(
333
- 'success' => false,
334
- 'message' => $request->get_error_message(),
335
- 'data' => $request,
336
- 'count' => 0,
337
- );
338
- }
339
-
340
- // Invalid response code.
341
- if ( wp_remote_retrieve_response_code( $request ) != 200 ) {
342
- return array(
343
- 'success' => false,
344
- 'message' => $request['response'],
345
- 'data' => $request,
346
- 'count' => 0,
347
- );
348
- }
349
-
350
- // Get body data.
351
- $body = wp_remote_retrieve_body( $request );
352
-
353
- // Is WP Error?
354
- if ( is_wp_error( $body ) ) {
355
- return array(
356
- 'success' => false,
357
- 'message' => $body->get_error_message(),
358
- 'data' => $request,
359
- 'count' => 0,
360
- );
361
- }
362
-
363
- // Decode body content.
364
- $body_decoded = json_decode( $body );
365
-
366
- return array(
367
- 'success' => true,
368
- 'message' => __( 'Request successfully processed!', 'cartflows' ),
369
- 'data' => (array) $body_decoded,
370
- 'count' => wp_remote_retrieve_header( $request, 'x-wp-total' ),
371
- );
372
- }
373
-
374
- }
375
-
376
- /**
377
- * Initialize class object with 'get_instance()' method
378
- */
379
- CartFlows_API::get_instance();
380
-
381
- endif;
 
1
+ <?php
2
+ /**
3
+ * CartFlows API
4
+ *
5
+ * @package CartFlows
6
+ * @since 1.0.0
7
+ */
8
+
9
+ if ( ! class_exists( 'CartFlows_API' ) ) :
10
+
11
+ /**
12
+ * CartFlows API
13
+ *
14
+ * @since 1.0.0
15
+ */
16
+ class CartFlows_API {
17
+
18
+ /**
19
+ * Instance
20
+ *
21
+ * @access private
22
+ * @var object Class object.
23
+ * @since 1.0.0
24
+ */
25
+ private static $instance;
26
+
27
+ /**
28
+ * Initiator
29
+ *
30
+ * @since 1.0.0
31
+ * @return object initialized object of class.
32
+ */
33
+ public static function get_instance() {
34
+ if ( ! isset( self::$instance ) ) {
35
+ self::$instance = new self();
36
+ }
37
+ return self::$instance;
38
+ }
39
+
40
+ /**
41
+ * Constructor
42
+ *
43
+ * @since 1.0.0
44
+ */
45
+ public function __construct() {
46
+ }
47
+
48
+ /**
49
+ * Get site URL.
50
+ *
51
+ * @since 1.0.0
52
+ *
53
+ * @return string Site URL.
54
+ */
55
+ public static function get_site_url() {
56
+ return apply_filters( 'cartflows_templates_url', CARTFLOWS_TEMPLATES_URL );
57
+ }
58
+
59
+ /**
60
+ * Get Client Site Templates Rest API URL.
61
+ *
62
+ * @since 1.0.0
63
+ *
64
+ * @return string API site URL.
65
+ */
66
+ public static function get_step_endpoint_url() {
67
+ return self::get_site_url() . 'wp-json/wp/v2/' . CARTFLOWS_STEP_POST_TYPE . '/';
68
+ }
69
+
70
+ /**
71
+ * Get Client Site Category Rest API URL.
72
+ *
73
+ * @since 1.0.0
74
+ *
75
+ * @return string API site URL.
76
+ */
77
+ public static function get_category_endpoint_url() {
78
+ return self::get_site_url() . 'wp-json/wp/v2/' . CARTFLOWS_TAXONOMY_STEP_PAGE_BUILDER . '/';
79
+ }
80
+
81
+ /**
82
+ * Get API request URL.
83
+ *
84
+ * @since 1.0.0
85
+ *
86
+ * @param string $api_base base of api request.
87
+ * @return string API site URL.
88
+ */
89
+ public static function get_request_api_url( $api_base = '' ) {
90
+ return self::get_site_url() . 'wp-json/' . CARTFLOWS_STEP_POST_TYPE . '/v1/' . $api_base;
91
+ }
92
+
93
+ /**
94
+ * License Args.
95
+ *
96
+ * @return array License arguments.
97
+ */
98
+ public static function get_licence_args() {
99
+ return apply_filters( 'cartflows_licence_args', array() );
100
+ }
101
+
102
+ /**
103
+ * Get single demo.
104
+ *
105
+ * @since 1.0.0
106
+ *
107
+ * @param string $site_id Template ID of the site.
108
+ * @return array Template data.
109
+ */
110
+ public static function get_template( $site_id ) {
111
+ // @codingStandardsIgnoreStart
112
+ $request_params = array(
113
+ 'licence_args' => self::get_licence_args(),
114
+ '_fields' => 'id,slug,status,type,link,title,featured_media,template,cartflows_step_page_builder,cartflows_step_type,cartflows_step_flow,featured_image_url,licence_status,flow_type,step_type,page_builder,divi_content,post_meta,content',
115
+ );
116
+ // @codingStandardsIgnoreEnd
117
+
118
+ $url = add_query_arg( $request_params, self::get_step_endpoint_url() . $site_id );
119
+
120
+ $api_args = array(
121
+ 'timeout' => 15,
122
+ );
123
+
124
+ $response = self::remote_get( $url, $api_args );
125
+
126
+ if ( $response['success'] ) {
127
+ $template = $response['data'];
128
+ return array(
129
+ 'title' => ( isset( $template['title']->rendered ) ) ? $template['title']->rendered : '',
130
+ 'post_meta' => ( isset( $template['post_meta'] ) ) ? $template['post_meta'] : '',
131
+ 'data' => $template,
132
+ 'original_content' => isset( $response['data']['divi_content'] ) ? $response['data']['divi_content'] : '',
133
+ 'divi_content' => isset( $response['data']['divi_content'] ) ? $response['data']['divi_content'] : '',
134
+ 'message' => $response['message'], // Your API Key is not valid. Please add valid API Key.
135
+ 'success' => $response['success'],
136
+ );
137
+ }
138
+
139
+ return array(
140
+ 'title' => '',
141
+ 'post_meta' => array(),
142
+ 'message' => $response['message'],
143
+ 'data' => $response['data'],
144
+ 'divi_content' => '',
145
+ 'success' => $response['success'],
146
+ );
147
+ }
148
+
149
+ /**
150
+ * Get Cloud Templates
151
+ *
152
+ * @since 1.0.0
153
+ *
154
+ * @param array $args For selecting the demos (Search terms, pagination etc).
155
+ * @return array CartFlows list.
156
+ */
157
+ public static function get_templates( $args = array() ) {
158
+
159
+ $request_params = wp_parse_args(
160
+ $args,
161
+ array(
162
+ 'page' => '1',
163
+ 'per_page' => '100',
164
+ )
165
+ );
166
+
167
+ $url = add_query_arg( $request_params, self::get_step_endpoint_url() );
168
+
169
+ $api_args = array(
170
+ 'timeout' => 15,
171
+ );
172
+
173
+ $response = self::remote_get( $url, $api_args );
174
+
175
+ if ( $response['success'] ) {
176
+ $templates_data = $response['data'];
177
+ $templates = array();
178
+ foreach ( $templates_data as $key => $template ) {
179
+
180
+ if ( ! isset( $template->id ) ) {
181
+ continue;
182
+ }
183
+
184
+ $templates[ $key ]['id'] = isset( $template->id ) ? esc_attr( $template->id ) : '';
185
+ $templates[ $key ]['slug'] = isset( $template->slug ) ? esc_attr( $template->slug ) : '';
186
+ $templates[ $key ]['link'] = isset( $template->link ) ? esc_url( $template->link ) : '';
187
+ $templates[ $key ]['date'] = isset( $template->date ) ? esc_attr( $template->date ) : '';
188
+ $templates[ $key ]['title'] = isset( $template->title->rendered ) ? esc_attr( $template->title->rendered ) : '';
189
+ $templates[ $key ]['featured_image_url'] = isset( $template->featured_image_url ) ? esc_url( $template->featured_image_url ) : '';
190
+ $templates[ $key ]['content'] = isset( $template->content->rendered ) ? $template->content->rendered : '';
191
+ $templates[ $key ]['divi_content'] = isset( $template->divi_content ) ? $template->divi_content : '';
192
+ $templates[ $key ]['post_meta'] = isset( $template->post_meta ) ? $template->post_meta : '';
193
+ }
194
+
195
+ return array(
196
+ 'templates' => $templates,
197
+ 'templates_count' => $response['count'],
198
+ 'data' => $response,
199
+ );
200
+ }
201
+
202
+ return array(
203
+ 'templates' => array(),
204
+ 'templates_count' => 0,
205
+ 'data' => $response,
206
+ );
207
+
208
+ }
209
+
210
+ /**
211
+ * Get categories.
212
+ *
213
+ * @since 1.0.0
214
+ * @param array $args Arguments.
215
+ * @return array Category data.
216
+ */
217
+ public static function get_categories( $args = array() ) {
218
+
219
+ $request_params = apply_filters(
220
+ 'cartflows_categories_api_params',
221
+ wp_parse_args(
222
+ $args,
223
+ array(
224
+ 'page' => '1',
225
+ 'per_page' => '100',
226
+ )
227
+ )
228
+ );
229
+
230
+ $url = add_query_arg( $request_params, self::get_category_endpoint_url() );
231
+
232
+ $api_args = apply_filters(
233
+ 'cartflows_api_args',
234
+ array(
235
+ 'timeout' => 15,
236
+ )
237
+ );
238
+
239
+ $response = self::remote_get( $url, $api_args );
240
+
241
+ if ( $response['success'] ) {
242
+ $categories_data = $response['data'];
243
+ $categories = array();
244
+
245
+ foreach ( $categories_data as $key => $category ) {
246
+ if ( isset( $category->count ) && ! empty( $category->count ) ) {
247
+ $categories[] = array(
248
+ 'id' => isset( $category->id ) ? absint( $category->id ) : 0,
249
+ 'count' => isset( $category->count ) ? absint( $category->count ) : 0,
250
+ 'description' => isset( $category->description ) ? $category->description : '',
251
+ 'link' => isset( $category->link ) ? esc_url( $category->link ) : '',
252
+ 'name' => isset( $category->name ) ? $category->name : '',
253
+ 'slug' => isset( $category->slug ) ? sanitize_text_field( $category->slug ) : '',
254
+ 'taxonomy' => isset( $category->taxonomy ) ? $category->taxonomy : '',
255
+ 'parent' => isset( $category->parent ) ? $category->parent : '',
256
+ );
257
+ }
258
+ }
259
+
260
+ return array(
261
+ 'categories' => $categories,
262
+ 'categories_count' => $response['count'],
263
+ 'data' => $response,
264
+ );
265
+ }
266
+
267
+ return array(
268
+ 'categories' => array(),
269
+ 'categories_count' => 0,
270
+ 'data' => $response,
271
+ );
272
+ }
273
+
274
+ /**
275
+ * Remote GET API Request
276
+ *
277
+ * @since 1.0.0
278
+ *
279
+ * @param string $url Target server API URL.
280
+ * @param array $args Array of arguments for the API request.
281
+ * @return mixed Return the API request result.
282
+ */
283
+ public static function remote_get( $url = '', $args = array() ) {
284
+ $request = wp_remote_get( $url, $args );
285
+ return self::request( $request );
286
+ }
287
+
288
+ /**
289
+ * Remote POST API Request
290
+ *
291
+ * @since 1.0.0
292
+ *
293
+ * @param string $url Target server API URL.
294
+ * @param array $args Array of arguments for the API request.
295
+ * @return mixed Return the API request result.
296
+ */
297
+ public static function remote_post( $url = '', $args = array() ) {
298
+ $request = wp_remote_post( $url, $args );
299
+
300
+ return self::request( $request );
301
+ }
302
+
303
+ /**
304
+ * Site API Request
305
+ *
306
+ * @since 1.0.0
307
+ *
308
+ * @param boolean $api_base Target server API URL.
309
+ * @param array $args Array of arguments for the API request.
310
+ * @return mixed Return the API request result.
311
+ */
312
+ public static function site_request( $api_base = '', $args = array() ) {
313
+
314
+ $api_url = self::get_request_api_url( $api_base );
315
+
316
+ return self::remote_post( $api_url, $args );
317
+ }
318
+
319
+ /**
320
+ * API Request
321
+ *
322
+ * Handle the API request and return the result.
323
+ *
324
+ * @since 1.0.0
325
+ *
326
+ * @param array $request Array of arguments for the API request.
327
+ * @return mixed Return the API request result.
328
+ */
329
+ public static function request( $request ) {
330
+
331
+ // Is WP Error?
332
+ if ( is_wp_error( $request ) ) {
333
+ return array(
334
+ 'success' => false,
335
+ 'message' => $request->get_error_message(),
336
+ 'data' => $request,
337
+ 'count' => 0,
338
+ );
339
+ }
340
+
341
+ // Invalid response code.
342
+ if ( wp_remote_retrieve_response_code( $request ) != 200 ) {
343
+ return array(
344
+ 'success' => false,
345
+ 'message' => $request['response'],
346
+ 'data' => $request,
347
+ 'count' => 0,
348
+ );
349
+ }
350
+
351
+ // Get body data.
352
+ $body = wp_remote_retrieve_body( $request );
353
+
354
+ // Is WP Error?
355
+ if ( is_wp_error( $body ) ) {
356
+ return array(
357
+ 'success' => false,
358
+ 'message' => $body->get_error_message(),
359
+ 'data' => $request,
360
+ 'count' => 0,
361
+ );
362
+ }
363
+
364
+ // Decode body content.
365
+ $body_decoded = json_decode( $body );
366
+
367
+ return array(
368
+ 'success' => true,
369
+ 'message' => __( 'Request successfully processed!', 'cartflows' ),
370
+ 'data' => (array) $body_decoded,
371
+ 'count' => wp_remote_retrieve_header( $request, 'x-wp-total' ),
372
+ );
373
+ }
374
+
375
+ }
376
+
377
+ /**
378
+ * Initialize class object with 'get_instance()' method
379
+ */
380
+ CartFlows_API::get_instance();
381
+
382
+ endif;
classes/class-cartflows-cloning.php CHANGED
@@ -1,465 +1,465 @@
1
- <?php
2
- /**
3
- * Cloning.
4
- *
5
- * @package cartflows-pro
6
- */
7
-
8
- /**
9
- * Initialization
10
- *
11
- * @since 1.0.0
12
- */
13
- class Cartflows_Cloning {
14
-
15
-
16
- /**
17
- * Member Variable
18
- *
19
- * @var instance
20
- */
21
- private static $instance;
22
-
23
- /**
24
- * Initiator
25
- */
26
- public static function get_instance() {
27
- if ( ! isset( self::$instance ) ) {
28
- self::$instance = new self();
29
- }
30
- return self::$instance;
31
- }
32
-
33
- /**
34
- * Constructor
35
- */
36
- public function __construct() {
37
-
38
- add_filter( 'post_row_actions', array( $this, 'clone_link' ), 99, 2 );
39
- add_action( 'admin_action_cartflows_clone_flow', array( $this, 'clone_flow' ) );
40
- add_action( 'admin_action_cartflows_clone_step', array( $this, 'clone_step' ) );
41
- }
42
-
43
- /**
44
- * Clone flow with steps and its meta.
45
- */
46
- public function clone_flow() {
47
-
48
- global $wpdb;
49
-
50
- if ( ! ( isset( $_GET['post'] ) || isset( $_POST['post'] ) || ( isset( $_REQUEST['action'] ) && 'cartflows_clone_flow' === $_REQUEST['action'] ) ) ) {
51
- wp_die( 'No post to duplicate has been supplied!' );
52
- }
53
-
54
- /*
55
- * Nonce verification
56
- */
57
- if ( ! isset( $_GET['flow_clone_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['flow_clone_nonce'] ) ), basename( __FILE__ ) ) ) {
58
- return;
59
- }
60
-
61
- /**
62
- * Get the original post id
63
- */
64
- $post_id = ( isset( $_GET['post'] ) ? absint( $_GET['post'] ) : absint( $_POST['post'] ) );
65
-
66
- /**
67
- * And all the original post data then
68
- */
69
- $post = get_post( $post_id );
70
-
71
- /**
72
- * Assign current user to be the new post author
73
- */
74
- $current_user = wp_get_current_user();
75
- $new_post_author = $current_user->ID;
76
-
77
- /**
78
- * If post data exists, create the post duplicate
79
- */
80
- if ( isset( $post ) && null !== $post ) {
81
-
82
- /**
83
- * New post data array
84
- */
85
-
86
- $args = array(
87
- 'comment_status' => $post->comment_status,
88
- 'ping_status' => $post->ping_status,
89
- 'post_author' => $new_post_author,
90
- 'post_content' => $post->post_content,
91
- 'post_excerpt' => $post->post_excerpt,
92
- 'post_name' => $post->post_name,
93
- 'post_parent' => $post->post_parent,
94
- 'post_password' => $post->post_password,
95
- 'post_status' => $post->post_status,
96
- 'post_title' => $post->post_title . ' Clone',
97
- 'post_type' => $post->post_type,
98
- 'to_ping' => $post->to_ping,
99
- 'menu_order' => $post->menu_order,
100
- );
101
-
102
- /**
103
- * Insert the post
104
- */
105
- $new_flow_id = wp_insert_post( $args );
106
-
107
- /**
108
- * Get all current post terms ad set them to the new post
109
- */
110
- // returns array of taxonomy names for post type, ex array("category", "post_tag");.
111
- $taxonomies = get_object_taxonomies( $post->post_type );
112
-
113
- foreach ( $taxonomies as $taxonomy ) {
114
-
115
- $post_terms = wp_get_object_terms( $post_id, $taxonomy, array( 'fields' => 'slugs' ) );
116
-
117
- wp_set_object_terms( $new_flow_id, $post_terms, $taxonomy, false );
118
- }
119
-
120
- /**
121
- * Duplicate all post meta just in two SQL queries
122
- */
123
- // @codingStandardsIgnoreStart
124
- $post_meta_infos = $wpdb->get_results(
125
- "SELECT meta_key, meta_value FROM $wpdb->postmeta WHERE post_id=$post_id"
126
- );
127
- // @codingStandardsIgnoreEnd
128
-
129
- if ( ! empty( $post_meta_infos ) ) {
130
-
131
- $sql_query = "INSERT INTO $wpdb->postmeta (post_id, meta_key, meta_value) VALUES ";
132
-
133
- $sql_query_sel = array();
134
-
135
- foreach ( $post_meta_infos as $meta_info ) {
136
-
137
- $meta_key = $meta_info->meta_key;
138
-
139
- if ( '_wp_old_slug' === $meta_key ) {
140
- continue;
141
- }
142
-
143
- $meta_value = addslashes( $meta_info->meta_value );
144
-
145
- $sql_query_sel[] = "($new_flow_id, '$meta_key', '$meta_value')";
146
- }
147
-
148
- $sql_query .= implode( ',', $sql_query_sel );
149
-
150
- // @codingStandardsIgnoreStart
151
- $wpdb->query( $sql_query );
152
- // @codingStandardsIgnoreEnd
153
- }
154
-
155
- /* Steps Cloning */
156
- $flow_steps = get_post_meta( $post_id, 'wcf-steps', true );
157
- $new_flow_steps = array();
158
-
159
- /* Set Steps Empty */
160
- update_post_meta( $new_flow_id, 'wcf-steps', $new_flow_steps );
161
-
162
- if ( is_array( $flow_steps ) && ! empty( $flow_steps ) ) {
163
-
164
- foreach ( $flow_steps as $index => $step_data ) {
165
-
166
- $step_id = $step_data['id'];
167
- $step_type = get_post_meta( $step_id, 'wcf-step-type', true );
168
-
169
- $step_object = get_post( $step_id );
170
-
171
- /**
172
- * New step post data array
173
- */
174
- $step_args = array(
175
- 'comment_status' => $step_object->comment_status,
176
- 'ping_status' => $step_object->ping_status,
177
- 'post_author' => $new_post_author,
178
- 'post_content' => $step_object->post_content,
179
- 'post_excerpt' => $step_object->post_excerpt,
180
- 'post_name' => $step_object->post_name,
181
- 'post_parent' => $step_object->post_parent,
182
- 'post_password' => $step_object->post_password,
183
- 'post_status' => $step_object->post_status,
184
- 'post_title' => $step_object->post_title,
185
- 'post_type' => $step_object->post_type,
186
- 'to_ping' => $step_object->to_ping,
187
- 'menu_order' => $step_object->menu_order,
188
- );
189
-
190
- /**
191
- * Insert the post
192
- */
193
- $new_step_id = wp_insert_post( $step_args );
194
-
195
- /**
196
- * Duplicate all step meta
197
- */
198
- // @codingStandardsIgnoreStart
199
- $post_meta_infos = $wpdb->get_results(
200
- "SELECT meta_key, meta_value FROM $wpdb->postmeta WHERE post_id=$step_id"
201
- );
202
- // @codingStandardsIgnoreEnd
203
-
204
- if ( ! empty( $post_meta_infos ) ) {
205
-
206
- $sql_query = "INSERT INTO $wpdb->postmeta (post_id, meta_key, meta_value) VALUES ";
207
-
208
- $sql_query_sel = array();
209
-
210
- foreach ( $post_meta_infos as $meta_info ) {
211
-
212
- $meta_key = $meta_info->meta_key;
213
-
214
- if ( '_wp_old_slug' === $meta_key ) {
215
- continue;
216
- }
217
-
218
- $meta_value = addslashes( $meta_info->meta_value );
219
-
220
- $sql_query_sel[] = "($new_step_id, '$meta_key', '$meta_value')";
221
- }
222
-
223
- $sql_query .= implode( ',', $sql_query_sel );
224
-
225
- // @codingStandardsIgnoreStart
226
- $wpdb->query( $sql_query );
227
- // @codingStandardsIgnoreEnd
228
- }
229
-
230
- // insert post meta.
231
- update_post_meta( $new_step_id, 'wcf-flow-id', $new_flow_id );
232
- update_post_meta( $new_step_id, 'wcf-step-type', $step_type );
233
-
234
- wp_set_object_terms( $new_step_id, $step_type, CARTFLOWS_TAXONOMY_STEP_TYPE );
235
- wp_set_object_terms( $new_step_id, 'flow-' . $new_flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
236
-
237
- /* Add New Flow Steps */
238
- $new_flow_steps[] = array(
239
- 'id' => $new_step_id,
240
- 'title' => $step_object->post_title,
241
- 'type' => $step_type,
242
- );
243
- }
244
- }
245
-
246
- /* Update New Flow Step Post Meta */
247
- update_post_meta( $new_flow_id, 'wcf-steps', $new_flow_steps );
248
-
249
- /* Clear Page Builder Cache */
250
- $this->clear_cache();
251
-
252
- /**
253
- * Redirect to the new flow edit screen
254
- */
255
- wp_safe_redirect( admin_url( 'post.php?action=edit&post=' . $new_flow_id ) );
256
- exit;
257
- } else {
258
- wp_die( 'Post creation failed, could not find original post: ' . $post_id );
259
- }
260
- }
261
-
262
- /**
263
- * Clone step with its meta.
264
- */
265
- public function clone_step() {
266
-
267
- global $wpdb;
268
-
269
- if ( ! ( isset( $_GET['post'] ) || isset( $_POST['post'] ) || ( isset( $_REQUEST['action'] ) && 'cartflows_clone_step' === $_REQUEST['action'] ) ) ) {
270
- wp_die( 'No post to duplicate has been supplied!' );
271
- }
272
-
273
- /*
274
- * Nonce verification
275
- */
276
- if ( ! isset( $_GET['step_clone_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['step_clone_nonce'] ) ), 'step_clone' ) ) {
277
- return;
278
- }
279
-
280
- /**
281
- * Get the original post id
282
- */
283
- $post_id = ( isset( $_GET['post'] ) ? absint( $_GET['post'] ) : absint( $_POST['post'] ) );
284
-
285
- /**
286
- * And all the original post data then
287
- */
288
- $post = get_post( $post_id );
289
-
290
- /**
291
- * Assign current user to be the new post author
292
- */
293
- $current_user = wp_get_current_user();
294
- $new_post_author = $current_user->ID;
295
-
296
- /**
297
- * If post data exists, create the post duplicate
298
- */
299
- if ( isset( $post ) && null !== $post ) {
300
-
301
- /**
302
- * New post data array
303
- */
304
- $args = array(
305
- 'comment_status' => $post->comment_status,
306
- 'ping_status' => $post->ping_status,
307
- 'post_author' => $new_post_author,
308
- 'post_content' => $post->post_content,
309
- 'post_excerpt' => $post->post_excerpt,
310
- 'post_name' => $post->post_name,
311
- 'post_parent' => $post->post_parent,
312
- 'post_password' => $post->post_password,
313
- 'post_status' => $post->post_status,
314
- 'post_title' => $post->post_title . ' Clone',
315
- 'post_type' => $post->post_type,
316
- 'to_ping' => $post->to_ping,
317
- 'menu_order' => $post->menu_order,
318
- );
319
-
320
- /**
321
- * Insert the post
322
- */
323
- $new_step_id = wp_insert_post( $args );
324
-
325
- /**
326
- * Get all current post terms ad set them to the new post
327
- */
328
- // returns array of taxonomy names for post type, ex array("category", "post_tag");.
329
- $taxonomies = get_object_taxonomies( $post->post_type );
330
-
331
- foreach ( $taxonomies as $taxonomy ) {
332
-
333
- $post_terms = wp_get_object_terms( $post_id, $taxonomy, array( 'fields' => 'slugs' ) );
334
-
335
- wp_set_object_terms( $new_step_id, $post_terms, $taxonomy, false );
336
- }
337
-
338
- /**
339
- * Duplicate all post meta just in two SQL queries
340
- */
341
- // @codingStandardsIgnoreStart
342
- $post_meta_infos = $wpdb->get_results(
343
- "SELECT meta_key, meta_value FROM $wpdb->postmeta WHERE post_id=$post_id"
344
- );
345
- // @codingStandardsIgnoreEnd
346
-
347
- if ( ! empty( $post_meta_infos ) ) {
348
-
349
- $sql_query = "INSERT INTO $wpdb->postmeta (post_id, meta_key, meta_value) VALUES ";
350
-
351
- $sql_query_sel = array();
352
-
353
- foreach ( $post_meta_infos as $meta_info ) {
354
-
355
- $meta_key = $meta_info->meta_key;
356
-
357
- if ( '_wp_old_slug' === $meta_key ) {
358
- continue;
359
- }
360
-
361
- $meta_value = addslashes( $meta_info->meta_value );
362
-
363
- $sql_query_sel[] = "($new_step_id, '$meta_key', '$meta_value')";
364
- }
365
-
366
- $sql_query .= implode( ',', $sql_query_sel );
367
-
368
- // @codingStandardsIgnoreStart
369
- $wpdb->query( $sql_query );
370
- // @codingStandardsIgnoreEnd
371
- }
372
-
373
- $flow_id = get_post_meta( $post_id, 'wcf-flow-id', true );
374
- $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
375
- $step_type = get_post_meta( $post_id, 'wcf-step-type', true );
376
-
377
- if ( ! is_array( $flow_steps ) ) {
378
- $flow_steps = array();
379
- }
380
-
381
- $flow_steps[] = array(
382
- 'id' => $new_step_id,
383
- 'title' => $post->post_title,
384
- 'type' => $step_type,
385
- );
386
-
387
- update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
388
-
389
- /* Clear Page Builder Cache */
390
- $this->clear_cache();
391
-
392
- /**
393
- * Redirect to the new flow edit screen
394
- */
395
- $redirect_url = add_query_arg( 'highlight-step-id', $new_step_id, get_edit_post_link( $flow_id, 'default' ) );
396
-
397
- wp_safe_redirect( $redirect_url );
398
- exit;
399
- } else {
400
- wp_die( 'Post creation failed, could not find original post: ' . $post_id );
401
- }
402
- }
403
-
404
- /**
405
- * Add the clone link to action list for flows row actions
406
- *
407
- * @param array $actions Actions array.
408
- * @param object $post Post object.
409
- *
410
- * @return array
411
- */
412
- public function clone_link( $actions, $post ) {
413
-
414
- if ( current_user_can( 'edit_posts' ) && isset( $post ) && CARTFLOWS_FLOW_POST_TYPE === $post->post_type ) {
415
-
416
- if ( isset( $actions['duplicate'] ) ) { // Duplicate page plugin remove.
417
- unset( $actions['duplicate'] );
418
- }
419
- if ( isset( $actions['edit_as_new_draft'] ) ) { // Duplicate post plugin remove.
420
- unset( $actions['edit_as_new_draft'] );
421
- }
422
-
423
- $actions['clone'] = '<a href="' . wp_nonce_url( 'admin.php?action=cartflows_clone_flow&post=' . $post->ID, basename( __FILE__ ), 'flow_clone_nonce' ) . '" title="' . __( 'Clone this flow', 'cartflows' ) . '" rel="permalink">' . __( 'Clone', 'cartflows' ) . '</a>';
424
-
425
- if ( ! _is_cartflows_pro() ) {
426
-
427
- $flow_posts = get_posts(
428
- array(
429
- 'posts_per_page' => 4,
430
- 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
431
- 'post_status' => array( 'publish', 'pending', 'draft', 'future', 'private', 'inherit', 'trash' ),
432
- )
433
- );
434
-
435
- if ( is_array( $flow_posts ) ) {
436
-
437
- $flow_count = count( $flow_posts );
438
-
439
- if ( $flow_count > 3 || 3 === $flow_count ) {
440
- unset( $actions['clone'] );
441
- }
442
- }
443
- }
444
- }
445
-
446
- return $actions;
447
- }
448
-
449
- /**
450
- * Clear Page Builder Cache
451
- */
452
- public function clear_cache() {
453
-
454
- // Clear 'Elementor' file cache.
455
- if ( class_exists( '\Elementor\Plugin' ) ) {
456
- Elementor\Plugin::$instance->files_manager->clear_cache();
457
- }
458
- }
459
-
460
- }
461
-
462
- /**
463
- * Kicking this off by calling 'get_instance()' method
464
- */
465
- Cartflows_Cloning::get_instance();
1
+ <?php
2
+ /**
3
+ * Cloning.
4
+ *
5
+ * @package cartflows-pro
6
+ */
7
+
8
+ /**
9
+ * Initialization
10
+ *
11
+ * @since 1.0.0
12
+ */
13
+ class Cartflows_Cloning {
14
+
15
+
16
+ /**
17
+ * Member Variable
18
+ *
19
+ * @var instance
20
+ */
21
+ private static $instance;
22
+
23
+ /**
24
+ * Initiator
25
+ */
26
+ public static function get_instance() {
27
+ if ( ! isset( self::$instance ) ) {
28
+ self::$instance = new self();
29
+ }
30
+ return self::$instance;
31
+ }
32
+
33
+ /**
34
+ * Constructor
35
+ */
36
+ public function __construct() {
37
+
38
+ add_filter( 'post_row_actions', array( $this, 'clone_link' ), 99, 2 );
39
+ add_action( 'admin_action_cartflows_clone_flow', array( $this, 'clone_flow' ) );
40
+ add_action( 'admin_action_cartflows_clone_step', array( $this, 'clone_step' ) );
41
+ }
42
+
43
+ /**
44
+ * Clone flow with steps and its meta.
45
+ */
46
+ public function clone_flow() {
47
+
48
+ global $wpdb;
49
+
50
+ if ( ! ( isset( $_GET['post'] ) || isset( $_POST['post'] ) || ( isset( $_REQUEST['action'] ) && 'cartflows_clone_flow' === $_REQUEST['action'] ) ) ) {
51
+ wp_die( 'No post to duplicate has been supplied!' );
52
+ }
53
+
54
+ /*
55
+ * Nonce verification
56
+ */
57
+ if ( ! isset( $_GET['flow_clone_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['flow_clone_nonce'] ) ), basename( __FILE__ ) ) ) {
58
+ return;
59
+ }
60
+
61
+ /**
62
+ * Get the original post id
63
+ */
64
+ $post_id = ( isset( $_GET['post'] ) ? absint( $_GET['post'] ) : absint( $_POST['post'] ) );
65
+
66
+ /**
67
+ * And all the original post data then
68
+ */
69
+ $post = get_post( $post_id );
70
+
71
+ /**
72
+ * Assign current user to be the new post author
73
+ */
74
+ $current_user = wp_get_current_user();
75
+ $new_post_author = $current_user->ID;
76
+
77
+ /**
78
+ * If post data exists, create the post duplicate
79
+ */
80
+ if ( isset( $post ) && null !== $post ) {
81
+
82
+ /**
83
+ * New post data array
84
+ */
85
+
86
+ $args = array(
87
+ 'comment_status' => $post->comment_status,
88
+ 'ping_status' => $post->ping_status,
89
+ 'post_author' => $new_post_author,
90
+ 'post_content' => $post->post_content,
91
+ 'post_excerpt' => $post->post_excerpt,
92
+ 'post_name' => $post->post_name,
93
+ 'post_parent' => $post->post_parent,
94
+ 'post_password' => $post->post_password,
95
+ 'post_status' => $post->post_status,
96
+ 'post_title' => $post->post_title . ' Clone',
97
+ 'post_type' => $post->post_type,
98
+ 'to_ping' => $post->to_ping,
99
+ 'menu_order' => $post->menu_order,
100
+ );
101
+
102
+ /**
103
+ * Insert the post
104
+ */
105
+ $new_flow_id = wp_insert_post( $args );
106
+
107
+ /**
108
+ * Get all current post terms ad set them to the new post
109
+ */
110
+ // returns array of taxonomy names for post type, ex array("category", "post_tag");.
111
+ $taxonomies = get_object_taxonomies( $post->post_type );
112
+
113
+ foreach ( $taxonomies as $taxonomy ) {
114
+
115
+ $post_terms = wp_get_object_terms( $post_id, $taxonomy, array( 'fields' => 'slugs' ) );
116
+
117
+ wp_set_object_terms( $new_flow_id, $post_terms, $taxonomy, false );
118
+ }
119
+
120
+ /**
121
+ * Duplicate all post meta just in two SQL queries
122
+ */
123
+ // @codingStandardsIgnoreStart
124
+ $post_meta_infos = $wpdb->get_results(
125
+ "SELECT meta_key, meta_value FROM $wpdb->postmeta WHERE post_id=$post_id"
126
+ );
127
+ // @codingStandardsIgnoreEnd
128
+
129
+ if ( ! empty( $post_meta_infos ) ) {
130
+
131
+ $sql_query = "INSERT INTO $wpdb->postmeta (post_id, meta_key, meta_value) VALUES ";
132
+
133
+ $sql_query_sel = array();
134
+
135
+ foreach ( $post_meta_infos as $meta_info ) {
136
+
137
+ $meta_key = $meta_info->meta_key;
138
+
139
+ if ( '_wp_old_slug' === $meta_key ) {
140
+ continue;
141
+ }
142
+
143
+ $meta_value = addslashes( $meta_info->meta_value );
144
+
145
+ $sql_query_sel[] = "($new_flow_id, '$meta_key', '$meta_value')";
146
+ }
147
+
148
+ $sql_query .= implode( ',', $sql_query_sel );
149
+
150
+ // @codingStandardsIgnoreStart
151
+ $wpdb->query( $sql_query );
152
+ // @codingStandardsIgnoreEnd
153
+ }
154
+
155
+ /* Steps Cloning */
156
+ $flow_steps = get_post_meta( $post_id, 'wcf-steps', true );
157
+ $new_flow_steps = array();
158
+
159
+ /* Set Steps Empty */
160
+ update_post_meta( $new_flow_id, 'wcf-steps', $new_flow_steps );
161
+
162
+ if ( is_array( $flow_steps ) && ! empty( $flow_steps ) ) {
163
+
164
+ foreach ( $flow_steps as $index => $step_data ) {
165
+
166
+ $step_id = $step_data['id'];
167
+ $step_type = get_post_meta( $step_id, 'wcf-step-type', true );
168
+
169
+ $step_object = get_post( $step_id );
170
+
171
+ /**
172
+ * New step post data array
173
+ */
174
+ $step_args = array(
175
+ 'comment_status' => $step_object->comment_status,
176
+ 'ping_status' => $step_object->ping_status,
177
+ 'post_author' => $new_post_author,
178
+ 'post_content' => $step_object->post_content,
179
+ 'post_excerpt' => $step_object->post_excerpt,
180
+ 'post_name' => $step_object->post_name,
181
+ 'post_parent' => $step_object->post_parent,
182
+ 'post_password' => $step_object->post_password,
183
+ 'post_status' => $step_object->post_status,
184
+ 'post_title' => $step_object->post_title,
185
+ 'post_type' => $step_object->post_type,
186
+ 'to_ping' => $step_object->to_ping,
187
+ 'menu_order' => $step_object->menu_order,
188
+ );
189
+
190
+ /**
191
+ * Insert the post
192
+ */
193
+ $new_step_id = wp_insert_post( $step_args );
194
+
195
+ /**
196
+ * Duplicate all step meta
197
+ */
198
+ // @codingStandardsIgnoreStart
199
+ $post_meta_infos = $wpdb->get_results(
200
+ "SELECT meta_key, meta_value FROM $wpdb->postmeta WHERE post_id=$step_id"
201
+ );
202
+ // @codingStandardsIgnoreEnd
203
+
204
+ if ( ! empty( $post_meta_infos ) ) {
205
+
206
+ $sql_query = "INSERT INTO $wpdb->postmeta (post_id, meta_key, meta_value) VALUES ";
207
+
208
+ $sql_query_sel = array();
209
+
210
+ foreach ( $post_meta_infos as $meta_info ) {
211
+
212
+ $meta_key = $meta_info->meta_key;
213
+
214
+ if ( '_wp_old_slug' === $meta_key ) {
215
+ continue;
216
+ }
217
+
218
+ $meta_value = addslashes( $meta_info->meta_value );
219
+
220
+ $sql_query_sel[] = "($new_step_id, '$meta_key', '$meta_value')";
221
+ }
222
+
223
+ $sql_query .= implode( ',', $sql_query_sel );
224
+
225
+ // @codingStandardsIgnoreStart
226
+ $wpdb->query( $sql_query );
227
+ // @codingStandardsIgnoreEnd
228
+ }
229
+
230
+ // insert post meta.
231
+ update_post_meta( $new_step_id, 'wcf-flow-id', $new_flow_id );
232
+ update_post_meta( $new_step_id, 'wcf-step-type', $step_type );
233
+
234
+ wp_set_object_terms( $new_step_id, $step_type, CARTFLOWS_TAXONOMY_STEP_TYPE );
235
+ wp_set_object_terms( $new_step_id, 'flow-' . $new_flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
236
+
237
+ /* Add New Flow Steps */
238
+ $new_flow_steps[] = array(
239
+ 'id' => $new_step_id,
240
+ 'title' => $step_object->post_title,
241
+ 'type' => $step_type,
242
+ );
243
+ }
244
+ }
245
+
246
+ /* Update New Flow Step Post Meta */
247
+ update_post_meta( $new_flow_id, 'wcf-steps', $new_flow_steps );
248
+
249
+ /* Clear Page Builder Cache */
250
+ $this->clear_cache();
251
+
252
+ /**
253
+ * Redirect to the new flow edit screen
254
+ */
255
+ wp_safe_redirect( admin_url( 'post.php?action=edit&post=' . $new_flow_id ) );
256
+ exit;
257
+ } else {
258
+ wp_die( 'Post creation failed, could not find original post: ' . $post_id );
259
+ }
260
+ }
261
+
262
+ /**
263
+ * Clone step with its meta.
264
+ */
265
+ public function clone_step() {
266
+
267
+ global $wpdb;
268
+
269
+ if ( ! ( isset( $_GET['post'] ) || isset( $_POST['post'] ) || ( isset( $_REQUEST['action'] ) && 'cartflows_clone_step' === $_REQUEST['action'] ) ) ) {
270
+ wp_die( 'No post to duplicate has been supplied!' );
271
+ }
272
+
273
+ /*
274
+ * Nonce verification
275
+ */
276
+ if ( ! isset( $_GET['step_clone_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['step_clone_nonce'] ) ), 'step_clone' ) ) {
277
+ return;
278
+ }
279
+
280
+ /**
281
+ * Get the original post id
282
+ */
283
+ $post_id = ( isset( $_GET['post'] ) ? absint( $_GET['post'] ) : absint( $_POST['post'] ) );
284
+
285
+ /**
286
+ * And all the original post data then
287
+ */
288
+ $post = get_post( $post_id );
289
+
290
+ /**
291
+ * Assign current user to be the new post author
292
+ */
293
+ $current_user = wp_get_current_user();
294
+ $new_post_author = $current_user->ID;
295
+
296
+ /**
297
+ * If post data exists, create the post duplicate
298
+ */
299
+ if ( isset( $post ) && null !== $post ) {
300
+
301
+ /**
302
+ * New post data array
303
+ */
304
+ $args = array(
305
+ 'comment_status' => $post->comment_status,
306
+ 'ping_status' => $post->ping_status,
307
+ 'post_author' => $new_post_author,
308
+ 'post_content' => $post->post_content,
309
+ 'post_excerpt' => $post->post_excerpt,
310
+ 'post_name' => $post->post_name,
311
+ 'post_parent' => $post->post_parent,
312
+ 'post_password' => $post->post_password,
313
+ 'post_status' => $post->post_status,
314
+ 'post_title' => $post->post_title . ' Clone',
315
+ 'post_type' => $post->post_type,
316
+ 'to_ping' => $post->to_ping,
317
+ 'menu_order' => $post->menu_order,
318
+ );
319
+
320
+ /**
321
+ * Insert the post
322
+ */
323
+ $new_step_id = wp_insert_post( $args );
324
+
325
+ /**
326
+ * Get all current post terms ad set them to the new post
327
+ */
328
+ // returns array of taxonomy names for post type, ex array("category", "post_tag");.
329
+ $taxonomies = get_object_taxonomies( $post->post_type );
330
+
331
+ foreach ( $taxonomies as $taxonomy ) {
332
+
333
+ $post_terms = wp_get_object_terms( $post_id, $taxonomy, array( 'fields' => 'slugs' ) );
334
+
335
+ wp_set_object_terms( $new_step_id, $post_terms, $taxonomy, false );
336
+ }
337
+
338
+ /**
339
+ * Duplicate all post meta just in two SQL queries
340
+ */
341
+ // @codingStandardsIgnoreStart
342
+ $post_meta_infos = $wpdb->get_results(
343
+ "SELECT meta_key, meta_value FROM $wpdb->postmeta WHERE post_id=$post_id"
344
+ );
345
+ // @codingStandardsIgnoreEnd
346
+
347
+ if ( ! empty( $post_meta_infos ) ) {
348
+
349
+ $sql_query = "INSERT INTO $wpdb->postmeta (post_id, meta_key, meta_value) VALUES ";
350
+
351
+ $sql_query_sel = array();
352
+
353
+ foreach ( $post_meta_infos as $meta_info ) {
354
+
355
+ $meta_key = $meta_info->meta_key;
356
+
357
+ if ( '_wp_old_slug' === $meta_key ) {
358
+ continue;
359
+ }
360
+
361
+ $meta_value = addslashes( $meta_info->meta_value );
362
+
363
+ $sql_query_sel[] = "($new_step_id, '$meta_key', '$meta_value')";
364
+ }
365
+
366
+ $sql_query .= implode( ',', $sql_query_sel );
367
+
368
+ // @codingStandardsIgnoreStart
369
+ $wpdb->query( $sql_query );
370
+ // @codingStandardsIgnoreEnd
371
+ }
372
+
373
+ $flow_id = get_post_meta( $post_id, 'wcf-flow-id', true );
374
+ $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
375
+ $step_type = get_post_meta( $post_id, 'wcf-step-type', true );
376
+
377
+ if ( ! is_array( $flow_steps ) ) {
378
+ $flow_steps = array();
379
+ }
380
+
381
+ $flow_steps[] = array(
382
+ 'id' => $new_step_id,
383
+ 'title' => $post->post_title,
384
+ 'type' => $step_type,
385
+ );
386
+
387
+ update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
388
+
389
+ /* Clear Page Builder Cache */
390
+ $this->clear_cache();
391
+
392
+ /**
393
+ * Redirect to the new flow edit screen
394
+ */
395
+ $redirect_url = add_query_arg( 'highlight-step-id', $new_step_id, get_edit_post_link( $flow_id, 'default' ) );
396
+
397
+ wp_safe_redirect( $redirect_url );
398
+ exit;
399
+ } else {
400
+ wp_die( 'Post creation failed, could not find original post: ' . $post_id );
401
+ }
402
+ }
403
+
404
+ /**
405
+ * Add the clone link to action list for flows row actions
406
+ *
407
+ * @param array $actions Actions array.
408
+ * @param object $post Post object.
409
+ *
410
+ * @return array
411
+ */
412
+ public function clone_link( $actions, $post ) {
413
+
414
+ if ( current_user_can( 'edit_posts' ) && isset( $post ) && CARTFLOWS_FLOW_POST_TYPE === $post->post_type ) {
415
+
416
+ if ( isset( $actions['duplicate'] ) ) { // Duplicate page plugin remove.
417
+ unset( $actions['duplicate'] );
418
+ }
419
+ if ( isset( $actions['edit_as_new_draft'] ) ) { // Duplicate post plugin remove.
420
+ unset( $actions['edit_as_new_draft'] );
421
+ }
422
+
423
+ $actions['clone'] = '<a href="' . wp_nonce_url( 'admin.php?action=cartflows_clone_flow&post=' . $post->ID, basename( __FILE__ ), 'flow_clone_nonce' ) . '" title="' . __( 'Clone this flow', 'cartflows' ) . '" rel="permalink">' . __( 'Clone', 'cartflows' ) . '</a>';
424
+
425
+ if ( ! _is_cartflows_pro() ) {
426
+
427
+ $flow_posts = get_posts(
428
+ array(
429
+ 'posts_per_page' => 4,
430
+ 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
431
+ 'post_status' => array( 'publish', 'pending', 'draft', 'future', 'private' ),
432
+ )
433
+ );
434
+
435
+ if ( is_array( $flow_posts ) ) {
436
+
437
+ $flow_count = count( $flow_posts );
438
+
439
+ if ( $flow_count > 3 || 3 === $flow_count ) {
440
+ unset( $actions['clone'] );
441
+ }
442
+ }
443
+ }
444
+ }
445
+
446
+ return $actions;
447
+ }
448
+
449
+ /**
450
+ * Clear Page Builder Cache
451
+ */
452
+ public function clear_cache() {
453
+
454
+ // Clear 'Elementor' file cache.
455
+ if ( class_exists( '\Elementor\Plugin' ) ) {
456
+ Elementor\Plugin::$instance->files_manager->clear_cache();
457
+ }
458
+ }
459
+
460
+ }
461
+
462
+ /**
463
+ * Kicking this off by calling 'get_instance()' method
464
+ */
465
+ Cartflows_Cloning::get_instance();
classes/class-cartflows-helper.php CHANGED
@@ -1,777 +1,787 @@
1
- <?php
2
- /**
3
- * CARTFLOWS Helper.
4
- *
5
- * @package CARTFLOWS
6
- */
7
-
8
- if ( ! defined( 'ABSPATH' ) ) {
9
- exit; // Exit if accessed directly.
10
- }
11
-
12
- /**
13
- * Class Cartflows_Helper.
14
- */
15
- class Cartflows_Helper {
16
-
17
- /**
18
- * Common global data
19
- *
20
- * @var zapier
21
- */
22
- private static $common = null;
23
-
24
- /**
25
- * Common Debug data
26
- *
27
- * @var zapier
28
- */
29
- private static $debug_data = null;
30
-
31
-
32
- /**
33
- * Permalink settings
34
- *
35
- * @var permalink_setting
36
- */
37
- private static $permalink_setting = null;
38
-
39
- /**
40
- * Google Analytics Settings
41
- *
42
- * @var permalink_setting
43
- */
44
- private static $google_analytics_settings = null;
45
-
46
- /**
47
- * Installed Plugins
48
- *
49
- * @since 1.1.4
50
- *
51
- * @access private
52
- * @var array Installed plugins list.
53
- */
54
- private static $installed_plugins = null;
55
-
56
- /**
57
- * Checkout Fields
58
- *
59
- * @var checkout_fields
60
- */
61
- private static $checkout_fields = null;
62
-
63
- /**
64
- * Facebook pixel global data
65
- *
66
- * @var faceboook
67
- */
68
- private static $facebook = null;
69
-
70
-
71
- /**
72
- * Returns an option from the database for
73
- * the admin settings page.
74
- *
75
- * @param string $key The option key.
76
- * @param mixed $default Option default value if option is not available.
77
- * @param boolean $network_override Whether to allow the network admin setting to be overridden on subsites.
78
- * @return string Return the option value
79
- */
80
- public static function get_admin_settings_option( $key, $default = false, $network_override = false ) {
81
-
82
- // Get the site-wide option if we're in the network admin.
83
- if ( $network_override && is_multisite() ) {
84
- $value = get_site_option( $key, $default );
85
- } else {
86
- $value = get_option( $key, $default );
87
- }
88
-
89
- return $value;
90
- }
91
-
92
- /**
93
- * Updates an option from the admin settings page.
94
- *
95
- * @param string $key The option key.
96
- * @param mixed $value The value to update.
97
- * @param bool $network Whether to allow the network admin setting to be overridden on subsites.
98
- * @return mixed
99
- */
100
- public static function update_admin_settings_option( $key, $value, $network = false ) {
101
-
102
- // Update the site-wide option since we're in the network admin.
103
- if ( $network && is_multisite() ) {
104
- update_site_option( $key, $value );
105
- } else {
106
- update_option( $key, $value );
107
- }
108
-
109
- }
110
-
111
- /**
112
- * Get single setting
113
- *
114
- * @since 1.1.4
115
- *
116
- * @param string $key Option key.
117
- * @param string $default Option default value if not exist.
118
- * @return mixed
119
- */
120
- public static function get_common_setting( $key = '', $default = '' ) {
121
- $settings = self::get_common_settings();
122
-
123
- if ( $settings && array_key_exists( $key, $settings ) ) {
124
- return $settings[ $key ];
125
- }
126
-
127
- return $default;
128
- }
129
-
130
- /**
131
- * Get single debug options
132
- *
133
- * @since 1.1.4
134
- *
135
- * @param string $key Option key.
136
- * @param string $default Option default value if not exist.
137
- * @return mixed
138
- */
139
- public static function get_debug_setting( $key = '', $default = '' ) {
140
- $debug_data = self::get_debug_settings();
141
-
142
- if ( $debug_data && array_key_exists( $key, $debug_data ) ) {
143
- return $debug_data[ $key ];
144
- }
145
-
146
- return $default;
147
- }
148
-
149
- /**
150
- * Get required plugins for page builder
151
- *
152
- * @since 1.1.4
153
- *
154
- * @param string $page_builder_slug Page builder slug.
155
- * @param string $default Default page builder.
156
- * @return array selected page builder required plugins list.
157
- */
158
- public static function get_required_plugins_for_page_builder( $page_builder_slug = '', $default = 'elementor' ) {
159
- $plugins = self::get_plugins_groupby_page_builders();
160
-
161
- if ( array_key_exists( $page_builder_slug, $plugins ) ) {
162
- return $plugins[ $page_builder_slug ];
163
- }
164
-
165
- return $plugins[ $default ];
166
- }
167
-
168
- /**
169
- * Get Plugins list by page builder.
170
- *
171
- * @since 1.1.4
172
- *
173
- * @return array Required Plugins list.
174
- */
175
- public static function get_plugins_groupby_page_builders() {
176
-
177
- $divi_status = self::get_plugin_status( 'divi-builder/divi-builder.php' );
178
- $theme_status = 'not-installed';
179
- if ( $divi_status ) {
180
- if ( true === Cartflows_Compatibility::get_instance()->is_divi_theme_installed() ) {
181
- $theme_status = 'installed';
182
- if ( false === Cartflows_Compatibility::get_instance()->is_divi_enabled() ) {
183
- $theme_status = 'deactivate';
184
- $divi_status = 'activate';
185
- } else {
186
- $divi_status = '';
187
- }
188
- }
189
- }
190
-
191
- $plugins = array(
192
- 'elementor' => array(
193
- 'title' => 'Elementor',
194
- 'plugins' => array(
195
- array(
196
- 'slug' => 'elementor', // For download from wp.org.
197
- 'init' => 'elementor/elementor.php',
198
- 'status' => self::get_plugin_status( 'elementor/elementor.php' ),
199
- ),
200
- ),
201
- ),
202
- 'divi' => array(
203
- 'title' => 'Divi',
204
- 'theme-status' => $theme_status,
205
- 'plugin-status' => $divi_status,
206
- 'plugins' => array(
207
- array(
208
- 'slug' => 'divi-builder', // For download from wp.org.
209
- 'init' => 'divi-builder/divi-builder.php',
210
- 'status' => $divi_status,
211
- ),
212
- ),
213
- ),
214
- );
215
-
216
- $plugins['beaver-builder'] = array(
217
- 'title' => 'Beaver Builder',
218
- 'plugins' => array(),
219
- );
220
-
221
- // Check Pro Exist.
222
- if ( file_exists( WP_PLUGIN_DIR . '/bb-plugin/fl-builder.php' ) && ! is_plugin_active( 'beaver-builder-lite-version/fl-builder.php' ) ) {
223
- $plugins['beaver-builder']['plugins'][] = array(
224
- 'slug' => 'bb-plugin',
225
- 'init' => 'bb-plugin/fl-builder.php',
226
- 'status' => self::get_plugin_status( 'bb-plugin/fl-builder.php' ),
227
- );
228
- } else {
229
- $plugins['beaver-builder']['plugins'][] = array(
230
- 'slug' => 'beaver-builder-lite-version', // For download from wp.org.
231
- 'init' => 'beaver-builder-lite-version/fl-builder.php',
232
- 'status' => self::get_plugin_status( 'beaver-builder-lite-version/fl-builder.php' ),
233
- );
234
- }
235
-
236
- if ( file_exists( WP_PLUGIN_DIR . '/bb-ultimate-addon/bb-ultimate-addon.php' ) && ! is_plugin_active( 'ultimate-addons-for-beaver-builder-lite/bb-ultimate-addon.php' ) ) {
237
- $plugins['beaver-builder']['plugins'][] = array(
238
- 'slug' => 'bb-ultimate-addon',
239
- 'init' => 'bb-ultimate-addon/bb-ultimate-addon.php',
240
- 'status' => self::get_plugin_status( 'bb-ultimate-addon/bb-ultimate-addon.php' ),
241
- );
242
- } else {
243
- $plugins['beaver-builder']['plugins'][] = array(
244
- 'slug' => 'ultimate-addons-for-beaver-builder-lite', // For download from wp.org.
245
- 'init' => 'ultimate-addons-for-beaver-builder-lite/bb-ultimate-addon.php',
246
- 'status' => self::get_plugin_status( 'ultimate-addons-for-beaver-builder-lite/bb-ultimate-addon.php' ),
247
- );
248
- }
249
-
250
- return $plugins;
251
- }
252
-
253
- /**
254
- * Get plugin status
255
- *
256
- * @since 1.1.4
257
- *
258
- * @param string $plugin_init_file Plguin init file.
259
- * @return mixed
260
- */
261
- public static function get_plugin_status( $plugin_init_file ) {
262
-
263
- if ( null == self::$installed_plugins ) {
264
- self::$installed_plugins = get_plugins();
265
- }
266
-
267
- if ( ! isset( self::$installed_plugins[ $plugin_init_file ] ) ) {
268
- return 'install';
269
- } elseif ( ! is_plugin_active( $plugin_init_file ) ) {
270
- return 'activate';
271
- } else {
272
- return;
273
- }
274
- }
275
-
276
- /**
277
- * Get zapier settings.
278
- *
279
- * @return array.
280
- */
281
- public static function get_common_settings() {
282
-
283
- if ( null === self::$common ) {
284
-
285
- $common_default = apply_filters(
286
- 'cartflows_common_settings_default',
287
- array(
288
- 'disallow_indexing' => 'disable',
289
- 'global_checkout' => '',
290
- 'default_page_builder' => 'elementor',
291
- )
292
- );
293
-
294
- $common = self::get_admin_settings_option( '_cartflows_common', false, false );
295
-
296
- $common = wp_parse_args( $common, $common_default );
297
-
298
- if ( ! did_action( 'wp' ) ) {
299
- return $common;
300
- } else {
301
- self::$common = $common;
302
- }
303
- }
304
-
305
- return self::$common;
306
- }
307
-
308
- /**
309
- * Get debug settings data.
310
- *
311
- * @return array.
312
- */
313
- public static function get_debug_settings() {
314
-
315
- if ( null === self::$debug_data ) {
316
-
317
- $debug_data_default = apply_filters(
318
- 'cartflows_debug_settings_default',
319
- array(
320
- 'allow_minified_files' => 'disable',
321
- )
322
- );
323
-
324
- $debug_data = self::get_admin_settings_option( '_cartflows_debug_data', false, false );
325
-
326
- $debug_data = wp_parse_args( $debug_data, $debug_data_default );
327
-
328
- if ( ! did_action( 'wp' ) ) {
329
- return $debug_data;
330
- } else {
331
- self::$debug_data = $debug_data;
332
- }
333
- }
334
-
335
- return self::$debug_data;
336
- }
337
-
338
-
339
- /**
340
- * Get debug settings data.
341
- *
342
- * @return array.
343
- */
344
- public static function get_permalink_settings() {
345
-
346
- if ( null === self::$permalink_setting ) {
347
-
348
- $permalink_default = apply_filters(
349
- 'cartflows_permalink_settings_default',
350
- array(
351
- 'permalink' => CARTFLOWS_STEP_POST_TYPE,
352
- 'permalink_flow_base' => CARTFLOWS_FLOW_POST_TYPE,
353
- 'permalink_structure' => '',
354
-
355
- )
356
- );
357
-
358
- $permalink_data = self::get_admin_settings_option( '_cartflows_permalink', false, false );
359
-
360
- $permalink_data = wp_parse_args( $permalink_data, $permalink_default );
361
-
362
- if ( ! did_action( 'wp' ) ) {
363
- return $permalink_data;
364
- } else {
365
- self::$permalink_setting = $permalink_data;
366
- }
367
- }
368
-
369
- return self::$permalink_setting;
370
- }
371
-
372
-
373
- /**
374
- * Get debug settings data.
375
- *
376
- * @return array.
377
- */
378
- public static function get_google_analytics_settings() {
379
-
380
- if ( null === self::$google_analytics_settings ) {
381
-
382
- $google_analytics_settings_default = apply_filters(
383
- 'cartflows_google_analytics_settings_default',
384
- array(
385
- 'enable_google_analytics' => 'disable',
386
- 'enable_google_analytics_for_site' => 'disable',
387
- 'google_analytics_id' => '',
388
- 'enable_begin_checkout' => 'disable',
389
- 'enable_add_to_cart' => 'disable',
390
- 'enable_add_payment_info' => 'disable',
391
- 'enable_purchase_event' => 'disable',
392
- )
393
- );
394
-
395
- $google_analytics_settings_data = self::get_admin_settings_option( '_cartflows_google_analytics', false, true );
396
-
397
- $google_analytics_settings_data = wp_parse_args( $google_analytics_settings_data, $google_analytics_settings_default );
398
-
399
- if ( ! did_action( 'wp' ) ) {
400
- return $google_analytics_settings_data;
401
- } else {
402
- self::$google_analytics_settings = $google_analytics_settings_data;
403
- }
404
- }
405
-
406
- return self::$google_analytics_settings = $google_analytics_settings_data; //phpcs:ignore
407
- }
408
-
409
- /**
410
- * Get Checkout field.
411
- *
412
- * @param string $key Field key.
413
- * @param int $post_id Post id.
414
- * @return array.
415
- */
416
- public static function get_checkout_fields( $key, $post_id ) {
417
-
418
- $saved_fields = get_post_meta( $post_id, 'wcf_fields_' . $key, true );
419
-
420
- if ( ! $saved_fields ) {
421
- $saved_fields = array();
422
- }
423
-
424
- $fields = array_filter( $saved_fields );
425
-
426
- if ( empty( $fields ) ) {
427
- if ( 'billing' === $key || 'shipping' === $key ) {
428
-
429
- $fields = WC()->countries->get_address_fields( WC()->countries->get_base_country(), $key . '_' );
430
-
431
- update_post_meta( $post_id, 'wcf_fields_' . $key, $fields );
432
- }
433
- }
434
-
435
- return $fields;
436
- }
437
-
438
- /**
439
- * Add Checkout field.
440
- *
441
- * @param string $type Field type.
442
- * @param string $field_key Field key.
443
- * @param array $field_data Field data.
444
- * @param int $post_id Post id.
445
- * @return boolean.
446
- */
447
- public static function add_checkout_field( $type, $field_key, $field_data = array(), $post_id ) {
448
-
449
- $fields = self::get_checkout_fields( $type, $post_id );
450
-
451
- $fields[ $field_key ] = $field_data;
452
-
453
- update_post_meta( $post_id, 'wcf_fields_' . $type, $fields );
454
-
455
- return true;
456
- }
457
-
458
- /**
459
- * Get checkout fields settings.
460
- *
461
- * @param string $type Field type.
462
- * @param string $field_key Field key.
463
- * @param int $post_id Post id.
464
- * @return array.
465
- */
466
- public static function delete_checkout_field( $type, $field_key, $post_id ) {
467
-
468
- $fields = self::get_checkout_fields( $type, $post_id );
469
-
470
- if ( isset( $fields[ $field_key ] ) ) {
471
- unset( $fields[ $field_key ] );
472
- }
473
-
474
- update_post_meta( $post_id, 'wcf_fields_' . $type, $fields );
475
-
476
- return true;
477
- }
478
-
479
- /**
480
- * Get checkout fields settings.
481
- *
482
- * @return array.
483
- */
484
- public static function get_checkout_fields_settings() {
485
-
486
- if ( null === self::$checkout_fields ) {
487
- $checkout_fields_default = array(
488
- 'enable_customization' => 'disable',
489
- 'enable_billing_fields' => 'disable',
490
- );
491
-
492
- $billing_fields = self::get_checkout_fields( 'billing' );
493
-
494
- if ( is_array( $billing_fields ) && ! empty( $billing_fields ) ) {
495
-
496
- foreach ( $billing_fields as $key => $value ) {
497
-
498
- $checkout_fields_default[ $key ] = 'enable';
499
- }
500
- }
501
-
502
- $checkout_fields = self::get_admin_settings_option( '_wcf_checkout_fields', false, false );
503
-
504
- self::$checkout_fields = wp_parse_args( $checkout_fields, $checkout_fields_default );
505
- }
506
-
507
- return self::$checkout_fields;
508
- }
509
-
510
- /**
511
- * Get meta options
512
- *
513
- * @since 1.0.0
514
- * @param int $post_id Product ID.
515
- * @param string $key Meta Key.
516
- * @param string $default Default value.
517
- * @return string Meta Value.
518
- */
519
- public static function get_meta_option( $post_id, $key, $default = '' ) {
520
-
521
- $value = get_post_meta( $post_id, $key, true );
522
-
523
- if ( ! $value ) {
524
- $value = $default;
525
- }
526
-
527
- return $value;
528
- }
529
-
530
- /**
531
- * Save meta option
532
- *
533
- * @since 1.0.0
534
- * @param int $post_id Product ID.
535
- * @param array $args Arguments array.
536
- */
537
- public static function save_meta_option( $post_id, $args = array() ) {
538
-
539
- if ( is_array( $args ) && ! empty( $args ) ) {
540
-
541
- foreach ( $args as $key => $value ) {
542
-
543
- update_post_meta( $post_id, $key, $value );
544
- }
545
- }
546
- }
547
-
548
- /**
549
- * Check if Elementor page builder is installed
550
- *
551
- * @since 1.0.0
552
- *
553
- * @access public
554
- */
555
- public static function is_elementor_installed() {
556
- $path = 'elementor/elementor.php';
557
- $plugins = get_plugins();
558
-
559
- return isset( $plugins[ $path ] );
560
- }
561
-
562
- /**
563
- * Check if Step has product assigned.
564
- *
565
- * @since 1.0.0
566
- * @param int $step_id step ID.
567
- *
568
- * @access public
569
- */
570
- public static function has_product_assigned( $step_id ) {
571
-
572
- $step_type = get_post_meta( $step_id, 'wcf-step-type', true );
573
-
574
- if ( 'checkout' == $step_type ) {
575
- $product = get_post_meta( $step_id, 'wcf-checkout-products', true );
576
- } else {
577
- $product = get_post_meta( $step_id, 'wcf-offer-product', true );
578
- }
579
-
580
- if ( ! empty( $product ) ) {
581
- return true;
582
- }
583
- return false;
584
-
585
- }
586
-
587
- /**
588
- * Get attributes for cartflows wrap.
589
- *
590
- * @since 1.1.4
591
- *
592
- * @access public
593
- */
594
- public static function get_cartflows_container_atts() {
595
-
596
- $attributes = apply_filters( 'cartflows_container_atts', array() );
597
- $atts_string = '';
598
-
599
- foreach ( $attributes as $key => $value ) {
600
-
601
- if ( ! $value ) {
602
- continue;
603
- }
604
-
605
- if ( true === $value ) {
606
- $atts_string .= esc_html( $key ) . ' ';
607
- } else {
608
- $atts_string .= sprintf( '%s="%s" ', esc_html( $key ), esc_attr( $value ) );
609
- }
610
- }
611
-
612
- return $atts_string;
613
- }
614
-
615
- /**
616
- * Get facebook pixel settings.
617
- *
618
- * @return facebook array.
619
- */
620
- public static function get_facebook_settings() {
621
-
622
- if ( null === self::$facebook ) {
623
-
624
- $facebook_default = array(
625
- 'facebook_pixel_id' => '',
626
- 'facebook_pixel_add_to_cart' => 'enable',
627
- 'facebook_pixel_initiate_checkout' => 'enable',
628
- 'facebook_pixel_add_payment_info' => 'enable',
629
- 'facebook_pixel_purchase_complete' => 'enable',
630
- 'facebook_pixel_tracking' => 'disable',
631
- 'facebook_pixel_tracking_for_site' => 'disable',
632
- );
633
-
634
- $facebook = self::get_admin_settings_option( '_cartflows_facebook', false, false );
635
-
636
- $facebook = wp_parse_args( $facebook, $facebook_default );
637
-
638
- self::$facebook = apply_filters( 'cartflows_facebook_settings_default', $facebook );
639
-
640
- }
641
-
642
- return self::$facebook;
643
- }
644
-
645
-
646
- /**
647
- * Prepare response data for facebook.
648
- *
649
- * @param int $order_id order_id.
650
- * @param array $offer_data offer data.
651
- */
652
- public static function send_fb_response_if_enabled( $order_id, $offer_data = array() ) {
653
-
654
- // Stop Execution if WooCommerce is not installed & don't set the cookie.
655
- if ( ! Cartflows_Loader::get_instance()->is_woo_active ) {
656
- return;
657
- }
658
-
659
- $fb_settings = self::get_facebook_settings();
660
- if ( 'enable' === $fb_settings['facebook_pixel_tracking'] ) {
661
- setcookie( 'wcf_order_details', wp_json_encode( self::prepare_purchase_data_fb_response( $order_id, $offer_data ) ), strtotime( '+1 year' ), '/' );
662
- }
663
-
664
- }
665
-
666
- /**
667
- * Prepare purchase response for facebook purcase event.
668
- *
669
- * @param integer $order_id order id.
670
- * @param array $offer_data offer data.
671
- * @return mixed
672
- */
673
- public static function prepare_purchase_data_fb_response( $order_id, $offer_data = array() ) {
674
-
675
- $thankyou = array();
676
-
677
- if ( ! Cartflows_Loader::get_instance()->is_woo_active ) {
678
- return $thankyou;
679
- }
680
-
681
- $thankyou['order_id'] = $order_id;
682
- $thankyou['content_type'] = 'product';
683
- $thankyou['currency'] = wcf()->options->get_checkout_meta_value( $order_id, '_order_currency' );
684
- $thankyou['userAgent'] = wcf()->options->get_checkout_meta_value( $order_id, '_customer_user_agent' );
685
- $thankyou['plugin'] = 'CartFlows';
686
- $order = wc_get_order( $order_id );
687
- if ( empty( $offer_data ) ) {
688
- // Iterating through each WC_Order_Item_Product objects.
689
- foreach ( $order->get_items() as $item_key => $item ) {
690
- $product = $item->get_product(); // Get the WC_Product object.
691
- $thankyou['content_ids'][] = (string) $product->get_id();
692
- }
693
- $thankyou['value'] = wcf()->options->get_checkout_meta_value( $order_id, '_order_total' );
694
- } else {
695
- $thankyou['content_ids'][] = (string) $offer_data['id'];
696
- $thankyou['value'] = $offer_data['total'];
697
- }
698
-
699
- return $thankyou;
700
- }
701
-
702
- /**
703
- * Prepare cart data for fb response.
704
- *
705
- * @return array
706
- */
707
- public static function prepare_cart_data_fb_response() {
708
-
709
- $params = array();
710
-
711
- if ( ! Cartflows_Loader::get_instance()->is_woo_active ) {
712
- return $params;
713
- }
714
-
715
- $cart_total = WC()->cart->get_cart_contents_total();
716
- $cart_items_count = WC()->cart->get_cart_contents_count();
717
- $items = WC()->cart->get_cart();
718
- $product_names = '';
719
- $category_names = '';
720
- $cart_contents = array();
721
- foreach ( $items as $item => $value ) {
722
-
723
- $_product = wc_get_product( $value['product_id'] );
724
- $params['content_ids'][] = (string) $_product->get_id();
725
- $product_names = $product_names . ', ' . $_product->get_title();
726
- $category_names = $category_names . ', ' . wp_strip_all_tags( wc_get_product_category_list( $_product->get_id() ) );
727
- array_push(
728
- $cart_contents,
729
- array(
730
- 'id' => $_product->get_id(),
731
- 'name' => $_product->get_title(),
732
- 'quantity' => $value['quantity'],
733
- 'item_price' => $_product->get_price(),
734
- )
735
- );
736
- }
737
-
738
- $user = wp_get_current_user();
739
- $roles = implode( ', ', $user->roles );
740
- $params['content_name'] = substr( $product_names, 2 );
741
- $params['categoey_name'] = substr( $category_names, 2 );
742
- $params['user_roles'] = $roles;
743
- $params['plugin'] = 'CartFlows';
744
- $params['contents'] = wp_json_encode( $cart_contents );
745
- $params['content_type'] = 'product';
746
- $params['value'] = $cart_total;
747
- $params['num_items'] = $cart_items_count;
748
- $params['currency'] = get_woocommerce_currency();
749
- $params['language'] = get_bloginfo( 'language' );
750
- $params['userAgent'] = wp_unslash( $_SERVER['HTTP_USER_AGENT'] ); //phpcs:ignore
751
- $params['product_catalog_id'] = '';
752
- $params['domain'] = get_site_url();
753
- return $params;
754
- }
755
-
756
- /**
757
- * Get the image url of size.
758
- *
759
- * @param int $post_id post id.
760
- * @param array $key key.
761
- * @param string $size image size.
762
- *
763
- * @return array
764
- */
765
- public static function get_image_url( $post_id, $key, $size = false ) {
766
-
767
- $url = get_post_meta( $post_id, $key, true );
768
- $img_obj = get_post_meta( $post_id, $key . '-obj', true );
769
- if ( is_array( $img_obj ) && ! empty( $img_obj ) && false !== $size ) {
770
-
771
- $url = ! empty( $img_obj['url'][ $size ] ) ? $img_obj['url'][ $size ] : $url;
772
- }
773
-
774
- return $url;
775
- }
776
-
777
- }
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * CARTFLOWS Helper.
4
+ *
5
+ * @package CARTFLOWS
6
+ */
7
+
8
+ if ( ! defined( 'ABSPATH' ) ) {
9
+ exit; // Exit if accessed directly.
10
+ }
11
+
12
+ /**
13
+ * Class Cartflows_Helper.
14
+ */
15
+ class Cartflows_Helper {
16
+
17
+ /**
18
+ * Common global data
19
+ *
20
+ * @var zapier
21
+ */
22
+ private static $common = null;
23
+
24
+ /**
25
+ * Common Debug data
26
+ *
27
+ * @var zapier
28
+ */
29
+ private static $debug_data = null;
30
+
31
+
32
+ /**
33
+ * Permalink settings
34
+ *
35
+ * @var permalink_setting
36
+ */
37
+ private static $permalink_setting = null;
38
+
39
+ /**
40
+ * Google Analytics Settings
41
+ *
42
+ * @var permalink_setting
43
+ */
44
+ private static $google_analytics_settings = null;
45
+
46
+ /**
47
+ * Installed Plugins
48
+ *
49
+ * @since 1.1.4
50
+ *
51
+ * @access private
52
+ * @var array Installed plugins list.
53
+ */
54
+ private static $installed_plugins = null;
55
+
56
+ /**
57
+ * Checkout Fields
58
+ *
59
+ * @var checkout_fields
60
+ */
61
+ private static $checkout_fields = null;
62
+
63
+ /**
64
+ * Facebook pixel global data
65
+ *
66
+ * @var faceboook
67
+ */
68
+ private static $facebook = null;
69
+
70
+
71
+ /**
72
+ * Returns an option from the database for
73
+ * the admin settings page.
74
+ *
75
+ * @param string $key The option key.
76
+ * @param mixed $default Option default value if option is not available.
77
+ * @param boolean $network_override Whether to allow the network admin setting to be overridden on subsites.
78
+ * @return string Return the option value
79
+ */
80
+ public static function get_admin_settings_option( $key, $default = false, $network_override = false ) {
81
+
82
+ // Get the site-wide option if we're in the network admin.
83
+ if ( $network_override && is_multisite() ) {
84
+ $value = get_site_option( $key, $default );
85
+ } else {
86
+ $value = get_option( $key, $default );
87
+ }
88
+
89
+ return $value;
90
+ }
91
+
92
+ /**
93
+ * Updates an option from the admin settings page.
94
+ *
95
+ * @param string $key The option key.
96
+ * @param mixed $value The value to update.
97
+ * @param bool $network Whether to allow the network admin setting to be overridden on subsites.
98
+ * @return mixed
99
+ */
100
+ public static function update_admin_settings_option( $key, $value, $network = false ) {
101
+
102
+ // Update the site-wide option since we're in the network admin.
103
+ if ( $network && is_multisite() ) {
104
+ update_site_option( $key, $value );
105
+ } else {
106
+ update_option( $key, $value );
107
+ }
108
+
109
+ }
110
+
111
+ /**
112
+ * Get single setting
113
+ *
114
+ * @since 1.1.4
115
+ *
116
+ * @param string $key Option key.
117
+ * @param string $default Option default value if not exist.
118
+ * @return mixed
119
+ */
120
+ public static function get_common_setting( $key = '', $default = '' ) {
121
+ $settings = self::get_common_settings();
122
+
123
+ if ( $settings && array_key_exists( $key, $settings ) ) {
124
+ return $settings[ $key ];
125
+ }
126
+
127
+ return $default;
128
+ }
129
+
130
+ /**
131
+ * Get single debug options
132
+ *
133
+ * @since 1.1.4
134
+ *
135
+ * @param string $key Option key.
136
+ * @param string $default Option default value if not exist.
137
+ * @return mixed
138
+ */
139
+ public static function get_debug_setting( $key = '', $default = '' ) {
140
+ $debug_data = self::get_debug_settings();
141
+
142
+ if ( $debug_data && array_key_exists( $key, $debug_data ) ) {
143
+ return $debug_data[ $key ];
144
+ }
145
+
146
+ return $default;
147
+ }
148
+
149
+ /**
150
+ * Get required plugins for page builder
151
+ *
152
+ * @since 1.1.4
153
+ *
154
+ * @param string $page_builder_slug Page builder slug.
155
+ * @param string $default Default page builder.
156
+ * @return array selected page builder required plugins list.
157
+ */
158
+ public static function get_required_plugins_for_page_builder( $page_builder_slug = '', $default = 'elementor' ) {
159
+ $plugins = self::get_plugins_groupby_page_builders();
160
+
161
+ if ( array_key_exists( $page_builder_slug, $plugins ) ) {
162
+ return $plugins[ $page_builder_slug ];
163
+ }
164
+
165
+ return $plugins[ $default ];
166
+ }
167
+
168
+ /**
169
+ * Get Plugins list by page builder.
170
+ *
171
+ * @since 1.1.4
172
+ *
173
+ * @return array Required Plugins list.
174
+ */
175
+ public static function get_plugins_groupby_page_builders() {
176
+
177
+ $divi_status = self::get_plugin_status( 'divi-builder/divi-builder.php' );
178
+ $theme_status = 'not-installed';
179
+ if ( $divi_status ) {
180
+ if ( true === Cartflows_Compatibility::get_instance()->is_divi_theme_installed() ) {
181
+ $theme_status = 'installed';
182
+ if ( false === Cartflows_Compatibility::get_instance()->is_divi_enabled() ) {
183
+ $theme_status = 'deactivate';
184
+ $divi_status = 'activate';
185
+ } else {
186
+ $divi_status = '';
187
+ }
188
+ }
189
+ }
190
+
191
+ $plugins = array(
192
+ 'elementor' => array(
193
+ 'title' => 'Elementor',
194
+ 'plugins' => array(
195
+ array(
196
+ 'slug' => 'elementor', // For download from wp.org.
197
+ 'init' => 'elementor/elementor.php',
198
+ 'status' => self::get_plugin_status( 'elementor/elementor.php' ),
199
+ ),
200
+ ),
201
+ ),
202
+ 'gutenberg' => array(
203
+ 'title' => 'Ultimate Addons for Gutenberg',
204
+ 'plugins' => array(
205
+ array(
206
+ 'slug' => 'ultimate-addons-for-gutenberg', // For download from wp.org.
207
+ 'init' => 'ultimate-addons-for-gutenberg/ultimate-addons-for-gutenberg.php',
208
+ 'status' => self::get_plugin_status( 'ultimate-addons-for-gutenberg/ultimate-addons-for-gutenberg.php' ),
209
+ ),
210
+ ),
211
+ ),
212
+ 'divi' => array(
213
+ 'title' => 'Divi',
214
+ 'theme-status' => $theme_status,
215
+ 'plugin-status' => $divi_status,
216
+ 'plugins' => array(
217
+ array(
218
+ 'slug' => 'divi-builder', // For download from wp.org.
219
+ 'init' => 'divi-builder/divi-builder.php',
220
+ 'status' => $divi_status,
221
+ ),
222
+ ),
223
+ ),
224
+ );
225
+
226
+ $plugins['beaver-builder'] = array(
227
+ 'title' => 'Beaver Builder',
228
+ 'plugins' => array(),
229
+ );
230
+
231
+ // Check Pro Exist.
232
+ if ( file_exists( WP_PLUGIN_DIR . '/bb-plugin/fl-builder.php' ) && ! is_plugin_active( 'beaver-builder-lite-version/fl-builder.php' ) ) {
233
+ $plugins['beaver-builder']['plugins'][] = array(
234
+ 'slug' => 'bb-plugin',
235
+ 'init' => 'bb-plugin/fl-builder.php',
236
+ 'status' => self::get_plugin_status( 'bb-plugin/fl-builder.php' ),
237
+ );
238
+ } else {
239
+ $plugins['beaver-builder']['plugins'][] = array(
240
+ 'slug' => 'beaver-builder-lite-version', // For download from wp.org.
241
+ 'init' => 'beaver-builder-lite-version/fl-builder.php',
242
+ 'status' => self::get_plugin_status( 'beaver-builder-lite-version/fl-builder.php' ),
243
+ );
244
+ }
245
+
246
+ if ( file_exists( WP_PLUGIN_DIR . '/bb-ultimate-addon/bb-ultimate-addon.php' ) && ! is_plugin_active( 'ultimate-addons-for-beaver-builder-lite/bb-ultimate-addon.php' ) ) {
247
+ $plugins['beaver-builder']['plugins'][] = array(
248
+ 'slug' => 'bb-ultimate-addon',
249
+ 'init' => 'bb-ultimate-addon/bb-ultimate-addon.php',
250
+ 'status' => self::get_plugin_status( 'bb-ultimate-addon/bb-ultimate-addon.php' ),
251
+ );
252
+ } else {
253
+ $plugins['beaver-builder']['plugins'][] = array(
254
+ 'slug' => 'ultimate-addons-for-beaver-builder-lite', // For download from wp.org.
255
+ 'init' => 'ultimate-addons-for-beaver-builder-lite/bb-ultimate-addon.php',
256
+ 'status' => self::get_plugin_status( 'ultimate-addons-for-beaver-builder-lite/bb-ultimate-addon.php' ),
257
+ );
258
+ }
259
+
260
+ return $plugins;
261
+ }
262
+
263
+ /**
264
+ * Get plugin status
265
+ *
266
+ * @since 1.1.4
267
+ *
268
+ * @param string $plugin_init_file Plguin init file.
269
+ * @return mixed
270
+ */
271
+ public static function get_plugin_status( $plugin_init_file ) {
272
+
273
+ if ( null == self::$installed_plugins ) {
274
+ self::$installed_plugins = get_plugins();
275
+ }
276
+
277
+ if ( ! isset( self::$installed_plugins[ $plugin_init_file ] ) ) {
278
+ return 'install';
279
+ } elseif ( ! is_plugin_active( $plugin_init_file ) ) {
280
+ return 'activate';
281
+ } else {
282
+ return;
283
+ }
284
+ }
285
+
286
+ /**
287
+ * Get zapier settings.
288
+ *
289
+ * @return array.
290
+ */
291
+ public static function get_common_settings() {
292
+
293
+ if ( null === self::$common ) {
294
+
295
+ $common_default = apply_filters(
296
+ 'cartflows_common_settings_default',
297
+ array(
298
+ 'disallow_indexing' => 'disable',
299
+ 'global_checkout' => '',
300
+ 'default_page_builder' => 'elementor',
301
+ )
302
+ );
303
+
304
+ $common = self::get_admin_settings_option( '_cartflows_common', false, false );
305
+
306
+ $common = wp_parse_args( $common, $common_default );
307
+
308
+ if ( ! did_action( 'wp' ) ) {
309
+ return $common;
310
+ } else {
311
+ self::$common = $common;
312
+ }
313
+ }
314
+
315
+ return self::$common;
316
+ }
317
+
318
+ /**
319
+ * Get debug settings data.
320
+ *
321
+ * @return array.
322
+ */
323
+ public static function get_debug_settings() {
324
+
325
+ if ( null === self::$debug_data ) {
326
+
327
+ $debug_data_default = apply_filters(
328
+ 'cartflows_debug_settings_default',
329
+ array(
330
+ 'allow_minified_files' => 'disable',
331
+ )
332
+ );
333
+
334
+ $debug_data = self::get_admin_settings_option( '_cartflows_debug_data', false, false );
335
+
336
+ $debug_data = wp_parse_args( $debug_data, $debug_data_default );
337
+
338
+ if ( ! did_action( 'wp' ) ) {
339
+ return $debug_data;
340
+ } else {
341
+ self::$debug_data = $debug_data;
342
+ }
343
+ }
344
+
345
+ return self::$debug_data;
346
+ }
347
+
348
+
349
+ /**
350
+ * Get debug settings data.
351
+ *
352
+ * @return array.
353
+ */
354
+ public static function get_permalink_settings() {
355
+
356
+ if ( null === self::$permalink_setting ) {
357
+
358
+ $permalink_default = apply_filters(
359
+ 'cartflows_permalink_settings_default',
360
+ array(
361
+ 'permalink' => CARTFLOWS_STEP_POST_TYPE,
362
+ 'permalink_flow_base' => CARTFLOWS_FLOW_POST_TYPE,
363
+ 'permalink_structure' => '',
364
+
365
+ )
366
+ );
367
+
368
+ $permalink_data = self::get_admin_settings_option( '_cartflows_permalink', false, false );
369
+
370
+ $permalink_data = wp_parse_args( $permalink_data, $permalink_default );
371
+
372
+ if ( ! did_action( 'wp' ) ) {
373
+ return $permalink_data;
374
+ } else {
375
+ self::$permalink_setting = $permalink_data;
376
+ }
377
+ }
378
+
379
+ return self::$permalink_setting;
380
+ }
381
+
382
+
383
+ /**
384
+ * Get debug settings data.
385
+ *
386
+ * @return array.
387
+ */
388
+ public static function get_google_analytics_settings() {
389
+
390
+ if ( null === self::$google_analytics_settings ) {
391
+
392
+ $google_analytics_settings_default = apply_filters(
393
+ 'cartflows_google_analytics_settings_default',
394
+ array(
395
+ 'enable_google_analytics' => 'disable',
396
+ 'enable_google_analytics_for_site' => 'disable',
397
+ 'google_analytics_id' => '',
398
+ 'enable_begin_checkout' => 'disable',
399
+ 'enable_add_to_cart' => 'disable',
400
+ 'enable_add_payment_info' => 'disable',
401
+ 'enable_purchase_event' => 'disable',
402
+ )
403
+ );
404
+
405
+ $google_analytics_settings_data = self::get_admin_settings_option( '_cartflows_google_analytics', false, true );
406
+
407
+ $google_analytics_settings_data = wp_parse_args( $google_analytics_settings_data, $google_analytics_settings_default );
408
+
409
+ if ( ! did_action( 'wp' ) ) {
410
+ return $google_analytics_settings_data;
411
+ } else {
412
+ self::$google_analytics_settings = $google_analytics_settings_data;
413
+ }
414
+ }
415
+
416
+ return self::$google_analytics_settings = $google_analytics_settings_data; //phpcs:ignore
417
+ }
418
+
419
+ /**
420
+ * Get Checkout field.
421
+ *
422
+ * @param string $key Field key.
423
+ * @param int $post_id Post id.
424
+ * @return array.
425
+ */
426
+ public static function get_checkout_fields( $key, $post_id ) {
427
+
428
+ $saved_fields = get_post_meta( $post_id, 'wcf_fields_' . $key, true );
429
+
430
+ if ( ! $saved_fields ) {
431
+ $saved_fields = array();
432
+ }
433
+
434
+ $fields = array_filter( $saved_fields );
435
+
436
+ if ( empty( $fields ) ) {
437
+ if ( 'billing' === $key || 'shipping' === $key ) {
438
+
439
+ $fields = WC()->countries->get_address_fields( WC()->countries->get_base_country(), $key . '_' );
440
+
441
+ update_post_meta( $post_id, 'wcf_fields_' . $key, $fields );
442
+ }
443
+ }
444
+
445
+ return $fields;
446
+ }
447
+
448
+ /**
449
+ * Add Checkout field.
450
+ *
451
+ * @param string $type Field type.
452
+ * @param string $field_key Field key.
453
+ * @param array $field_data Field data.
454
+ * @param int $post_id Post id.
455
+ * @return boolean.
456
+ */
457
+ public static function add_checkout_field( $type, $field_key, $field_data = array(), $post_id ) {
458
+
459
+ $fields = self::get_checkout_fields( $type, $post_id );
460
+
461
+ $fields[ $field_key ] = $field_data;
462
+
463
+ update_post_meta( $post_id, 'wcf_fields_' . $type, $fields );
464
+
465
+ return true;
466
+ }
467
+
468
+ /**
469
+ * Get checkout fields settings.
470
+ *
471
+ * @param string $type Field type.
472
+ * @param string $field_key Field key.
473
+ * @param int $post_id Post id.
474
+ * @return array.
475
+ */
476
+ public static function delete_checkout_field( $type, $field_key, $post_id ) {
477
+
478
+ $fields = self::get_checkout_fields( $type, $post_id );
479
+
480
+ if ( isset( $fields[ $field_key ] ) ) {
481
+ unset( $fields[ $field_key ] );
482
+ }
483
+
484
+ update_post_meta( $post_id, 'wcf_fields_' . $type, $fields );
485
+
486
+ return true;
487
+ }
488
+
489
+ /**
490
+ * Get checkout fields settings.
491
+ *
492
+ * @return array.
493
+ */
494
+ public static function get_checkout_fields_settings() {
495
+
496
+ if ( null === self::$checkout_fields ) {
497
+ $checkout_fields_default = array(
498
+ 'enable_customization' => 'disable',
499
+ 'enable_billing_fields' => 'disable',
500
+ );
501
+
502
+ $billing_fields = self::get_checkout_fields( 'billing' );
503
+
504
+ if ( is_array( $billing_fields ) && ! empty( $billing_fields ) ) {
505
+
506
+ foreach ( $billing_fields as $key => $value ) {
507
+
508
+ $checkout_fields_default[ $key ] = 'enable';
509
+ }
510
+ }
511
+
512
+ $checkout_fields = self::get_admin_settings_option( '_wcf_checkout_fields', false, false );
513
+
514
+ self::$checkout_fields = wp_parse_args( $checkout_fields, $checkout_fields_default );
515
+ }
516
+
517
+ return self::$checkout_fields;
518
+ }
519
+
520
+ /**
521
+ * Get meta options
522
+ *
523
+ * @since 1.0.0
524
+ * @param int $post_id Product ID.
525
+ * @param string $key Meta Key.
526
+ * @param string $default Default value.
527
+ * @return string Meta Value.
528
+ */
529
+ public static function get_meta_option( $post_id, $key, $default = '' ) {
530
+
531
+ $value = get_post_meta( $post_id, $key, true );
532
+
533
+ if ( ! $value ) {
534
+ $value = $default;
535
+ }
536
+
537
+ return $value;
538
+ }
539
+
540
+ /**
541
+ * Save meta option
542
+ *
543
+ * @since 1.0.0
544
+ * @param int $post_id Product ID.
545
+ * @param array $args Arguments array.
546
+ */
547
+ public static function save_meta_option( $post_id, $args = array() ) {
548
+
549
+ if ( is_array( $args ) && ! empty( $args ) ) {
550
+
551
+ foreach ( $args as $key => $value ) {
552
+
553
+ update_post_meta( $post_id, $key, $value );
554
+ }
555
+ }
556
+ }
557
+
558
+ /**
559
+ * Check if Elementor page builder is installed
560
+ *
561
+ * @since 1.0.0
562
+ *
563
+ * @access public
564
+ */
565
+ public static function is_elementor_installed() {
566
+ $path = 'elementor/elementor.php';
567
+ $plugins = get_plugins();
568
+
569
+ return isset( $plugins[ $path ] );
570
+ }
571
+
572
+ /**
573
+ * Check if Step has product assigned.
574
+ *
575
+ * @since 1.0.0
576
+ * @param int $step_id step ID.
577
+ *
578
+ * @access public
579
+ */
580
+ public static function has_product_assigned( $step_id ) {
581
+
582
+ $step_type = get_post_meta( $step_id, 'wcf-step-type', true );
583
+
584
+ if ( 'checkout' == $step_type ) {
585
+ $product = get_post_meta( $step_id, 'wcf-checkout-products', true );
586
+ } else {
587
+ $product = get_post_meta( $step_id, 'wcf-offer-product', true );
588
+ }
589
+
590
+ if ( ! empty( $product ) ) {
591
+ return true;
592
+ }
593
+ return false;
594
+
595
+ }
596
+
597
+ /**
598
+ * Get attributes for cartflows wrap.
599
+ *
600
+ * @since 1.1.4
601
+ *
602
+ * @access public
603
+ */
604
+ public static function get_cartflows_container_atts() {
605
+
606
+ $attributes = apply_filters( 'cartflows_container_atts', array() );
607
+ $atts_string = '';
608
+
609
+ foreach ( $attributes as $key => $value ) {
610
+
611
+ if ( ! $value ) {
612
+ continue;
613
+ }
614
+
615
+ if ( true === $value ) {
616
+ $atts_string .= esc_html( $key ) . ' ';
617
+ } else {
618
+ $atts_string .= sprintf( '%s="%s" ', esc_html( $key ), esc_attr( $value ) );
619
+ }
620
+ }
621
+
622
+ return $atts_string;
623
+ }
624
+
625
+ /**
626
+ * Get facebook pixel settings.
627
+ *
628
+ * @return facebook array.
629
+ */
630
+ public static function get_facebook_settings() {
631
+
632
+ if ( null === self::$facebook ) {
633
+
634
+ $facebook_default = array(
635
+ 'facebook_pixel_id' => '',
636
+ 'facebook_pixel_add_to_cart' => 'enable',
637
+ 'facebook_pixel_initiate_checkout' => 'enable',
638
+ 'facebook_pixel_add_payment_info' => 'enable',
639
+ 'facebook_pixel_purchase_complete' => 'enable',
640
+ 'facebook_pixel_tracking' => 'disable',
641
+ 'facebook_pixel_tracking_for_site' => 'disable',
642
+ );
643
+
644
+ $facebook = self::get_admin_settings_option( '_cartflows_facebook', false, false );
645
+
646
+ $facebook = wp_parse_args( $facebook, $facebook_default );
647
+
648
+ self::$facebook = apply_filters( 'cartflows_facebook_settings_default', $facebook );
649
+
650
+ }
651
+
652
+ return self::$facebook;
653
+ }
654
+
655
+
656
+ /**
657
+ * Prepare response data for facebook.
658
+ *
659
+ * @param int $order_id order_id.
660
+ * @param array $offer_data offer data.
661
+ */
662
+ public static function send_fb_response_if_enabled( $order_id, $offer_data = array() ) {
663
+
664
+ // Stop Execution if WooCommerce is not installed & don't set the cookie.
665
+ if ( ! Cartflows_Loader::get_instance()->is_woo_active ) {
666
+ return;
667
+ }
668
+
669
+ $fb_settings = self::get_facebook_settings();
670
+ if ( 'enable' === $fb_settings['facebook_pixel_tracking'] ) {
671
+ setcookie( 'wcf_order_details', wp_json_encode( self::prepare_purchase_data_fb_response( $order_id, $offer_data ) ), strtotime( '+1 year' ), '/' );
672
+ }
673
+
674
+ }
675
+
676
+ /**
677
+ * Prepare purchase response for facebook purcase event.
678
+ *
679
+ * @param integer $order_id order id.
680
+ * @param array $offer_data offer data.
681
+ * @return mixed
682
+ */
683
+ public static function prepare_purchase_data_fb_response( $order_id, $offer_data = array() ) {
684
+
685
+ $thankyou = array();
686
+
687
+ if ( ! Cartflows_Loader::get_instance()->is_woo_active ) {
688
+ return $thankyou;
689
+ }
690
+
691
+ $thankyou['order_id'] = $order_id;
692
+ $thankyou['content_type'] = 'product';
693
+ $thankyou['currency'] = wcf()->options->get_checkout_meta_value( $order_id, '_order_currency' );
694
+ $thankyou['userAgent'] = wcf()->options->get_checkout_meta_value( $order_id, '_customer_user_agent' );
695
+ $thankyou['plugin'] = 'CartFlows';
696
+ $order = wc_get_order( $order_id );
697
+ if ( empty( $offer_data ) ) {
698
+ // Iterating through each WC_Order_Item_Product objects.
699
+ foreach ( $order->get_items() as $item_key => $item ) {
700
+ $product = $item->get_product(); // Get the WC_Product object.
701
+ $thankyou['content_ids'][] = (string) $product->get_id();
702
+ }
703
+ $thankyou['value'] = wcf()->options->get_checkout_meta_value( $order_id, '_order_total' );
704
+ } else {
705
+ $thankyou['content_ids'][] = (string) $offer_data['id'];
706
+ $thankyou['value'] = $offer_data['total'];
707
+ }
708
+
709
+ return $thankyou;
710
+ }
711
+
712
+ /**
713
+ * Prepare cart data for fb response.
714
+ *
715
+ * @return array
716
+ */
717
+ public static function prepare_cart_data_fb_response() {
718
+
719
+ $params = array();
720
+
721
+ if ( ! Cartflows_Loader::get_instance()->is_woo_active ) {
722
+ return $params;
723
+ }
724
+
725
+ $cart_total = WC()->cart->get_cart_contents_total();
726
+ $cart_items_count = WC()->cart->get_cart_contents_count();
727
+ $items = WC()->cart->get_cart();
728
+ $product_names = '';
729
+ $category_names = '';
730
+ $cart_contents = array();
731
+ foreach ( $items as $item => $value ) {
732
+
733
+ $_product = wc_get_product( $value['product_id'] );
734
+ $params['content_ids'][] = (string) $_product->get_id();
735
+ $product_names = $product_names . ', ' . $_product->get_title();
736
+ $category_names = $category_names . ', ' . wp_strip_all_tags( wc_get_product_category_list( $_product->get_id() ) );
737
+ array_push(
738
+ $cart_contents,
739
+ array(
740
+ 'id' => $_product->get_id(),
741
+ 'name' => $_product->get_title(),
742
+ 'quantity' => $value['quantity'],
743
+ 'item_price' => $_product->get_price(),
744
+ )
745
+ );
746
+ }
747
+
748
+ $user = wp_get_current_user();
749
+ $roles = implode( ', ', $user->roles );
750
+ $params['content_name'] = substr( $product_names, 2 );
751
+ $params['categoey_name'] = substr( $category_names, 2 );
752
+ $params['user_roles'] = $roles;
753
+ $params['plugin'] = 'CartFlows';
754
+ $params['contents'] = wp_json_encode( $cart_contents );
755
+ $params['content_type'] = 'product';
756
+ $params['value'] = $cart_total;
757
+ $params['num_items'] = $cart_items_count;
758
+ $params['currency'] = get_woocommerce_currency();
759
+ $params['language'] = get_bloginfo( 'language' );
760
+ $params['userAgent'] = wp_unslash( $_SERVER['HTTP_USER_AGENT'] ); //phpcs:ignore
761
+ $params['product_catalog_id'] = '';
762
+ $params['domain'] = get_site_url();
763
+ return $params;
764
+ }
765
+
766
+ /**
767
+ * Get the image url of size.
768
+ *
769
+ * @param int $post_id post id.
770
+ * @param array $key key.
771
+ * @param string $size image size.
772
+ *
773
+ * @return array
774
+ */
775
+ public static function get_image_url( $post_id, $key, $size = false ) {
776
+
777
+ $url = get_post_meta( $post_id, $key, true );
778
+ $img_obj = get_post_meta( $post_id, $key . '-obj', true );
779
+ if ( is_array( $img_obj ) && ! empty( $img_obj ) && false !== $size ) {
780
+
781
+ $url = ! empty( $img_obj['url'][ $size ] ) ? $img_obj['url'][ $size ] : $url;
782
+ }
783
+
784
+ return $url;
785
+ }
786
+
787
+ }
classes/class-cartflows-importer.php CHANGED
@@ -1,1692 +1,1739 @@
1
- <?php
2
- /**
3
- * CartFlows Admin
4
- *
5
- * @package CartFlows
6
- * @since 1.0.0
7
- */
8
-
9
- if ( ! class_exists( 'CartFlows_Importer' ) ) :
10
-
11
- /**
12
- * CartFlows Import
13
- *
14
- * @since 1.0.0
15
- */
16
- class CartFlows_Importer {
17
-
18
- /**
19
- * Instance
20
- *
21
- * @since 1.0.0
22
- * @access private
23
- * @var object Class object.
24
- */
25
- private static $instance;
26
-
27
- /**
28
- * Initiator
29
- *
30
- * @since 1.0.0
31
- * @return object initialized object of class.
32
- */
33
- public static function get_instance() {
34
- if ( ! isset( self::$instance ) ) {
35
- self::$instance = new self();
36
- }
37
-
38
- return self::$instance;
39
- }
40
-
41
- /**
42
- * Constructor
43
- *
44
- * @since 1.0.0
45
- */
46
- public function __construct() {
47
- add_action( 'admin_enqueue_scripts', array( $this, 'scripts' ) );
48
-
49
- add_action( 'wp_ajax_cartflows_step_import', array( $this, 'import_step' ) );
50
- add_action( 'wp_ajax_cartflows_create_flow', array( $this, 'create_flow' ) );
51
- add_action( 'wp_ajax_cartflows_import_flow_step', array( $this, 'import_flow' ) );
52
- add_action( 'wp_ajax_cartflows_default_flow', array( $this, 'create_default_flow' ) );
53
- add_action( 'wp_ajax_cartflows_step_create_blank', array( $this, 'step_create_blank' ) );
54
-
55
- add_action( 'admin_footer', array( $this, 'js_templates' ) );
56
- add_action( 'cartflows_import_complete', array( $this, 'clear_cache' ) );
57
-
58
- add_filter( 'cartflows_admin_js_localize', array( $this, 'localize_vars' ) );
59
-
60
- add_action( 'wp_ajax_cartflows_activate_plugin', array( $this, 'activate_plugin' ) );
61
-
62
- add_action( 'admin_menu', array( $this, 'add_to_menus' ) );
63
- add_action( 'admin_init', array( $this, 'export_json' ) );
64
- add_action( 'admin_init', array( $this, 'import_json' ) );
65
- add_filter( 'post_row_actions', array( $this, 'export_link' ), 10, 2 );
66
- add_action( 'admin_action_cartflows_export_flow', array( $this, 'export_flow' ) );
67
- }
68
-
69
- /**
70
- * Add the export link to action list for flows row actions
71
- *
72
- * @since 1.1.4
73
- *
74
- * @param array $actions Actions array.
75
- * @param object $post Post object.
76
- *
77
- * @return array
78
- */
79
- public function export_link( $actions, $post ) {
80
- if ( current_user_can( 'edit_posts' ) && isset( $post ) && CARTFLOWS_FLOW_POST_TYPE === $post->post_type ) {
81
- $actions['export'] = '<a href="' . wp_nonce_url( 'admin.php?action=cartflows_export_flow&post=' . $post->ID, basename( __FILE__ ), 'flow_export_nonce' ) . '" title="' . __( 'Export this flow', 'cartflows' ) . '" rel="permalink">' . __( 'Export', 'cartflows' ) . '</a>';
82
- }
83
- return $actions;
84
- }
85
-
86
- /**
87
- * Add menus
88
- *
89
- * @since 1.1.4
90
- */
91
- public function add_to_menus() {
92
- add_submenu_page( 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE, __( 'Flow Export', 'cartflows' ), __( 'Flow Export', 'cartflows' ), 'export', 'flow_exporter', array( $this, 'exporter_markup' ) );
93
- add_submenu_page( 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE, __( 'Flow Import', 'cartflows' ), __( 'Flow Import', 'cartflows' ), 'import', 'flow_importer', array( $this, 'importer_markup' ) );
94
- }
95
-
96
- /**
97
- * Export flow with steps and its meta
98
- *
99
- * @since 1.1.4
100
- */
101
- public function export_flow() {
102
-
103
- if ( ! ( isset( $_GET['post'] ) || isset( $_POST['post'] ) || ( isset( $_REQUEST['action'] ) && 'cartflows_export_flow' == $_REQUEST['action'] ) ) ) {
104
- wp_die( esc_html__( 'No post to export has been supplied!', 'cartflows' ) );
105
- }
106
-
107
- if ( ! isset( $_GET['flow_export_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['flow_export_nonce'] ) ), basename( __FILE__ ) ) ) {
108
- return;
109
- }
110
-
111
- // Get the original post id.
112
- $flow_id = ( isset( $_GET['post'] ) ? absint( $_GET['post'] ) : absint( $_POST['post'] ) );
113
-
114
- $flows = array();
115
- $flows[] = $this->get_flow_export_data( $flow_id );
116
- $flows = apply_filters( 'cartflows_export_data', $flows );
117
-
118
- nocache_headers();
119
- header( 'Content-Type: application/json; charset=utf-8' );
120
- header( 'Content-Disposition: attachment; filename=cartflows-flow-' . $flow_id . '-' . gmdate( 'm-d-Y' ) . '.json' );
121
- header( 'Expires: 0' );
122
-
123
- echo wp_json_encode( $flows );
124
- exit;
125
- }
126
-
127
- /**
128
- * Export flow markup
129
- *
130
- * @since 1.1.4
131
- */
132
- public function exporter_markup() {
133
- include_once CARTFLOWS_DIR . 'includes/exporter.php';
134
- }
135
-
136
- /**
137
- * Import flow markup
138
- *
139
- * @since 1.1.4
140
- */
141
- public function importer_markup() {
142
- include_once CARTFLOWS_DIR . 'includes/importer.php';
143
- }
144
-
145
- /**
146
- * Export flow
147
- *
148
- * @since 1.1.4
149
- */
150
- public function export_json() {
151
- if ( empty( $_POST['cartflows-action'] ) || 'export' != $_POST['cartflows-action'] ) {
152
- return;
153
- }
154
-
155
- if ( isset( $_POST['cartflows-action-nonce'] ) && ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['cartflows-action-nonce'] ) ), 'cartflows-action-nonce' ) ) {
156
- return;
157
- }
158
-
159
- if ( ! current_user_can( 'manage_options' ) ) {
160
- return;
161
- }
162
-
163
- $flows = $this->get_all_flow_export_data();
164
- $flows = apply_filters( 'cartflows_export_data', $flows );
165
-
166
- nocache_headers();
167
- header( 'Content-Type: application/json; charset=utf-8' );
168
- header( 'Content-Disposition: attachment; filename=cartflows-flow-export-' . gmdate( 'm-d-Y' ) . '.json' );
169
- header( 'Expires: 0' );
170
-
171
- echo wp_json_encode( $flows );
172
- exit;
173
- }
174
-
175
- /**
176
- * Get flow export data
177
- *
178
- * @since 1.1.4
179
- *
180
- * @param integer $flow_id Flow ID.
181
- * @return array
182
- */
183
- public function get_flow_export_data( $flow_id ) {
184
-
185
- $export_all = apply_filters( 'cartflows_export_all', false );
186
-
187
- $valid_step_meta_keys = array(
188
- '_wp_page_template',
189
- '_thumbnail_id',
190
- 'classic-editor-remember',
191
- );
192
-
193
- $new_steps = array();
194
- $steps = get_post_meta( $flow_id, 'wcf-steps', true );
195
- if ( $steps ) {
196
- foreach ( $steps as $key => $step ) {
197
-
198
- // Add step post meta.
199
- $new_all_meta = array();
200
- $all_meta = get_post_meta( $step['id'] );
201
- if ( is_array( $all_meta ) ) {
202
-
203
- if ( $export_all ) {
204
- foreach ( $all_meta as $meta_key => $value ) {
205
- $new_all_meta[ $meta_key ] = maybe_unserialize( $value[0] );
206
- }
207
- } else {
208
-
209
- foreach ( $all_meta as $meta_key => $value ) {
210
- if ( substr( $meta_key, 0, strlen( 'wcf' ) ) === 'wcf' ) {
211
- $new_all_meta[ $meta_key ] = maybe_unserialize( $value[0] );
212
- } elseif ( in_array( $meta_key, $valid_step_meta_keys, true ) ) {
213
- $new_all_meta[ $meta_key ] = maybe_unserialize( $value[0] );
214
- }
215
- }
216
- }
217
- }
218
-
219
- // Add single step.
220
- $step_data_arr = array(
221
- 'title' => get_the_title( $step['id'] ),
222
- 'type' => $step['type'],
223
- 'meta' => $new_all_meta,
224
- 'post_content' => '',
225
- );
226
-
227
- if ( $export_all ) {
228
-
229
- $step_post_obj = get_post( $step['id'] );
230
-
231
- $step_data_arr['post_content'] = $step_post_obj->post_content;
232
- }
233
-
234
- $new_steps[] = $step_data_arr;
235
- }
236
- }
237
-
238
- // Add single flow.
239
- return array(
240
- 'title' => get_the_title( $flow_id ),
241
- 'steps' => $new_steps,
242
- );
243
- }
244
-
245
- /**
246
- * Get all flow export data
247
- *
248
- * @since 1.1.4
249
- */
250
- public function get_all_flow_export_data() {
251
-
252
- $query_args = array(
253
- 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
254
-
255
- // Query performance optimization.
256
- 'fields' => 'ids',
257
- 'no_found_rows' => true,
258
- 'posts_per_page' => -1,
259
- );
260
-
261
- $query = new WP_Query( $query_args );
262
- $flows = array();
263
- if ( $query->posts ) {
264
- foreach ( $query->posts as $key => $post_id ) {
265
- $flows[] = $this->get_flow_export_data( $post_id );
266
- }
267
- }
268
-
269
- return $flows;
270
- }
271
-
272
- /**
273
- * Import our exported file
274
- *
275
- * @since 1.1.4
276
- */
277
- public function import_json() {
278
- if ( empty( $_POST['cartflows-action'] ) || 'import' != $_POST['cartflows-action'] ) {
279
- return;
280
- }
281
-
282
- if ( isset( $_POST['cartflows-action-nonce'] ) && ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['cartflows-action-nonce'] ) ), 'cartflows-action-nonce' ) ) {
283
- return;
284
- }
285
-
286
- if ( ! current_user_can( 'manage_options' ) ) {
287
- return;
288
- }
289
-
290
- $filename = $_FILES['file']['name']; //phpcs:ignore
291
- $file_info = explode( '.', $filename );
292
- $extension = end( $file_info );
293
-
294
- if ( 'json' != $extension ) {
295
- wp_die( esc_html__( 'Please upload a valid .json file', 'cartflows' ) );
296
- }
297
-
298
- $file = $_FILES['file']['tmp_name']; //phpcs:ignore
299
-
300
- if ( empty( $file ) ) {
301
- wp_die( esc_html__( 'Please upload a file to import', 'cartflows' ) );
302
- }
303
-
304
- // Retrieve the settings from the file and convert the JSON object to an array.
305
- $flows = json_decode( file_get_contents( $file ), true );//phpcs:ignore
306
-
307
- $this->import_from_json_data( $flows );
308
-
309
- add_action( 'admin_notices', array( $this, 'imported_successfully' ) );
310
- }
311
-
312
- /**
313
- * Import flow from the JSON data
314
- *
315
- * @since x.x.x
316
- * @param array $flows JSON array.
317
- * @return void
318
- */
319
- public function import_from_json_data( $flows ) {
320
- if ( $flows ) {
321
-
322
- foreach ( $flows as $key => $flow ) {
323
-
324
- $flow_title = $flow['title'];
325
- if ( post_exists( $flow['title'] ) ) {
326
- $flow_title = $flow['title'] . ' Copy';
327
- }
328
-
329
- // Create post object.
330
- $new_flow_args = apply_filters(
331
- 'cartflows_flow_importer_args',
332
- array(
333
- 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
334
- 'post_title' => $flow_title,
335
- 'post_status' => 'draft',
336
- )
337
- );
338
-
339
- // Insert the post into the database.
340
- $flow_id = wp_insert_post( $new_flow_args );
341
-
342
- /**
343
- * Fire after flow import
344
- *
345
- * @since x.x.x
346
- * @param int $flow_id Flow ID.
347
- * @param array $new_flow_args Flow post args.
348
- * @param array $flows Flow JSON data.
349
- */
350
- do_action( 'cartflows_flow_imported', $flow_id, $new_flow_args, $flows );
351
-
352
- if ( $flow['steps'] ) {
353
- foreach ( $flow['steps'] as $key => $step ) {
354
-
355
- $new_step_args = apply_filters(
356
- 'cartflows_step_importer_args',
357
- array(
358
- 'post_type' => CARTFLOWS_STEP_POST_TYPE,
359
- 'post_title' => $step['title'],
360
- 'post_status' => 'publish',
361
- 'meta_input' => $step['meta'],
362
- 'post_content' => isset( $step['post_content'] ) ? $step['post_content'] : '',
363
- )
364
- );
365
-
366
- $new_step_id = wp_insert_post( $new_step_args );
367
-
368
- /**
369
- * Fire after step import
370
- *
371
- * @since x.x.x
372
- * @param int $new_step_id step ID.
373
- * @param int $flow_id flow ID.
374
- * @param array $new_step_args Step post args.
375
- * @param array $flow_steps Flow steps.
376
- * @param array $flows All flows JSON data.
377
- */
378
- do_action( 'cartflows_step_imported', $new_step_id, $flow_id, $new_step_args, $flow['steps'], $flows );
379
-
380
- // Insert post meta.
381
- update_post_meta( $new_step_id, 'wcf-flow-id', $flow_id );
382
-
383
- $step_taxonomy = CARTFLOWS_TAXONOMY_STEP_TYPE;
384
- $current_term = term_exists( $step['type'], $step_taxonomy );
385
-
386
- // // Set type object.
387
- $data = get_term( $current_term['term_id'], $step_taxonomy );
388
- $step_slug = $data->slug;
389
- wp_set_object_terms( $new_step_id, $data->slug, $step_taxonomy );
390
-
391
- // Set type.
392
- update_post_meta( $new_step_id, 'wcf-step-type', $data->slug );
393
-
394
- // Set flow.
395
- wp_set_object_terms( $new_step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
396
-
397
- self::get_instance()->set_step_to_flow( $flow_id, $new_step_id, $step['title'], $step_slug );
398
-
399
- if ( isset( $step['post_content'] ) && ! empty( $step['post_content'] ) ) {
400
-
401
- // Download and replace images.
402
- $content = $this->get_content( $step['post_content'] );
403
-
404
- // Update post content.
405
- wp_update_post(
406
- array(
407
- 'ID' => $new_step_id,
408
- 'post_content' => $content,
409
- )
410
- );
411
- }
412
- }
413
- }
414
- }
415
- }
416
- }
417
-
418
- /**
419
- * Download and Replace hotlink images
420
- *
421
- * @since x.x.x
422
- *
423
- * @param string $content Mixed post content.
424
- * @return array Hotlink image array.
425
- */
426
- public function get_content( $content = '' ) {
427
-
428
- $all_links = wp_extract_urls( $content );
429
- $image_links = array();
430
- $image_map = array();
431
-
432
- // Not have any link.
433
- if ( empty( $all_links ) ) {
434
- return $content;
435
- }
436
-
437
- foreach ( $all_links as $key => $link ) {
438
- if ( preg_match( '/\.(jpg|jpeg|png|gif)/i', $link ) ) {
439
- $image_links[] = $link;
440
- }
441
- }
442
-
443
- // Not have any image link.
444
- if ( empty( $image_links ) ) {
445
- return $content;
446
- }
447
-
448
- foreach ( $image_links as $key => $image_url ) {
449
-
450
- // Download remote image.
451
- $image = array(
452
- 'url' => $image_url,
453
- 'id' => wp_rand( 000, 999 ),
454
- );
455
- $downloaded_image = CartFlows_Import_Image::get_instance()->import( $image );
456
-
457
- // Old and New image mapping links.
458
- $image_map[ $image_url ] = $downloaded_image['url'];
459
- }
460
-
461
- // Replace old image links with new image links.
462
- foreach ( $image_map as $old_url => $new_url ) {
463
- $content = str_replace( $old_url, $new_url, $content );
464
- }
465
-
466
- return $content;
467
-
468
- }
469
-
470
- /**
471
- * Imported notice
472
- *
473
- * @since 1.1.4
474
- */
475
- public function imported_successfully() {
476
- ?>
477
- <div class="notice notice-success">
478
- <p><?php esc_html_e( 'Successfully imported flows.', 'cartflows' ); ?></p>
479
- </div>
480
- <?php
481
- }
482
-
483
- /**
484
- * Clear Cache.
485
- *
486
- * @since 1.0.0
487
- */
488
- public function clear_cache() {
489
- // Clear 'Elementor' file cache.
490
- if ( class_exists( '\Elementor\Plugin' ) ) {
491
- Elementor\Plugin::$instance->files_manager->clear_cache();
492
- }
493
- }
494
-
495
- /**
496
- * JS Templates
497
- *
498
- * @since 1.0.0
499
- *
500
- * @return void
501
- */
502
- public function js_templates() {
503
-
504
- // Loading Templates.
505
- ?>
506
- <script type="text/template" id="tmpl-cartflows-step-loading">
507
- <div class="template-message-block cartflows-step-loading">
508
- <h2>
509
- <span class="spinner"></span>
510
- <?php esc_html_e( 'Loading Steps', 'cartflows' ); ?>
511
- </h2>
512
- <p class="description"><?php esc_html_e( 'Getting steps from the cloud. Please wait for the moment.', 'cartflows' ); ?></p>
513
- </div>
514
- </script>
515
-
516
- <?php
517
- // Search Templates.
518
- ?>
519
- <script type="text/template" id="tmpl-cartflows-searching-templates">
520
- <div class="template-message-block cartflows-searching-templates">
521
- <h2>
522
- <span class="spinner"></span>
523
- <?php esc_html_e( 'Searching Template..', 'cartflows' ); ?>
524
- </h2>
525
- <p class="description"><?php esc_html_e( 'Getting templates from the cloud. Please wait for the moment.', 'cartflows' ); ?></p>
526
- </div>
527
- </script>
528
-
529
- <?php
530
- // CartFlows Importing Template.
531
- ?>
532
- <script type="text/template" id="tmpl-cartflows-step-importing">
533
- <div class="template-message-block cartflows-step-importing">
534
- <h2><span class="spinner"></span> <?php esc_html_e( 'Importing..', 'cartflows' ); ?></h2>
535
- </div>
536
- </script>
537
-
538
- <?php
539
- // CartFlows Imported.
540
- ?>
541
- <script type="text/template" id="tmpl-cartflows-step-imported">
542
- <div class="template-message-block cartflows-step-imported">
543
- <h2><span class="dashicons dashicons-yes"></span> <?php esc_html_e( 'Imported', 'cartflows' ); ?></h2>
544
- <p class="description"><?php esc_html_e( 'Thanks for patience', 'cartflows' ); ?> <span class="dashicons dashicons-smiley"></span></p></div>
545
- </script>
546
-
547
- <?php
548
- // No templates.
549
- ?>
550
- <script type="text/template" id="tmpl-cartflows-no-steps">
551
- <div class="cartflows-no-steps">
552
- <div class="template-message-block">
553
- <h2><?php esc_html_e( 'Coming Soon!', 'cartflows' ); ?></h2>
554
- <p class="description"></p>
555
- </div>
556
- </div>
557
- </script>
558
-
559
- <?php
560
- // No templates.
561
- ?>
562
- <script type="text/template" id="tmpl-cartflows-no-flows">
563
- <div class="cartflows-no-flows">
564
- <div class="template-message-block">
565
- <h2><?php esc_html_e( 'Coming Soon!', 'cartflows' ); ?></h2>
566
- <p class="description"></p>
567
- </div>
568
- </div>
569
- </script>
570
-
571
- <?php
572
- // Error handling.
573
- ?>
574
- <script type="text/template" id="tmpl-templator-error">
575
- <div class="notice notice-error"><p>{{ data }}</p></div>
576
- </script>
577
-
578
- <?php
579
- // Redirect to Elementor.
580
- ?>
581
- <script type="text/template" id="tmpl-templator-redirect-to-elementor">
582
- <div class="template-message-block templator-redirect-to-elementor">
583
- <h2><span class="dashicons dashicons-yes"></span> <?php esc_html_e( 'Imported', 'cartflows' ); ?></h2>
584
- <p class="description"><?php esc_html_e( 'Thanks for patience', 'cartflows' ); ?> <span class="dashicons dashicons-smiley"></span><br/><br/><?php esc_html_e( 'Redirecting to the Elementor edit window.', 'cartflows' ); ?> </p></div>
585
- </script>
586
-
587
- <?php
588
- /**
589
- * Responsive Buttons
590
- */
591
- ?>
592
- <script type="text/template" id="tmpl-cartflows-responsive-view">
593
- <span class="responsive-view">
594
- <span class="actions">
595
- <a class="desktop" href="#"><span data-view="desktop " class="active dashicons dashicons-desktop"></span></a>
596
- <a class="tablet" href="#"><span data-view="tablet" class="dashicons dashicons-tablet"></span></a>
597
- <a class="mobile" href="#"><span data-view="mobile" class="dashicons dashicons-smartphone"></span></a>
598
- </span>
599
- </span>
600
- </script>
601
-
602
- <?php
603
- // Templates data.
604
- ?>
605
- <script type="text/template" id="tmpl-cartflows-flows-list">
606
-
607
- <# console.log( data.items.length ) #>
608
- <# console.log( data.items ) #>
609
- <# if ( data.items.length ) { #>
610
- <# for ( key in data.items ) { #>
611
- <#
612
- var flow_steps = [];
613
- if( data.items[ key ].flow_steps ) {
614
- flow_steps = data.items[ key ].flow_steps.map(function(value,index) {
615
- return value['id'];
616
- });
617
- }
618
- #>
619
- <div class="inner">
620
- <div class="template">
621
- <span class="thumbnail site-preview cartflows-preview-flow-steps" data-flow-steps="{{ JSON.stringify( data.items[ key ].flow_steps ) }}" data-title="{{ data.items[ key ].title.rendered }}">
622
- <div class="template-screenshot">
623
- <# if( data.items[ key ].featured_image_url ) { #>
624
- <img src="{{ data.items[ key ].featured_image_url }}" />
625
- <# } else { #>
626
- <img src="<?php echo esc_attr( CARTFLOWS_URL ); ?>assets/images/400x400.jpg" />
627
- <# } #>
628
- </div>
629
- <# if( data.items[ key ].flow_type && 'pro' === data.items[ key ].flow_type.slug ) { #>
630
- <span class="wcf-flow-type pro"><?php esc_html_e( 'Pro', 'cartflows' ); ?></span>
631
- <# } #>
632
- <# if( data.items[ key ].woo_required ) { #>
633
- <div class="notice notice-info" style="width: auto;">
634
- <p class="wcf-learn-how">
635
- Install/Activate WooCommerce to use this template.
636
- <a href="https://cartflows.com/docs/cartflows-step-types/" target="_blank">
637
- <strong><?php esc_html_e( 'Learn How', 'cartflows' ); ?></strong>
638
- <i class="dashicons dashicons-external"></i>
639
- </a>
640
- </p>
641
- </div>
642
- <# } else { #>
643
- <a href="<?php echo CARTFLOWS_TEMPLATES_URL . 'preview/?'; ?>flow={{ data.items[ key ].id }}&title={{{ data.items[ key ].title.rendered }}}" class="preview" target="_blank">Preview <i class="dashicons dashicons-external"></i></a>
644
- <# } #>
645
-
646
- </span>
647
- <div class="template-id-container">
648
- <h3 class="template-name"> {{{ data.items[ key ].title.rendered }}} </h3>
649
- <div class="template-actions">
650
-
651
- <#
652
- if( data.items[ key ].page_builder.slug ) {
653
- required_plugin_group = data.items[ key ].page_builder.slug;
654
- } else {
655
- required_plugin_group = '';
656
- }
657
-
658
- if( data.items[ key ].page_builder.slug && CartFlowsImportVars.required_plugins[data.items[ key ].page_builder.slug] && CartFlowsImportVars.required_plugins[data.items[ key ].page_builder.slug].button_title ) {
659
- import_btn_title = CartFlowsImportVars.required_plugins[ data.items[ key ].page_builder.slug ].button_title;
660
- } else {
661
- import_btn_title = 'Import';
662
- } #>
663
-
664
- <# if( data.items[ key ].licence_status && 'valid' === data.items[ key ].licence_status ) { #>
665
- <# if( ! data.items[ key ].woo_required ) { #>
666
- <a data-flow-steps="{{ flow_steps }}" data-required-plugin-group="{{required_plugin_group}}" href="#" class="button button-primary cartflows-step-import" data-template-id="{{ data.items[ key ].id }}">{{ import_btn_title }}</a>
667
- <# } else { #>
668
- <a href='#' class='wcf-activate-wc button-primary'>Install & activate Woo</a>
669
- <# } #>
670
- <# } else if( CartFlowsImportVars._is_pro_active ) { #>
671
- <a target="_blank" href="<?php echo esc_url( admin_url( 'plugins.php?cartflows-license-popup' ) ); ?>" class="button button-primary"><?php esc_html_e( 'Activate License', 'cartflows' ); ?></a>
672
- <# } else { #>
673
- <a target="_blank" href="<?php echo esc_url( CARTFLOWS_DOMAIN_URL ); ?>" class="button button-primary"><?php esc_html_e( 'Get Pro', 'cartflows' ); ?></a>
674
- <# } #>
675
- </div>
676
- </div>
677
- </div>
678
- </div>
679
- <# } #>
680
- <# } #>
681
- </script>
682
-
683
- <?php
684
- // Empty Step.
685
- ?>
686
- <script type="text/template" id="tmpl-cartflows-create-blank-step">
687
- <div class="inner">
688
- <div class="template">
689
- <span class="thumbnail site-preview cartflows-flow-preview">
690
- <div class="template-screenshot">
691
- <img src="<?php echo esc_attr( CARTFLOWS_URL ); ?>assets/images/start-scratch.jpg" />
692
- </div>
693
- <div id="wcf_create_notice" class=""><a href="https://cartflows.com/" target="_blank"></a></div>
694
- </span>
695
- <div class="template-id-container">
696
- <h3 class="template-name"> Blank </h3>
697
- <div class="template-actions">
698
- <a href="#" class="button button-primary cartflows-step-import-blank"><?php esc_html_e( 'Create', 'cartflows' ); ?></a>
699
- </div>
700
- </div>
701
- </div>
702
- </div>
703
- </script>
704
-
705
- <?php
706
- // Templates data.
707
- ?>
708
- <script type="text/template" id="tmpl-cartflows-steps-list">
709
- <# if ( data.items.length ) { #>
710
- <# for ( key in data.items ) { #>
711
- <#
712
- var flow_steps = [];
713
- if( data.items[ key ].flow_steps ) {
714
- flow_steps = data.items[ key ].flow_steps.map(function(value,index) {
715
- return value['id'];
716
- });
717
- }
718
- #>
719
- <div class="inner">
720
- <div class="template">
721
- <span class="thumbnail site-preview cartflows-preview-flow-steps" data-flow-steps="{{ JSON.stringify( data.items[ key ].flow_steps ) }}" data-title="{{ data.items[ key ].title.rendered }}">
722
- <div class="template-screenshot">
723
- <# if( data.items[ key ].featured_image_url ) { #>
724
- <img src="{{ data.items[ key ].featured_image_url }}" />
725
- <# } else { #>
726
- <img src="<?php echo esc_attr( CARTFLOWS_URL ); ?>assets/images/400x400.jpg" />
727
- <# } #>
728
- </div>
729
- <div id="wcf_create_notice" class=""><a href="https://cartflows.com/" target="_blank"></a></div>
730
-
731
- <# if( data.items[ key ].woo_required ) { #>
732
- <div class="notice notice-info" style="width: auto;">
733
- <p class="wcf-learn-how">
734
- Install/Activate WooCommerce to use this template.
735
- <a href="https://cartflows.com/docs/cartflows-step-types/" target="_blank">
736
- <strong><?php esc_html_e( 'Learn How', 'cartflows' ); ?></strong>
737
- <i class="dashicons dashicons-external"></i>
738
- </a>
739
- </p>
740
- </div>
741
- <# } else { #>
742
- <a href="<?php echo CARTFLOWS_TEMPLATES_URL . 'preview/?'; ?>step={{ data.items[ key ].id }}&title={{{ data.items[ key ].title.rendered }}}" class="preview" target="_blank">Preview <i class="dashicons dashicons-external"></i></a>
743
- <# } #>
744
-
745
- <# if( data.items[ key ].flow_type && 'pro' === data.items[ key ].flow_type.slug ) { #>
746
- <span class="wcf-flow-type pro"><?php esc_html_e( 'Pro', 'cartflows' ); ?></span>
747
- <# } #>
748
- </span>
749
- <div class="template-id-container">
750
- <h3 class="template-name"> {{{ data.items[ key ].title.rendered }}} </h3>
751
- <div class="template-actions">
752
-
753
- <#
754
-
755
- var step_slug = data.items[ key ].step_type.slug || '';
756
- var step_title = data.items[ key ].step_type.name || '';
757
- var import_btn_title = 'Import';
758
-
759
- var required_plugin_group = '';
760
- if( data.items[ key ].page_builder ) {
761
- required_plugin_group = data.items[ key ].page_builder.slug;
762
-
763
- if( data.items[ key ].page_builder.slug && CartFlowsImportVars.required_plugins[data.items[ key ].page_builder.slug] && CartFlowsImportVars.required_plugins[data.items[ key ].page_builder.slug].button_title ) {
764
- import_btn_title = CartFlowsImportVars.required_plugins[ data.items[ key ].page_builder.slug ].button_title;
765
- }
766
- }
767
- #>
768
-
769
- <# if( data.items[ key ].licence_status && 'valid' === data.items[ key ].licence_status ) { #>
770
-
771
- <# if( ! data.items[ key ].woo_required ) { #>
772
- <a data-slug="{{step_slug}}" data-title="{{step_title}}" data-flow-steps="{{ flow_steps }}" data-required-plugin-group="{{required_plugin_group}}" href="#" class="button button-primary cartflows-step-import" data-template-id="{{ data.items[ key ].id }}">{{ import_btn_title }}</a>
773
- <# } else { #>
774
- <a href='#' class='wcf-activate-wc button-primary'>Install & activate Woo</a>
775
- <# } #>
776
-
777
- <# } else if( CartFlowsImportVars._is_pro_active ) { #>
778
- <a target="_blank" href="<?php echo esc_url( admin_url( 'plugins.php?cartflows-license-popup' ) ); ?>" class="button button-primary"><?php esc_html_e( 'Activate License', 'cartflows' ); ?></a>
779
- <# } else { #>
780
- <a target="_blank" href="<?php echo esc_url( CARTFLOWS_DOMAIN_URL ); ?>" class="button button-primary"><?php esc_html_e( 'Get Pro', 'cartflows' ); ?></a>
781
- <# } #>
782
- </div>
783
- </div>
784
- </div>
785
- </div>
786
- <# } #>
787
- <# } #>
788
- </script>
789
-
790
- <?php
791
- /**
792
- * TMPL - Website Unreachable
793
- */
794
- ?>
795
- <script type="text/template" id="tmpl-cartflows-website-unreachable">
796
- <div class="postbox cartflows-website-unreachable">
797
- <h2><?php esc_html_e( 'Under Maintenance..', 'cartflows' ); ?></h2>
798
- <p><?php esc_html_e( 'If you are seeing this message, most likely our servers are under routine maintenance and we will be back shortly.', 'cartflows' ); ?></p>
799
- <p><?php esc_html_e( 'In rare case, it is possible your website is having trouble connecting with ours. If you need help, please feel free to get in touch with us from our website..', 'cartflows' ); ?></p>
800
- </div>
801
- </script>
802
-
803
- <?php
804
- /**
805
- * TMPL - Filters
806
- */
807
- ?>
808
- <script type="text/template" id="tmpl-cartflows-page-builder-notice">
809
- <?php
810
- $default_page_builder = Cartflows_Helper::get_common_setting( 'default_page_builder' );
811
- $page_builder = Cartflows_Helper::get_required_plugins_for_page_builder( Cartflows_Helper::get_common_setting( 'default_page_builder' ) );
812
- $title = $page_builder['title'];
813
-
814
- $plugin_string = '<a href="#" data-slug="' . esc_html( $default_page_builder ) . '" class="wcf-install-plugin">Please click here and activate ' . esc_html( $title ) . '</a>';
815
- $theme_status = '';
816
- if ( 'divi' === $default_page_builder ) {
817
-
818
- $theme_status = $page_builder['theme-status'];
819
- $plugin_status = $page_builder['plugin-status'];
820
-
821
- if ( 'deactivate' === $theme_status || 'install' === $plugin_status ) {
822
- $plugin_string = 'Please activate ' . esc_html( $title );
823
- } elseif ( ( 'deactivate' === $theme_status || 'not-installed' === $theme_status ) && 'install' === $plugin_status ) {
824
- $plugin_string = 'Please install and activate ' . esc_html( $title );
825
- }
826
- }
827
- ?>
828
- <div class="wcf-page-builder-message">
829
- <p><?php /* translators: %s: Plugin string */ printf( __( '%1$s to see CartFlows templates. If you prefer another page builder tool, you can <a href="%2$s" target="blank">select it here</a>.', 'cartflows' ), $plugin_string, admin_url( 'admin.php?page=' . CARTFLOWS_SETTINGS . '&action=common-settings#form-field-wcf_default_page_builder' ) ); ?></p>
830
- <p>If your preferred page builder is not available, feel free to <a href="#" data-slug="canvas" class="wcf-create-from-scratch-link">create your own</a> pages using page builder of your choice as CartFlows works with all major page builders.</p>
831
- <p>We plan to add design templates made with more page builder shortly!</p>
832
- </div>
833
- </script>
834
-
835
- <?php
836
- /**
837
- * TMPL - Filters
838
- */
839
- ?>
840
- <script type="text/template" id="tmpl-cartflows-term-filters-dropdown">
841
- <# if ( data ) { #>
842
- <select class="{{ data.args.wrapper_class }} {{ data.args.class }}">
843
- <# if ( data.args.show_all ) { #>
844
- <option value="all"> <?php esc_html_e( 'All', 'cartflows' ); ?> </option>
845
- <# } #>
846
- <# if ( CartFlowsImportVars.step_type === data.args.remote_slug ) { #>
847
- <option value=""> <?php esc_html_e( 'Select Step Type', 'cartflows' ); ?> </option>
848
- <# } #>
849
- <# var step_slug_data = []; #>
850
- <# for ( key in data.items ) { #>
851
- <option value='{{ data.items[ key ].id }}' data-group='{{ data.items[ key ].id }}' class="{{ data.items[ key ].name }}" data-slug="{{ data.items[ key ].slug }}" data-title="{{ data.items[ key ].name }}">{{ data.items[ key ].name }}</option>
852
-
853
- <# step_slug_data.push( data.items[ key ].slug ); #>
854
-
855
- <# } #>
856
- <# if( step_slug_data.indexOf("optin") === -1){ #>
857
- <option value='0' data-group='0' class="Optin (Woo)" data-slug="optin" data-title="Optin (Woo)">Optin (Woo)</option>
858
- <# } #>
859
- </select>
860
- <# } #>
861
- </script>
862
-
863
- <script type="text/template" id="tmpl-cartflows-term-filters">
864
-
865
- <# if ( data ) { #>
866
-
867
- <?php /* <# if ( CartFlowsImportVars.flow_page_builder === data.args.remote_slug || CartFlowsImportVars.step_page_builder === data.args.remote_slug ) { #> */ ?>
868
- <ul class="{{ data.args.wrapper_class }} {{ data.args.class }}">
869
-
870
- <# if ( data.args.show_all ) { #>
871
- <li>
872
- <a href="#" data-group="all"> All </a>
873
- </li>
874
- <# } #>
875
-
876
- <# for ( key in data.items ) { #>
877
- <li>
878
- <a href="#" data-group='{{ data.items[ key ].id }}' class="{{ data.items[ key ].name }}" data-slug="{{ data.items[ key ].slug }}" data-title="{{ data.items[ key ].name }}">{{ data.items[ key ].name }}</a>
879
- </li>
880
- <# } #>
881
-
882
- </ul>
883
-
884
- <?php
885
-
886
- /**
887
- <# } else { #>
888
- <select class="{{ data.args.wrapper_class }} {{ data.args.class }}">
889
-
890
- <# if ( data.args.show_all ) { #>
891
- <option value="all"> <?php _e( 'All', 'cartflows' ); ?> </option>
892
- <# } #>
893
-
894
- <# if ( CartFlowsImportVars.step_type === data.args.remote_slug ) { #>
895
- <option value=""> <?php _e( 'Select Step Type', 'cartflows' ); ?> </option>
896
- <# } #>
897
-
898
- <# for ( key in data.items ) { #>
899
- <option value='{{ data.items[ key ].id }}' data-group='{{ data.items[ key ].id }}' class="{{ data.items[ key ].name }}" data-slug="{{ data.items[ key ].slug }}" data-title="{{ data.items[ key ].name }}">{{ data.items[ key ].name }}</option>
900
- <# } #>
901
-
902
- </select>
903
- */
904
- ?>
905
-
906
- <?php /* <# } #> */ ?>
907
-
908
- <# } #>
909
- </script>
910
-
911
- <?php
912
- // Step Type.
913
- ?>
914
- <script type="text/template" id="tmpl-cartflows-step-types">
915
- <ul class="wcf-tab nav-tabs">
916
- <# if( data.items_count ) { #>
917
- <# for( key in data.items ) { #>
918
- <# console.log( data.items[ key ].id ) #>
919
- <li data-slug="{{data.items[ key ].slug}}" data-title="{{ data.items[ key ].name }}">
920
- <a href="#{{{ data.items[ key ].slug }}}">{{{ data.items[ key ].name }}}</a>
921
- </li>
922
- <# } #>
923
- <# } #>
924
- </ul>
925
- </script>
926
-
927
- <?php
928
- // Add to library button.
929
- ?>
930
- <script type="text/template" id="tmpl-templator-add-to-library">
931
- <a class="templator-add-to-library page-title-action cartflows-load-steps-library"><i class="dashicons dashicons-cloud"></i><?php esc_attr_e( 'Import from Cloud', 'cartflows' ); ?></a>
932
- </script>
933
- <?php
934
- }
935
-
936
- /**
937
- * Enqueue scripts
938
- *
939
- * @since 1.0.0
940
- *
941
- * @hook admin_enqueue_scripts
942
- * @param string $hook Current page hook.
943
- */
944
- public function scripts( $hook = '' ) {
945
-
946
- if ( ! self::is_supported_post( get_current_screen()->post_type ) ) {
947
- return;
948
- }
949
-
950
- wp_enqueue_script( 'cartflows-rest-api', CARTFLOWS_URL . 'assets/js/rest-api.js', array( 'jquery' ), CARTFLOWS_VER, true );
951
- wp_enqueue_style( 'cartflows-import', CARTFLOWS_URL . 'assets/css/import.css', null, CARTFLOWS_VER, 'all' );
952
- wp_style_add_data( 'cartflows-import', 'rtl', 'replace' );
953
- wp_enqueue_script( 'cartflows-import', CARTFLOWS_URL . 'assets/js/import.js', array( 'jquery', 'wp-util', 'cartflows-rest-api', 'updates' ), CARTFLOWS_VER, true );
954
-
955
- $installed_plugins = get_plugins();
956
- $is_wc_installed = isset( $installed_plugins['woocommerce/woocommerce.php'] ) ? 'yes' : 'no';
957
- $is_wc_activated = wcf()->is_woo_active ? 'yes' : 'no';
958
-
959
- $localize_vars = array(
960
- '_is_pro_active' => _is_cartflows_pro(),
961
- 'is_wc_installed' => $is_wc_installed,
962
- 'is_wc_activated' => $is_wc_activated,
963
-
964
- // Flow and its rest fields.
965
- 'flow' => CARTFLOWS_FLOW_POST_TYPE,
966
- 'flow_fields' => array(
967
- 'id',
968
- 'title',
969
- 'flow_type',
970
- 'page_builder',
971
- 'flow_steps',
972
- 'licence_status',
973
- 'featured_image_url',
974
- 'featured_media', // @required for field `featured_image_url`.
975
- ),
976
-
977
- // Flow type and rest fields.
978
- 'flow_type' => CARTFLOWS_TAXONOMY_FLOW_CATEGORY,
979
- 'flow_type_fields' => array(
980
- 'id',
981
- 'name',
982
- 'slug',
983
- ),
984
-
985
- // Flow page builder and rest fields.
986
- 'flow_page_builder' => CARTFLOWS_TAXONOMY_FLOW_PAGE_BUILDER,
987
- 'flow_page_builder_fields' => array(
988
- 'id',
989
- 'name',
990
- 'slug',
991
- ),
992
-
993
- // Step page builder and rest fields.
994
- 'step_page_builder' => CARTFLOWS_TAXONOMY_STEP_PAGE_BUILDER,
995
- 'step_page_builder_fields' => array(
996
- 'id',
997
- 'name',
998
- 'slug',
999
- ),
1000
-
1001
- // Step and its rest fields.
1002
- 'step' => CARTFLOWS_STEP_POST_TYPE,
1003
- 'step_fields' => array(
1004
- 'title',
1005
- 'featured_image_url',
1006
- 'featured_media', // @required for field `featured_image_url`.
1007
- 'id',
1008
- 'flow_type',
1009
- 'step_type',
1010
- 'page_builder',
1011
- 'licence_status',
1012
- ),
1013
-
1014
- // Step type and its rest fields.
1015
- 'step_type' => CARTFLOWS_TAXONOMY_STEP_TYPE,
1016
- 'step_type_fields' => array(
1017
- 'id',
1018
- 'name',
1019
- 'slug',
1020
- ),
1021
-
1022
- 'domain_url' => CARTFLOWS_DOMAIN_URL,
1023
- 'server_url' => CARTFLOWS_TEMPLATES_URL,
1024
- 'server_rest_url' => CARTFLOWS_TEMPLATES_URL . 'wp-json/wp/v2/',
1025
- 'site_url' => site_url(),
1026
- 'import_url' => admin_url( 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE . '&page=flow_importer' ),
1027
- 'export_url' => admin_url( 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE . '&page=flow_exporter' ),
1028
- 'admin_url' => admin_url(),
1029
- 'licence_args' => CartFlows_API::get_instance()->get_licence_args(),
1030
- 'ajaxurl' => admin_url( 'admin-ajax.php' ),
1031
- 'debug' => ( ( defined( 'WP_DEBUG' ) && WP_DEBUG ) || isset( $_GET['debug'] ) ) ? true : false, //phpcs:ignore
1032
-
1033
- 'required_plugins' => Cartflows_Helper::get_plugins_groupby_page_builders(),
1034
-
1035
- 'default_page_builder' => Cartflows_Helper::get_common_setting( 'default_page_builder' ),
1036
- );
1037
-
1038
- $localize_vars['cartflows_activate_plugin_nonce'] = wp_create_nonce( 'cartflows_activate_plugin' );
1039
-
1040
- // var_dump(Cartflows_Helper::get_common_setting( 'default_page_builder' ));
1041
- // wp_die( );
1042
- // Add thickbox.
1043
- add_thickbox();
1044
-
1045
- wp_localize_script( 'cartflows-import', 'CartFlowsImportVars', $localize_vars );
1046
- wp_localize_script( 'cartflows-rest-api', 'CartFlowsImportVars', $localize_vars );
1047
- }
1048
-
1049
- /**
1050
- * Import.
1051
- *
1052
- * @since 1.0.0
1053
- *
1054
- * @hook wp_ajax_cartflows_import_flow_step
1055
- * @return void
1056
- */
1057
- public function import_flow() {
1058
-
1059
- if ( ! current_user_can( 'manage_options' ) ) {
1060
- return;
1061
- }
1062
-
1063
- check_ajax_referer( 'cf-import-flow-step', 'security' );
1064
-
1065
- $flow_id = isset( $_POST['flow_id'] ) ? intval( $_POST['flow_id'] ) : '';
1066
- $template_id = isset( $_POST['template_id'] ) ? intval( $_POST['template_id'] ) : '';
1067
-
1068
- wcf()->logger->import_log( '------------------------------------' );
1069
- wcf()->logger->import_log( 'STARTED! Importing FLOW' );
1070
- wcf()->logger->import_log( '------------------------------------' );
1071
- wcf()->logger->import_log( '(✓) Creating new step from remote step [' . $template_id . '] for FLOW ' . get_the_title( $flow_id ) . ' [' . $flow_id . ']' );
1072
-
1073
- $response = CartFlows_API::get_instance()->get_template( $template_id );
1074
-
1075
- $post_content = isset( $response['data']['content']->rendered ) ? $response['data']['content']->rendered : '';
1076
- if ( 'divi' === Cartflows_Helper::get_common_setting( 'default_page_builder' ) ) {
1077
- if ( isset( $response['data']['divi_content'] ) && ! empty( $response['data']['divi_content'] ) ) {
1078
- $post_content = $response['data']['divi_content'];
1079
- }
1080
- }
1081
-
1082
- if ( false === $response['success'] ) {
1083
- wcf()->logger->import_log( '(✕) Failed to fetch remote data.' );
1084
- wp_send_json_error( $response );
1085
- }
1086
-
1087
- wcf()->logger->import_log( '(✓) Successfully getting remote step response ' . wp_json_encode( $response ) );
1088
-
1089
- $new_step_id = wp_insert_post(
1090
- array(
1091
- 'post_type' => CARTFLOWS_STEP_POST_TYPE,
1092
- 'post_title' => $response['title'],
1093
- 'post_content' => $post_content,
1094
- 'post_status' => 'publish',
1095
- )
1096
- );
1097
-
1098
- if ( is_wp_error( $new_step_id ) ) {
1099
- wcf()->logger->import_log( '() Failed to create new step for flow ' . $flow_id );
1100
- wp_send_json_error( $new_step_id );
1101
- }
1102
-
1103
- if ( 'divi' === Cartflows_Helper::get_common_setting( 'default_page_builder' ) ) {
1104
- if ( isset( $response['data']['divi_content'] ) && ! empty( $response['data']['divi_content'] ) ) {
1105
- update_post_meta( $new_step_id, 'divi_content', $response['data']['divi_content'] );
1106
- }
1107
- }
1108
-
1109
- /* Imported Step */
1110
- update_post_meta( $new_step_id, 'cartflows_imported_step', 'yes' );
1111
-
1112
- wcf()->logger->import_log( '(✓) Created new step ' . '"' . $response['title'] . '" id ' . $new_step_id );//phpcs:ignore
1113
- // insert post meta.
1114
- update_post_meta( $new_step_id, 'wcf-flow-id', $flow_id );
1115
- wcf()->logger->import_log( '(✓) Added flow ID ' . $flow_id . ' in post meta key wcf-flow-id.' );
1116
-
1117
- /**
1118
- * Import & Set type.
1119
- */
1120
- $term = isset( $response['data']['step_type'] ) ? $response['data']['step_type'] : '';
1121
-
1122
- $term_slug = '';
1123
- if ( $term ) {
1124
-
1125
- $taxonomy = CARTFLOWS_TAXONOMY_STEP_TYPE;
1126
- $term_exist = term_exists( $term->slug, $taxonomy );
1127
-
1128
- if ( empty( $term_exist ) ) {
1129
- $terms = array(
1130
- array(
1131
- 'name' => $term->name,
1132
- 'slug' => $term->slug,
1133
- ),
1134
- );
1135
-
1136
- Cartflows_Step_Post_Type::get_instance()->add_terms( $taxonomy, $terms );
1137
- wcf()->logger->import_log( '(✓) Created new term name ' . $term->name . ' | term slug ' . $term->slug );
1138
- }
1139
-
1140
- $current_term = term_exists( $term->slug, $taxonomy );
1141
-
1142
- // Set type object.
1143
- $data = get_term( $current_term['term_id'], $taxonomy );
1144
- $term_slug = $data->slug;
1145
- $term_name = $data->name;
1146
- wp_set_object_terms( $new_step_id, $term_slug, CARTFLOWS_TAXONOMY_STEP_TYPE );
1147
- wcf()->logger->import_log( '(✓) Assigned existing term ' . $term_name . ' to the template ' . $new_step_id );
1148
-
1149
- // Set type.
1150
- update_post_meta( $new_step_id, 'wcf-step-type', $term_slug );
1151
- wcf()->logger->import_log( '(✓) Updated term ' . $term_name . ' to the post meta wcf-step-type.' );
1152
- }
1153
-
1154
- // Set flow.
1155
- wp_set_object_terms( $new_step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
1156
- wcf()->logger->import_log( '(✓) Assigned flow step flow-' . $flow_id );
1157
-
1158
- /**
1159
- * Update steps for the current flow.
1160
- */
1161
- $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
1162
-
1163
- if ( ! is_array( $flow_steps ) ) {
1164
- $flow_steps = array();
1165
- }
1166
-
1167
- $flow_steps[] = array(
1168
- 'id' => $new_step_id,
1169
- 'title' => $response['title'],
1170
- 'type' => $term_slug,
1171
- );
1172
- update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
1173
- wcf()->logger->import_log( '(✓) Updated flow steps post meta key \'wcf-steps\' ' . wp_json_encode( $flow_steps ) );
1174
-
1175
- // Import Post Meta.
1176
- self::import_post_meta( $new_step_id, $response );
1177
-
1178
- wcf()->logger->import_log( '(✓) Importing step "' . get_the_title( $new_step_id ) . '" [' . $new_step_id . '] for FLOW "' . get_the_title( $flow_id ) . '" [' . $flow_id . ']' );
1179
- wcf()->logger->import_log( '------------------------------------' );
1180
- wcf()->logger->import_log( 'COMPLETE! Importing FLOW' );
1181
- wcf()->logger->import_log( '------------------------------------' );
1182
-
1183
- do_action( 'cartflows_import_complete' );
1184
- wcf()->logger->import_log( '(✓) BATCH STARTED for step ' . $new_step_id . ' for Blog name \'' . get_bloginfo( 'name' ) . '\' (' . get_current_blog_id() . ')' );
1185
-
1186
- // Batch Process.
1187
- do_action( 'cartflows_after_template_import', $new_step_id, $response );
1188
-
1189
- /**
1190
- * End
1191
- */
1192
- wp_send_json_success( $new_step_id );
1193
- }
1194
-
1195
- /**
1196
- * Import Step.
1197
- *
1198
- * @since 1.0.0
1199
- * @hook wp_ajax_cartflows_step_import
1200
- *
1201
- * @return void
1202
- */
1203
- public function create_default_flow() {
1204
-
1205
- if ( ! current_user_can( 'manage_options' ) ) {
1206
- return;
1207
- }
1208
-
1209
- check_ajax_referer( 'cf-default-flow', 'security' );
1210
-
1211
- // Create post object.
1212
- $new_flow_post = array(
1213
- 'post_content' => '',
1214
- 'post_status' => 'publish',
1215
- 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
1216
- );
1217
-
1218
- // Insert the post into the database.
1219
- $flow_id = wp_insert_post( $new_flow_post );
1220
-
1221
- if ( is_wp_error( $flow_id ) ) {
1222
- wp_send_json_error( $flow_id->get_error_message() );
1223
- }
1224
-
1225
- $flow_steps = array();
1226
-
1227
- if ( wcf()->is_woo_active ) {
1228
- $steps_data = array(
1229
- 'sales' => array(
1230
- 'title' => __( 'Sales Landing', 'cartflows' ),
1231
- 'type' => 'landing',
1232
- ),
1233
- 'order-form' => array(
1234
- 'title' => __( 'Checkout (Woo)', 'cartflows' ),
1235
- 'type' => 'checkout',
1236
- ),
1237
- 'order-confirmation' => array(
1238
- 'title' => __( 'Thank You (Woo)', 'cartflows' ),
1239
- 'type' => 'thankyou',
1240
- ),
1241
- );
1242
-
1243
- } else {
1244
- $steps_data = array(
1245
- 'landing' => array(
1246
- 'title' => __( 'Landing', 'cartflows' ),
1247
- 'type' => 'landing',
1248
- ),
1249
- 'thankyou' => array(
1250
- 'title' => __( 'Thank You', 'cartflows' ),
1251
- 'type' => 'landing',
1252
- ),
1253
- );
1254
- }
1255
-
1256
- foreach ( $steps_data as $slug => $data ) {
1257
-
1258
- $post_content = '';
1259
- $step_type = trim( $data['type'] );
1260
-
1261
- $step_id = wp_insert_post(
1262
- array(
1263
- 'post_type' => CARTFLOWS_STEP_POST_TYPE,
1264
- 'post_title' => $data['title'],
1265
- 'post_content' => $post_content,
1266
- 'post_status' => 'publish',
1267
- )
1268
- );
1269
-
1270
- if ( is_wp_error( $step_id ) ) {
1271
- wp_send_json_error( $step_id->get_error_message() );
1272
- }
1273
-
1274
- if ( $step_id ) {
1275
-
1276
- $flow_steps[] = array(
1277
- 'id' => $step_id,
1278
- 'title' => $data['title'],
1279
- 'type' => $step_type,
1280
- );
1281
-
1282
- // insert post meta.
1283
- update_post_meta( $step_id, 'wcf-flow-id', $flow_id );
1284
- update_post_meta( $step_id, 'wcf-step-type', $step_type );
1285
-
1286
- wp_set_object_terms( $step_id, $step_type, CARTFLOWS_TAXONOMY_STEP_TYPE );
1287
- wp_set_object_terms( $step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
1288
-
1289
- update_post_meta( $step_id, '_wp_page_template', 'cartflows-default' );
1290
- }
1291
- }
1292
-
1293
- update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
1294
-
1295
- wp_send_json_success( $flow_id );
1296
- }
1297
-
1298
- /**
1299
- * Create Flow
1300
- *
1301
- * @return void
1302
- */
1303
- public function create_flow() {
1304
-
1305
- if ( ! current_user_can( 'manage_options' ) ) {
1306
- return;
1307
- }
1308
-
1309
- check_ajax_referer( 'cf-create-flow', 'security' );
1310
-
1311
- // Create post object.
1312
- $new_flow_post = array(
1313
- 'post_content' => '',
1314
- 'post_status' => 'publish',
1315
- 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
1316
- );
1317
-
1318
- // Insert the post into the database.
1319
- $flow_id = wp_insert_post( $new_flow_post );
1320
-
1321
- if ( is_wp_error( $flow_id ) ) {
1322
- wp_send_json_error( $flow_id->get_error_message() );
1323
- }
1324
-
1325
- /* Imported Flow */
1326
- update_post_meta( $flow_id, 'cartflows_imported_flow', 'yes' );
1327
-
1328
- wp_send_json_success( $flow_id );
1329
- }
1330
-
1331
- /**
1332
- * Create Step
1333
- *
1334
- * @return void
1335
- */
1336
- public function import_step() {
1337
-
1338
- if ( ! current_user_can( 'manage_options' ) ) {
1339
- return;
1340
- }
1341
-
1342
- check_ajax_referer( 'cf-step-import', 'security' );
1343
-
1344
- $template_id = isset( $_POST['template_id'] ) ? intval( $_POST['template_id'] ) : '';
1345
- $flow_id = isset( $_POST['flow_id'] ) ? intval( $_POST['flow_id'] ) : '';
1346
- $step_title = isset( $_POST['step_title'] ) ? sanitize_text_field( wp_unslash( $_POST['step_title'] ) ) : '';
1347
- $step_type = isset( $_POST['step_type'] ) ? sanitize_title( wp_unslash( $_POST['step_type'] ) ) : '';
1348
- $step_custom_title = isset( $_POST['step_custom_title'] ) ? sanitize_title( wp_unslash( $_POST['step_custom_title'] ) ) : $step_title;
1349
-
1350
- $cartflow_meta = Cartflows_Flow_Meta::get_instance();
1351
-
1352
- $post_id = $cartflow_meta->create_step( $flow_id, $step_type, $step_custom_title );
1353
-
1354
- wcf()->logger->import_log( '------------------------------------' );
1355
- wcf()->logger->import_log( 'STARTED! Importing STEP' );
1356
- wcf()->logger->import_log( '------------------------------------' );
1357
-
1358
- if ( empty( $template_id ) || empty( $post_id ) ) {
1359
- /* translators: %s: template ID */
1360
- $data = sprintf( __( 'Invalid template id %1$s or post id %2$s.', 'cartflows' ), $template_id, $post_id );
1361
- wcf()->logger->import_log( $data );
1362
- wp_send_json_error( $data );
1363
- }
1364
-
1365
- wcf()->logger->import_log( 'Remote Step ' . $template_id . ' for local flow "' . get_the_title( $post_id ) . '" [' . $post_id . ']' );
1366
-
1367
- $response = CartFlows_API::get_instance()->get_template( $template_id );
1368
-
1369
- if ( 'divi' === Cartflows_Helper::get_common_setting( 'default_page_builder' ) ) {
1370
- if ( isset( $response['data']['divi_content'] ) && ! empty( $response['data']['divi_content'] ) ) {
1371
- update_post_meta( $post_id, 'divi_content', $response['data']['divi_content'] );
1372
-
1373
- wp_update_post(
1374
- array(
1375
- 'ID' => $post_id,
1376
- 'post_content' => $response['data']['divi_content'],
1377
- )
1378
- );
1379
- }
1380
- }
1381
-
1382
- /* Imported Step */
1383
- update_post_meta( $post_id, 'cartflows_imported_step', 'yes' );
1384
-
1385
- // Import Post Meta.
1386
- self::import_post_meta( $post_id, $response );
1387
-
1388
- do_action( 'cartflows_import_complete' );
1389
-
1390
- // Batch Process.
1391
- do_action( 'cartflows_after_template_import', $post_id, $response );
1392
-
1393
- wcf()->logger->import_log( '------------------------------------' );
1394
- wcf()->logger->import_log( 'COMPLETE! Importing Step' );
1395
- wcf()->logger->import_log( '------------------------------------' );
1396
-
1397
- wp_send_json_success( $post_id );
1398
- }
1399
-
1400
- /**
1401
- * Import Step.
1402
- *
1403
- * @since 1.0.0
1404
- * @hook wp_ajax_cartflows_step_create_blank
1405
- *
1406
- * @return void
1407
- */
1408
- public function step_create_blank() {
1409
-
1410
- if ( ! current_user_can( 'manage_options' ) ) {
1411
- return;
1412
- }
1413
-
1414
- check_ajax_referer( 'cf-step-create-blank', 'security' );
1415
-
1416
- $flow_id = isset( $_POST['flow_id'] ) ? intval( $_POST['flow_id'] ) : '';
1417
- $step_type = isset( $_POST['step_type'] ) ? sanitize_text_field( wp_unslash( $_POST['step_type'] ) ) : '';
1418
- $step_title = isset( $_POST['step_title'] ) ? sanitize_text_field( wp_unslash( $_POST['step_title'] ) ) : '';
1419
-
1420
- if ( empty( $flow_id ) || empty( $step_type ) ) {
1421
- /* translators: %s: flow ID */
1422
- $data = sprintf( __( 'Invalid flow id %1$s OR step type %2$s.', 'cartflows' ), $flow_id, $step_type );
1423
- wcf()->logger->import_log( $data );
1424
- wp_send_json_error( $data );
1425
- }
1426
-
1427
- wcf()->logger->import_log( '------------------------------------' );
1428
- wcf()->logger->import_log( 'STARTED! Creating Blank STEP for Flow ' . $flow_id );
1429
-
1430
- $step_type_title = str_replace( '-', ' ', $step_type );
1431
- $step_type_slug = strtolower( str_replace( '-', ' ', $step_type ) );
1432
-
1433
- $new_step_id = wp_insert_post(
1434
- array(
1435
- 'post_type' => CARTFLOWS_STEP_POST_TYPE,
1436
- 'post_title' => $step_title,
1437
- 'post_content' => '',
1438
- 'post_status' => 'publish',
1439
- )
1440
- );
1441
-
1442
- // insert post meta.
1443
- update_post_meta( $new_step_id, 'wcf-flow-id', $flow_id );
1444
-
1445
- $taxonomy = CARTFLOWS_TAXONOMY_STEP_TYPE;
1446
- $term_exist = term_exists( $step_type_slug, $taxonomy );
1447
-
1448
- if ( empty( $term_exist ) ) {
1449
- $terms = array(
1450
- array(
1451
- 'name' => $step_type_title,
1452
- 'slug' => $step_type_slug,
1453
- ),
1454
- );
1455
-
1456
- Cartflows_Step_Post_Type::get_instance()->add_terms( $taxonomy, $terms );
1457
- wcf()->logger->import_log( '(✓) Created new term name ' . $step_type_title . ' | term slug ' . $step_type_slug );
1458
- }
1459
-
1460
- $current_term = term_exists( $step_type_slug, $taxonomy );
1461
-
1462
- // Set type object.
1463
- $data = get_term( $current_term['term_id'], $taxonomy );
1464
- $step_slug = $data->slug;
1465
- wp_set_object_terms( $new_step_id, $data->slug, CARTFLOWS_TAXONOMY_STEP_TYPE );
1466
- wcf()->logger->import_log( '(✓) Assigned existing term ' . $step_type_title . ' to the template ' . $new_step_id );
1467
-
1468
- // Set Default page Layout.
1469
- update_post_meta( $new_step_id, '_wp_page_template', 'cartflows-default' );
1470
-
1471
- // Set type.
1472
- update_post_meta( $new_step_id, 'wcf-step-type', $data->slug );
1473
- wcf()->logger->import_log( '(✓) Updated term ' . $data->name . ' to the post meta wcf-step-type.' );
1474
-
1475
- // Set flow.
1476
- wp_set_object_terms( $new_step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
1477
- wcf()->logger->import_log( '(✓) Assigned flow step flow-' . $flow_id );
1478
-
1479
- self::get_instance()->set_step_to_flow( $flow_id, $new_step_id, $step_type_title, $step_slug );
1480
-
1481
- wcf()->logger->import_log( 'COMPLETE! Creating Blank STEP for Flow ' . $flow_id );
1482
- wcf()->logger->import_log( '------------------------------------' );
1483
-
1484
- wp_send_json_success( $new_step_id );
1485
- }
1486
-
1487
- /**
1488
- * Import Post Meta
1489
- *
1490
- * @since 1.0.0
1491
- *
1492
- * @param integer $post_id Post ID.
1493
- * @param array $response Post meta.
1494
- * @return void
1495
- */
1496
- public static function import_post_meta( $post_id, $response ) {
1497
-
1498
- $metadata = (array) $response['post_meta'];
1499
-
1500
- foreach ( $metadata as $meta_key => $meta_value ) {
1501
- $meta_value = isset( $meta_value[0] ) ? $meta_value[0] : '';
1502
-
1503
- if ( $meta_value ) {
1504
-
1505
- if ( is_serialized( $meta_value, true ) ) {
1506
- $raw_data = maybe_unserialize( stripslashes( $meta_value ) );
1507
- } elseif ( is_array( $meta_value ) ) {
1508
- $raw_data = json_decode( stripslashes( $meta_value ), true );
1509
- } else {
1510
- $raw_data = $meta_value;
1511
- }
1512
-
1513
- if ( '_elementor_data' === $meta_key ) {
1514
- if ( is_array( $raw_data ) ) {
1515
- $raw_data = wp_slash( wp_json_encode( $raw_data ) );
1516
- } else {
1517
- $raw_data = wp_slash( $raw_data );
1518
- }
1519
- }
1520
- if ( '_elementor_data' !== $meta_key && '_elementor_draft' !== $meta_key && '_fl_builder_data' !== $meta_key && '_fl_builder_draft' !== $meta_key ) {
1521
- if ( is_array( $raw_data ) ) {
1522
- wcf()->logger->import_log( '(✓) Added post meta ' . $meta_key . ' | ' . wp_json_encode( $raw_data ) );
1523
- } else {
1524
- if ( ! is_object( $raw_data ) ) {
1525
- wcf()->logger->import_log( '(✓) Added post meta ' . $meta_key . ' | ' . $raw_data );
1526
- }
1527
- }
1528
- }
1529
-
1530
- update_post_meta( $post_id, $meta_key, $raw_data );
1531
- }
1532
- }
1533
- }
1534
-
1535
- /**
1536
- * Import Template for Elementor
1537
- *
1538
- * @since 1.0.0
1539
- *
1540
- * @param integer $post_id Post ID.
1541
- * @param array $response Post meta.
1542
- * @param array $page_build_data Page build data.
1543
- * @return void
1544
- */
1545
- public static function import_template_elementor( $post_id, $response, $page_build_data ) {
1546
- if ( ! is_plugin_active( 'elementor/elementor.php' ) ) {
1547
- $data = __( 'Elementor is not activated. Please activate plugin Elementor Page Builder to import the step.', 'cartflows' );
1548
- wcf()->logger->import_log( $data );
1549
- wp_send_json_error( $data );
1550
- }
1551
-
1552
- require_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-importer-elementor.php';
1553
-
1554
- wcf()->logger->import_log( '# Started "importing page builder data" for step ' . $post_id );
1555
-
1556
- $obj = new \Elementor\TemplateLibrary\CartFlows_Importer_Elementor();
1557
- $obj->import_single_template( $post_id );
1558
-
1559
- wcf()->logger->import_log( '# Complete "importing page builder data" for step ' . $post_id );
1560
- }
1561
-
1562
- /**
1563
- * Supported post types
1564
- *
1565
- * @since 1.0.0
1566
- *
1567
- * @return array Supported post types.
1568
- */
1569
- public static function supported_post_types() {
1570
- return apply_filters(
1571
- 'cartflows_supported_post_types',
1572
- array(
1573
- CARTFLOWS_FLOW_POST_TYPE,
1574
- )
1575
- );
1576
- }
1577
-
1578
- /**
1579
- * Check supported post type
1580
- *
1581
- * @since 1.0.0
1582
- *
1583
- * @param string $post_type Post type.
1584
- * @return boolean Supported post type status.
1585
- */
1586
- public static function is_supported_post( $post_type = '' ) {
1587
-
1588
- if ( in_array( $post_type, self::supported_post_types(), true ) ) {
1589
- return true;
1590
- }
1591
-
1592
- return false;
1593
- }
1594
-
1595
- /**
1596
- * Set steps to the flow
1597
- *
1598
- * @param integer $flow_id Flow ID.
1599
- * @param integer $new_step_id New step ID.
1600
- * @param string $step_title Flow Type.
1601
- * @param string $step_slug Flow Type.
1602
- */
1603
- public function set_step_to_flow( $flow_id, $new_step_id, $step_title, $step_slug ) {
1604
- // Update steps for the current flow.
1605
- $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
1606
-
1607
- if ( ! is_array( $flow_steps ) ) {
1608
- $flow_steps = array();
1609
- }
1610
-
1611
- $flow_steps[] = array(
1612
- 'id' => $new_step_id,
1613
- 'title' => $step_title,
1614
- 'type' => $step_slug,
1615
- );
1616
- update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
1617
- wcf()->logger->import_log( '(✓) Updated flow steps post meta key \'wcf-steps\' ' . wp_json_encode( $flow_steps ) );
1618
- }
1619
-
1620
- /**
1621
- * Localize variables in admin
1622
- *
1623
- * @param array $vars variables.
1624
- */
1625
- public function localize_vars( $vars ) {
1626
-
1627
- $ajax_actions = array(
1628
- 'cf_step_import',
1629
- 'cf_load_steps',
1630
- 'cf_create_flow',
1631
- 'cf_default_flow',
1632
- 'cf_step_create_blank',
1633
- 'cf_import_flow_step',
1634
- );
1635
-
1636
- foreach ( $ajax_actions as $action ) {
1637
-
1638
- $vars[ $action . '_nonce' ] = wp_create_nonce( str_replace( '_', '-', $action ) );
1639
- }
1640
-
1641
- return $vars;
1642
- }
1643
-
1644
- /**
1645
- * Ajax action to activate plugin
1646
- */
1647
- public function activate_plugin() {
1648
-
1649
- if ( ! check_ajax_referer( 'cartflows_activate_plugin', 'security', false ) ) {
1650
- wp_send_json_error( esc_html__( 'Action failed. Invalid Security Nonce.', 'cartflows' ) );
1651
- }
1652
-
1653
- if ( ! current_user_can( 'activate_plugins' ) ) {
1654
- wp_send_json_error(
1655
- array(
1656
- 'success' => false,
1657
- 'message' => __( 'User have not plugin install permissions.', 'cartflows' ),
1658
- )
1659
- );
1660
- }
1661
-
1662
- $plugin_init = isset( $_POST['plugin_init'] ) ? sanitize_text_field( wp_unslash( $_POST['plugin_init'] ) ) : '';
1663
-
1664
- $activate = activate_plugin( $plugin_init, '', false, true );
1665
-
1666
- if ( is_wp_error( $activate ) ) {
1667
- wp_send_json_error(
1668
- array(
1669
- 'success' => false,
1670
- 'message' => $activate->get_error_message(),
1671
- 'init' => $plugin_init,
1672
- )
1673
- );
1674
- }
1675
-
1676
- wp_send_json_success(
1677
- array(
1678
- 'success' => true,
1679
- 'message' => __( 'Plugin Successfully Activated', 'cartflows' ),
1680
- 'init' => $plugin_init,
1681
- )
1682
- );
1683
- }
1684
-
1685
- }
1686
-
1687
- /**
1688
- * Initialize class object with 'get_instance()' method
1689
- */
1690
- CartFlows_Importer::get_instance();
1691
-
1692
- endif;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * CartFlows Admin
4
+ *
5
+ * @package CartFlows
6
+ * @since 1.0.0
7
+ */
8
+
9
+ if ( ! class_exists( 'CartFlows_Importer' ) ) :
10
+
11
+ /**
12
+ * CartFlows Import
13
+ *
14
+ * @since 1.0.0
15
+ */
16
+ class CartFlows_Importer {
17
+
18
+ /**
19
+ * Instance
20
+ *
21
+ * @since 1.0.0
22
+ * @access private
23
+ * @var object Class object.
24
+ */
25
+ private static $instance;
26
+
27
+ /**
28
+ * Initiator
29
+ *
30
+ * @since 1.0.0
31
+ * @return object initialized object of class.
32
+ */
33
+ public static function get_instance() {
34
+ if ( ! isset( self::$instance ) ) {
35
+ self::$instance = new self();
36
+ }
37
+
38
+ return self::$instance;
39
+ }
40
+
41
+ /**
42
+ * Constructor
43
+ *
44
+ * @since 1.0.0
45
+ */
46
+ public function __construct() {
47
+ add_action( 'admin_enqueue_scripts', array( $this, 'scripts' ) );
48
+
49
+ add_action( 'wp_ajax_cartflows_step_import', array( $this, 'import_step' ) );
50
+ add_action( 'wp_ajax_cartflows_create_flow', array( $this, 'create_flow' ) );
51
+ add_action( 'wp_ajax_cartflows_import_flow_step', array( $this, 'import_flow' ) );
52
+ add_action( 'wp_ajax_cartflows_default_flow', array( $this, 'create_default_flow' ) );
53
+ add_action( 'wp_ajax_cartflows_step_create_blank', array( $this, 'step_create_blank' ) );
54
+
55
+ add_action( 'admin_footer', array( $this, 'js_templates' ) );
56
+ add_action( 'cartflows_import_complete', array( $this, 'clear_cache' ) );
57
+
58
+ add_filter( 'cartflows_admin_js_localize', array( $this, 'localize_vars' ) );
59
+
60
+ add_action( 'wp_ajax_cartflows_activate_plugin', array( $this, 'activate_plugin' ) );
61
+
62
+ add_action( 'admin_menu', array( $this, 'add_to_menus' ) );
63
+ add_action( 'admin_init', array( $this, 'export_json' ) );
64
+ add_action( 'admin_init', array( $this, 'import_json' ) );
65
+ add_filter( 'post_row_actions', array( $this, 'export_link' ), 10, 2 );
66
+ add_action( 'admin_action_cartflows_export_flow', array( $this, 'export_flow' ) );
67
+ }
68
+
69
+ /**
70
+ * Add the export link to action list for flows row actions
71
+ *
72
+ * @since 1.1.4
73
+ *
74
+ * @param array $actions Actions array.
75
+ * @param object $post Post object.
76
+ *
77
+ * @return array
78
+ */
79
+ public function export_link( $actions, $post ) {
80
+ if ( current_user_can( 'edit_posts' ) && isset( $post ) && CARTFLOWS_FLOW_POST_TYPE === $post->post_type ) {
81
+ $actions['export'] = '<a href="' . wp_nonce_url( 'admin.php?action=cartflows_export_flow&post=' . $post->ID, basename( __FILE__ ), 'flow_export_nonce' ) . '" title="' . __( 'Export this flow', 'cartflows' ) . '" rel="permalink">' . __( 'Export', 'cartflows' ) . '</a>';
82
+ }
83
+ return $actions;
84
+ }
85
+
86
+ /**
87
+ * Add menus
88
+ *
89
+ * @since 1.1.4
90
+ */
91
+ public function add_to_menus() {
92
+ add_submenu_page( 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE, __( 'Flow Export', 'cartflows' ), __( 'Flow Export', 'cartflows' ), 'export', 'flow_exporter', array( $this, 'exporter_markup' ) );
93
+ add_submenu_page( 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE, __( 'Flow Import', 'cartflows' ), __( 'Flow Import', 'cartflows' ), 'import', 'flow_importer', array( $this, 'importer_markup' ) );
94
+ }
95
+
96
+ /**
97
+ * Export flow with steps and its meta
98
+ *
99
+ * @since 1.1.4
100
+ */
101
+ public function export_flow() {
102
+
103
+ if ( ! ( isset( $_GET['post'] ) || isset( $_POST['post'] ) || ( isset( $_REQUEST['action'] ) && 'cartflows_export_flow' == $_REQUEST['action'] ) ) ) {
104
+ wp_die( esc_html__( 'No post to export has been supplied!', 'cartflows' ) );
105
+ }
106
+
107
+ if ( ! isset( $_GET['flow_export_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['flow_export_nonce'] ) ), basename( __FILE__ ) ) ) {
108
+ return;
109
+ }
110
+
111
+ // Get the original post id.
112
+ $flow_id = ( isset( $_GET['post'] ) ? absint( $_GET['post'] ) : absint( $_POST['post'] ) );
113
+
114
+ $flows = array();
115
+ $flows[] = $this->get_flow_export_data( $flow_id );
116
+ $flows = apply_filters( 'cartflows_export_data', $flows );
117
+
118
+ nocache_headers();
119
+ header( 'Content-Type: application/json; charset=utf-8' );
120
+ header( 'Content-Disposition: attachment; filename=cartflows-flow-' . $flow_id . '-' . gmdate( 'm-d-Y' ) . '.json' );
121
+ header( 'Expires: 0' );
122
+
123
+ echo wp_json_encode( $flows );
124
+ exit;
125
+ }
126
+
127
+ /**
128
+ * Export flow markup
129
+ *
130
+ * @since 1.1.4
131
+ */
132
+ public function exporter_markup() {
133
+ include_once CARTFLOWS_DIR . 'includes/exporter.php';
134
+ }
135
+
136
+ /**
137
+ * Import flow markup
138
+ *
139
+ * @since 1.1.4
140
+ */
141
+ public function importer_markup() {
142
+ include_once CARTFLOWS_DIR . 'includes/importer.php';
143
+ }
144
+
145
+ /**
146
+ * Export flow
147
+ *
148
+ * @since 1.1.4
149
+ */
150
+ public function export_json() {
151
+ if ( empty( $_POST['cartflows-action'] ) || 'export' != $_POST['cartflows-action'] ) {
152
+ return;
153
+ }
154
+
155
+ if ( isset( $_POST['cartflows-action-nonce'] ) && ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['cartflows-action-nonce'] ) ), 'cartflows-action-nonce' ) ) {
156
+ return;
157
+ }
158
+
159
+ if ( ! current_user_can( 'manage_options' ) ) {
160
+ return;
161
+ }
162
+
163
+ $flows = $this->get_all_flow_export_data();
164
+ $flows = apply_filters( 'cartflows_export_data', $flows );
165
+
166
+ nocache_headers();
167
+ header( 'Content-Type: application/json; charset=utf-8' );
168
+ header( 'Content-Disposition: attachment; filename=cartflows-flow-export-' . gmdate( 'm-d-Y' ) . '.json' );
169
+ header( 'Expires: 0' );
170
+
171
+ echo wp_json_encode( $flows );
172
+ exit;
173
+ }
174
+
175
+ /**
176
+ * Get flow export data
177
+ *
178
+ * @since 1.1.4
179
+ *
180
+ * @param integer $flow_id Flow ID.
181
+ * @return array
182
+ */
183
+ public function get_flow_export_data( $flow_id ) {
184
+
185
+ $export_all = apply_filters( 'cartflows_export_all', true );
186
+
187
+ $valid_step_meta_keys = array(
188
+ '_wp_page_template',
189
+ '_thumbnail_id',
190
+ 'classic-editor-remember',
191
+ );
192
+
193
+ $new_steps = array();
194
+ $steps = get_post_meta( $flow_id, 'wcf-steps', true );
195
+ if ( $steps ) {
196
+ foreach ( $steps as $key => $step ) {
197
+
198
+ // Add step post meta.
199
+ $new_all_meta = array();
200
+ $all_meta = get_post_meta( $step['id'] );
201
+
202
+ // Add single step.
203
+ $step_data_arr = array(
204
+ 'title' => get_the_title( $step['id'] ),
205
+ 'type' => $step['type'],
206
+ 'meta' => $all_meta,
207
+ 'post_content' => '',
208
+ );
209
+
210
+ if ( $export_all ) {
211
+
212
+ $step_post_obj = get_post( $step['id'] );
213
+
214
+ $step_data_arr['post_content'] = $step_post_obj->post_content;
215
+ }
216
+
217
+ $new_steps[] = $step_data_arr;
218
+ }
219
+ }
220
+
221
+ // Add single flow.
222
+ return array(
223
+ 'title' => get_the_title( $flow_id ),
224
+ 'steps' => $new_steps,
225
+ );
226
+ }
227
+
228
+ /**
229
+ * Get all flow export data
230
+ *
231
+ * @since 1.1.4
232
+ */
233
+ public function get_all_flow_export_data() {
234
+
235
+ $query_args = array(
236
+ 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
237
+
238
+ // Query performance optimization.
239
+ 'fields' => 'ids',
240
+ 'no_found_rows' => true,
241
+ 'posts_per_page' => -1,
242
+ );
243
+
244
+ $query = new WP_Query( $query_args );
245
+ $flows = array();
246
+ if ( $query->posts ) {
247
+ foreach ( $query->posts as $key => $post_id ) {
248
+ $flows[] = $this->get_flow_export_data( $post_id );
249
+ }
250
+ }
251
+
252
+ return $flows;
253
+ }
254
+
255
+ /**
256
+ * Import our exported file
257
+ *
258
+ * @since 1.1.4
259
+ */
260
+ public function import_json() {
261
+ if ( empty( $_POST['cartflows-action'] ) || 'import' != $_POST['cartflows-action'] ) {
262
+ return;
263
+ }
264
+
265
+ if ( isset( $_POST['cartflows-action-nonce'] ) && ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['cartflows-action-nonce'] ) ), 'cartflows-action-nonce' ) ) {
266
+ return;
267
+ }
268
+
269
+ if ( ! current_user_can( 'manage_options' ) ) {
270
+ return;
271
+ }
272
+
273
+ $filename = $_FILES['file']['name']; //phpcs:ignore
274
+ $file_info = explode( '.', $filename );
275
+ $extension = end( $file_info );
276
+
277
+ if ( 'json' != $extension ) {
278
+ wp_die( esc_html__( 'Please upload a valid .json file', 'cartflows' ) );
279
+ }
280
+
281
+ $file = $_FILES['file']['tmp_name']; //phpcs:ignore
282
+
283
+ if ( empty( $file ) ) {
284
+ wp_die( esc_html__( 'Please upload a file to import', 'cartflows' ) );
285
+ }
286
+
287
+ // Retrieve the settings from the file and convert the JSON object to an array.
288
+ $flows = json_decode( file_get_contents( $file ), true );//phpcs:ignore
289
+
290
+ $this->import_from_json_data( $flows );
291
+
292
+ add_action( 'admin_notices', array( $this, 'imported_successfully' ) );
293
+ }
294
+
295
+ /**
296
+ * Import flow from the JSON data
297
+ *
298
+ * @since x.x.x
299
+ * @param array $flows JSON array.
300
+ * @return void
301
+ */
302
+ public function import_from_json_data( $flows ) {
303
+ if ( $flows ) {
304
+
305
+ $default_page_builder = Cartflows_Helper::get_common_setting( 'default_page_builder' );
306
+
307
+ foreach ( $flows as $key => $flow ) {
308
+
309
+ $flow_title = $flow['title'];
310
+ if ( post_exists( $flow['title'] ) ) {
311
+ $flow_title = $flow['title'] . ' Copy';
312
+ }
313
+
314
+ // Create post object.
315
+ $new_flow_args = apply_filters(
316
+ 'cartflows_flow_importer_args',
317
+ array(
318
+ 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
319
+ 'post_title' => $flow_title,
320
+ 'post_status' => 'publish',
321
+ )
322
+ );
323
+
324
+ // Insert the post into the database.
325
+ $flow_id = wp_insert_post( $new_flow_args );
326
+
327
+ /**
328
+ * Fire after flow import
329
+ *
330
+ * @since x.x.x
331
+ * @param int $flow_id Flow ID.
332
+ * @param array $new_flow_args Flow post args.
333
+ * @param array $flows Flow JSON data.
334
+ */
335
+ do_action( 'cartflows_flow_imported', $flow_id, $new_flow_args, $flows );
336
+
337
+ if ( $flow['steps'] ) {
338
+ foreach ( $flow['steps'] as $key => $step ) {
339
+
340
+ $new_all_meta = array();
341
+ if ( is_array( $step['meta'] ) ) {
342
+ foreach ( $step['meta'] as $meta_key => $mvalue ) {
343
+ $new_all_meta[ $meta_key ] = maybe_unserialize( $mvalue[0] );
344
+ }
345
+ }
346
+ $new_step_args = apply_filters(
347
+ 'cartflows_step_importer_args',
348
+ array(
349
+ 'post_type' => CARTFLOWS_STEP_POST_TYPE,
350
+ 'post_title' => $step['title'],
351
+ 'post_status' => 'publish',
352
+ 'meta_input' => $new_all_meta,
353
+ 'post_content' => isset( $step['post_content'] ) ? $step['post_content'] : '',
354
+ )
355
+ );
356
+
357
+ $new_step_id = wp_insert_post( $new_step_args );
358
+
359
+ /**
360
+ * Fire after step import
361
+ *
362
+ * @since x.x.x
363
+ * @param int $new_step_id step ID.
364
+ * @param int $flow_id flow ID.
365
+ * @param array $new_step_args Step post args.
366
+ * @param array $flow_steps Flow steps.
367
+ * @param array $flows All flows JSON data.
368
+ */
369
+ do_action( 'cartflows_step_imported', $new_step_id, $flow_id, $new_step_args, $flow['steps'], $flows );
370
+
371
+ // Insert post meta.
372
+ update_post_meta( $new_step_id, 'wcf-flow-id', $flow_id );
373
+
374
+ $step_taxonomy = CARTFLOWS_TAXONOMY_STEP_TYPE;
375
+ $current_term = term_exists( $step['type'], $step_taxonomy );
376
+
377
+ // // Set type object.
378
+ $data = get_term( $current_term['term_id'], $step_taxonomy );
379
+ $step_slug = $data->slug;
380
+ wp_set_object_terms( $new_step_id, $data->slug, $step_taxonomy );
381
+
382
+ // Set type.
383
+ update_post_meta( $new_step_id, 'wcf-step-type', $data->slug );
384
+
385
+ // Set flow.
386
+ wp_set_object_terms( $new_step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
387
+
388
+ self::get_instance()->set_step_to_flow( $flow_id, $new_step_id, $step['title'], $step_slug );
389
+
390
+ if ( isset( $step['post_content'] ) && ! empty( $step['post_content'] ) ) {
391
+
392
+ // Download and replace images.
393
+ $content = $this->get_content( $step['post_content'] );
394
+
395
+ // Update post content.
396
+ wp_update_post(
397
+ array(
398
+ 'ID' => $new_step_id,
399
+ 'post_content' => $content,
400
+ )
401
+ );
402
+ }
403
+
404
+ // Elementor Data.
405
+ if ( ( 'elementor' === $default_page_builder ) && class_exists( '\Elementor\Plugin' ) ) {
406
+ // Add "elementor" in import [queue].
407
+ // @todo Remove required `allow_url_fopen` support.
408
+ if ( ini_get( 'allow_url_fopen' ) && isset( $step['meta']['_elementor_data'] ) ) {
409
+ $obj = new \Elementor\TemplateLibrary\CartFlows_Importer_Elementor();
410
+ $obj->import_single_template( $new_step_id );
411
+ }
412
+ }
413
+
414
+ // Beaver Builder.
415
+ if ( ( 'beaver-builder' === $default_page_builder ) && class_exists( 'FLBuilder' ) ) {
416
+ if ( isset( $step['meta']['_fl_builder_data'] ) ) {
417
+ CartFlows_Importer_Beaver_Builder::get_instance()->import_single_post( $new_step_id );
418
+ }
419
+ }
420
+ }
421
+ }
422
+ }
423
+ }
424
+ }
425
+
426
+ /**
427
+ * Download and Replace hotlink images
428
+ *
429
+ * @since x.x.x
430
+ *
431
+ * @param string $content Mixed post content.
432
+ * @return array Hotlink image array.
433
+ */
434
+ public function get_content( $content = '' ) {
435
+
436
+ $content = stripslashes( $content );
437
+
438
+ // Extract all links.
439
+ $all_links = wp_extract_urls( $content );
440
+
441
+ // Not have any link.
442
+ if ( empty( $all_links ) ) {
443
+ return $content;
444
+ }
445
+
446
+ $link_mapping = array();
447
+ $image_links = array();
448
+ $other_links = array();
449
+
450
+ // Extract normal and image links.
451
+ foreach ( $all_links as $key => $link ) {
452
+ if ( preg_match( '/^((https?:\/\/)|(www\.))([a-z0-9-].?)+(:[0-9]+)?\/[\w\-]+\.(jpg|png|gif|jpeg)\/?$/i', $link ) ) {
453
+
454
+ // Get all image links.
455
+ // Avoid *-150x, *-300x and *-1024x images.
456
+ if (
457
+ false === strpos( $link, '-150x' ) &&
458
+ false === strpos( $link, '-300x' ) &&
459
+ false === strpos( $link, '-1024x' )
460
+ ) {
461
+ $image_links[] = $link;
462
+ }
463
+ } else {
464
+
465
+ // Collect other links.
466
+ $other_links[] = $link;
467
+ }
468
+ }
469
+
470
+ // Step 1: Download images.
471
+ if ( ! empty( $image_links ) ) {
472
+ foreach ( $image_links as $key => $image_url ) {
473
+ // Download remote image.
474
+ $image = array(
475
+ 'url' => $image_url,
476
+ 'id' => 0,
477
+ );
478
+ $downloaded_image = CartFlows_Import_Image::get_instance()->import( $image );
479
+
480
+ // Old and New image mapping links.
481
+ $link_mapping[ $image_url ] = $downloaded_image['url'];
482
+ }
483
+ }
484
+
485
+ // Step 3: Replace mapping links.
486
+ foreach ( $link_mapping as $old_url => $new_url ) {
487
+ $content = str_replace( $old_url, $new_url, $content );
488
+
489
+ // Replace the slashed URLs if any exist.
490
+ $old_url = str_replace( '/', '/\\', $old_url );
491
+ $new_url = str_replace( '/', '/\\', $new_url );
492
+ $content = str_replace( $old_url, $new_url, $content );
493
+ }
494
+
495
+ return $content;
496
+ }
497
+
498
+ /**
499
+ * Imported notice
500
+ *
501
+ * @since 1.1.4
502
+ */
503
+ public function imported_successfully() {
504
+ ?>
505
+ <div class="notice notice-success">
506
+ <p><?php esc_html_e( 'Successfully imported flows.', 'cartflows' ); ?></p>
507
+ </div>
508
+ <?php
509
+ }
510
+
511
+ /**
512
+ * Clear Cache.
513
+ *
514
+ * @since 1.0.0
515
+ */
516
+ public function clear_cache() {
517
+ // Clear 'Elementor' file cache.
518
+ if ( class_exists( '\Elementor\Plugin' ) ) {
519
+ \Elementor\Plugin::$instance->files_manager->clear_cache();
520
+ }
521
+ }
522
+
523
+ /**
524
+ * JS Templates
525
+ *
526
+ * @since 1.0.0
527
+ *
528
+ * @return void
529
+ */
530
+ public function js_templates() {
531
+
532
+ // Loading Templates.
533
+ ?>
534
+ <script type="text/template" id="tmpl-cartflows-step-loading">
535
+ <div class="template-message-block cartflows-step-loading">
536
+ <h2>
537
+ <span class="spinner"></span>
538
+ <?php esc_html_e( 'Loading Steps', 'cartflows' ); ?>
539
+ </h2>
540
+ <p class="description"><?php esc_html_e( 'Getting steps from the cloud. Please wait for the moment.', 'cartflows' ); ?></p>
541
+ </div>
542
+ </script>
543
+
544
+ <?php
545
+ // Search Templates.
546
+ ?>
547
+ <script type="text/template" id="tmpl-cartflows-searching-templates">
548
+ <div class="template-message-block cartflows-searching-templates">
549
+ <h2>
550
+ <span class="spinner"></span>
551
+ <?php esc_html_e( 'Searching Template..', 'cartflows' ); ?>
552
+ </h2>
553
+ <p class="description"><?php esc_html_e( 'Getting templates from the cloud. Please wait for the moment.', 'cartflows' ); ?></p>
554
+ </div>
555
+ </script>
556
+
557
+ <?php
558
+ // CartFlows Importing Template.
559
+ ?>
560
+ <script type="text/template" id="tmpl-cartflows-step-importing">
561
+ <div class="template-message-block cartflows-step-importing">
562
+ <h2><span class="spinner"></span> <?php esc_html_e( 'Importing..', 'cartflows' ); ?></h2>
563
+ </div>
564
+ </script>
565
+
566
+ <?php
567
+ // CartFlows Imported.
568
+ ?>
569
+ <script type="text/template" id="tmpl-cartflows-step-imported">
570
+ <div class="template-message-block cartflows-step-imported">
571
+ <h2><span class="dashicons dashicons-yes"></span> <?php esc_html_e( 'Imported', 'cartflows' ); ?></h2>
572
+ <p class="description"><?php esc_html_e( 'Thanks for patience', 'cartflows' ); ?> <span class="dashicons dashicons-smiley"></span></p></div>
573
+ </script>
574
+
575
+ <?php
576
+ // No templates.
577
+ ?>
578
+ <script type="text/template" id="tmpl-cartflows-no-steps">
579
+ <div class="cartflows-no-steps">
580
+ <div class="template-message-block">
581
+ <h2><?php esc_html_e( 'Coming Soon!', 'cartflows' ); ?></h2>
582
+ <p class="description"></p>
583
+ </div>
584
+ </div>
585
+ </script>
586
+
587
+ <?php
588
+ // No templates.
589
+ ?>
590
+ <script type="text/template" id="tmpl-cartflows-no-flows">
591
+ <div class="cartflows-no-flows">
592
+ <div class="template-message-block">
593
+ <h2><?php esc_html_e( 'Coming Soon!', 'cartflows' ); ?></h2>
594
+ <p class="description"></p>
595
+ </div>
596
+ </div>
597
+ </script>
598
+
599
+ <?php
600
+ // Error handling.
601
+ ?>
602
+ <script type="text/template" id="tmpl-templator-error">
603
+ <div class="notice notice-error"><p>{{ data }}</p></div>
604
+ </script>
605
+
606
+ <?php
607
+ // Redirect to Elementor.
608
+ ?>
609
+ <script type="text/template" id="tmpl-templator-redirect-to-elementor">
610
+ <div class="template-message-block templator-redirect-to-elementor">
611
+ <h2><span class="dashicons dashicons-yes"></span> <?php esc_html_e( 'Imported', 'cartflows' ); ?></h2>
612
+ <p class="description"><?php esc_html_e( 'Thanks for patience', 'cartflows' ); ?> <span class="dashicons dashicons-smiley"></span><br/><br/><?php esc_html_e( 'Redirecting to the Elementor edit window.', 'cartflows' ); ?> </p></div>
613
+ </script>
614
+
615
+ <?php
616
+ /**
617
+ * Responsive Buttons
618
+ */
619
+ ?>
620
+ <script type="text/template" id="tmpl-cartflows-responsive-view">
621
+ <span class="responsive-view">
622
+ <span class="actions">
623
+ <a class="desktop" href="#"><span data-view="desktop " class="active dashicons dashicons-desktop"></span></a>
624
+ <a class="tablet" href="#"><span data-view="tablet" class="dashicons dashicons-tablet"></span></a>
625
+ <a class="mobile" href="#"><span data-view="mobile" class="dashicons dashicons-smartphone"></span></a>
626
+ </span>
627
+ </span>
628
+ </script>
629
+
630
+ <?php
631
+ // Templates data.
632
+ ?>
633
+ <script type="text/template" id="tmpl-cartflows-flows-list">
634
+
635
+ <# console.log( data.items.length ) #>
636
+ <# console.log( data.items ) #>
637
+ <# if ( data.items.length ) { #>
638
+ <# for ( key in data.items ) { #>
639
+ <#
640
+ var flow_steps = [];
641
+ if( data.items[ key ].flow_steps ) {
642
+ flow_steps = data.items[ key ].flow_steps.map(function(value,index) {
643
+ return value['id'];
644
+ });
645
+ }
646
+ #>
647
+ <div class="inner">
648
+ <div class="template">
649
+ <span class="thumbnail site-preview cartflows-preview-flow-steps" data-flow-steps="{{ JSON.stringify( data.items[ key ].flow_steps ) }}" data-title="{{ data.items[ key ].title.rendered }}">
650
+ <div class="template-screenshot">
651
+ <# if( data.items[ key ].featured_image_url ) { #>
652
+ <img src="{{ data.items[ key ].featured_image_url }}" />
653
+ <# } else { #>
654
+ <img src="<?php echo esc_attr( CARTFLOWS_URL ); ?>assets/images/400x400.jpg" />
655
+ <# } #>
656
+ </div>
657
+ <# if( data.items[ key ].flow_type && 'pro' === data.items[ key ].flow_type.slug ) { #>
658
+ <span class="wcf-flow-type pro"><?php esc_html_e( 'Pro', 'cartflows' ); ?></span>
659
+ <# } #>
660
+ <# if( data.items[ key ].woo_required ) { #>
661
+ <div class="notice notice-info" style="width: auto;">
662
+ <p class="wcf-learn-how">
663
+ Install/Activate WooCommerce to use this template.
664
+ <a href="https://cartflows.com/docs/cartflows-step-types/" target="_blank">
665
+ <strong><?php esc_html_e( 'Learn How', 'cartflows' ); ?></strong>
666
+ <i class="dashicons dashicons-external"></i>
667
+ </a>
668
+ </p>
669
+ </div>
670
+ <# } else { #>
671
+ <a href="<?php echo CARTFLOWS_TEMPLATES_URL . 'preview/?'; ?>flow={{ data.items[ key ].id }}&title={{{ data.items[ key ].title.rendered }}}" class="preview" target="_blank">Preview <i class="dashicons dashicons-external"></i></a>
672
+ <# } #>
673
+
674
+ </span>
675
+ <div class="template-id-container">
676
+ <h3 class="template-name"> {{{ data.items[ key ].title.rendered }}} </h3>
677
+ <div class="template-actions">
678
+
679
+ <#
680
+ if( data.items[ key ].page_builder.slug ) {
681
+ required_plugin_group = data.items[ key ].page_builder.slug;
682
+ } else {
683
+ required_plugin_group = '';
684
+ }
685
+
686
+ if( data.items[ key ].page_builder.slug && CartFlowsImportVars.required_plugins[data.items[ key ].page_builder.slug] && CartFlowsImportVars.required_plugins[data.items[ key ].page_builder.slug].button_title ) {
687
+ import_btn_title = CartFlowsImportVars.required_plugins[ data.items[ key ].page_builder.slug ].button_title;
688
+ } else {
689
+ import_btn_title = 'Import';
690
+ } #>
691
+
692
+ <# if( data.items[ key ].licence_status && 'valid' === data.items[ key ].licence_status ) { #>
693
+ <# if( ! data.items[ key ].woo_required ) { #>
694
+ <a data-flow-steps="{{ flow_steps }}" data-required-plugin-group="{{required_plugin_group}}" href="#" class="button button-primary cartflows-step-import" data-template-id="{{ data.items[ key ].id }}">{{ import_btn_title }}</a>
695
+ <# } else { #>
696
+ <a href='#' class='wcf-activate-wc button-primary'>Install & activate Woo</a>
697
+ <# } #>
698
+ <# } else if( CartFlowsImportVars._is_pro_active ) { #>
699
+ <a target="_blank" href="<?php echo esc_url( admin_url( 'plugins.php?cartflows-license-popup' ) ); ?>" class="button button-primary"><?php esc_html_e( 'Activate License', 'cartflows' ); ?></a>
700
+ <# } else { #>
701
+ <a target="_blank" href="<?php echo esc_url( CARTFLOWS_DOMAIN_URL ); ?>" class="button button-primary"><?php esc_html_e( 'Get Pro', 'cartflows' ); ?></a>
702
+ <# } #>
703
+ </div>
704
+ </div>
705
+ </div>
706
+ </div>
707
+ <# } #>
708
+ <# } #>
709
+ </script>
710
+
711
+ <?php
712
+ // Empty Step.
713
+ ?>
714
+ <script type="text/template" id="tmpl-cartflows-create-blank-step">
715
+ <div class="inner">
716
+ <div class="template">
717
+ <span class="thumbnail site-preview cartflows-flow-preview">
718
+ <div class="template-screenshot">
719
+ <img src="<?php echo esc_attr( CARTFLOWS_URL ); ?>assets/images/start-scratch.jpg" />
720
+ </div>
721
+ <div id="wcf_create_notice" class=""><a href="https://cartflows.com/" target="_blank"></a></div>
722
+ </span>
723
+ <div class="template-id-container">
724
+ <h3 class="template-name"> Blank </h3>
725
+ <div class="template-actions">
726
+ <a href="#" class="button button-primary cartflows-step-import-blank"><?php esc_html_e( 'Create', 'cartflows' ); ?></a>
727
+ </div>
728
+ </div>
729
+ </div>
730
+ </div>
731
+ </script>
732
+
733
+ <?php
734
+ // Templates data.
735
+ ?>
736
+ <script type="text/template" id="tmpl-cartflows-steps-list">
737
+ <# if ( data.items.length ) { #>
738
+ <# for ( key in data.items ) { #>
739
+ <#
740
+ var flow_steps = [];
741
+ if( data.items[ key ].flow_steps ) {
742
+ flow_steps = data.items[ key ].flow_steps.map(function(value,index) {
743
+ return value['id'];
744
+ });
745
+ }
746
+ #>
747
+ <div class="inner">
748
+ <div class="template">
749
+ <span class="thumbnail site-preview cartflows-preview-flow-steps" data-flow-steps="{{ JSON.stringify( data.items[ key ].flow_steps ) }}" data-title="{{ data.items[ key ].title.rendered }}">
750
+ <div class="template-screenshot">
751
+ <# if( data.items[ key ].featured_image_url ) { #>
752
+ <img src="{{ data.items[ key ].featured_image_url }}" />
753
+ <# } else { #>
754
+ <img src="<?php echo esc_attr( CARTFLOWS_URL ); ?>assets/images/400x400.jpg" />
755
+ <# } #>
756
+ </div>
757
+ <div id="wcf_create_notice" class=""><a href="https://cartflows.com/" target="_blank"></a></div>
758
+
759
+ <# if( data.items[ key ].woo_required ) { #>
760
+ <div class="notice notice-info" style="width: auto;">
761
+ <p class="wcf-learn-how">
762
+ Install/Activate WooCommerce to use this template.
763
+ <a href="https://cartflows.com/docs/cartflows-step-types/" target="_blank">
764
+ <strong><?php esc_html_e( 'Learn How', 'cartflows' ); ?></strong>
765
+ <i class="dashicons dashicons-external"></i>
766
+ </a>
767
+ </p>
768
+ </div>
769
+ <# } else { #>
770
+ <a href="<?php echo CARTFLOWS_TEMPLATES_URL . 'preview/?'; ?>step={{ data.items[ key ].id }}&title={{{ data.items[ key ].title.rendered }}}" class="preview" target="_blank">Preview <i class="dashicons dashicons-external"></i></a>
771
+ <# } #>
772
+
773
+ <# if( data.items[ key ].flow_type && 'pro' === data.items[ key ].flow_type.slug ) { #>
774
+ <span class="wcf-flow-type pro"><?php esc_html_e( 'Pro', 'cartflows' ); ?></span>
775
+ <# } #>
776
+ </span>
777
+ <div class="template-id-container">
778
+ <h3 class="template-name"> {{{ data.items[ key ].title.rendered }}} </h3>
779
+ <div class="template-actions">
780
+
781
+ <#
782
+
783
+ var step_slug = data.items[ key ].step_type.slug || '';
784
+ var step_title = data.items[ key ].step_type.name || '';
785
+ var import_btn_title = 'Import';
786
+
787
+ var required_plugin_group = '';
788
+ if( data.items[ key ].page_builder ) {
789
+ required_plugin_group = data.items[ key ].page_builder.slug;
790
+
791
+ if( data.items[ key ].page_builder.slug && CartFlowsImportVars.required_plugins[data.items[ key ].page_builder.slug] && CartFlowsImportVars.required_plugins[data.items[ key ].page_builder.slug].button_title ) {
792
+ import_btn_title = CartFlowsImportVars.required_plugins[ data.items[ key ].page_builder.slug ].button_title;
793
+ }
794
+ }
795
+ #>
796
+
797
+ <# if( data.items[ key ].licence_status && 'valid' === data.items[ key ].licence_status ) { #>
798
+
799
+ <# if( ! data.items[ key ].woo_required ) { #>
800
+ <a data-slug="{{step_slug}}" data-title="{{step_title}}" data-flow-steps="{{ flow_steps }}" data-required-plugin-group="{{required_plugin_group}}" href="#" class="button button-primary cartflows-step-import" data-template-id="{{ data.items[ key ].id }}">{{ import_btn_title }}</a>
801
+ <# } else { #>
802
+ <a href='#' class='wcf-activate-wc button-primary'>Install & activate Woo</a>
803
+ <# } #>
804
+
805
+ <# } else if( CartFlowsImportVars._is_pro_active ) { #>
806
+ <a target="_blank" href="<?php echo esc_url( admin_url( 'plugins.php?cartflows-license-popup' ) ); ?>" class="button button-primary"><?php esc_html_e( 'Activate License', 'cartflows' ); ?></a>
807
+ <# } else { #>
808
+ <a target="_blank" href="<?php echo esc_url( CARTFLOWS_DOMAIN_URL ); ?>" class="button button-primary"><?php esc_html_e( 'Get Pro', 'cartflows' ); ?></a>
809
+ <# } #>
810
+ </div>
811
+ </div>
812
+ </div>
813
+ </div>
814
+ <# } #>
815
+ <# } #>
816
+ </script>
817
+
818
+ <?php
819
+ /**
820
+ * TMPL - Website Unreachable
821
+ */
822
+ ?>
823
+ <script type="text/template" id="tmpl-cartflows-website-unreachable">
824
+ <div class="postbox cartflows-website-unreachable">
825
+ <h2><?php esc_html_e( 'Under Maintenance..', 'cartflows' ); ?></h2>
826
+ <p><?php esc_html_e( 'If you are seeing this message, most likely our servers are under routine maintenance and we will be back shortly.', 'cartflows' ); ?></p>
827
+ <p><?php esc_html_e( 'In rare case, it is possible your website is having trouble connecting with ours. If you need help, please feel free to get in touch with us from our website..', 'cartflows' ); ?></p>
828
+ </div>
829
+ </script>
830
+
831
+ <?php
832
+ /**
833
+ * TMPL - Filters
834
+ */
835
+ ?>
836
+ <script type="text/template" id="tmpl-cartflows-page-builder-notice">
837
+ <?php
838
+ $default_page_builder = Cartflows_Helper::get_common_setting( 'default_page_builder' );
839
+ $page_builder = Cartflows_Helper::get_required_plugins_for_page_builder( Cartflows_Helper::get_common_setting( 'default_page_builder' ) );
840
+ $title = $page_builder['title'];
841
+
842
+ $plugin_string = '<a href="#" data-slug="' . esc_html( $default_page_builder ) . '" class="wcf-install-plugin">Please click here and activate ' . esc_html( $title ) . '</a>';
843
+ $theme_status = '';
844
+ if ( 'divi' === $default_page_builder ) {
845
+
846
+ $theme_status = $page_builder['theme-status'];
847
+ $plugin_status = $page_builder['plugin-status'];
848
+
849
+ if ( 'deactivate' === $theme_status || 'install' === $plugin_status ) {
850
+ $plugin_string = 'Please activate ' . esc_html( $title );
851
+ } elseif ( ( 'deactivate' === $theme_status || 'not-installed' === $theme_status ) && 'install' === $plugin_status ) {
852
+ $plugin_string = 'Please install and activate ' . esc_html( $title );
853
+ }
854
+ }
855
+ ?>
856
+ <div class="wcf-page-builder-message">
857
+ <p><?php /* translators: %s: Plugin string */ printf( __( '%1$s to see CartFlows templates. If you prefer another page builder tool, you can <a href="%2$s" target="blank">select it here</a>.', 'cartflows' ), $plugin_string, admin_url( 'admin.php?page=' . CARTFLOWS_SETTINGS . '&action=common-settings#form-field-wcf_default_page_builder' ) ); ?></p>
858
+ <p>If your preferred page builder is not available, feel free to <a href="#" data-slug="canvas" class="wcf-create-from-scratch-link">create your own</a> pages using page builder of your choice as CartFlows works with all major page builders.</p>
859
+ <p>We plan to add design templates made with more page builder shortly!</p>
860
+ </div>
861
+ </script>
862
+
863
+ <?php
864
+ /**
865
+ * TMPL - Filters
866
+ */
867
+ ?>
868
+ <script type="text/template" id="tmpl-cartflows-term-filters-dropdown">
869
+ <# if ( data ) { #>
870
+ <select class="{{ data.args.wrapper_class }} {{ data.args.class }}">
871
+ <# if ( data.args.show_all ) { #>
872
+ <option value="all"> <?php esc_html_e( 'All', 'cartflows' ); ?> </option>
873
+ <# } #>
874
+ <# if ( CartFlowsImportVars.step_type === data.args.remote_slug ) { #>
875
+ <option value=""> <?php esc_html_e( 'Select Step Type', 'cartflows' ); ?> </option>
876
+ <# } #>
877
+ <# var step_slug_data = []; #>
878
+ <# for ( key in data.items ) { #>
879
+ <option value='{{ data.items[ key ].id }}' data-group='{{ data.items[ key ].id }}' class="{{ data.items[ key ].name }}" data-slug="{{ data.items[ key ].slug }}" data-title="{{ data.items[ key ].name }}">{{ data.items[ key ].name }}</option>
880
+
881
+ <# step_slug_data.push( data.items[ key ].slug ); #>
882
+
883
+ <# } #>
884
+ <# if( step_slug_data.indexOf("optin") === -1){ #>
885
+ <option value='0' data-group='0' class="Optin (Woo)" data-slug="optin" data-title="Optin (Woo)">Optin (Woo)</option>
886
+ <# } #>
887
+ </select>
888
+ <# } #>
889
+ </script>
890
+
891
+ <script type="text/template" id="tmpl-cartflows-term-filters">
892
+
893
+ <# if ( data ) { #>
894
+
895
+ <?php /* <# if ( CartFlowsImportVars.flow_page_builder === data.args.remote_slug || CartFlowsImportVars.step_page_builder === data.args.remote_slug ) { #> */ ?>
896
+ <ul class="{{ data.args.wrapper_class }} {{ data.args.class }}">
897
+
898
+ <# if ( data.args.show_all ) { #>
899
+ <li>
900
+ <a href="#" data-group="all"> All </a>
901
+ </li>
902
+ <# } #>
903
+
904
+ <# for ( key in data.items ) { #>
905
+ <li>
906
+ <a href="#" data-group='{{ data.items[ key ].id }}' class="{{ data.items[ key ].name }}" data-slug="{{ data.items[ key ].slug }}" data-title="{{ data.items[ key ].name }}">{{ data.items[ key ].name }}</a>
907
+ </li>
908
+ <# } #>
909
+
910
+ </ul>
911
+
912
+ <?php
913
+
914
+ /**
915
+ <# } else { #>
916
+ <select class="{{ data.args.wrapper_class }} {{ data.args.class }}">
917
+
918
+ <# if ( data.args.show_all ) { #>
919
+ <option value="all"> <?php _e( 'All', 'cartflows' ); ?> </option>
920
+ <# } #>
921
+
922
+ <# if ( CartFlowsImportVars.step_type === data.args.remote_slug ) { #>
923
+ <option value=""> <?php _e( 'Select Step Type', 'cartflows' ); ?> </option>
924
+ <# } #>
925
+
926
+ <# for ( key in data.items ) { #>
927
+ <option value='{{ data.items[ key ].id }}' data-group='{{ data.items[ key ].id }}' class="{{ data.items[ key ].name }}" data-slug="{{ data.items[ key ].slug }}" data-title="{{ data.items[ key ].name }}">{{ data.items[ key ].name }}</option>
928
+ <# } #>
929
+
930
+ </select>
931
+ */
932
+ ?>
933
+
934
+ <?php /* <# } #> */ ?>
935
+
936
+ <# } #>
937
+ </script>
938
+
939
+ <?php
940
+ // Step Type.
941
+ ?>
942
+ <script type="text/template" id="tmpl-cartflows-step-types">
943
+ <ul class="wcf-tab nav-tabs">
944
+ <# if( data.items_count ) { #>
945
+ <# for( key in data.items ) { #>
946
+ <# console.log( data.items[ key ].id ) #>
947
+ <li data-slug="{{data.items[ key ].slug}}" data-title="{{ data.items[ key ].name }}">
948
+ <a href="#{{{ data.items[ key ].slug }}}">{{{ data.items[ key ].name }}}</a>
949
+ </li>
950
+ <# } #>
951
+ <# } #>
952
+ </ul>
953
+ </script>
954
+
955
+ <?php
956
+ // Add to library button.
957
+ ?>
958
+ <script type="text/template" id="tmpl-templator-add-to-library">
959
+ <a class="templator-add-to-library page-title-action cartflows-load-steps-library"><i class="dashicons dashicons-cloud"></i><?php esc_attr_e( 'Import from Cloud', 'cartflows' ); ?></a>
960
+ </script>
961
+ <?php
962
+ }
963
+
964
+ /**
965
+ * Enqueue scripts
966
+ *
967
+ * @since 1.0.0
968
+ *
969
+ * @hook admin_enqueue_scripts
970
+ * @param string $hook Current page hook.
971
+ */
972
+ public function scripts( $hook = '' ) {
973
+
974
+ if ( ! self::is_supported_post( get_current_screen()->post_type ) ) {
975
+ return;
976
+ }
977
+
978
+ wp_enqueue_script( 'cartflows-rest-api', CARTFLOWS_URL . 'assets/js/rest-api.js', array( 'jquery' ), CARTFLOWS_VER, true );
979
+ wp_enqueue_style( 'cartflows-import', CARTFLOWS_URL . 'assets/css/import.css', null, CARTFLOWS_VER, 'all' );
980
+ wp_style_add_data( 'cartflows-import', 'rtl', 'replace' );
981
+ wp_enqueue_script( 'cartflows-import', CARTFLOWS_URL . 'assets/js/import.js', array( 'jquery', 'wp-util', 'cartflows-rest-api', 'updates' ), CARTFLOWS_VER, true );
982
+
983
+ $installed_plugins = get_plugins();
984
+ $is_wc_installed = isset( $installed_plugins['woocommerce/woocommerce.php'] ) ? 'yes' : 'no';
985
+ $is_wc_activated = wcf()->is_woo_active ? 'yes' : 'no';
986
+
987
+ $localize_vars = array(
988
+ '_is_pro_active' => _is_cartflows_pro(),
989
+ 'is_wc_installed' => $is_wc_installed,
990
+ 'is_wc_activated' => $is_wc_activated,
991
+
992
+ // Flow and its rest fields.
993
+ 'flow' => CARTFLOWS_FLOW_POST_TYPE,
994
+ 'flow_fields' => array(
995
+ 'id',
996
+ 'title',
997
+ 'flow_type',
998
+ 'page_builder',
999
+ 'flow_steps',
1000
+ 'licence_status',
1001
+ 'featured_image_url',
1002
+ 'featured_media', // @required for field `featured_image_url`.
1003
+ ),
1004
+
1005
+ // Flow type and rest fields.
1006
+ 'flow_type' => CARTFLOWS_TAXONOMY_FLOW_CATEGORY,
1007
+ 'flow_type_fields' => array(
1008
+ 'id',
1009
+ 'name',
1010
+ 'slug',
1011
+ ),
1012
+
1013
+ // Flow page builder and rest fields.
1014
+ 'flow_page_builder' => CARTFLOWS_TAXONOMY_FLOW_PAGE_BUILDER,
1015
+ 'flow_page_builder_fields' => array(
1016
+ 'id',
1017
+ 'name',
1018
+ 'slug',
1019
+ ),
1020
+
1021
+ // Step page builder and rest fields.
1022
+ 'step_page_builder' => CARTFLOWS_TAXONOMY_STEP_PAGE_BUILDER,
1023
+ 'step_page_builder_fields' => array(
1024
+ 'id',
1025
+ 'name',
1026
+ 'slug',
1027
+ ),
1028
+
1029
+ // Step and its rest fields.
1030
+ 'step' => CARTFLOWS_STEP_POST_TYPE,
1031
+ 'step_fields' => array(
1032
+ 'title',
1033
+ 'featured_image_url',
1034
+ 'featured_media', // @required for field `featured_image_url`.
1035
+ 'id',
1036
+ 'flow_type',
1037
+ 'step_type',
1038
+ 'page_builder',
1039
+ 'licence_status',
1040
+ ),
1041
+
1042
+ // Step type and its rest fields.
1043
+ 'step_type' => CARTFLOWS_TAXONOMY_STEP_TYPE,
1044
+ 'step_type_fields' => array(
1045
+ 'id',
1046
+ 'name',
1047
+ 'slug',
1048
+ ),
1049
+
1050
+ 'domain_url' => CARTFLOWS_DOMAIN_URL,
1051
+ 'server_url' => CARTFLOWS_TEMPLATES_URL,
1052
+ 'server_rest_url' => CARTFLOWS_TEMPLATES_URL . 'wp-json/wp/v2/',
1053
+ 'site_url' => site_url(),
1054
+ 'import_url' => admin_url( 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE . '&page=flow_importer' ),
1055
+ 'export_url' => admin_url( 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE . '&page=flow_exporter' ),
1056
+ 'admin_url' => admin_url(),
1057
+ 'licence_args' => CartFlows_API::get_instance()->get_licence_args(),
1058
+ 'ajaxurl' => admin_url( 'admin-ajax.php' ),
1059
+ 'debug' => ( ( defined( 'WP_DEBUG' ) && WP_DEBUG ) || isset( $_GET['debug'] ) ) ? true : false, //phpcs:ignore
1060
+
1061
+ 'required_plugins' => Cartflows_Helper::get_plugins_groupby_page_builders(),
1062
+
1063
+ 'default_page_builder' => Cartflows_Helper::get_common_setting( 'default_page_builder' ),
1064
+ );
1065
+
1066
+ $localize_vars['cartflows_activate_plugin_nonce'] = wp_create_nonce( 'cartflows_activate_plugin' );
1067
+
1068
+ // var_dump(Cartflows_Helper::get_common_setting( 'default_page_builder' ));
1069
+ // wp_die( );
1070
+ // Add thickbox.
1071
+ add_thickbox();
1072
+
1073
+ wp_localize_script( 'cartflows-import', 'CartFlowsImportVars', $localize_vars );
1074
+ wp_localize_script( 'cartflows-rest-api', 'CartFlowsImportVars', $localize_vars );
1075
+ }
1076
+
1077
+ /**
1078
+ * Import.
1079
+ *
1080
+ * @since 1.0.0
1081
+ *
1082
+ * @hook wp_ajax_cartflows_import_flow_step
1083
+ * @return void
1084
+ */
1085
+ public function import_flow() {
1086
+
1087
+ if ( ! current_user_can( 'manage_options' ) ) {
1088
+ return;
1089
+ }
1090
+
1091
+ check_ajax_referer( 'cf-import-flow-step', 'security' );
1092
+
1093
+ $flow_id = isset( $_POST['flow_id'] ) ? intval( $_POST['flow_id'] ) : '';
1094
+ $template_id = isset( $_POST['template_id'] ) ? intval( $_POST['template_id'] ) : '';
1095
+
1096
+ wcf()->logger->import_log( '------------------------------------' );
1097
+ wcf()->logger->import_log( 'STARTED! Importing FLOW' );
1098
+ wcf()->logger->import_log( '------------------------------------' );
1099
+ wcf()->logger->import_log( '() Creating new step from remote step [' . $template_id . '] for FLOW ' . get_the_title( $flow_id ) . ' [' . $flow_id . ']' );
1100
+
1101
+ $response = CartFlows_API::get_instance()->get_template( $template_id );
1102
+
1103
+ $post_content = isset( $response['data']['content']->rendered ) ? $response['data']['content']->rendered : '';
1104
+ if ( 'divi' === Cartflows_Helper::get_common_setting( 'default_page_builder' ) ) {
1105
+ if ( isset( $response['data']['divi_content'] ) && ! empty( $response['data']['divi_content'] ) ) {
1106
+ $post_content = $response['data']['divi_content'];
1107
+ }
1108
+ }
1109
+
1110
+ if ( 'gutenberg' === Cartflows_Helper::get_common_setting( 'default_page_builder' ) ) {
1111
+ if ( isset( $response['data']['divi_content'] ) && ! empty( $response['data']['divi_content'] ) ) {
1112
+ $post_content = $response['data']['divi_content'];
1113
+ }
1114
+ }
1115
+
1116
+ if ( false === $response['success'] ) {
1117
+ wcf()->logger->import_log( '(✕) Failed to fetch remote data.' );
1118
+ wp_send_json_error( $response );
1119
+ }
1120
+
1121
+ wcf()->logger->import_log( '(✓) Successfully getting remote step response ' . wp_json_encode( $response ) );
1122
+
1123
+ $new_step_id = wp_insert_post(
1124
+ array(
1125
+ 'post_type' => CARTFLOWS_STEP_POST_TYPE,
1126
+ 'post_title' => $response['title'],
1127
+ 'post_content' => $post_content,
1128
+ 'post_status' => 'publish',
1129
+ )
1130
+ );
1131
+
1132
+ if ( is_wp_error( $new_step_id ) ) {
1133
+ wcf()->logger->import_log( '(✕) Failed to create new step for flow ' . $flow_id );
1134
+ wp_send_json_error( $new_step_id );
1135
+ }
1136
+
1137
+ if ( 'divi' === Cartflows_Helper::get_common_setting( 'default_page_builder' ) ) {
1138
+ if ( isset( $response['data']['divi_content'] ) && ! empty( $response['data']['divi_content'] ) ) {
1139
+ update_post_meta( $new_step_id, 'divi_content', $response['data']['divi_content'] );
1140
+ }
1141
+ }
1142
+
1143
+ /* Imported Step */
1144
+ update_post_meta( $new_step_id, 'cartflows_imported_step', 'yes' );
1145
+
1146
+ wcf()->logger->import_log( '(✓) Created new step ' . '"' . $response['title'] . '" id ' . $new_step_id );//phpcs:ignore
1147
+ // insert post meta.
1148
+ update_post_meta( $new_step_id, 'wcf-flow-id', $flow_id );
1149
+ wcf()->logger->import_log( '(✓) Added flow ID ' . $flow_id . ' in post meta key wcf-flow-id.' );
1150
+
1151
+ /**
1152
+ * Import & Set type.
1153
+ */
1154
+ $term = isset( $response['data']['step_type'] ) ? $response['data']['step_type'] : '';
1155
+
1156
+ $term_slug = '';
1157
+ if ( $term ) {
1158
+
1159
+ $taxonomy = CARTFLOWS_TAXONOMY_STEP_TYPE;
1160
+ $term_exist = term_exists( $term->slug, $taxonomy );
1161
+
1162
+ if ( empty( $term_exist ) ) {
1163
+ $terms = array(
1164
+ array(
1165
+ 'name' => $term->name,
1166
+ 'slug' => $term->slug,
1167
+ ),
1168
+ );
1169
+
1170
+ Cartflows_Step_Post_Type::get_instance()->add_terms( $taxonomy, $terms );
1171
+ wcf()->logger->import_log( '(✓) Created new term name ' . $term->name . ' | term slug ' . $term->slug );
1172
+ }
1173
+
1174
+ $current_term = term_exists( $term->slug, $taxonomy );
1175
+
1176
+ // Set type object.
1177
+ $data = get_term( $current_term['term_id'], $taxonomy );
1178
+ $term_slug = $data->slug;
1179
+ $term_name = $data->name;
1180
+ wp_set_object_terms( $new_step_id, $term_slug, CARTFLOWS_TAXONOMY_STEP_TYPE );
1181
+ wcf()->logger->import_log( '(✓) Assigned existing term ' . $term_name . ' to the template ' . $new_step_id );
1182
+
1183
+ // Set type.
1184
+ update_post_meta( $new_step_id, 'wcf-step-type', $term_slug );
1185
+ wcf()->logger->import_log( '(✓) Updated term ' . $term_name . ' to the post meta wcf-step-type.' );
1186
+ }
1187
+
1188
+ // Set flow.
1189
+ wp_set_object_terms( $new_step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
1190
+ wcf()->logger->import_log( '(✓) Assigned flow step flow-' . $flow_id );
1191
+
1192
+ /**
1193
+ * Update steps for the current flow.
1194
+ */
1195
+ $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
1196
+
1197
+ if ( ! is_array( $flow_steps ) ) {
1198
+ $flow_steps = array();
1199
+ }
1200
+
1201
+ $flow_steps[] = array(
1202
+ 'id' => $new_step_id,
1203
+ 'title' => $response['title'],
1204
+ 'type' => $term_slug,
1205
+ );
1206
+ update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
1207
+ wcf()->logger->import_log( '(✓) Updated flow steps post meta key \'wcf-steps\' ' . wp_json_encode( $flow_steps ) );
1208
+
1209
+ // Import Post Meta.
1210
+ self::import_post_meta( $new_step_id, $response );
1211
+
1212
+ wcf()->logger->import_log( '(✓) Importing step "' . get_the_title( $new_step_id ) . '" [' . $new_step_id . '] for FLOW "' . get_the_title( $flow_id ) . '" [' . $flow_id . ']' );
1213
+ wcf()->logger->import_log( '------------------------------------' );
1214
+ wcf()->logger->import_log( 'COMPLETE! Importing FLOW' );
1215
+ wcf()->logger->import_log( '------------------------------------' );
1216
+
1217
+ do_action( 'cartflows_import_complete' );
1218
+ wcf()->logger->import_log( '(✓) BATCH STARTED for step ' . $new_step_id . ' for Blog name \'' . get_bloginfo( 'name' ) . '\' (' . get_current_blog_id() . ')' );
1219
+
1220
+ // Batch Process.
1221
+ do_action( 'cartflows_after_template_import', $new_step_id, $response );
1222
+
1223
+ /**
1224
+ * End
1225
+ */
1226
+ wp_send_json_success( $new_step_id );
1227
+ }
1228
+
1229
+ /**
1230
+ * Import Step.
1231
+ *
1232
+ * @since 1.0.0
1233
+ * @hook wp_ajax_cartflows_step_import
1234
+ *
1235
+ * @return void
1236
+ */
1237
+ public function create_default_flow() {
1238
+
1239
+ if ( ! current_user_can( 'manage_options' ) ) {
1240
+ return;
1241
+ }
1242
+
1243
+ check_ajax_referer( 'cf-default-flow', 'security' );
1244
+
1245
+ // Create post object.
1246
+ $new_flow_post = array(
1247
+ 'post_content' => '',
1248
+ 'post_status' => 'publish',
1249
+ 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
1250
+ );
1251
+
1252
+ // Insert the post into the database.
1253
+ $flow_id = wp_insert_post( $new_flow_post );
1254
+
1255
+ if ( is_wp_error( $flow_id ) ) {
1256
+ wp_send_json_error( $flow_id->get_error_message() );
1257
+ }
1258
+
1259
+ $flow_steps = array();
1260
+
1261
+ if ( wcf()->is_woo_active ) {
1262
+ $steps_data = array(
1263
+ 'sales' => array(
1264
+ 'title' => __( 'Sales Landing', 'cartflows' ),
1265
+ 'type' => 'landing',
1266
+ ),
1267
+ 'order-form' => array(
1268
+ 'title' => __( 'Checkout (Woo)', 'cartflows' ),
1269
+ 'type' => 'checkout',
1270
+ ),
1271
+ 'order-confirmation' => array(
1272
+ 'title' => __( 'Thank You (Woo)', 'cartflows' ),
1273
+ 'type' => 'thankyou',
1274
+ ),
1275
+ );
1276
+
1277
+ } else {
1278
+ $steps_data = array(
1279
+ 'landing' => array(
1280
+ 'title' => __( 'Landing', 'cartflows' ),
1281
+ 'type' => 'landing',
1282
+ ),
1283
+ 'thankyou' => array(
1284
+ 'title' => __( 'Thank You', 'cartflows' ),
1285
+ 'type' => 'landing',
1286
+ ),
1287
+ );
1288
+ }
1289
+
1290
+ foreach ( $steps_data as $slug => $data ) {
1291
+
1292
+ $post_content = '';
1293
+ $step_type = trim( $data['type'] );
1294
+
1295
+ $step_id = wp_insert_post(
1296
+ array(
1297
+ 'post_type' => CARTFLOWS_STEP_POST_TYPE,
1298
+ 'post_title' => $data['title'],
1299
+ 'post_content' => $post_content,
1300
+ 'post_status' => 'publish',
1301
+ )
1302
+ );
1303
+
1304
+ if ( is_wp_error( $step_id ) ) {
1305
+ wp_send_json_error( $step_id->get_error_message() );
1306
+ }
1307
+
1308
+ if ( $step_id ) {
1309
+
1310
+ $flow_steps[] = array(
1311
+ 'id' => $step_id,
1312
+ 'title' => $data['title'],
1313
+ 'type' => $step_type,
1314
+ );
1315
+
1316
+ // insert post meta.
1317
+ update_post_meta( $step_id, 'wcf-flow-id', $flow_id );
1318
+ update_post_meta( $step_id, 'wcf-step-type', $step_type );
1319
+
1320
+ wp_set_object_terms( $step_id, $step_type, CARTFLOWS_TAXONOMY_STEP_TYPE );
1321
+ wp_set_object_terms( $step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
1322
+
1323
+ update_post_meta( $step_id, '_wp_page_template', 'cartflows-default' );
1324
+ }
1325
+ }
1326
+
1327
+ update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
1328
+
1329
+ wp_send_json_success( $flow_id );
1330
+ }
1331
+
1332
+ /**
1333
+ * Create Flow
1334
+ *
1335
+ * @return void
1336
+ */
1337
+ public function create_flow() {
1338
+
1339
+ if ( ! current_user_can( 'manage_options' ) ) {
1340
+ return;
1341
+ }
1342
+
1343
+ check_ajax_referer( 'cf-create-flow', 'security' );
1344
+
1345
+ // Create post object.
1346
+ $new_flow_post = array(
1347
+ 'post_content' => '',
1348
+ 'post_status' => 'publish',
1349
+ 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
1350
+ );
1351
+
1352
+ // Insert the post into the database.
1353
+ $flow_id = wp_insert_post( $new_flow_post );
1354
+
1355
+ if ( is_wp_error( $flow_id ) ) {
1356
+ wp_send_json_error( $flow_id->get_error_message() );
1357
+ }
1358
+
1359
+ /* Imported Flow */
1360
+ update_post_meta( $flow_id, 'cartflows_imported_flow', 'yes' );
1361
+
1362
+ wp_send_json_success( $flow_id );
1363
+ }
1364
+
1365
+ /**
1366
+ * Create Step
1367
+ *
1368
+ * @return void
1369
+ */
1370
+ public function import_step() {
1371
+
1372
+ if ( ! current_user_can( 'manage_options' ) ) {
1373
+ return;
1374
+ }
1375
+
1376
+ check_ajax_referer( 'cf-step-import', 'security' );
1377
+
1378
+ $template_id = isset( $_POST['template_id'] ) ? intval( $_POST['template_id'] ) : '';
1379
+ $flow_id = isset( $_POST['flow_id'] ) ? intval( $_POST['flow_id'] ) : '';
1380
+ $step_title = isset( $_POST['step_title'] ) ? sanitize_text_field( wp_unslash( $_POST['step_title'] ) ) : '';
1381
+ $step_type = isset( $_POST['step_type'] ) ? sanitize_title( wp_unslash( $_POST['step_type'] ) ) : '';
1382
+ $step_custom_title = isset( $_POST['step_custom_title'] ) ? sanitize_title( wp_unslash( $_POST['step_custom_title'] ) ) : $step_title;
1383
+
1384
+ $cartflow_meta = Cartflows_Flow_Meta::get_instance();
1385
+
1386
+ $post_id = $cartflow_meta->create_step( $flow_id, $step_type, $step_custom_title );
1387
+
1388
+ wcf()->logger->import_log( '------------------------------------' );
1389
+ wcf()->logger->import_log( 'STARTED! Importing STEP' );
1390
+ wcf()->logger->import_log( '------------------------------------' );
1391
+
1392
+ if ( empty( $template_id ) || empty( $post_id ) ) {
1393
+ /* translators: %s: template ID */
1394
+ $data = sprintf( __( 'Invalid template id %1$s or post id %2$s.', 'cartflows' ), $template_id, $post_id );
1395
+ wcf()->logger->import_log( $data );
1396
+ wp_send_json_error( $data );
1397
+ }
1398
+
1399
+ wcf()->logger->import_log( 'Remote Step ' . $template_id . ' for local flow "' . get_the_title( $post_id ) . '" [' . $post_id . ']' );
1400
+
1401
+ $response = CartFlows_API::get_instance()->get_template( $template_id );
1402
+
1403
+ if ( 'divi' === Cartflows_Helper::get_common_setting( 'default_page_builder' ) ) {
1404
+ if ( isset( $response['data']['divi_content'] ) && ! empty( $response['data']['divi_content'] ) ) {
1405
+
1406
+ update_post_meta( $post_id, 'divi_content', $response['data']['divi_content'] );
1407
+
1408
+ wp_update_post(
1409
+ array(
1410
+ 'ID' => $post_id,
1411
+ 'post_content' => $response['data']['divi_content'],
1412
+ )
1413
+ );
1414
+ }
1415
+ }
1416
+
1417
+ if ( 'gutenberg' === Cartflows_Helper::get_common_setting( 'default_page_builder' ) ) {
1418
+ if ( isset( $response['data']['divi_content'] ) && ! empty( $response['data']['divi_content'] ) ) {
1419
+
1420
+ wp_update_post(
1421
+ array(
1422
+ 'ID' => $post_id,
1423
+ 'post_content' => $response['data']['divi_content'],
1424
+ )
1425
+ );
1426
+ }
1427
+ }
1428
+
1429
+ /* Imported Step */
1430
+ update_post_meta( $post_id, 'cartflows_imported_step', 'yes' );
1431
+
1432
+ // Import Post Meta.
1433
+ self::import_post_meta( $post_id, $response );
1434
+
1435
+ do_action( 'cartflows_import_complete' );
1436
+
1437
+ // Batch Process.
1438
+ do_action( 'cartflows_after_template_import', $post_id, $response );
1439
+
1440
+ wcf()->logger->import_log( '------------------------------------' );
1441
+ wcf()->logger->import_log( 'COMPLETE! Importing Step' );
1442
+ wcf()->logger->import_log( '------------------------------------' );
1443
+
1444
+ wp_send_json_success( $post_id );
1445
+ }
1446
+
1447
+ /**
1448
+ * Import Step.
1449
+ *
1450
+ * @since 1.0.0
1451
+ * @hook wp_ajax_cartflows_step_create_blank
1452
+ *
1453
+ * @return void
1454
+ */
1455
+ public function step_create_blank() {
1456
+
1457
+ if ( ! current_user_can( 'manage_options' ) ) {
1458
+ return;
1459
+ }
1460
+
1461
+ check_ajax_referer( 'cf-step-create-blank', 'security' );
1462
+
1463
+ $flow_id = isset( $_POST['flow_id'] ) ? intval( $_POST['flow_id'] ) : '';
1464
+ $step_type = isset( $_POST['step_type'] ) ? sanitize_text_field( wp_unslash( $_POST['step_type'] ) ) : '';
1465
+ $step_title = isset( $_POST['step_title'] ) ? sanitize_text_field( wp_unslash( $_POST['step_title'] ) ) : '';
1466
+
1467
+ if ( empty( $flow_id ) || empty( $step_type ) ) {
1468
+ /* translators: %s: flow ID */
1469
+ $data = sprintf( __( 'Invalid flow id %1$s OR step type %2$s.', 'cartflows' ), $flow_id, $step_type );
1470
+ wcf()->logger->import_log( $data );
1471
+ wp_send_json_error( $data );
1472
+ }
1473
+
1474
+ wcf()->logger->import_log( '------------------------------------' );
1475
+ wcf()->logger->import_log( 'STARTED! Creating Blank STEP for Flow ' . $flow_id );
1476
+
1477
+ $step_type_title = str_replace( '-', ' ', $step_type );
1478
+ $step_type_slug = strtolower( str_replace( '-', ' ', $step_type ) );
1479
+
1480
+ $new_step_id = wp_insert_post(
1481
+ array(
1482
+ 'post_type' => CARTFLOWS_STEP_POST_TYPE,
1483
+ 'post_title' => $step_title,
1484
+ 'post_content' => '',
1485
+ 'post_status' => 'publish',
1486
+ )
1487
+ );
1488
+
1489
+ // insert post meta.
1490
+ update_post_meta( $new_step_id, 'wcf-flow-id', $flow_id );
1491
+
1492
+ $taxonomy = CARTFLOWS_TAXONOMY_STEP_TYPE;
1493
+ $term_exist = term_exists( $step_type_slug, $taxonomy );
1494
+
1495
+ if ( empty( $term_exist ) ) {
1496
+ $terms = array(
1497
+ array(
1498
+ 'name' => $step_type_title,
1499
+ 'slug' => $step_type_slug,
1500
+ ),
1501
+ );
1502
+
1503
+ Cartflows_Step_Post_Type::get_instance()->add_terms( $taxonomy, $terms );
1504
+ wcf()->logger->import_log( '(✓) Created new term name ' . $step_type_title . ' | term slug ' . $step_type_slug );
1505
+ }
1506
+
1507
+ $current_term = term_exists( $step_type_slug, $taxonomy );
1508
+
1509
+ // Set type object.
1510
+ $data = get_term( $current_term['term_id'], $taxonomy );
1511
+ $step_slug = $data->slug;
1512
+ wp_set_object_terms( $new_step_id, $data->slug, CARTFLOWS_TAXONOMY_STEP_TYPE );
1513
+ wcf()->logger->import_log( '(✓) Assigned existing term ' . $step_type_title . ' to the template ' . $new_step_id );
1514
+
1515
+ // Set Default page Layout.
1516
+ update_post_meta( $new_step_id, '_wp_page_template', 'cartflows-default' );
1517
+
1518
+ // Set type.
1519
+ update_post_meta( $new_step_id, 'wcf-step-type', $data->slug );
1520
+ wcf()->logger->import_log( '(✓) Updated term ' . $data->name . ' to the post meta wcf-step-type.' );
1521
+
1522
+ // Set flow.
1523
+ wp_set_object_terms( $new_step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
1524
+ wcf()->logger->import_log( '(✓) Assigned flow step flow-' . $flow_id );
1525
+
1526
+ self::get_instance()->set_step_to_flow( $flow_id, $new_step_id, $step_type_title, $step_slug );
1527
+
1528
+ wcf()->logger->import_log( 'COMPLETE! Creating Blank STEP for Flow ' . $flow_id );
1529
+ wcf()->logger->import_log( '------------------------------------' );
1530
+
1531
+ wp_send_json_success( $new_step_id );
1532
+ }
1533
+
1534
+ /**
1535
+ * Import Post Meta
1536
+ *
1537
+ * @since 1.0.0
1538
+ *
1539
+ * @param integer $post_id Post ID.
1540
+ * @param array $response Post meta.
1541
+ * @return void
1542
+ */
1543
+ public static function import_post_meta( $post_id, $response ) {
1544
+
1545
+ $metadata = (array) $response['post_meta'];
1546
+
1547
+ foreach ( $metadata as $meta_key => $meta_value ) {
1548
+ $meta_value = isset( $meta_value[0] ) ? $meta_value[0] : '';
1549
+
1550
+ if ( $meta_value ) {
1551
+
1552
+ if ( is_serialized( $meta_value, true ) ) {
1553
+ $raw_data = maybe_unserialize( stripslashes( $meta_value ) );
1554
+ } elseif ( is_array( $meta_value ) ) {
1555
+ $raw_data = json_decode( stripslashes( $meta_value ), true );
1556
+ } else {
1557
+ $raw_data = $meta_value;
1558
+ }
1559
+
1560
+ if ( '_elementor_data' === $meta_key ) {
1561
+ if ( is_array( $raw_data ) ) {
1562
+ $raw_data = wp_slash( wp_json_encode( $raw_data ) );
1563
+ } else {
1564
+ $raw_data = wp_slash( $raw_data );
1565
+ }
1566
+ }
1567
+ if ( '_elementor_data' !== $meta_key && '_elementor_draft' !== $meta_key && '_fl_builder_data' !== $meta_key && '_fl_builder_draft' !== $meta_key ) {
1568
+ if ( is_array( $raw_data ) ) {
1569
+ wcf()->logger->import_log( '(✓) Added post meta ' . $meta_key . ' | ' . wp_json_encode( $raw_data ) );
1570
+ } else {
1571
+ if ( ! is_object( $raw_data ) ) {
1572
+ wcf()->logger->import_log( '(✓) Added post meta ' . $meta_key . ' | ' . $raw_data );
1573
+ }
1574
+ }
1575
+ }
1576
+
1577
+ update_post_meta( $post_id, $meta_key, $raw_data );
1578
+ }
1579
+ }
1580
+ }
1581
+
1582
+ /**
1583
+ * Import Template for Elementor
1584
+ *
1585
+ * @since 1.0.0
1586
+ *
1587
+ * @param integer $post_id Post ID.
1588
+ * @param array $response Post meta.
1589
+ * @param array $page_build_data Page build data.
1590
+ * @return void
1591
+ */
1592
+ public static function import_template_elementor( $post_id, $response, $page_build_data ) {
1593
+ if ( ! is_plugin_active( 'elementor/elementor.php' ) ) {
1594
+ $data = __( 'Elementor is not activated. Please activate plugin Elementor Page Builder to import the step.', 'cartflows' );
1595
+ wcf()->logger->import_log( $data );
1596
+ wp_send_json_error( $data );
1597
+ }
1598
+
1599
+ require_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-importer-elementor.php';
1600
+
1601
+ wcf()->logger->import_log( '# Started "importing page builder data" for step ' . $post_id );
1602
+
1603
+ $obj = new \Elementor\TemplateLibrary\CartFlows_Importer_Elementor();
1604
+ $obj->import_single_template( $post_id );
1605
+
1606
+ wcf()->logger->import_log( '# Complete "importing page builder data" for step ' . $post_id );
1607
+ }
1608
+
1609
+ /**
1610
+ * Supported post types
1611
+ *
1612
+ * @since 1.0.0
1613
+ *
1614
+ * @return array Supported post types.
1615
+ */
1616
+ public static function supported_post_types() {
1617
+ return apply_filters(
1618
+ 'cartflows_supported_post_types',
1619
+ array(
1620
+ CARTFLOWS_FLOW_POST_TYPE,
1621
+ )
1622
+ );
1623
+ }
1624
+
1625
+ /**
1626
+ * Check supported post type
1627
+ *
1628
+ * @since 1.0.0
1629
+ *
1630
+ * @param string $post_type Post type.
1631
+ * @return boolean Supported post type status.
1632
+ */
1633
+ public static function is_supported_post( $post_type = '' ) {
1634
+
1635
+ if ( in_array( $post_type, self::supported_post_types(), true ) ) {
1636
+ return true;
1637
+ }
1638
+
1639
+ return false;
1640
+ }
1641
+
1642
+ /**
1643
+ * Set steps to the flow
1644
+ *
1645
+ * @param integer $flow_id Flow ID.
1646
+ * @param integer $new_step_id New step ID.
1647
+ * @param string $step_title Flow Type.
1648
+ * @param string $step_slug Flow Type.
1649
+ */
1650
+ public function set_step_to_flow( $flow_id, $new_step_id, $step_title, $step_slug ) {
1651
+ // Update steps for the current flow.
1652
+ $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
1653
+
1654
+ if ( ! is_array( $flow_steps ) ) {
1655
+ $flow_steps = array();
1656
+ }
1657
+
1658
+ $flow_steps[] = array(
1659
+ 'id' => $new_step_id,
1660
+ 'title' => $step_title,
1661
+ 'type' => $step_slug,
1662
+ );
1663
+ update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
1664
+ wcf()->logger->import_log( '(✓) Updated flow steps post meta key \'wcf-steps\' ' . wp_json_encode( $flow_steps ) );
1665
+ }
1666
+
1667
+ /**
1668
+ * Localize variables in admin
1669
+ *
1670
+ * @param array $vars variables.
1671
+ */
1672
+ public function localize_vars( $vars ) {
1673
+
1674
+ $ajax_actions = array(
1675
+ 'cf_step_import',
1676
+ 'cf_load_steps',
1677
+ 'cf_create_flow',
1678
+ 'cf_default_flow',
1679
+ 'cf_step_create_blank',
1680
+ 'cf_import_flow_step',
1681
+ );
1682
+
1683
+ foreach ( $ajax_actions as $action ) {
1684
+
1685
+ $vars[ $action . '_nonce' ] = wp_create_nonce( str_replace( '_', '-', $action ) );
1686
+ }
1687
+
1688
+ return $vars;
1689
+ }
1690
+
1691
+ /**
1692
+ * Ajax action to activate plugin
1693
+ */
1694
+ public function activate_plugin() {
1695
+
1696
+ if ( ! check_ajax_referer( 'cartflows_activate_plugin', 'security', false ) ) {
1697
+ wp_send_json_error( esc_html__( 'Action failed. Invalid Security Nonce.', 'cartflows' ) );
1698
+ }
1699
+
1700
+ if ( ! current_user_can( 'activate_plugins' ) ) {
1701
+ wp_send_json_error(
1702
+ array(
1703
+ 'success' => false,
1704
+ 'message' => __( 'User have not plugin install permissions.', 'cartflows' ),
1705
+ )
1706
+ );
1707
+ }
1708
+
1709
+ $plugin_init = isset( $_POST['plugin_init'] ) ? sanitize_text_field( wp_unslash( $_POST['plugin_init'] ) ) : '';
1710
+
1711
+ $activate = activate_plugin( $plugin_init, '', false, true );
1712
+
1713
+ if ( is_wp_error( $activate ) ) {
1714
+ wp_send_json_error(
1715
+ array(
1716
+ 'success' => false,
1717
+ 'message' => $activate->get_error_message(),
1718
+ 'init' => $plugin_init,
1719
+ )
1720
+ );
1721
+ }
1722
+
1723
+ wp_send_json_success(
1724
+ array(
1725
+ 'success' => true,
1726
+ 'message' => __( 'Plugin Successfully Activated', 'cartflows' ),
1727
+ 'init' => $plugin_init,
1728
+ )
1729
+ );
1730
+ }
1731
+
1732
+ }
1733
+
1734
+ /**
1735
+ * Initialize class object with 'get_instance()' method
1736
+ */
1737
+ CartFlows_Importer::get_instance();
1738
+
1739
+ endif;
classes/class-cartflows-loader.php CHANGED
@@ -125,7 +125,7 @@ if ( ! class_exists( 'Cartflows_Loader' ) ) {
125
  define( 'CARTFLOWS_BASE', plugin_basename( CARTFLOWS_FILE ) );
126
  define( 'CARTFLOWS_DIR', plugin_dir_path( CARTFLOWS_FILE ) );
127
  define( 'CARTFLOWS_URL', plugins_url( '/', CARTFLOWS_FILE ) );
128
- define( 'CARTFLOWS_VER', '1.5.9' );
129
  define( 'CARTFLOWS_SLUG', 'cartflows' );
130
  define( 'CARTFLOWS_SETTINGS', 'cartflows_settings' );
131
 
125
  define( 'CARTFLOWS_BASE', plugin_basename( CARTFLOWS_FILE ) );
126
  define( 'CARTFLOWS_DIR', plugin_dir_path( CARTFLOWS_FILE ) );
127
  define( 'CARTFLOWS_URL', plugins_url( '/', CARTFLOWS_FILE ) );
128
+ define( 'CARTFLOWS_VER', '1.5.10' );
129
  define( 'CARTFLOWS_SLUG', 'cartflows' );
130
  define( 'CARTFLOWS_SETTINGS', 'cartflows_settings' );
131
 
classes/class-cartflows-meta-fields.php CHANGED
@@ -116,16 +116,16 @@ class Cartflows_Meta_Fields {
116
 
117
  if ( false === $posts ) {
118
  $posts = $wpdb->get_results( // phpcs:ignore
119
- $wpdb->prepare(
120
- "SELECT *
121
  FROM {$wpdb->prefix}posts
122
  WHERE post_type = %s
123
  AND post_title LIKE %s
124
  AND post_status = %s",
125
- 'shop_coupon',
126
- $wpdb->esc_like( $term ) . '%',
127
- 'publish'
128
- )
129
  );
130
  wp_cache_set( 'wcf_search_coupons', $posts, 'wcf_funnel_Cart' );
131
  }
116
 
117
  if ( false === $posts ) {
118
  $posts = $wpdb->get_results( // phpcs:ignore
119
+ $wpdb->prepare(
120
+ "SELECT *
121
  FROM {$wpdb->prefix}posts
122
  WHERE post_type = %s
123
  AND post_title LIKE %s
124
  AND post_status = %s",
125
+ 'shop_coupon',
126
+ $wpdb->esc_like( $term ) . '%',
127
+ 'publish'
128
+ )
129
  );
130
  wp_cache_set( 'wcf_search_coupons', $posts, 'wcf_funnel_Cart' );
131
  }
classes/class-cartflows-utils.php CHANGED
@@ -1,591 +1,591 @@
1
- <?php
2
- /**
3
- * Utils.
4
- *
5
- * @package CARTFLOWS
6
- */
7
-
8
- if ( ! defined( 'ABSPATH' ) ) {
9
- exit; // Exit if accessed directly.
10
- }
11
-
12
- /**
13
- * Class Cartflows_Utils.
14
- */
15
- class Cartflows_Utils {
16
-
17
- /**
18
- * Member Variable
19
- *
20
- * @var instance
21
- */
22
- private static $instance;
23
-
24
- /**
25
- * Member Variable
26
- *
27
- * @var checkout_products
28
- */
29
- public $checkout_products = array();
30
-
31
-
32
- /**
33
- * Initiator
34
- */
35
- public static function get_instance() {
36
- if ( ! isset( self::$instance ) ) {
37
- self::$instance = new self();
38
- }
39
- return self::$instance;
40
- }
41
-
42
- /**
43
- * Constructor
44
- */
45
- public function __construct() {
46
- }
47
-
48
- /**
49
- * Get current post type
50
- *
51
- * @param string $post_type post type.
52
- * @return string
53
- */
54
- public function current_post_type( $post_type = '' ) {
55
-
56
- if ( '' === $post_type ) {
57
- $post_type = get_post_type();
58
- }
59
-
60
- return $post_type;
61
- }
62
-
63
- /**
64
- * Check if post type is of step.
65
- *
66
- * @param string $post_type post type.
67
- * @return bool
68
- */
69
- public function is_step_post_type( $post_type = '' ) {
70
-
71
- if ( $this->get_step_post_type() === $this->current_post_type( $post_type ) ) {
72
-
73
- return true;
74
- }
75
-
76
- return false;
77
- }
78
-
79
- /**
80
- * Check if post type is of flow.
81
- *
82
- * @param string $post_type post type.
83
- * @return bool
84
- */
85
- public function is_flow_post_type( $post_type = '' ) {
86
-
87
- if ( $this->get_flow_post_type() === $this->current_post_type( $post_type ) ) {
88
-
89
- return true;
90
- }
91
-
92
- return false;
93
- }
94
-
95
- /**
96
- * Get post type of step.
97
- *
98
- * @return string
99
- */
100
- public function get_step_post_type() {
101
-
102
- return CARTFLOWS_STEP_POST_TYPE;
103
- }
104
-
105
- /**
106
- * Get post type of flow.
107
- *
108
- * @return string
109
- */
110
- public function get_flow_post_type() {
111
-
112
- return CARTFLOWS_FLOW_POST_TYPE;
113
- }
114
-
115
- /**
116
- * Get flow id
117
- *
118
- * @return int
119
- */
120
- public function get_flow_id() {
121
-
122
- global $post;
123
-
124
- return get_post_meta( $post->ID, 'wcf-flow-id', true );
125
- }
126
-
127
- /**
128
- * Get flow id by step
129
- *
130
- * @param int $step_id step ID.
131
- * @return int
132
- */
133
- public function get_flow_id_from_step_id( $step_id ) {
134
-
135
- return get_post_meta( $step_id, 'wcf-flow-id', true );
136
- }
137
-
138
- /**
139
- * Get flow steps by id
140
- *
141
- * @param int $flow_id flow ID.
142
- * @return int
143
- */
144
- public function get_flow_steps( $flow_id ) {
145
-
146
- $steps = get_post_meta( $flow_id, 'wcf-steps', true );
147
-
148
- if ( is_array( $steps ) && ! empty( $steps ) ) {
149
- return $steps;
150
- }
151
-
152
- return false;
153
- }
154
-
155
- /**
156
- * Get template type of step
157
- *
158
- * @param int $step_id step ID.
159
- * @return int
160
- */
161
- public function get_step_type( $step_id ) {
162
-
163
- return get_post_meta( $step_id, 'wcf-step-type', true );
164
- }
165
-
166
- /**
167
- * Get next id for step
168
- *
169
- * @param int $flow_id flow ID.
170
- * @param int $step_id step ID.
171
- * @return bool
172
- */
173
- public function get_next_step_id( $flow_id, $step_id ) {
174
-
175
- $steps = $this->get_flow_steps( $flow_id );
176
- $step_id = intval( $step_id );
177
-
178
- if ( ! $steps ) {
179
- return false;
180
- }
181
-
182
- foreach ( $steps as $i => $step ) {
183
-
184
- if ( intval( $step['id'] ) === $step_id ) {
185
-
186
- $next_i = $i + 1;
187
-
188
- if ( isset( $steps[ $next_i ] ) ) {
189
-
190
- $navigation = $steps[ $next_i ];
191
-
192
- return intval( $navigation['id'] );
193
- }
194
-
195
- break;
196
- }
197
- }
198
-
199
- return false;
200
- }
201
-
202
- /**
203
- * Get next id for step
204
- *
205
- * @param int $order_id order ID.
206
- * @return int
207
- */
208
- public function get_flow_id_from_order( $order_id ) {
209
-
210
- $flow_id = get_post_meta( $order_id, '_wcf_flow_id', true );
211
-
212
- return intval( $flow_id );
213
- }
214
-
215
- /**
216
- * Get checkout id for order
217
- *
218
- * @param int $order_id order ID.
219
- * @return int
220
- */
221
- public function get_checkout_id_from_order( $order_id ) {
222
-
223
- $checkout_id = get_post_meta( $order_id, '_wcf_checkout_id', true );
224
-
225
- return intval( $checkout_id );
226
- }
227
-
228
- /**
229
- * We are using this function mostly in ajax on checkout page
230
- *
231
- * @return bool
232
- */
233
- public function get_checkout_id_from_post_data() {
234
-
235
- if ( isset( $_POST['_wcf_checkout_id'] ) ) { //phpcs:ignore
236
-
237
- $checkout_id = filter_var( wp_unslash( $_POST['_wcf_checkout_id'] ), FILTER_SANITIZE_NUMBER_INT ); //phpcs:ignore
238
-
239
- return intval( $checkout_id );
240
- }
241
-
242
- return false;
243
- }
244
-
245
- /**
246
- * We are using this function mostly in ajax on checkout page
247
- *
248
- * @return bool
249
- */
250
- public function get_flow_id_from_post_data() {
251
-
252
- if ( isset( $_POST['_wcf_flow_id'] ) ) { //phpcs:ignore
253
-
254
- $flow_id = filter_var( wp_unslash( $_POST['_wcf_flow_id'] ), FILTER_SANITIZE_NUMBER_INT ); //phpcs:ignore
255
-
256
- return intval( $flow_id );
257
- }
258
-
259
- return false;
260
- }
261
-
262
- /**
263
- * Get optin id for order
264
- *
265
- * @param int $order_id order ID.
266
- * @return int
267
- */
268
- public function get_optin_id_from_order( $order_id ) {
269
-
270
- $optin_id = get_post_meta( $order_id, '_wcf_optin_id', true );
271
-
272
- return intval( $optin_id );
273
- }
274
-
275
- /**
276
- * We are using this function mostly in ajax on checkout page
277
- *
278
- * @return bool
279
- */
280
- public function get_optin_id_from_post_data() {
281
-
282
- if ( isset( $_POST['_wcf_optin_id'] ) ) { //phpcs:ignore
283
-
284
- $optin_id = filter_var( wp_unslash( $_POST['_wcf_optin_id'] ), FILTER_SANITIZE_NUMBER_INT ); //phpcs:ignore
285
-
286
- return intval( $optin_id );
287
- }
288
-
289
- return false;
290
- }
291
-
292
- /**
293
- * Check for thank you page
294
- *
295
- * @param int $step_id step ID.
296
- * @return bool
297
- */
298
- public function check_is_thankyou_page( $step_id ) {
299
-
300
- $step_type = $this->get_step_type( $step_id );
301
-
302
- if ( 'thankyou' === $step_type ) {
303
-
304
- return true;
305
- }
306
-
307
- return false;
308
- }
309
-
310
- /**
311
- * Check for offer page
312
- *
313
- * @param int $step_id step ID.
314
- * @return bool
315
- */
316
- public function check_is_offer_page( $step_id ) {
317
-
318
- $step_type = $this->get_step_type( $step_id );
319
-
320
- if ( 'upsell' === $step_type || 'downsell' === $step_type ) {
321
-
322
- return true;
323
- }
324
-
325
- return false;
326
- }
327
-
328
- /**
329
- * Check if loaded page requires woo.
330
- *
331
- * @return bool
332
- */
333
- public function check_is_woo_required_page() {
334
-
335
- global $post;
336
- $step_id = $post->ID;
337
- $woo_not_required_type = array( 'landing' );
338
- $step_type = $this->get_step_type( $step_id );
339
- return ( ! in_array( $step_type, $woo_not_required_type, true ) );
340
- }
341
-
342
- /**
343
- * Define constant for cache
344
- *
345
- * @return void
346
- */
347
- public function do_not_cache() {
348
-
349
- global $post;
350
-
351
- if ( ! apply_filters( 'cartflows_do_not_cache_step', true, $post->ID ) ) {
352
- return;
353
- }
354
-
355
- wcf_maybe_define_constant( 'DONOTCACHEPAGE', true );
356
- wcf_maybe_define_constant( 'DONOTCACHEOBJECT', true );
357
- wcf_maybe_define_constant( 'DONOTCACHEDB', true );
358
-
359
- nocache_headers();
360
- }
361
-
362
- /**
363
- * Get linking url
364
- *
365
- * @param array $args query args.
366
- * @return string
367
- */
368
- public function get_linking_url( $args = array() ) {
369
-
370
- $url = get_home_url();
371
-
372
- $url = add_query_arg( $args, $url );
373
-
374
- return $url;
375
- }
376
-
377
- /**
378
- * Get assets urls
379
- *
380
- * @return array
381
- * @since 1.1.6
382
- */
383
- public function get_assets_path() {
384
-
385
- $rtl = '';
386
-
387
- if ( is_rtl() ) {
388
- $rtl = '-rtl';
389
- }
390
-
391
- $file_prefix = '';
392
- $dir_name = '';
393
-
394
- $is_min = apply_filters( 'cartflows_load_min_assets', false );
395
-
396
- if ( $is_min ) {
397
- $file_prefix = '.min';
398
- $dir_name = 'min-';
399
- }
400
-
401
- $js_gen_path = CARTFLOWS_URL . 'assets/' . $dir_name . 'js/';
402
- $css_gen_path = CARTFLOWS_URL . 'assets/' . $dir_name . 'css/';
403
-
404
- return array(
405
- 'css' => $css_gen_path,
406
- 'js' => $js_gen_path,
407
- 'file_prefix' => $file_prefix,
408
- 'rtl' => $rtl,
409
- );
410
- }
411
-
412
- /**
413
- * Get assets css url
414
- *
415
- * @param string $file file name.
416
- * @return string
417
- * @since 1.1.6
418
- */
419
- public function get_css_url( $file ) {
420
-
421
- $assets_vars = wcf()->assets_vars;
422
-
423
- $url = $assets_vars['css'] . $file . $assets_vars['rtl'] . $assets_vars['file_prefix'] . '.css';
424
-
425
- return $url;
426
- }
427
-
428
- /**
429
- * Get assets js url
430
- *
431
- * @param string $file file name.
432
- * @return string
433
- * @since 1.1.6
434
- */
435
- public function get_js_url( $file ) {
436
-
437
- $assets_vars = wcf()->assets_vars;
438
-
439
- $url = $assets_vars['js'] . $file . $assets_vars['file_prefix'] . '.js';
440
-
441
- return $url;
442
- }
443
-
444
- /**
445
- * Get unique id.
446
- *
447
- * @param int $length Length.
448
- *
449
- * @return string
450
- */
451
- public function get_unique_id( $length = 8 ) {
452
-
453
- return substr( md5( microtime() ), 0, $length );
454
- }
455
-
456
- /**
457
- * Get selected checkout products and data
458
- *
459
- * @param int $checkout_id Checkout id..
460
- * @param array $saved_products Saved product.
461
- *
462
- * @return array
463
- */
464
- public function get_selected_checkout_products( $checkout_id = '', $saved_products = array() ) {
465
-
466
- if ( empty( $checkout_id ) ) {
467
-
468
- global $post;
469
-
470
- $checkout_id = $post->ID;
471
- }
472
-
473
- if ( ! isset( $this->checkout_products[ $checkout_id ] ) ) {
474
-
475
- if ( ! empty( $saved_products ) ) {
476
-
477
- $products = $saved_products;
478
- } else {
479
-
480
- $products = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-checkout-products' );
481
- }
482
-
483
- $verify_url_data = false;
484
- $default_add_to_cart = false;
485
- $default_ids = array();
486
- $default_add_to_cart = true;
487
-
488
- if ( isset( $_GET['wcf-default'] ) ) { //phpcs:ignore
489
- //phpcs:ignore WordPress.Security.NonceVerification.Recommended
490
- $default_sequence = sanitize_text_field( wp_unslash( $_GET['wcf-default'] ) );
491
- $default_ids = array_map( 'intval', explode( ',', $default_sequence ) );
492
- $verify_url_data = true;
493
- }
494
-
495
- if ( is_array( $products ) ) {
496
-
497
- foreach ( $products as $in => $data ) {
498
-
499
- if ( $verify_url_data ) {
500
-
501
- $default_add_to_cart = false;
502
- $sequence = $in + 1;
503
-
504
- if ( in_array( $sequence, $default_ids, true ) ) {
505
- $default_add_to_cart = true;
506
- }
507
- }
508
-
509
- $default_data = array(
510
- 'quantity' => 1,
511
- 'discount_type' => '',
512
- 'discount_value' => '',
513
- 'unique_id' => $this->get_unique_id(),
514
- 'add_to_cart' => $default_add_to_cart,
515
- );
516
-
517
- $products[ $in ] = wp_parse_args( $products[ $in ], $default_data );
518
- }
519
- }
520
-
521
- $this->checkout_products[ $checkout_id ] = $products;
522
- }
523
-
524
- return $this->checkout_products[ $checkout_id ];
525
- }
526
-
527
- /**
528
- * Get selected checkout products and data
529
- *
530
- * @param int $checkout_id Checkout id..
531
- * @param array $products_data Saved product.
532
- *
533
- * @return array
534
- */
535
- public function set_selcted_checkout_products( $checkout_id = '', $products_data = array() ) {
536
-
537
- if ( empty( $checkout_id ) ) {
538
-
539
- global $post;
540
-
541
- $checkout_id = $post->ID;
542
- }
543
-
544
- if ( isset( $this->checkout_products[ $checkout_id ] ) ) {
545
-
546
- $products = $this->checkout_products[ $checkout_id ];
547
- } else {
548
- $products = $this->get_selected_checkout_products( $checkout_id );
549
- }
550
-
551
- if ( is_array( $products ) && ! empty( $products_data ) ) {
552
-
553
- foreach ( $products as $in => $data ) {
554
-
555
- if ( isset( $products_data[ $in ] ) ) {
556
- $products[ $in ] = wp_parse_args( $products_data[ $in ], $products[ $in ] );
557
- }
558
- }
559
- }
560
-
561
- $this->checkout_products[ $checkout_id ] = $products;
562
-
563
- return $this->checkout_products[ $checkout_id ];
564
- }
565
- }
566
-
567
- /**
568
- * Get a specific property of an array without needing to check if that property exists.
569
- *
570
- * Provide a default value if you want to return a specific value if the property is not set.
571
- *
572
- * @param array $array Array from which the property's value should be retrieved.
573
- * @param string $prop Name of the property to be retrieved.
574
- * @param string $default Optional. Value that should be returned if the property is not set or empty. Defaults to null.
575
- *
576
- * @return null|string|mixed The value
577
- */
578
- function wcf_get_prop( $array, $prop, $default = null ) {
579
-
580
- if ( ! is_array( $array ) && ! ( is_object( $array ) && $array instanceof ArrayAccess ) ) {
581
- return $default;
582
- }
583
-
584
- if ( isset( $array[ $prop ] ) ) {
585
- $value = $array[ $prop ];
586
- } else {
587
- $value = '';
588
- }
589
-
590
- return empty( $value ) && null !== $default ? $default : $value;
591
- }
1
+ <?php
2
+ /**
3
+ * Utils.
4
+ *
5
+ * @package CARTFLOWS
6
+ */
7
+
8
+ if ( ! defined( 'ABSPATH' ) ) {
9
+ exit; // Exit if accessed directly.
10
+ }
11
+
12
+ /**
13
+ * Class Cartflows_Utils.
14
+ */
15
+ class Cartflows_Utils {
16
+
17
+ /**
18
+ * Member Variable
19
+ *
20
+ * @var instance
21
+ */
22
+ private static $instance;
23
+
24
+ /**
25
+ * Member Variable
26
+ *
27
+ * @var checkout_products
28
+ */
29
+ public $checkout_products = array();
30
+
31
+
32
+ /**
33
+ * Initiator
34
+ */
35
+ public static function get_instance() {
36
+ if ( ! isset( self::$instance ) ) {
37
+ self::$instance = new self();
38
+ }
39
+ return self::$instance;
40
+ }
41
+
42
+ /**
43
+ * Constructor
44
+ */
45
+ public function __construct() {
46
+ }
47
+
48
+ /**
49
+ * Get current post type
50
+ *
51
+ * @param string $post_type post type.
52
+ * @return string
53
+ */
54
+ public function current_post_type( $post_type = '' ) {
55
+
56
+ if ( '' === $post_type ) {
57
+ $post_type = get_post_type();
58
+ }
59
+
60
+ return $post_type;
61
+ }
62
+
63
+ /**
64
+ * Check if post type is of step.
65
+ *
66
+ * @param string $post_type post type.
67
+ * @return bool
68
+ */
69
+ public function is_step_post_type( $post_type = '' ) {
70
+
71
+ if ( $this->get_step_post_type() === $this->current_post_type( $post_type ) ) {
72
+
73
+ return true;
74
+ }
75
+
76
+ return false;
77
+ }
78
+
79
+ /**
80
+ * Check if post type is of flow.
81
+ *
82
+ * @param string $post_type post type.
83
+ * @return bool
84
+ */
85
+ public function is_flow_post_type( $post_type = '' ) {
86
+
87
+ if ( $this->get_flow_post_type() === $this->current_post_type( $post_type ) ) {
88
+
89
+ return true;
90
+ }
91
+
92
+ return false;
93
+ }
94
+
95
+ /**
96
+ * Get post type of step.
97
+ *
98
+ * @return string
99
+ */
100
+ public function get_step_post_type() {
101
+
102
+ return CARTFLOWS_STEP_POST_TYPE;
103
+ }
104
+
105
+ /**
106
+ * Get post type of flow.
107
+ *
108
+ * @return string
109
+ */
110
+ public function get_flow_post_type() {
111
+
112
+ return CARTFLOWS_FLOW_POST_TYPE;
113
+ }
114
+
115
+ /**
116
+ * Get flow id
117
+ *
118
+ * @return int
119
+ */
120
+ public function get_flow_id() {
121
+
122
+ global $post;
123
+
124
+ return get_post_meta( $post->ID, 'wcf-flow-id', true );
125
+ }
126
+
127
+ /**
128
+ * Get flow id by step
129
+ *
130
+ * @param int $step_id step ID.
131
+ * @return int
132
+ */
133
+ public function get_flow_id_from_step_id( $step_id ) {
134
+
135
+ return get_post_meta( $step_id, 'wcf-flow-id', true );
136
+ }
137
+
138
+ /**
139
+ * Get flow steps by id
140
+ *
141
+ * @param int $flow_id flow ID.
142
+ * @return int
143
+ */
144
+ public function get_flow_steps( $flow_id ) {
145
+
146
+ $steps = get_post_meta( $flow_id, 'wcf-steps', true );
147
+
148
+ if ( is_array( $steps ) && ! empty( $steps ) ) {
149
+ return $steps;
150
+ }
151
+
152
+ return false;
153
+ }
154
+
155
+ /**
156
+ * Get template type of step
157
+ *
158
+ * @param int $step_id step ID.
159
+ * @return int
160
+ */
161
+ public function get_step_type( $step_id ) {
162
+
163
+ return get_post_meta( $step_id, 'wcf-step-type', true );
164
+ }
165
+
166
+ /**
167
+ * Get next id for step
168
+ *
169
+ * @param int $flow_id flow ID.
170
+ * @param int $step_id step ID.
171
+ * @return bool
172
+ */
173
+ public function get_next_step_id( $flow_id, $step_id ) {
174
+
175
+ $steps = $this->get_flow_steps( $flow_id );
176
+ $step_id = intval( $step_id );
177
+
178
+ if ( ! $steps ) {
179
+ return false;
180
+ }
181
+
182
+ foreach ( $steps as $i => $step ) {
183
+
184
+ if ( intval( $step['id'] ) === $step_id ) {
185
+
186
+ $next_i = $i + 1;
187
+
188
+ if ( isset( $steps[ $next_i ] ) ) {
189
+
190
+ $navigation = $steps[ $next_i ];
191
+
192
+ return intval( $navigation['id'] );
193
+ }
194
+
195
+ break;
196
+ }
197
+ }
198
+
199
+ return false;
200
+ }
201
+
202
+ /**
203
+ * Get next id for step
204
+ *
205
+ * @param int $order_id order ID.
206
+ * @return int
207
+ */
208
+ public function get_flow_id_from_order( $order_id ) {
209
+
210
+ $flow_id = get_post_meta( $order_id, '_wcf_flow_id', true );
211
+
212
+ return intval( $flow_id );
213
+ }
214
+
215
+ /**
216
+ * Get checkout id for order
217
+ *
218
+ * @param int $order_id order ID.
219
+ * @return int
220
+ */
221
+ public function get_checkout_id_from_order( $order_id ) {
222
+
223
+ $checkout_id = get_post_meta( $order_id, '_wcf_checkout_id', true );
224
+
225
+ return intval( $checkout_id );
226
+ }
227
+
228
+ /**
229
+ * We are using this function mostly in ajax on checkout page
230
+ *
231
+ * @return bool
232
+ */
233
+ public function get_checkout_id_from_post_data() {
234
+
235
+ if ( isset( $_POST['_wcf_checkout_id'] ) ) { //phpcs:ignore
236
+
237
+ $checkout_id = filter_var( wp_unslash( $_POST['_wcf_checkout_id'] ), FILTER_SANITIZE_NUMBER_INT ); //phpcs:ignore
238
+
239
+ return intval( $checkout_id );
240
+ }
241
+
242
+ return false;
243
+ }
244
+
245
+ /**
246
+ * We are using this function mostly in ajax on checkout page
247
+ *
248
+ * @return bool
249
+ */
250
+ public function get_flow_id_from_post_data() {
251
+
252
+ if ( isset( $_POST['_wcf_flow_id'] ) ) { //phpcs:ignore
253
+
254
+ $flow_id = filter_var( wp_unslash( $_POST['_wcf_flow_id'] ), FILTER_SANITIZE_NUMBER_INT ); //phpcs:ignore
255
+
256
+ return intval( $flow_id );
257
+ }
258
+
259
+ return false;
260
+ }
261
+
262
+ /**
263
+ * Get optin id for order
264
+ *
265
+ * @param int $order_id order ID.
266
+ * @return int
267
+ */
268
+ public function get_optin_id_from_order( $order_id ) {
269
+
270
+ $optin_id = get_post_meta( $order_id, '_wcf_optin_id', true );
271
+
272
+ return intval( $optin_id );
273
+ }
274
+
275
+ /**
276
+ * We are using this function mostly in ajax on checkout page
277
+ *
278
+ * @return bool
279
+ */
280
+ public function get_optin_id_from_post_data() {
281
+
282
+ if ( isset( $_POST['_wcf_optin_id'] ) ) { //phpcs:ignore
283
+
284
+ $optin_id = filter_var( wp_unslash( $_POST['_wcf_optin_id'] ), FILTER_SANITIZE_NUMBER_INT ); //phpcs:ignore
285
+
286
+ return intval( $optin_id );
287
+ }
288
+
289
+ return false;
290
+ }
291
+
292
+ /**
293
+ * Check for thank you page
294
+ *
295
+ * @param int $step_id step ID.
296
+ * @return bool
297
+ */
298
+ public function check_is_thankyou_page( $step_id ) {
299
+
300
+ $step_type = $this->get_step_type( $step_id );
301
+
302
+ if ( 'thankyou' === $step_type ) {
303
+
304
+ return true;
305
+ }
306
+
307
+ return false;
308
+ }
309
+
310
+ /**
311
+ * Check for offer page
312
+ *
313
+ * @param int $step_id step ID.
314
+ * @return bool
315
+ */
316
+ public function check_is_offer_page( $step_id ) {
317
+
318
+ $step_type = $this->get_step_type( $step_id );
319
+
320
+ if ( 'upsell' === $step_type || 'downsell' === $step_type ) {
321
+
322
+ return true;
323
+ }
324
+
325
+ return false;
326
+ }
327
+
328
+ /**
329
+ * Check if loaded page requires woo.
330
+ *
331
+ * @return bool
332
+ */
333
+ public function check_is_woo_required_page() {
334
+
335
+ global $post;
336
+ $step_id = $post->ID;
337
+ $woo_not_required_type = array( 'landing' );
338
+ $step_type = $this->get_step_type( $step_id );
339
+ return ( ! in_array( $step_type, $woo_not_required_type, true ) );
340
+ }
341
+
342
+ /**
343
+ * Define constant for cache
344
+ *
345
+ * @return void
346
+ */
347
+ public function do_not_cache() {
348
+
349
+ global $post;
350
+
351
+ if ( ! apply_filters( 'cartflows_do_not_cache_step', true, $post->ID ) ) {
352
+ return;
353
+ }
354
+
355
+ wcf_maybe_define_constant( 'DONOTCACHEPAGE', true );
356
+ wcf_maybe_define_constant( 'DONOTCACHEOBJECT', true );
357
+ wcf_maybe_define_constant( 'DONOTCACHEDB', true );
358
+
359
+ nocache_headers();
360
+ }
361
+
362
+ /**
363
+ * Get linking url
364
+ *
365
+ * @param array $args query args.
366
+ * @return string
367
+ */
368
+ public function get_linking_url( $args = array() ) {
369
+
370
+ $url = get_home_url();
371
+
372
+ $url = add_query_arg( $args, $url );
373
+
374
+ return $url;
375
+ }
376
+
377
+ /**
378
+ * Get assets urls
379
+ *
380
+ * @return array
381
+ * @since 1.1.6
382
+ */
383
+ public function get_assets_path() {
384
+
385
+ $rtl = '';
386
+
387
+ if ( is_rtl() ) {
388
+ $rtl = '-rtl';
389
+ }
390
+
391
+ $file_prefix = '';
392
+ $dir_name = '';
393
+
394
+ $is_min = apply_filters( 'cartflows_load_min_assets', false );
395
+
396
+ if ( $is_min ) {
397
+ $file_prefix = '.min';
398
+ $dir_name = 'min-';
399
+ }
400
+
401
+ $js_gen_path = CARTFLOWS_URL . 'assets/' . $dir_name . 'js/';
402
+ $css_gen_path = CARTFLOWS_URL . 'assets/' . $dir_name . 'css/';
403
+
404
+ return array(
405
+ 'css' => $css_gen_path,
406
+ 'js' => $js_gen_path,
407
+ 'file_prefix' => $file_prefix,
408
+ 'rtl' => $rtl,
409
+ );
410
+ }
411
+
412
+ /**
413
+ * Get assets css url
414
+ *
415
+ * @param string $file file name.
416
+ * @return string
417
+ * @since 1.1.6
418
+ */
419
+ public function get_css_url( $file ) {
420
+
421
+ $assets_vars = wcf()->assets_vars;
422
+
423
+ $url = $assets_vars['css'] . $file . $assets_vars['rtl'] . $assets_vars['file_prefix'] . '.css';
424
+
425
+ return $url;
426
+ }
427
+
428
+ /**
429
+ * Get assets js url
430
+ *
431
+ * @param string $file file name.
432
+ * @return string
433
+ * @since 1.1.6
434
+ */
435
+ public function get_js_url( $file ) {
436
+
437
+ $assets_vars = wcf()->assets_vars;
438
+
439
+ $url = $assets_vars['js'] . $file . $assets_vars['file_prefix'] . '.js';
440
+
441
+ return $url;
442
+ }
443
+
444
+ /**
445
+ * Get unique id.
446
+ *
447
+ * @param int $length Length.
448
+ *
449
+ * @return string
450
+ */
451
+ public function get_unique_id( $length = 8 ) {
452
+
453
+ return substr( md5( microtime() ), 0, $length );
454
+ }
455
+
456
+ /**
457
+ * Get selected checkout products and data
458
+ *
459
+ * @param int $checkout_id Checkout id..
460
+ * @param array $saved_products Saved product.
461
+ *
462
+ * @return array
463
+ */
464
+ public function get_selected_checkout_products( $checkout_id = '', $saved_products = array() ) {
465
+
466
+ if ( empty( $checkout_id ) ) {
467
+
468
+ global $post;
469
+
470
+ $checkout_id = $post->ID;
471
+ }
472
+
473
+ if ( ! isset( $this->checkout_products[ $checkout_id ] ) ) {
474
+
475
+ if ( ! empty( $saved_products ) ) {
476
+
477
+ $products = $saved_products;
478
+ } else {
479
+
480
+ $products = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-checkout-products' );
481
+ }
482
+
483
+ $verify_url_data = false;
484
+ $default_add_to_cart = false;
485
+ $default_ids = array();
486
+ $default_add_to_cart = true;
487
+
488
+ if ( isset( $_GET['wcf-default'] ) ) { //phpcs:ignore
489
+ //phpcs:ignore WordPress.Security.NonceVerification.Recommended
490
+ $default_sequence = sanitize_text_field( wp_unslash( $_GET['wcf-default'] ) );
491
+ $default_ids = array_map( 'intval', explode( ',', $default_sequence ) );
492
+ $verify_url_data = true;
493
+ }
494
+
495
+ if ( is_array( $products ) ) {
496
+
497
+ foreach ( $products as $in => $data ) {
498
+
499
+ if ( $verify_url_data ) {
500
+
501
+ $default_add_to_cart = false;
502
+ $sequence = $in + 1;
503
+
504
+ if ( in_array( $sequence, $default_ids, true ) ) {
505
+ $default_add_to_cart = true;
506
+ }
507
+ }
508
+
509
+ $default_data = array(
510
+ 'quantity' => 1,
511
+ 'discount_type' => '',
512
+ 'discount_value' => '',
513
+ 'unique_id' => $this->get_unique_id(),
514
+ 'add_to_cart' => $default_add_to_cart,
515
+ );
516
+
517
+ $products[ $in ] = wp_parse_args( $products[ $in ], $default_data );
518
+ }
519
+ }
520
+
521
+ $this->checkout_products[ $checkout_id ] = $products;
522
+ }
523
+
524
+ return $this->checkout_products[ $checkout_id ];
525
+ }
526
+
527
+ /**
528
+ * Get selected checkout products and data
529
+ *
530
+ * @param int $checkout_id Checkout id..
531
+ * @param array $products_data Saved product.
532
+ *
533
+ * @return array
534
+ */
535
+ public function set_selcted_checkout_products( $checkout_id = '', $products_data = array() ) {
536
+
537
+ if ( empty( $checkout_id ) ) {
538
+
539
+ global $post;
540
+
541
+ $checkout_id = $post->ID;
542
+ }
543
+
544
+ if ( isset( $this->checkout_products[ $checkout_id ] ) ) {
545
+
546
+ $products = $this->checkout_products[ $checkout_id ];
547
+ } else {
548
+ $products = $this->get_selected_checkout_products( $checkout_id );
549
+ }
550
+
551
+ if ( is_array( $products ) && ! empty( $products_data ) ) {
552
+
553
+ foreach ( $products as $in => $data ) {
554
+
555
+ if ( isset( $products_data[ $in ] ) ) {
556
+ $products[ $in ] = wp_parse_args( $products_data[ $in ], $products[ $in ] );
557
+ }
558
+ }
559
+ }
560
+
561
+ $this->checkout_products[ $checkout_id ] = $products;
562
+
563
+ return $this->checkout_products[ $checkout_id ];
564
+ }
565
+ }
566
+
567
+ /**
568
+ * Get a specific property of an array without needing to check if that property exists.
569
+ *
570
+ * Provide a default value if you want to return a specific value if the property is not set.
571
+ *
572
+ * @param array $array Array from which the property's value should be retrieved.
573
+ * @param string $prop Name of the property to be retrieved.
574
+ * @param string $default Optional. Value that should be returned if the property is not set or empty. Defaults to null.
575
+ *
576
+ * @return null|string|mixed The value
577
+ */
578
+ function wcf_get_prop( $array, $prop, $default = null ) {
579
+
580
+ if ( ! is_array( $array ) && ! ( is_object( $array ) && $array instanceof ArrayAccess ) ) {
581
+ return $default;
582
+ }
583
+
584
+ if ( isset( $array[ $prop ] ) ) {
585
+ $value = $array[ $prop ];
586
+ } else {
587
+ $value = '';
588
+ }
589
+
590
+ return empty( $value ) && null !== $default ? $default : $value;
591
+ }
classes/class-cartflows-wizard.php CHANGED
@@ -1,688 +1,698 @@
1
- <?php
2
- /**
3
- * CartFlows- Onboarding Wizard
4
- *
5
- * @package cartflows
6
- */
7
-
8
- if ( ! defined( 'ABSPATH' ) ) {
9
- exit;
10
- }
11
-
12
- if ( ! class_exists( 'CartFlows_Wizard' ) ) :
13
-
14
- /**
15
- * CartFlows_Wizard class.
16
- */
17
- class CartFlows_Wizard {
18
-
19
- /**
20
- * Hook in tabs.
21
- */
22
- public function __construct() {
23
-
24
- if ( apply_filters( 'cartflows_enable_setup_wizard', true ) && current_user_can( 'manage_options' ) ) {
25
- add_action( 'admin_menu', array( $this, 'admin_menus' ) );
26
- add_action( 'admin_init', array( $this, 'setup_wizard' ) );
27
- add_action( 'admin_notices', array( $this, 'show_setup_wizard' ) );
28
- add_action( 'wp_ajax_page_builder_step_save', array( $this, 'page_builder_step_save' ) );
29
- add_action( 'wp_ajax_page_builder_save_option', array( $this, 'save_page_builder_option' ) );
30
- add_action( 'admin_head', array( $this, 'add_mautic_form_script' ) );
31
- add_action( 'woocommerce_installed', array( $this, 'disable_woo_setup_redirect' ) );
32
-
33
- add_action( 'wp_ajax_wcf_activate_wc_plugins', array( $this, 'activate_wc_plugins' ) );
34
-
35
- add_action( 'admin_init', array( $this, 'hide_notices' ) );
36
-
37
- }
38
- }
39
-
40
-
41
- /**
42
- * Hide a notice if the GET variable is set.
43
- */
44
- public function hide_notices() {
45
-
46
- if ( ! isset( $_GET['wcf-hide-notice'] ) ) {
47
- return;
48
- }
49
-
50
- $wcf_hide_notice = filter_input( INPUT_GET, 'wcf-hide-notice', FILTER_SANITIZE_STRING );
51
- $_wcf_notice_nonce = filter_input( INPUT_GET, '_wcf_notice_nonce', FILTER_SANITIZE_STRING );
52
-
53
- if ( $wcf_hide_notice && $_wcf_notice_nonce && wp_verify_nonce( sanitize_text_field( wp_unslash( $_wcf_notice_nonce ) ), 'wcf_hide_notices_nonce' ) ) {
54
- update_option( 'wcf_setup_skipped', true );
55
- }
56
- }
57
-
58
- /**
59
- * Disable the woo redirect for new setup.
60
- */
61
- public function disable_woo_setup_redirect() {
62
-
63
- if ( empty( $_GET['page'] ) || 'cartflow-setup' !== $_GET['page'] ) { //phpcs:ignore
64
- return;
65
- }
66
-
67
- delete_transient( '_wc_activation_redirect' );
68
- }
69
-
70
- /**
71
- * Show action links on the plugin screen.
72
- *
73
- * @since 1.0.0
74
- * @return void
75
- */
76
- public function show_setup_wizard() {
77
-
78
- $status = get_option( 'wcf_setup_complete', false );
79
- $skip_setup = get_option( 'wcf_setup_skipped', false );
80
-
81
- if ( false === $status && ! $skip_setup ) { ?>
82
- <div class="notice notice-info">
83
- <p><b><?php esc_html_e( 'Thanks for installing and using CartFlows!', 'cartflows' ); ?></b></p>
84
- <p><?php esc_html_e( 'It is easy to use the CartFlows. Please use the setup wizard to quick start setup.', 'cartflows' ); ?></p>
85
- <p>
86
- <a href="<?php echo esc_url( admin_url( 'index.php?page=cartflow-setup' ) ); ?>" class="button button-primary"> <?php esc_html_e( 'Start Wizard', 'cartflows' ); ?></a>
87
- <a class="button-secondary" href="<?php echo esc_url( wp_nonce_url( add_query_arg( 'wcf-hide-notice', 'install' ), 'wcf_hide_notices_nonce', '_wcf_notice_nonce' ) ); ?>"><?php esc_html_e( 'Skip Setup', 'cartflows' ); ?></a>
88
- </p>
89
- </div>
90
- <?php
91
- }
92
- }
93
-
94
- /**
95
- * Add admin menus/screens.
96
- */
97
- public function admin_menus() {
98
-
99
- if ( empty( $_GET['page'] ) || 'cartflow-setup' !== $_GET['page'] ) { //phpcs:ignore
100
- return;
101
- }
102
-
103
- add_dashboard_page( '', '', 'manage_options', 'cartflow-setup', '' );
104
- }
105
-
106
- /**
107
- * Show the setup wizard.
108
- */
109
- public function setup_wizard() {
110
-
111
- if ( empty( $_GET['page'] ) || 'cartflow-setup' !== $_GET['page'] ) { //phpcs:ignore
112
- return;
113
- }
114
-
115
- $this->steps = array(
116
- 'basic-config' => array(
117
- 'name' => __( 'Welcome', 'cartflows' ),
118
- 'view' => array( $this, 'welcome_step' ),
119
- 'handler' => array( $this, 'welcome_step_save' ),
120
- ),
121
- 'page-builder' => array(
122
- 'name' => __( 'Page Builder', 'cartflows' ),
123
- 'view' => array( $this, 'page_builder_step' ),
124
- ),
125
- 'checkout' => array(
126
- 'name' => __( 'Checkout', 'cartflows' ),
127
- 'view' => array( $this, 'checkout_step' ),
128
- ),
129
- 'training' => array(
130
- 'name' => __( 'Training', 'cartflows' ),
131
- 'view' => array( $this, 'training_step' ),
132
- ),
133
- 'setup-ready' => array(
134
- 'name' => __( 'Ready!', 'cartflows' ),
135
- 'view' => array( $this, 'ready_step' ),
136
- 'handler' => '',
137
- ),
138
- );
139
-
140
- $this->step = isset( $_GET['step'] ) ? sanitize_text_field( $_GET['step'] ) : current( array_keys( $this->steps ) ); //phpcs:ignore
141
-
142
- wp_enqueue_style( 'cartflows-setup', CARTFLOWS_URL . 'admin/assets/css/setup-wizard.css', array( 'dashicons' ), CARTFLOWS_VER );
143
- wp_style_add_data( 'cartflows-setup', 'rtl', 'replace' );
144
-
145
- wp_enqueue_script( 'cartflows-setup', CARTFLOWS_URL . 'admin/assets/js/setup-wizard.js', array( 'jquery', 'wp-util', 'updates' ), CARTFLOWS_VER, false );
146
-
147
- wp_localize_script( 'cartflows-setup', 'cartflows_setup_vars', self::localize_vars() );
148
-
149
- wp_enqueue_media();
150
-
151
- if ( ! empty( $_POST['save_step'] ) && isset( $this->steps[ $this->step ]['handler'] ) ) { //phpcs:ignore
152
- call_user_func( $this->steps[ $this->step ]['handler'] );
153
- }
154
-
155
- ob_start();
156
- $this->setup_wizard_header();
157
- $this->setup_wizard_steps();
158
- $this->setup_wizard_content();
159
- $this->setup_wizard_footer();
160
- exit;
161
- }
162
-
163
- /**
164
- * Get current step slug
165
- */
166
- public function get_current_step_slug() {
167
- $keys = array_keys( $this->steps );
168
- return $keys[ array_search( $this->step, array_keys( $this->steps ), true ) ];
169
- }
170
-
171
- /**
172
- * Get previous step link
173
- */
174
- public function get_prev_step_link() {
175
- $keys = array_keys( $this->steps );
176
- return add_query_arg( 'step', $keys[ array_search( $this->step, array_keys( $this->steps ), true ) - 1 ] );
177
- }
178
-
179
- /**
180
- * Get next step link
181
- */
182
- public function get_next_step_link() {
183
- $keys = array_keys( $this->steps );
184
- return add_query_arg( 'step', $keys[ array_search( $this->step, array_keys( $this->steps ), true ) + 1 ] );
185
- }
186
-
187
- /**
188
- * Get next step link
189
- */
190
- public function get_next_step_plain_link() {
191
- $keys = array_keys( $this->steps );
192
- $step_index = array_search( $this->step, $keys, true );
193
- $step_index = ( count( $keys ) == $step_index + 1 ) ? $step_index : $step_index + 1;
194
- $step = $keys[ $step_index ];
195
- return admin_url( 'index.php?page=cartflow-setup&step=' . $step );
196
- }
197
-
198
- /**
199
- * Setup Wizard Header.
200
- */
201
- public function setup_wizard_header() {
202
- set_current_screen();
203
- ?>
204
- <html <?php language_attributes(); ?>>
205
- <html>
206
- <head>
207
- <meta name="viewport" content="width=device-width" />
208
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
209
- <title><?php esc_html_e( 'CartFlows Setup', 'cartflows' ); ?></title>
210
-
211
- <script type="text/javascript">
212
- addLoadEvent = function(func){if(typeof jQuery!="undefined")jQuery(document).ready(func);else if(typeof wpOnload!='function'){wpOnload=func;}else{var oldonload=wpOnload;wpOnload=function(){oldonload();func();}}};
213
- var ajaxurl = '<?php echo admin_url( 'admin-ajax.php', 'relative' ); ?>';
214
- var pagenow = '';
215
- </script>
216
- <?php wp_print_scripts( array( 'cartflows-setup' ) ); ?>
217
- <?php do_action( 'admin_print_styles' ); ?>
218
- <?php do_action( 'admin_head' ); ?>
219
- </head>
220
- <body class="cartflows-setup wp-core-ui cartflows-step-<?php echo esc_attr( $this->get_current_step_slug() ); ?>">
221
- <div id="cartflows-logo">
222
- <img height="40" class="wcf-logo" src="<?php echo CARTFLOWS_URL . 'assets/images/cartflows-logo.svg'; ?>" />
223
- </div>
224
- <?php
225
- }
226
-
227
- /**
228
- * Setup Wizard Footer.
229
- */
230
- public function setup_wizard_footer() {
231
-
232
- $admin_url = admin_url( 'admin.php?page=cartflows_settings' );
233
- ?>
234
- <div class="close-button-wrapper">
235
- <a href="<?php echo esc_url( $admin_url ); ?>" class="wizard-close-link" ><?php esc_html_e( 'Exit Setup Wizard', 'cartflows' ); ?></a>
236
- </div>
237
- </body>
238
- </html>
239
- <?php
240
- }
241
-
242
- /**
243
- * Output the steps.
244
- */
245
- public function setup_wizard_steps() {
246
-
247
- $ouput_steps = $this->steps;
248
- ?>
249
- <ol class="cartflows-setup-steps">
250
- <?php
251
- foreach ( $ouput_steps as $step_key => $step ) :
252
- $classes = '';
253
- $activated = false;
254
- if ( $step_key === $this->step ) {
255
- $classes = 'active';
256
- $activated = true;
257
- } elseif ( array_search( $this->step, array_keys( $this->steps ), true ) > array_search( $step_key, array_keys( $this->steps ), true ) ) {
258
- $classes = 'done';
259
- $activated = true;
260
- }
261
- ?>
262
- <li class="<?php echo esc_attr( $classes ); ?>">
263
- <span><?php echo esc_html( $step['name'] ); ?></span>
264
- </li>
265
- <?php endforeach; ?>
266
- </ol>
267
- <?php
268
- }
269
-
270
- /**
271
- * Output the content for the current step.
272
- */
273
- public function setup_wizard_content() {
274
- ?>
275
- <input type="hidden" class="wcf-redirect-link" data-redirect-link="<?php echo esc_url_raw( $this->get_next_step_plain_link() ); ?>" >
276
- <?php
277
-
278
- echo '<div class="cartflows-setup-content">';
279
- call_user_func( $this->steps[ $this->step ]['view'] );
280
- echo '</div>';
281
- }
282
-
283
- /**
284
- * Introduction step.
285
- */
286
- public function welcome_step() {
287
- ?>
288
- <h1><?php esc_html_e( 'Welcome to CartFlows!', 'cartflows' ); ?></h1>
289
- <p><?php esc_html_e( 'Thank you for choosing CartFlows to get more leads, increase conversions, & maximize profits. This short setup wizard will guide you though configuring CartFlows and creating your first funnel.', 'cartflows' ); ?></p>
290
- <form method="post">
291
- <div class="cartflows-setup-actions step">
292
- <div class="button-prev-wrap">
293
- </div>
294
- <div class="button-next-wrap">
295
- <input type="submit" class="uct-activate button-primary button button-large " value="<?php esc_html_e( 'Lets Go »', 'cartflows' ); ?>" name="save_step" />
296
- </div>
297
- <?php wp_nonce_field( 'cartflow-setup' ); ?>
298
- </div>
299
- </form>
300
- <?php
301
- }
302
-
303
- /**
304
- * Save Locale Settings.
305
- */
306
- public function welcome_step_save() {
307
- check_admin_referer( 'cartflow-setup' );
308
-
309
- // Update site title & tagline.
310
- $redirect_url = $this->get_next_step_link();
311
-
312
- wp_safe_redirect( esc_url_raw( $redirect_url ) );
313
- exit;
314
- }
315
-
316
- /**
317
- * Locale settings
318
- */
319
- public function page_builder_step() {
320
- ?>
321
-
322
- <h1><?php esc_html_e( 'Page Builder Setup', 'cartflows' ); ?></h1>
323
- <p class="description"><?php esc_html_e( 'Please select a page builder you would like to use with CartFlows.', 'cartflows' ); ?></p>
324
- <form method="post">
325
- <table class="cartflows-table widefat">
326
- <tr class="cartflows-row">
327
- <td class="cartflows-row-heading">
328
- <label><?php esc_html_e( 'Select Page Builder', 'cartflows' ); ?></label>
329
- </td>
330
- <td class="cartflows-row-content">
331
- <?php
332
- $installed_plugins = get_plugins();
333
- $plugins = array(
334
- array(
335
- 'title' => __( 'Elementor', 'cartflows' ),
336
- 'value' => 'elementor',
337
- 'data' => array(
338
- 'slug' => 'elementor',
339
- 'init' => 'elementor/elementor.php',
340
- 'active' => is_plugin_active( 'elementor/elementor.php' ) ? 'yes' : 'no',
341
- 'install' => isset( $installed_plugins['elementor/elementor.php'] ) ? 'yes' : 'no',
342
- ),
343
- ),
344
- array(
345
- 'title' => __( 'Beaver Builder Plugin (Lite Version)', 'cartflows' ),
346
- 'value' => 'beaver-builder',
347
- 'data' => array(
348
- 'slug' => 'beaver-builder-lite-version',
349
- 'init' => 'beaver-builder-lite-version/fl-builder.php',
350
- 'active' => is_plugin_active( 'beaver-builder-lite-version/fl-builder.php' ) ? 'yes' : 'no',
351
- 'install' => isset( $installed_plugins['beaver-builder-lite-version/fl-builder.php'] ) ? 'yes' : 'no',
352
- ),
353
- ),
354
- array(
355
- 'title' => __( 'Divi', 'cartflows' ),
356
- 'value' => 'divi',
357
- 'data' => array(
358
- 'slug' => 'divi',
359
- 'init' => 'divi',
360
- 'active' => 'yes',
361
- 'install' => 'NA',
362
- ),
363
- ),
364
- array(
365
- 'title' => __( 'Other', 'cartflows' ),
366
- 'value' => 'other',
367
- 'data' => array(
368
- 'slug' => 'other',
369
- 'init' => false,
370
- 'active' => 'yes',
371
- 'install' => 'NA',
372
- ),
373
- ),
374
- );
375
- ?>
376
- <input type="hidden" name="save-pb-input" id="save-pb-option" value="1" />
377
- <select name="page-builder" class="page-builder-list" data-redirect-link="<?php echo esc_url_raw( $this->get_next_step_plain_link() ); ?>">
378
- <?php
379
- foreach ( $plugins as $key => $plugin ) {
380
- echo '<option value="' . esc_attr( $plugin['value'] ) . '" data-install="' . esc_attr( $plugin['data']['install'] ) . '" data-active="' . esc_attr( $plugin['data']['active'] ) . '" data-slug="' . esc_attr( $plugin['data']['slug'] ) . '" data-init="' . esc_attr( $plugin['data']['init'] ) . '">' . esc_html( $plugin['title'] ) . '</option>';
381
- }
382
- ?>
383
- </select>
384
- </td>
385
- </tr>
386
- </table>
387
- <p><?php esc_html_e( 'While CartFlows Should work with most page builders, we offer templates for the above page builders.', 'cartflows' ); ?></p>
388
- <div class="cartflows-setup-actions step">
389
- <div class="button-prev-wrap">
390
- <a href="<?php echo esc_url( $this->get_prev_step_link() ); ?>" class="button-primary button button-large button-prev" ><?php esc_html_e( '« Previous', 'cartflows' ); ?></a>
391
- </div>
392
- <div class="button-next-wrap">
393
- <a href="<?php echo esc_url_raw( $this->get_next_step_plain_link() ); ?>" class="button button-large button-next" ><?php esc_html_e( 'Skip this step', 'cartflows' ); ?></a>
394
- <a href="#" class="button button-primary wcf-install-plugins"><?php esc_html_e( 'Next »', 'cartflows' ); ?></a>
395
- </div>
396
- <?php wp_nonce_field( 'cartflow-setup' ); ?>
397
- </div>
398
- </form>
399
- <?php
400
- }
401
-
402
- /**
403
- * Render checkout step.
404
- */
405
- public function checkout_step() {
406
-
407
- $installed_plugins = get_plugins();
408
- $is_wc_installed = isset( $installed_plugins['woocommerce/woocommerce.php'] ) ? 'yes' : 'no';
409
- $is_wcf_ca_installed = isset( $installed_plugins['woo-cart-abandonment-recovery/woo-cart-abandonment-recovery.php'] ) ? 'yes' : 'no';
410
- $is_active = class_exists( 'WooCommerce' ) ? 'yes' : 'no';
411
- $is_wcf_ca_active = class_exists( 'CARTFLOWS_CA_Loader' ) ? 'yes' : 'no';
412
- ?>
413
- <h1><?php esc_html_e( 'Choose a checkout', 'cartflows' ); ?></h1>
414
- <div class="cartflows-setup-message">
415
- <p>
416
- <?php esc_html_e( 'While CartFlows is designed to use WooCommerce sell digital and physical products, not all funnels need a checkout system.', 'cartflows' ); ?>
417
- </p>
418
- <h4 class="cartflows-setup-message-title"><?php esc_html_e( 'Would you like to install WooCommerce to sell digital and physical products in your funnels?', 'cartflows' ); ?></h4>
419
- <span><input data-wcf-ca-active="<?php echo esc_attr( $is_wcf_ca_active ); ?>" data-wcf-ca-install="<?php echo esc_attr( $is_wcf_ca_installed ); ?>" data-woo-active="<?php echo esc_attr( $is_active ); ?>" data-woo-install="<?php echo esc_attr( $is_wc_installed ); ?>" type="hidden" class="wcf-install-wc-input" name="installl-woocommerce" value="" checked></span>
420
- </div>
421
-
422
- <div class="cartflows-setup-extra-notice">
423
-
424
- <span>
425
- <?php esc_html_e( 'The following plugin will be installed and activated for you:', 'cartflows' ); ?>
426
- <a target="_blank" href="https://wordpress.org/plugins/woo-cart-abandonment-recovery/"> <?php esc_html_e( 'WooCommerce', 'cartflows' ); ?></a>,
427
- <a target="_blank" href="https://wordpress.org/plugins/woo-cart-abandonment-recovery/"> <?php esc_html_e( 'WooCommerce Cart Abandonment Recovery', 'cartflows' ); ?></a>
428
-
429
- </span>
430
-
431
- </div>
432
-
433
- <div class="cartflows-setup-actions step">
434
- <div class="button-prev-wrap">
435
- <a href="<?php echo esc_url( $this->get_prev_step_link() ); ?>" class="button-primary button button-large button-prev" ><?php esc_html_e( '« Previous', 'cartflows' ); ?></a>
436
- </div>
437
- <div class="button-next-wrap">
438
- <a href="<?php echo esc_url_raw( $this->get_next_step_plain_link() ); ?>" class="button button-large button-next"><?php esc_html_e( 'No thanks', 'cartflows' ); ?></a>
439
- <a class="wcf-install-wc button-primary button button-large" name="save_step" > <?php esc_html_e( 'Yes', 'cartflows' ); ?> </a>
440
- </div>
441
- </div>
442
-
443
- <?php
444
- }
445
-
446
- /**
447
- * Save Locale Settings.
448
- */
449
- public function activate_wc_plugins() {
450
-
451
- check_ajax_referer( 'wcf-wc-plugins-activate', 'security' );
452
-
453
- $plugin_slug_arr = array(
454
- 'woocommerce/woocommerce.php' => true,
455
- 'woo-cart-abandonment-recovery/woo-cart-abandonment-recovery.php' => false,
456
- );
457
-
458
- $activate = array(
459
- 'woocommerce/woocommerce.php' => false,
460
- 'woo-cart-abandonment-recovery/woo-cart-abandonment-recovery.php' => false,
461
- );
462
-
463
- foreach ( $plugin_slug_arr as $slug => $do_silently ) {
464
-
465
- $activate[ $slug ] = activate_plugin( $slug, '', false, $do_silently );
466
- }
467
-
468
- foreach ( $activate as $slug => $data ) {
469
-
470
- if ( is_wp_error( $data ) ) {
471
- wp_send_json_error(
472
- array(
473
- 'success' => false,
474
- 'message' => $data->get_error_message(),
475
- )
476
- );
477
- }
478
- }
479
-
480
- wp_send_json_success();
481
- }
482
-
483
- /**
484
- * Save Locale Settings.
485
- */
486
- public function page_builder_step_save() {
487
-
488
- if ( ! current_user_can( 'manage_options' ) ) {
489
- return;
490
- }
491
-
492
- check_ajax_referer( 'wcf-page-builder-step-save', 'security' );
493
-
494
- $plugin_init = isset( $_POST['plugin_init'] ) ? sanitize_text_field( wp_unslash( $_POST['plugin_init'] ) ) : '';
495
- $save_option = ( isset( $_POST['save_builder_option'] ) && 'true' == $_POST['save_builder_option'] ) ? true : false;
496
- $plugin_slug = filter_input( INPUT_POST, 'page_builder', FILTER_SANITIZE_STRING );
497
-
498
- $do_sliently = true;
499
- if ( 'woo-cart-abandonment-recovery' === $plugin_slug ) {
500
- $do_sliently = false;
501
- }
502
-
503
- $activate = activate_plugin( $plugin_init, '', false, $do_sliently );
504
-
505
- if ( $save_option ) {
506
- $this->save_page_builder_option();
507
- }
508
-
509
- if ( is_wp_error( $activate ) ) {
510
- wp_send_json_error(
511
- array(
512
- 'success' => false,
513
- 'message' => $activate->get_error_message(),
514
- )
515
- );
516
- }
517
-
518
- wp_send_json_success(
519
- array( 'plugin' => $plugin_slug )
520
- );
521
- }
522
-
523
- /**
524
- * Save selected page builder in options database.
525
- */
526
- public function save_page_builder_option() {
527
-
528
- if ( ! current_user_can( 'manage_options' ) ) {
529
- return;
530
- }
531
-
532
- $page_builder = isset( $_POST['page_builder'] ) ? sanitize_text_field( wp_unslash( $_POST['page_builder'] ) ) : ''; //phpcs:ignore
533
-
534
- $wcf_settings = get_option( '_cartflows_common', array() );
535
-
536
- if ( false !== strpos( $page_builder, 'beaver-builder' ) ) {
537
- $page_builder = 'beaver-builder';
538
- }
539
-
540
- $wcf_settings['default_page_builder'] = $page_builder;
541
-
542
- update_option( '_cartflows_common', $wcf_settings );
543
-
544
- wp_send_json_success(
545
- array( 'plugin' => $page_builder )
546
- );
547
-
548
- }
549
-
550
- /**
551
- * Final step.
552
- */
553
- public function ready_step() {
554
-
555
- // Set setup wizard status to complete.
556
- update_option( 'wcf_setup_complete', true );
557
- ?>
558
- <h1><?php esc_html_e( 'Congratulations, You Did It!', 'cartflows' ); ?></h1>
559
-
560
- <div class="cartflows-setup-next-steps">
561
- <div class="cartflows-setup-next-steps-last">
562
-
563
- <p class="success">
564
- <?php
565
- esc_html_e( 'CartFlows is ready to use on your website. You\'ve successfully completed the setup process and all that is left for you to do is create your first flow.', 'cartflows' )
566
- ?>
567
- </p>
568
-
569
-
570
- <ul class="wcf-wizard-next-steps">
571
- <li class="wcf-wizard-next-step-item">
572
- <div class="wcf-wizard-next-step-description">
573
- <p class="next-step-heading">Next step</p>
574
- <h3 class="next-step-description">Create First Flow</h3>
575
- <p class="next-step-extra-info">You're ready to add flows to your website.</p>
576
- </div>
577
- <div class="wcf-wizard-next-step-action">
578
- <p class="wc-setup-actions step">
579
- <a href="<?php echo esc_url( admin_url( 'edit.php?post_type=cartflows_flow&add-new-flow' ) ); ?>" type="button" class="button button-primary button-hero" ><?php esc_html_e( 'Create a flow', 'cartflows' ); ?></a>
580
- </p>
581
- </div>
582
- </li>
583
- </ul>
584
-
585
- </div>
586
- </div>
587
- <?php
588
- }
589
-
590
- /**
591
- * Training course step.
592
- */
593
- public function training_step() {
594
- $current_user = wp_get_current_user();
595
- ?>
596
- <h1><?php esc_html_e( 'Exclusive CartFlows Training Course Offer', 'cartflows' ); ?></h1>
597
-
598
- <div id="mauticform_wrapper_cartflowsonboarding" class="mauticform_wrapper">
599
- <form autocomplete="false" role="form" method="post" action="https://go.cartflows.com/form/submit?formId=2" id="mauticform_cartflowsonboarding" data-mautic-form="cartflowsonboarding" enctype="multipart/form-data">
600
- <div class="mauticform-error" id="mauticform_cartflowsonboarding_error"></div>
601
- <div class="mauticform-message" id="mauticform_cartflowsonboarding_message"></div>
602
- <div class="mauticform-innerform">
603
- <div class="mauticform-page-wrapper mauticform-page-1" data-mautic-form-page="1">
604
- <div id="mauticform_cartflowsonboarding_enter_your_email" class="mauticform-row mauticform-email mauticform-field-1">
605
- <div class="cartflows-setup-message">
606
- <p>
607
- <?php esc_html_e( 'We want you to get off to a great start using CartFlows, so we would like to give access to our exclusive training course.', 'cartflows' ); ?>
608
- <?php esc_html_e( 'Get access to this couse, for free, by entering your email below.', 'cartflows' ); ?>
609
- </p>
610
- <input id="mauticform_input_cartflowsonboarding_enter_your_email" name="mauticform[enter_your_email]" placeholder="<?php esc_html_e( 'Enter Email address', 'cartflows' ); ?>" value="<?php echo $current_user->user_email; ?>" class="mauticform-input" type="email">
611
- </div>
612
- <span class="mauticform-errormsg" style="display: none;"></span>
613
- </div>
614
- </div>
615
- </div>
616
-
617
- <input type="hidden" name="mauticform[formId]" id="mauticform_cartflowsonboarding_id" value="2">
618
- <input type="hidden" name="mauticform[return]" id="mauticform_cartflowsonboarding_return" value="">
619
- <input type="hidden" name="mauticform[formName]" id="mauticform_cartflowsonboarding_name" value="cartflowsonboarding">
620
- <div class="cartflows-setup-actions step">
621
- <div class="button-prev-wrap">
622
- <a href="<?php echo esc_url( $this->get_prev_step_link() ); ?>" class="button-primary button button-large button-prev" ><?php esc_html_e( '« Previous', 'cartflows' ); ?></a>
623
- </div>
624
- <div class="button-next-wrap">
625
- <a href="<?php echo esc_url_raw( $this->get_next_step_plain_link() ); ?>" class="button button-large button-next"><?php esc_html_e( 'No thanks', 'cartflows' ); ?></a>
626
- <button type="submit" name="mauticform[submit]" id="mauticform_input_cartflowsonboarding_submit" value="<?php esc_html_e( 'Allow', 'cartflows' ); ?>" class="mautic-form-submit btn btn-default button-primary button button-large button-next" name="save_step"><?php esc_html_e( 'Allow', 'cartflows' ); ?></button>
627
- </div>
628
- </div>
629
- </form>
630
- </div>
631
- <?php
632
- }
633
-
634
- /**
635
- * Localize variables in admin
636
- */
637
- public function localize_vars() {
638
-
639
- $vars = array();
640
-
641
- $ajax_actions = array(
642
- 'wcf_page_builder_step_save',
643
- 'wcf_wc_plugins_activate',
644
- );
645
-
646
- foreach ( $ajax_actions as $action ) {
647
-
648
- $vars[ $action . '_nonce' ] = wp_create_nonce( str_replace( '_', '-', $action ) );
649
- }
650
-
651
- return $vars;
652
- }
653
-
654
- /**
655
- * Add JS script for mautic form
656
- */
657
- public function add_mautic_form_script() {
658
-
659
- if ( ! isset( $_REQUEST['page'] ) || ( isset( $_REQUEST['page'] ) && 'cartflow-setup' !== $_REQUEST['page'] ) ) { //phpcs:ignore
660
- return;
661
- }
662
- ?>
663
-
664
- <script type="text/javascript">
665
- /** This section is only needed once per page if manually copying **/
666
- if (typeof MauticSDKLoaded == 'undefined') {
667
- var MauticSDKLoaded = true;
668
- var head = document.getElementsByTagName('head')[0];
669
- var script = document.createElement('script');
670
- script.type = 'text/javascript';
671
- script.src = 'https://go.cartflows.com/media/js/mautic-form.js';
672
- script.onload = function() {
673
- MauticSDK.onLoad();
674
- };
675
- head.appendChild(script);
676
- var MauticDomain = 'https://go.cartflows.com';
677
- var MauticLang = {
678
- 'submittingMessage': "Please wait..."
679
- };
680
- }
681
- </script>
682
- <?php
683
- }
684
- }
685
-
686
- new CartFlows_Wizard();
687
-
688
- endif;
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * CartFlows- Onboarding Wizard
4
+ *
5
+ * @package cartflows
6
+ */
7
+
8
+ if ( ! defined( 'ABSPATH' ) ) {
9
+ exit;
10
+ }
11
+
12
+ if ( ! class_exists( 'CartFlows_Wizard' ) ) :
13
+
14
+ /**
15
+ * CartFlows_Wizard class.
16
+ */
17
+ class CartFlows_Wizard {
18
+
19
+ /**
20
+ * Hook in tabs.
21
+ */
22
+ public function __construct() {
23
+
24
+ if ( apply_filters( 'cartflows_enable_setup_wizard', true ) && current_user_can( 'manage_options' ) ) {
25
+ add_action( 'admin_menu', array( $this, 'admin_menus' ) );
26
+ add_action( 'admin_init', array( $this, 'setup_wizard' ) );
27
+ add_action( 'admin_notices', array( $this, 'show_setup_wizard' ) );
28
+ add_action( 'wp_ajax_page_builder_step_save', array( $this, 'page_builder_step_save' ) );
29
+ add_action( 'wp_ajax_page_builder_save_option', array( $this, 'save_page_builder_option' ) );
30
+ add_action( 'admin_head', array( $this, 'add_mautic_form_script' ) );
31
+ add_action( 'woocommerce_installed', array( $this, 'disable_woo_setup_redirect' ) );
32
+
33
+ add_action( 'wp_ajax_wcf_activate_wc_plugins', array( $this, 'activate_wc_plugins' ) );
34
+
35
+ add_action( 'admin_init', array( $this, 'hide_notices' ) );
36
+
37
+ }
38
+ }
39
+
40
+
41
+ /**
42
+ * Hide a notice if the GET variable is set.
43
+ */
44
+ public function hide_notices() {
45
+
46
+ if ( ! isset( $_GET['wcf-hide-notice'] ) ) {
47
+ return;
48
+ }
49
+
50
+ $wcf_hide_notice = filter_input( INPUT_GET, 'wcf-hide-notice', FILTER_SANITIZE_STRING );
51
+ $_wcf_notice_nonce = filter_input( INPUT_GET, '_wcf_notice_nonce', FILTER_SANITIZE_STRING );
52
+
53
+ if ( $wcf_hide_notice && $_wcf_notice_nonce && wp_verify_nonce( sanitize_text_field( wp_unslash( $_wcf_notice_nonce ) ), 'wcf_hide_notices_nonce' ) ) {
54
+ update_option( 'wcf_setup_skipped', true );
55
+ }
56
+ }
57
+
58
+ /**
59
+ * Disable the woo redirect for new setup.
60
+ */
61
+ public function disable_woo_setup_redirect() {
62
+
63
+ if ( empty( $_GET['page'] ) || 'cartflow-setup' !== $_GET['page'] ) { //phpcs:ignore
64
+ return;
65
+ }
66
+
67
+ delete_transient( '_wc_activation_redirect' );
68
+ }
69
+
70
+ /**
71
+ * Show action links on the plugin screen.
72
+ *
73
+ * @since 1.0.0
74
+ * @return void
75
+ */
76
+ public function show_setup_wizard() {
77
+
78
+ $status = get_option( 'wcf_setup_complete', false );
79
+ $skip_setup = get_option( 'wcf_setup_skipped', false );
80
+
81
+ if ( false === $status && ! $skip_setup ) { ?>
82
+ <div class="notice notice-info">
83
+ <p><b><?php esc_html_e( 'Thanks for installing and using CartFlows!', 'cartflows' ); ?></b></p>
84
+ <p><?php esc_html_e( 'It is easy to use the CartFlows. Please use the setup wizard to quick start setup.', 'cartflows' ); ?></p>
85
+ <p>
86
+ <a href="<?php echo esc_url( admin_url( 'index.php?page=cartflow-setup' ) ); ?>" class="button button-primary"> <?php esc_html_e( 'Start Wizard', 'cartflows' ); ?></a>
87
+ <a class="button-secondary" href="<?php echo esc_url( wp_nonce_url( add_query_arg( 'wcf-hide-notice', 'install' ), 'wcf_hide_notices_nonce', '_wcf_notice_nonce' ) ); ?>"><?php esc_html_e( 'Skip Setup', 'cartflows' ); ?></a>
88
+ </p>
89
+ </div>
90
+ <?php
91
+ }
92
+ }
93
+
94
+ /**
95
+ * Add admin menus/screens.
96
+ */
97
+ public function admin_menus() {
98
+
99
+ if ( empty( $_GET['page'] ) || 'cartflow-setup' !== $_GET['page'] ) { //phpcs:ignore
100
+ return;
101
+ }
102
+
103
+ add_dashboard_page( '', '', 'manage_options', 'cartflow-setup', '' );
104
+ }
105
+
106
+ /**
107
+ * Show the setup wizard.
108
+ */
109
+ public function setup_wizard() {
110
+
111
+ if ( empty( $_GET['page'] ) || 'cartflow-setup' !== $_GET['page'] ) { //phpcs:ignore
112
+ return;
113
+ }
114
+
115
+ $this->steps = array(
116
+ 'basic-config' => array(
117
+ 'name' => __( 'Welcome', 'cartflows' ),
118
+ 'view' => array( $this, 'welcome_step' ),
119
+ 'handler' => array( $this, 'welcome_step_save' ),
120
+ ),
121
+ 'page-builder' => array(
122
+ 'name' => __( 'Page Builder', 'cartflows' ),
123
+ 'view' => array( $this, 'page_builder_step' ),
124
+ ),
125
+ 'checkout' => array(
126
+ 'name' => __( 'Checkout', 'cartflows' ),
127
+ 'view' => array( $this, 'checkout_step' ),
128
+ ),
129
+ 'training' => array(
130
+ 'name' => __( 'Training', 'cartflows' ),
131
+ 'view' => array( $this, 'training_step' ),
132
+ ),
133
+ 'setup-ready' => array(
134
+ 'name' => __( 'Ready!', 'cartflows' ),
135
+ 'view' => array( $this, 'ready_step' ),
136
+ 'handler' => '',
137
+ ),
138
+ );
139
+
140
+ $this->step = isset( $_GET['step'] ) ? sanitize_text_field( $_GET['step'] ) : current( array_keys( $this->steps ) ); //phpcs:ignore
141
+
142
+ wp_enqueue_style( 'cartflows-setup', CARTFLOWS_URL . 'admin/assets/css/setup-wizard.css', array( 'dashicons' ), CARTFLOWS_VER );
143
+ wp_style_add_data( 'cartflows-setup', 'rtl', 'replace' );
144
+
145
+ wp_enqueue_script( 'cartflows-setup', CARTFLOWS_URL . 'admin/assets/js/setup-wizard.js', array( 'jquery', 'wp-util', 'updates' ), CARTFLOWS_VER, false );
146
+
147
+ wp_localize_script( 'cartflows-setup', 'cartflows_setup_vars', self::localize_vars() );
148
+
149
+ wp_enqueue_media();
150
+
151
+ if ( ! empty( $_POST['save_step'] ) && isset( $this->steps[ $this->step ]['handler'] ) ) { //phpcs:ignore
152
+ call_user_func( $this->steps[ $this->step ]['handler'] );
153
+ }
154
+
155
+ ob_start();
156
+ $this->setup_wizard_header();
157
+ $this->setup_wizard_steps();
158
+ $this->setup_wizard_content();
159
+ $this->setup_wizard_footer();
160
+ exit;
161
+ }
162
+
163
+ /**
164
+ * Get current step slug
165
+ */
166
+ public function get_current_step_slug() {
167
+ $keys = array_keys( $this->steps );
168
+ return $keys[ array_search( $this->step, array_keys( $this->steps ), true ) ];
169
+ }
170
+
171
+ /**
172
+ * Get previous step link
173
+ */
174
+ public function get_prev_step_link() {
175
+ $keys = array_keys( $this->steps );
176
+ return add_query_arg( 'step', $keys[ array_search( $this->step, array_keys( $this->steps ), true ) - 1 ] );
177
+ }
178
+
179
+ /**
180
+ * Get next step link
181
+ */
182
+ public function get_next_step_link() {
183
+ $keys = array_keys( $this->steps );
184
+ return add_query_arg( 'step', $keys[ array_search( $this->step, array_keys( $this->steps ), true ) + 1 ] );
185
+ }
186
+
187
+ /**
188
+ * Get next step link
189
+ */
190
+ public function get_next_step_plain_link() {
191
+ $keys = array_keys( $this->steps );
192
+ $step_index = array_search( $this->step, $keys, true );
193
+ $step_index = ( count( $keys ) == $step_index + 1 ) ? $step_index : $step_index + 1;
194
+ $step = $keys[ $step_index ];
195
+ return admin_url( 'index.php?page=cartflow-setup&step=' . $step );
196
+ }
197
+
198
+ /**
199
+ * Setup Wizard Header.
200
+ */
201
+ public function setup_wizard_header() {
202
+ set_current_screen();
203
+ ?>
204
+ <html <?php language_attributes(); ?>>
205
+ <html>
206
+ <head>
207
+ <meta name="viewport" content="width=device-width" />
208
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
209
+ <title><?php esc_html_e( 'CartFlows Setup', 'cartflows' ); ?></title>
210
+
211
+ <script type="text/javascript">
212
+ addLoadEvent = function(func){if(typeof jQuery!="undefined")jQuery(document).ready(func);else if(typeof wpOnload!='function'){wpOnload=func;}else{var oldonload=wpOnload;wpOnload=function(){oldonload();func();}}};
213
+ var ajaxurl = '<?php echo admin_url( 'admin-ajax.php', 'relative' ); ?>';
214
+ var pagenow = '';
215
+ </script>
216
+ <?php wp_print_scripts( array( 'cartflows-setup' ) ); ?>
217
+ <?php do_action( 'admin_print_styles' ); ?>
218
+ <?php do_action( 'admin_head' ); ?>
219
+ </head>
220
+ <body class="cartflows-setup wp-core-ui cartflows-step-<?php echo esc_attr( $this->get_current_step_slug() ); ?>">
221
+ <div id="cartflows-logo">
222
+ <img height="40" class="wcf-logo" src="<?php echo CARTFLOWS_URL . 'assets/images/cartflows-logo.svg'; ?>" />
223
+ </div>
224
+ <?php
225
+ }
226
+
227
+ /**
228
+ * Setup Wizard Footer.
229
+ */
230
+ public function setup_wizard_footer() {
231
+
232
+ $admin_url = admin_url( 'admin.php?page=cartflows_settings' );
233
+ ?>
234
+ <div class="close-button-wrapper">
235
+ <a href="<?php echo esc_url( $admin_url ); ?>" class="wizard-close-link" ><?php esc_html_e( 'Exit Setup Wizard', 'cartflows' ); ?></a>
236
+ </div>
237
+ </body>
238
+ </html>
239
+ <?php
240
+ }
241
+
242
+ /**
243
+ * Output the steps.
244
+ */
245
+ public function setup_wizard_steps() {
246
+
247
+ $ouput_steps = $this->steps;
248
+ ?>
249
+ <ol class="cartflows-setup-steps">
250
+ <?php
251
+ foreach ( $ouput_steps as $step_key => $step ) :
252
+ $classes = '';
253
+ $activated = false;
254
+ if ( $step_key === $this->step ) {
255
+ $classes = 'active';
256
+ $activated = true;
257
+ } elseif ( array_search( $this->step, array_keys( $this->steps ), true ) > array_search( $step_key, array_keys( $this->steps ), true ) ) {
258
+ $classes = 'done';
259
+ $activated = true;
260
+ }
261
+ ?>
262
+ <li class="<?php echo esc_attr( $classes ); ?>">
263
+ <span><?php echo esc_html( $step['name'] ); ?></span>
264
+ </li>
265
+ <?php endforeach; ?>
266
+ </ol>
267
+ <?php
268
+ }
269
+
270
+ /**
271
+ * Output the content for the current step.
272
+ */
273
+ public function setup_wizard_content() {
274
+ ?>
275
+ <input type="hidden" class="wcf-redirect-link" data-redirect-link="<?php echo esc_url_raw( $this->get_next_step_plain_link() ); ?>" >
276
+ <?php
277
+
278
+ echo '<div class="cartflows-setup-content">';
279
+ call_user_func( $this->steps[ $this->step ]['view'] );
280
+ echo '</div>';
281
+ }
282
+
283
+ /**
284
+ * Introduction step.
285
+ */
286
+ public function welcome_step() {
287
+ ?>
288
+ <h1><?php esc_html_e( 'Welcome to CartFlows!', 'cartflows' ); ?></h1>
289
+ <p><?php esc_html_e( 'Thank you for choosing CartFlows to get more leads, increase conversions, & maximize profits. This short setup wizard will guide you though configuring CartFlows and creating your first funnel.', 'cartflows' ); ?></p>
290
+ <form method="post">
291
+ <div class="cartflows-setup-actions step">
292
+ <div class="button-prev-wrap">
293
+ </div>
294
+ <div class="button-next-wrap">
295
+ <input type="submit" class="uct-activate button-primary button button-large " value="<?php esc_html_e( 'Lets Go »', 'cartflows' ); ?>" name="save_step" />
296
+ </div>
297
+ <?php wp_nonce_field( 'cartflow-setup' ); ?>
298
+ </div>
299
+ </form>
300
+ <?php
301
+ }
302
+
303
+ /**
304
+ * Save Locale Settings.
305
+ */
306
+ public function welcome_step_save() {
307
+ check_admin_referer( 'cartflow-setup' );
308
+
309
+ // Update site title & tagline.
310
+ $redirect_url = $this->get_next_step_link();
311
+
312
+ wp_safe_redirect( esc_url_raw( $redirect_url ) );
313
+ exit;
314
+ }
315
+
316
+ /**
317
+ * Locale settings
318
+ */
319
+ public function page_builder_step() {
320
+ ?>
321
+
322
+ <h1><?php esc_html_e( 'Page Builder Setup', 'cartflows' ); ?></h1>
323
+ <p class="description"><?php esc_html_e( 'Please select a page builder you would like to use with CartFlows.', 'cartflows' ); ?></p>
324
+ <form method="post">
325
+ <table class="cartflows-table widefat">
326
+ <tr class="cartflows-row">
327
+ <td class="cartflows-row-heading">
328
+ <label><?php esc_html_e( 'Select Page Builder', 'cartflows' ); ?></label>
329
+ </td>
330
+ <td class="cartflows-row-content">
331
+ <?php
332
+ $installed_plugins = get_plugins();
333
+ $plugins = array(
334
+ array(
335
+ 'title' => __( 'Elementor', 'cartflows' ),
336
+ 'value' => 'elementor',
337
+ 'data' => array(
338
+ 'slug' => 'elementor',
339
+ 'init' => 'elementor/elementor.php',
340
+ 'active' => is_plugin_active( 'elementor/elementor.php' ) ? 'yes' : 'no',
341
+ 'install' => isset( $installed_plugins['elementor/elementor.php'] ) ? 'yes' : 'no',
342
+ ),
343
+ ),
344
+ array(
345
+ 'title' => __( 'Beaver Builder Plugin (Lite Version)', 'cartflows' ),
346
+ 'value' => 'beaver-builder',
347
+ 'data' => array(
348
+ 'slug' => 'beaver-builder-lite-version',
349
+ 'init' => 'beaver-builder-lite-version/fl-builder.php',
350
+ 'active' => is_plugin_active( 'beaver-builder-lite-version/fl-builder.php' ) ? 'yes' : 'no',
351
+ 'install' => isset( $installed_plugins['beaver-builder-lite-version/fl-builder.php'] ) ? 'yes' : 'no',
352
+ ),
353
+ ),
354
+ array(
355
+ 'title' => __( 'Divi', 'cartflows' ),
356
+ 'value' => 'divi',
357
+ 'data' => array(
358
+ 'slug' => 'divi',
359
+ 'init' => 'divi',
360
+ 'active' => 'yes',
361
+ 'install' => 'NA',
362
+ ),
363
+ ),
364
+ array(
365
+ 'title' => __( 'Gutenberg', 'cartflows' ),
366
+ 'value' => 'gutenberg',
367
+ 'data' => array(
368
+ 'slug' => 'ultimate-addons-for-gutenberg',
369
+ 'init' => 'ultimate-addons-for-gutenberg/ultimate-addons-for-gutenberg.php',
370
+ 'active' => is_plugin_active( 'ultimate-addons-for-gutenberg/ultimate-addons-for-gutenberg.php' ) ? 'yes' : 'no',
371
+ 'install' => isset( $installed_plugins['ultimate-addons-for-gutenberg/ultimate-addons-for-gutenberg.php'] ) ? 'yes' : 'no',
372
+ ),
373
+ ),
374
+ array(
375
+ 'title' => __( 'Other', 'cartflows' ),
376
+ 'value' => 'other',
377
+ 'data' => array(
378
+ 'slug' => 'other',
379
+ 'init' => false,
380
+ 'active' => 'yes',
381
+ 'install' => 'NA',
382
+ ),
383
+ ),
384
+ );
385
+ ?>
386
+ <input type="hidden" name="save-pb-input" id="save-pb-option" value="1" />
387
+ <select name="page-builder" class="page-builder-list" data-redirect-link="<?php echo esc_url_raw( $this->get_next_step_plain_link() ); ?>">
388
+ <?php
389
+ foreach ( $plugins as $key => $plugin ) {
390
+ echo '<option value="' . esc_attr( $plugin['value'] ) . '" data-install="' . esc_attr( $plugin['data']['install'] ) . '" data-active="' . esc_attr( $plugin['data']['active'] ) . '" data-slug="' . esc_attr( $plugin['data']['slug'] ) . '" data-init="' . esc_attr( $plugin['data']['init'] ) . '">' . esc_html( $plugin['title'] ) . '</option>';
391
+ }
392
+ ?>
393
+ </select>
394
+ </td>
395
+ </tr>
396
+ </table>
397
+ <p><?php esc_html_e( 'While CartFlows Should work with most page builders, we offer templates for the above page builders.', 'cartflows' ); ?></p>
398
+ <div class="cartflows-setup-actions step">
399
+ <div class="button-prev-wrap">
400
+ <a href="<?php echo esc_url( $this->get_prev_step_link() ); ?>" class="button-primary button button-large button-prev" ><?php esc_html_e( '« Previous', 'cartflows' ); ?></a>
401
+ </div>
402
+ <div class="button-next-wrap">
403
+ <a href="<?php echo esc_url_raw( $this->get_next_step_plain_link() ); ?>" class="button button-large button-next" ><?php esc_html_e( 'Skip this step', 'cartflows' ); ?></a>
404
+ <a href="#" class="button button-primary wcf-install-plugins"><?php esc_html_e( 'Next »', 'cartflows' ); ?></a>
405
+ </div>
406
+ <?php wp_nonce_field( 'cartflow-setup' ); ?>
407
+ </div>
408
+ </form>
409
+ <?php
410
+ }
411
+
412
+ /**
413
+ * Render checkout step.
414
+ */
415
+ public function checkout_step() {
416
+
417
+ $installed_plugins = get_plugins();
418
+ $is_wc_installed = isset( $installed_plugins['woocommerce/woocommerce.php'] ) ? 'yes' : 'no';
419
+ $is_wcf_ca_installed = isset( $installed_plugins['woo-cart-abandonment-recovery/woo-cart-abandonment-recovery.php'] ) ? 'yes' : 'no';
420
+ $is_active = class_exists( 'WooCommerce' ) ? 'yes' : 'no';
421
+ $is_wcf_ca_active = class_exists( 'CARTFLOWS_CA_Loader' ) ? 'yes' : 'no';
422
+ ?>
423
+ <h1><?php esc_html_e( 'Choose a checkout', 'cartflows' ); ?></h1>
424
+ <div class="cartflows-setup-message">
425
+ <p>
426
+ <?php esc_html_e( 'While CartFlows is designed to use WooCommerce sell digital and physical products, not all funnels need a checkout system.', 'cartflows' ); ?>
427
+ </p>
428
+ <h4 class="cartflows-setup-message-title"><?php esc_html_e( 'Would you like to install WooCommerce to sell digital and physical products in your funnels?', 'cartflows' ); ?></h4>
429
+ <span><input data-wcf-ca-active="<?php echo esc_attr( $is_wcf_ca_active ); ?>" data-wcf-ca-install="<?php echo esc_attr( $is_wcf_ca_installed ); ?>" data-woo-active="<?php echo esc_attr( $is_active ); ?>" data-woo-install="<?php echo esc_attr( $is_wc_installed ); ?>" type="hidden" class="wcf-install-wc-input" name="installl-woocommerce" value="" checked></span>
430
+ </div>
431
+
432
+ <div class="cartflows-setup-extra-notice">
433
+
434
+ <span>
435
+ <?php esc_html_e( 'The following plugin will be installed and activated for you:', 'cartflows' ); ?>
436
+ <a target="_blank" href="https://wordpress.org/plugins/woo-cart-abandonment-recovery/"> <?php esc_html_e( 'WooCommerce', 'cartflows' ); ?></a>,
437
+ <a target="_blank" href="https://wordpress.org/plugins/woo-cart-abandonment-recovery/"> <?php esc_html_e( 'WooCommerce Cart Abandonment Recovery', 'cartflows' ); ?></a>
438
+
439
+ </span>
440
+
441
+ </div>
442
+
443
+ <div class="cartflows-setup-actions step">
444
+ <div class="button-prev-wrap">
445
+ <a href="<?php echo esc_url( $this->get_prev_step_link() ); ?>" class="button-primary button button-large button-prev" ><?php esc_html_e( '« Previous', 'cartflows' ); ?></a>
446
+ </div>
447
+ <div class="button-next-wrap">
448
+ <a href="<?php echo esc_url_raw( $this->get_next_step_plain_link() ); ?>" class="button button-large button-next"><?php esc_html_e( 'No thanks', 'cartflows' ); ?></a>
449
+ <a class="wcf-install-wc button-primary button button-large" name="save_step" > <?php esc_html_e( 'Yes', 'cartflows' ); ?> </a>
450
+ </div>
451
+ </div>
452
+
453
+ <?php
454
+ }
455
+
456
+ /**
457
+ * Save Locale Settings.
458
+ */
459
+ public function activate_wc_plugins() {
460
+
461
+ check_ajax_referer( 'wcf-wc-plugins-activate', 'security' );
462
+
463
+ $plugin_slug_arr = array(
464
+ 'woocommerce/woocommerce.php' => true,
465
+ 'woo-cart-abandonment-recovery/woo-cart-abandonment-recovery.php' => false,
466
+ );
467
+
468
+ $activate = array(
469
+ 'woocommerce/woocommerce.php' => false,
470
+ 'woo-cart-abandonment-recovery/woo-cart-abandonment-recovery.php' => false,
471
+ );
472
+
473
+ foreach ( $plugin_slug_arr as $slug => $do_silently ) {
474
+
475
+ $activate[ $slug ] = activate_plugin( $slug, '', false, $do_silently );
476
+ }
477
+
478
+ foreach ( $activate as $slug => $data ) {
479
+
480
+ if ( is_wp_error( $data ) ) {
481
+ wp_send_json_error(
482
+ array(
483
+ 'success' => false,
484
+ 'message' => $data->get_error_message(),
485
+ )
486
+ );
487
+ }
488
+ }
489
+
490
+ wp_send_json_success();
491
+ }
492
+
493
+ /**
494
+ * Save Locale Settings.
495
+ */
496
+ public function page_builder_step_save() {
497
+
498
+ if ( ! current_user_can( 'manage_options' ) ) {
499
+ return;
500
+ }
501
+
502
+ check_ajax_referer( 'wcf-page-builder-step-save', 'security' );
503
+
504
+ $plugin_init = isset( $_POST['plugin_init'] ) ? sanitize_text_field( wp_unslash( $_POST['plugin_init'] ) ) : '';
505
+ $save_option = ( isset( $_POST['save_builder_option'] ) && 'true' == $_POST['save_builder_option'] ) ? true : false;
506
+ $plugin_slug = filter_input( INPUT_POST, 'page_builder', FILTER_SANITIZE_STRING );
507
+
508
+ $do_sliently = true;
509
+ if ( 'woo-cart-abandonment-recovery' === $plugin_slug ) {
510
+ $do_sliently = false;
511
+ }
512
+
513
+ $activate = activate_plugin( $plugin_init, '', false, $do_sliently );
514
+
515
+ if ( $save_option ) {
516
+ $this->save_page_builder_option();
517
+ }
518
+
519
+ if ( is_wp_error( $activate ) ) {
520
+ wp_send_json_error(
521
+ array(
522
+ 'success' => false,
523
+ 'message' => $activate->get_error_message(),
524
+ )
525
+ );
526
+ }
527
+
528
+ wp_send_json_success(
529
+ array( 'plugin' => $plugin_slug )
530
+ );
531
+ }
532
+
533
+ /**
534
+ * Save selected page builder in options database.
535
+ */
536
+ public function save_page_builder_option() {
537
+
538
+ if ( ! current_user_can( 'manage_options' ) ) {
539
+ return;
540
+ }
541
+
542
+ $page_builder = isset( $_POST['page_builder'] ) ? sanitize_text_field( wp_unslash( $_POST['page_builder'] ) ) : ''; //phpcs:ignore
543
+
544
+ $wcf_settings = get_option( '_cartflows_common', array() );
545
+
546
+ if ( false !== strpos( $page_builder, 'beaver-builder' ) ) {
547
+ $page_builder = 'beaver-builder';
548
+ }
549
+
550
+ $wcf_settings['default_page_builder'] = $page_builder;
551
+
552
+ update_option( '_cartflows_common', $wcf_settings );
553
+
554
+ wp_send_json_success(
555
+ array( 'plugin' => $page_builder )
556
+ );
557
+
558
+ }
559
+
560
+ /**
561
+ * Final step.
562
+ */
563
+ public function ready_step() {
564
+
565
+ // Set setup wizard status to complete.
566
+ update_option( 'wcf_setup_complete', true );
567
+ ?>
568
+ <h1><?php esc_html_e( 'Congratulations, You Did It!', 'cartflows' ); ?></h1>
569
+
570
+ <div class="cartflows-setup-next-steps">
571
+ <div class="cartflows-setup-next-steps-last">
572
+
573
+ <p class="success">
574
+ <?php
575
+ esc_html_e( 'CartFlows is ready to use on your website. You\'ve successfully completed the setup process and all that is left for you to do is create your first flow.', 'cartflows' )
576
+ ?>
577
+ </p>
578
+
579
+
580
+ <ul class="wcf-wizard-next-steps">
581
+ <li class="wcf-wizard-next-step-item">
582
+ <div class="wcf-wizard-next-step-description">
583
+ <p class="next-step-heading">Next step</p>
584
+ <h3 class="next-step-description">Create First Flow</h3>
585
+ <p class="next-step-extra-info">You're ready to add flows to your website.</p>
586
+ </div>
587
+ <div class="wcf-wizard-next-step-action">
588
+ <p class="wc-setup-actions step">
589
+ <a href="<?php echo esc_url( admin_url( 'edit.php?post_type=cartflows_flow&add-new-flow' ) ); ?>" type="button" class="button button-primary button-hero" ><?php esc_html_e( 'Create a flow', 'cartflows' ); ?></a>
590
+ </p>
591
+ </div>
592
+ </li>
593
+ </ul>
594
+
595
+ </div>
596
+ </div>
597
+ <?php
598
+ }
599
+
600
+ /**
601
+ * Training course step.
602
+ */
603
+ public function training_step() {
604
+ $current_user = wp_get_current_user();
605
+ ?>
606
+ <h1><?php esc_html_e( 'Exclusive CartFlows Training Course Offer', 'cartflows' ); ?></h1>
607
+
608
+ <div id="mauticform_wrapper_cartflowsonboarding" class="mauticform_wrapper">
609
+ <form autocomplete="false" role="form" method="post" action="https://go.cartflows.com/form/submit?formId=2" id="mauticform_cartflowsonboarding" data-mautic-form="cartflowsonboarding" enctype="multipart/form-data">
610
+ <div class="mauticform-error" id="mauticform_cartflowsonboarding_error"></div>
611
+ <div class="mauticform-message" id="mauticform_cartflowsonboarding_message"></div>
612
+ <div class="mauticform-innerform">
613
+ <div class="mauticform-page-wrapper mauticform-page-1" data-mautic-form-page="1">
614
+ <div id="mauticform_cartflowsonboarding_enter_your_email" class="mauticform-row mauticform-email mauticform-field-1">
615
+ <div class="cartflows-setup-message">
616
+ <p>
617
+ <?php esc_html_e( 'We want you to get off to a great start using CartFlows, so we would like to give access to our exclusive training course.', 'cartflows' ); ?>
618
+ <?php esc_html_e( 'Get access to this couse, for free, by entering your email below.', 'cartflows' ); ?>
619
+ </p>
620
+ <input id="mauticform_input_cartflowsonboarding_enter_your_email" name="mauticform[enter_your_email]" placeholder="<?php esc_html_e( 'Enter Email address', 'cartflows' ); ?>" value="<?php echo $current_user->user_email; ?>" class="mauticform-input" type="email">
621
+ </div>
622
+ <span class="mauticform-errormsg" style="display: none;"></span>
623
+ </div>
624
+ </div>
625
+ </div>
626
+
627
+ <input type="hidden" name="mauticform[formId]" id="mauticform_cartflowsonboarding_id" value="2">
628
+ <input type="hidden" name="mauticform[return]" id="mauticform_cartflowsonboarding_return" value="">
629
+ <input type="hidden" name="mauticform[formName]" id="mauticform_cartflowsonboarding_name" value="cartflowsonboarding">
630
+ <div class="cartflows-setup-actions step">
631
+ <div class="button-prev-wrap">
632
+ <a href="<?php echo esc_url( $this->get_prev_step_link() ); ?>" class="button-primary button button-large button-prev" ><?php esc_html_e( '« Previous', 'cartflows' ); ?></a>
633
+ </div>
634
+ <div class="button-next-wrap">
635
+ <a href="<?php echo esc_url_raw( $this->get_next_step_plain_link() ); ?>" class="button button-large button-next"><?php esc_html_e( 'No thanks', 'cartflows' ); ?></a>
636
+ <button type="submit" name="mauticform[submit]" id="mauticform_input_cartflowsonboarding_submit" value="<?php esc_html_e( 'Allow', 'cartflows' ); ?>" class="mautic-form-submit btn btn-default button-primary button button-large button-next" name="save_step"><?php esc_html_e( 'Allow', 'cartflows' ); ?></button>
637
+ </div>
638
+ </div>
639
+ </form>
640
+ </div>
641
+ <?php
642
+ }
643
+
644
+ /**
645
+ * Localize variables in admin
646
+ */
647
+ public function localize_vars() {
648
+
649
+ $vars = array();
650
+
651
+ $ajax_actions = array(
652
+ 'wcf_page_builder_step_save',
653
+ 'wcf_wc_plugins_activate',
654
+ );
655
+
656
+ foreach ( $ajax_actions as $action ) {
657
+
658
+ $vars[ $action . '_nonce' ] = wp_create_nonce( str_replace( '_', '-', $action ) );
659
+ }
660
+
661
+ return $vars;
662
+ }
663
+
664
+ /**
665
+ * Add JS script for mautic form
666
+ */
667
+ public function add_mautic_form_script() {
668
+
669
+ if ( ! isset( $_REQUEST['page'] ) || ( isset( $_REQUEST['page'] ) && 'cartflow-setup' !== $_REQUEST['page'] ) ) { //phpcs:ignore
670
+ return;
671
+ }
672
+ ?>
673
+
674
+ <script type="text/javascript">
675
+ /** This section is only needed once per page if manually copying **/
676
+ if (typeof MauticSDKLoaded == 'undefined') {
677
+ var MauticSDKLoaded = true;
678
+ var head = document.getElementsByTagName('head')[0];
679
+ var script = document.createElement('script');
680
+ script.type = 'text/javascript';
681
+ script.src = 'https://go.cartflows.com/media/js/mautic-form.js';
682
+ script.onload = function() {
683
+ MauticSDK.onLoad();
684
+ };
685
+ head.appendChild(script);
686
+ var MauticDomain = 'https://go.cartflows.com';
687
+ var MauticLang = {
688
+ 'submittingMessage': "Please wait..."
689
+ };
690
+ }
691
+ </script>
692
+ <?php
693
+ }
694
+ }
695
+
696
+ new CartFlows_Wizard();
697
+
698
+ endif;
includes/admin/cartflows-admin.php CHANGED
@@ -1,35 +1,35 @@
1
- <?php
2
- /**
3
- * CARTFLOWS Admin HTML.
4
- *
5
- * @package CARTFLOWS
6
- */
7
-
8
- ?>
9
- <div class="wcf-menu-page-wrapper">
10
- <div id="wcf-menu-page">
11
- <div class="wcf-menu-page-header <?php echo esc_attr( implode( ' ', $header_wrapper_class ) ); ?>">
12
- <div class="wcf-container wcf-flex">
13
- <div class="wcf-title">
14
- <span class="screen-reader-text"><?php echo esc_attr( CARTFLOWS_PLUGIN_NAME ); ?></span>
15
- <img class="wcf-logo" src="<?php echo esc_attr( CARTFLOWS_URL ) . 'assets/images/cartflows-logo.svg'; ?>" />
16
- </div>
17
- <div class="wcf-top-links">
18
- <?php
19
- esc_attr_e( 'Modernizing WordPress eCommerce!', 'cartflows' );
20
- ?>
21
- </div>
22
- </div>
23
- </div>
24
-
25
- <?php
26
- // Settings update message.
27
- if ( isset( $_REQUEST['message'] ) && ( 'saved' === $_REQUEST['message'] ) ) { //phpcs:ignore
28
- ?>
29
- <div id="message" class="notice notice-success is-dismissive wcf-notice"><p> <?php esc_html_e( 'Settings saved successfully.', 'cartflows' ); ?> </p></div>
30
- <?php
31
- }
32
- ?>
33
- <?php do_action( 'cartflows_render_admin_content' ); ?>
34
- </div>
35
- </div>
1
+ <?php
2
+ /**
3
+ * CARTFLOWS Admin HTML.
4
+ *
5
+ * @package CARTFLOWS
6
+ */
7
+
8
+ ?>
9
+ <div class="wcf-menu-page-wrapper">
10
+ <div id="wcf-menu-page">
11
+ <div class="wcf-menu-page-header <?php echo esc_attr( implode( ' ', $header_wrapper_class ) ); ?>">
12
+ <div class="wcf-container wcf-flex">
13
+ <div class="wcf-title">
14
+ <span class="screen-reader-text"><?php echo esc_attr( CARTFLOWS_PLUGIN_NAME ); ?></span>
15
+ <img class="wcf-logo" src="<?php echo esc_attr( CARTFLOWS_URL ) . 'assets/images/cartflows-logo.svg'; ?>" />
16
+ </div>
17
+ <div class="wcf-top-links">
18
+ <?php
19
+ esc_attr_e( 'Modernizing WordPress eCommerce!', 'cartflows' );
20
+ ?>
21
+ </div>
22
+ </div>
23
+ </div>
24
+
25
+ <?php
26
+ // Settings update message.
27
+ if ( isset( $_REQUEST['message'] ) && ( 'saved' === $_REQUEST['message'] ) ) { //phpcs:ignore
28
+ ?>
29
+ <div id="message" class="notice notice-success is-dismissive wcf-notice"><p> <?php esc_html_e( 'Settings saved successfully.', 'cartflows' ); ?> </p></div>
30
+ <?php
31
+ }
32
+ ?>
33
+ <?php do_action( 'cartflows_render_admin_content', $menu_page_slug ); ?>
34
+ </div>
35
+ </div>
includes/admin/cartflows-general.php CHANGED
@@ -1,522 +1,525 @@
1
- <?php
2
- /**
3
- * General settings
4
- *
5
- * @package CartFlows
6
- */
7
-
8
- $settings = Cartflows_Helper::get_common_settings();
9
-
10
- $debug_data = Cartflows_Helper::get_debug_settings();
11
-
12
- $permalink_settings = Cartflows_Helper::get_permalink_settings();
13
-
14
- $google_analytics_settings = Cartflows_Helper::get_google_analytics_settings();
15
-
16
- $facebook_settings = Cartflows_Helper::get_facebook_settings();
17
-
18
- $debug_on = ( isset( $_GET['debug'] ) ) ? sanitize_text_field( wp_unslash( $_GET['debug'] ) ) : 'false'; //phpcs:ignore
19
-
20
- $error_log = filter_input( INPUT_GET, 'cartflows-error-log', FILTER_VALIDATE_BOOLEAN );
21
- ?>
22
-
23
-
24
- <?php if ( $error_log ) : ?>
25
- <div class="wrap wcf-addon-wrap wcf-clear wcf-container">
26
- <?php Cartflows_Logger::status_logs_file(); ?>
27
- </div>
28
- <?php else : ?>
29
- <div class="wrap wcf-addon-wrap wcf-clear wcf-container">
30
- <input type="hidden" name="action" value="wcf_save_common_settings">
31
- <h1 class="screen-reader-text"><?php esc_html_e( 'General Settings', 'cartflows' ); ?></h1>
32
-
33
- <div id="poststuff">
34
- <div id="post-body" class="columns-2">
35
- <div id="post-body-content">
36
-
37
- <!-- Getting Started -->
38
- <div class="postbox introduction">
39
- <h2 class="hndle wcf-normal-cusror ui-sortable-handle">
40
- <span><?php esc_html_e( 'Getting Started', 'cartflows' ); ?></span>
41
- </h2>
42
- <div class="inside">
43
- <div class="iframe-wrap">
44
- <iframe width="560" height="315" src="https://www.youtube.com/embed/SlE0moPKjMY" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
45
- </div>
46
- <p>
47
- <?php
48
- esc_attr_e( 'Modernizing WordPress eCommerce!', 'cartflows' );
49
- ?>
50
- </p>
51
- </div>
52
- </div>
53
- <!-- Getting Started -->
54
-
55
- <!-- General Settings -->
56
- <div class="general-settings-form postbox">
57
- <h2 class="hndle wcf-normal-cusror ui-sortable-handle">
58
- <span><?php esc_html_e( 'General Settings', 'cartflows' ); ?></span>
59
- </h2>
60
- <div class="inside">
61
- <form method="post" class="wrap wcf-clear" action="" >
62
- <div class="form-wrap">
63
- <?php
64
-
65
- do_action( 'cartflows_before_settings_fields', $settings );
66
-
67
- echo Cartflows_Admin_Fields::checkobox_field(
68
- array(
69
- 'id' => 'wcf_disallow_indexing',
70
- 'name' => '_cartflows_common[disallow_indexing]',
71
- 'title' => __( 'Disallow search engines from indexing flows', 'cartflows' ),
72
- 'value' => $settings['disallow_indexing'],
73
- )
74
- );
75
-
76
- if ( wcf()->is_woo_active ) {
77
- echo Cartflows_Admin_Fields::flow_checkout_selection_field(
78
- array(
79
- 'id' => 'wcf_global_checkout',
80
- 'name' => '_cartflows_common[global_checkout]',
81
- 'title' => __( 'Global Checkout', 'cartflows' ),
82
- 'value' => $settings['global_checkout'],
83
- )
84
- );
85
- }
86
- echo Cartflows_Admin_Fields::select_field(
87
- array(
88
- 'id' => 'wcf_default_page_builder',
89
- 'name' => '_cartflows_common[default_page_builder]',
90
- 'title' => __( 'Show Templates designed with', 'cartflows' ),
91
- 'description' => __( 'CartFlows offers flow templates that can be imported in one click. These templates are available in few different page builders. Please choose your preferred page builder from the list so you will only see templates that are made using that page builder..', 'cartflows' ),
92
- 'value' => $settings['default_page_builder'],
93
- 'options' => array(
94
- 'elementor' => __( 'Elementor', 'cartflows' ),
95
- 'beaver-builder' => __( 'Beaver Builder', 'cartflows' ),
96
- 'divi' => __( 'Divi', 'cartflows' ),
97
- 'other' => __( 'Other', 'cartflows' ),
98
- ),
99
- )
100
- );
101
-
102
- do_action( 'cartflows_after_settings_fields', $settings );
103
-
104
- ?>
105
- </div>
106
- <?php submit_button( __( 'Save Changes', 'cartflows' ), 'cartflows-common-setting-save-btn button-primary button', 'submit', false ); ?>
107
- <?php wp_nonce_field( 'cartflows-common-settings', 'cartflows-common-settings-nonce' ); ?>
108
- </form>
109
- </div>
110
- </div>
111
- <!-- General Settings -->
112
-
113
- <!-- Permalink Settings -->
114
- <div class="general-settingss-form postbox">
115
- <h2 class="hndle wcf-normal-cusror ui-sortable-handle">
116
- <span><?php esc_html_e( 'Permalink Settings', 'cartflows' ); ?></span>
117
- </h2>
118
- <div class="inside">
119
- <form method="post" class="wrap wcf-clear" action="" >
120
- <div class="form-wrap wcf_permalink_settings">
121
- <?php
122
-
123
- echo Cartflows_Admin_Fields::radio_field(
124
- array(
125
- 'id' => 'permalink_structure',
126
- 'name' => '_cartflows_permalink[permalink_structure]',
127
- 'value' => $permalink_settings['permalink_structure'],
128
- 'options' => array(
129
- '' =>
130
- array(
131
- 'label' => __( 'Default', 'cartflows' ),
132
- 'description' => 'Default WordPress Permalink',
133
- ),
134
-
135
- '/' . CARTFLOWS_FLOW_POST_TYPE . '/%flowname%/' . CARTFLOWS_STEP_POST_TYPE =>
136
- array(
137
- 'label' => __( 'Flow and Step Slug', 'cartflows' ),
138
- 'description' => '/<code>' . CARTFLOWS_FLOW_POST_TYPE . '</code>/%flowname%/<code>' . CARTFLOWS_STEP_POST_TYPE . '</code>/%stepname%/',
139
- ),
140
-
141
- '/' . CARTFLOWS_FLOW_POST_TYPE . '/%flowname%' =>
142
- array(
143
- 'label' => __( 'Flow Slug', 'cartflows' ),
144
- 'description' => '/<code>' . CARTFLOWS_FLOW_POST_TYPE . '</code>/%flowname%/%stepname%/',
145
- ),
146
-
147
- '/%flowname%/' . CARTFLOWS_STEP_POST_TYPE =>
148
- array(
149
- 'label' => __( 'Step Slug', 'cartflows' ),
150
- 'description' => '/%flowname%/<code>' . CARTFLOWS_STEP_POST_TYPE . '</code>/%stepname%/',
151
- ),
152
- ),
153
- )
154
- );
155
- ?>
156
- <hr/>
157
- <?php
158
-
159
- echo Cartflows_Admin_Fields::title_field(
160
- array(
161
- 'title' => __( 'Post Type Permalink Base', 'cartflows' ),
162
- )
163
- );
164
-
165
- echo Cartflows_Admin_Fields::text_field(
166
- array(
167
- 'id' => 'wcf_permalink_step_base',
168
- 'name' => '_cartflows_permalink[permalink]',
169
- 'title' => __( 'Step Base', 'cartflows' ),
170
- 'value' => $permalink_settings['permalink'],
171
- 'placeholder' => CARTFLOWS_STEP_POST_TYPE,
172
- )
173
- );
174
-
175
- echo Cartflows_Admin_Fields::text_field(
176
- array(
177
- 'id' => 'wcf_permalink_flow_base',
178
- 'name' => '_cartflows_permalink[permalink_flow_base]',
179
- 'title' => __( 'Flow Base', 'cartflows' ),
180
- 'value' => $permalink_settings['permalink_flow_base'],
181
- 'placeholder' => CARTFLOWS_FLOW_POST_TYPE,
182
- )
183
- );
184
-
185
- ?>
186
-
187
-
188
- </div>
189
- <p>
190
- <?php submit_button( __( 'Save Changes', 'cartflows' ), 'cartflows-common-setting-save-btn button-primary button', 'submit', false ); ?>
191
- <?php submit_button( __( 'Set Default', 'cartflows' ), 'cartflows-common-setting-save-btn button-primary button', 'reset', false ); ?>
192
- <?php wp_nonce_field( 'cartflows-permalink-settings', 'cartflows-permalink-settings-nonce' ); ?>
193
- </p>
194
-
195
-
196
- </form>
197
- </div>
198
- </div>
199
- <!-- Permalink Settings -->
200
-
201
- <!-- Facebook Pixel Tracking -->
202
- <div class="general-settingss-form postbox">
203
- <h2 class="wcf-facebook-hndle wcf-normal-cusror ui-sortable-handle hndle">
204
-
205
- <span><?php esc_html_e( 'Facebook Pixel Settings', 'cartflows' ); ?></span>
206
- </h2>
207
-
208
- <form method="post" class="wrap wcf-clear" action="">
209
- <div class="form-wrap">
210
- <input type="hidden" name="action" value="wcf_save_facebook_pixel_settings">
211
- <div id="post-body">
212
-
213
- <div class="inside">
214
- <div class="form-wrap">
215
- <?php
216
- echo Cartflows_Admin_Fields::checkobox_field(
217
- array(
218
- 'id' => 'wcf_facebook_pixel_tracking',
219
- 'name' => '_cartflows_facebook[facebook_pixel_tracking]',
220
- 'title' => __( 'Enable Facebook Pixel Tracking', 'cartflows' ),
221
- 'value' => $facebook_settings['facebook_pixel_tracking'],
222
- )
223
- );
224
-
225
- echo "<div class='wcf-fb-pixel-wrapper'>";
226
- ?>
227
- <hr/>
228
- <?php
229
- echo Cartflows_Admin_Fields::checkobox_field(
230
- array(
231
- 'id' => 'wcf_facebook_pixel_tracking_for_site',
232
- 'name' => '_cartflows_facebook[facebook_pixel_tracking_for_site]',
233
- 'title' => __( 'Enable for the whole site', 'cartflows' ),
234
- 'value' => $facebook_settings['facebook_pixel_tracking_for_site'],
235
- )
236
- );
237
-
238
- echo Cartflows_Admin_Fields::title_field(
239
- array(
240
- 'title' => '',
241
- 'description' => __( 'If this option is unchecked, it will only apply to CartFlows steps.', 'cartflows' ),
242
- )
243
- );
244
- ?>
245
- <hr/>
246
- <?php
247
- echo Cartflows_Admin_Fields::text_field(
248
- array(
249
- 'id' => 'wcf_facebook_pixel_id',
250
- 'name' => '_cartflows_facebook[facebook_pixel_id]',
251
- 'title' => __( 'Enter Facebook pixel ID', 'cartflows' ),
252
- 'value' => $facebook_settings['facebook_pixel_id'],
253
- )
254
- );
255
-
256
-
257
- echo Cartflows_Admin_Fields::title_field(
258
- array(
259
- 'title' => __( 'Enable Events:', 'cartflows' ),
260
- )
261
- );
262
-
263
-
264
- echo Cartflows_Admin_Fields::checkobox_field(
265
- array(
266
- 'id' => 'wcf_facebook_pixel_initiate_checkout',
267
- 'name' => '_cartflows_facebook[facebook_pixel_initiate_checkout]',
268
- 'title' => __( 'Initiate Checkout', 'cartflows' ),
269
- 'value' => $facebook_settings['facebook_pixel_initiate_checkout'],
270
- )
271
- );
272
-
273
- echo Cartflows_Admin_Fields::checkobox_field(
274
- array(
275
- 'id' => 'wcf_facebook_pixel_add_payment_info',
276
- 'name' => '_cartflows_facebook[facebook_pixel_add_payment_info]',
277
- 'title' => __( 'Add Payment Info', 'cartflows' ),
278
- 'value' => $facebook_settings['facebook_pixel_add_payment_info'],
279
- )
280
- );
281
-
282
- echo Cartflows_Admin_Fields::checkobox_field(
283
- array(
284
- 'id' => 'wcf_facebook_pixel_purchase_complete',
285
- 'name' => '_cartflows_facebook[facebook_pixel_purchase_complete]',
286
- 'title' => __( 'Purchase Complete', 'cartflows' ),
287
- 'value' => $facebook_settings['facebook_pixel_purchase_complete'],
288
- )
289
- );
290
-
291
- echo '</div>';
292
-
293
- ?>
294
- </div>
295
-
296
- <?php submit_button( __( 'Save Changes', 'cartflows' ), 'cartflows-facebook-setting-save-btn button-primary button', 'submit', false ); ?>
297
- <?php wp_nonce_field( 'cartflows-facebook-settings', 'cartflows-facebook-settings-nonce' ); ?>
298
- </div>
299
- </div>
300
- </div>
301
- </form>
302
- </div>
303
- <!-- Facebook Pixel Tracking -->
304
-
305
- <!-- Google Analytics Tracking -->
306
- <div class="general-settingss-form postbox">
307
- <h2 class="hndle wcf-normal-cusror ui-sortable-handle">
308
- <span><?php esc_html_e( 'Google Analytics Settings', 'cartflows' ); ?></span>
309
- </h2>
310
- <div class="inside">
311
- <form method="post" class="wrap wcf-clear" action="" >
312
- <div class="form-wrap">
313
- <?php
314
-
315
- echo Cartflows_Admin_Fields::checkobox_field(
316
- array(
317
- 'id' => 'enable_google-analytics-id',
318
- 'name' => '_cartflows_google_analytics[enable_google_analytics]',
319
- 'title' => __( 'Enable Google Analytics Tracking', 'cartflows' ),
320
- 'value' => $google_analytics_settings['enable_google_analytics'],
321
- )
322
- );
323
-
324
- echo "<div class='wcf-google-analytics-wrapper'>";
325
- ?>
326
- <hr/>
327
- <?php
328
- echo Cartflows_Admin_Fields::checkobox_field(
329
- array(
330
- 'id' => 'enable_google_analytics_for_site',
331
- 'name' => '_cartflows_google_analytics[enable_google_analytics_for_site]',
332
- 'title' => __( 'Enable for the whole website', 'cartflows' ),
333
- 'value' => $google_analytics_settings['enable_google_analytics_for_site'],
334
- )
335
- );
336
-
337
- echo Cartflows_Admin_Fields::title_field(
338
- array(
339
- 'title' => '',
340
- 'description' => __( 'If this option is unchecked, it will only apply to CartFlows steps.', 'cartflows' ),
341
- )
342
- );
343
- ?>
344
- <hr/>
345
- <?php
346
- echo Cartflows_Admin_Fields::text_field(
347
- array(
348
- 'id' => 'google-analytics-id',
349
- 'name' => '_cartflows_google_analytics[google_analytics_id]',
350
- 'title' => __( 'Google Analytics ID', 'cartflows' ),
351
- 'value' => $google_analytics_settings['google_analytics_id'],
352
- 'description' => __( 'Log into your <a href="https://analytics.google.com/" target="_blank">google analytics account</a> to find your ID. eg: UA-XXXXXX-X&period;', 'cartflows' ),
353
- )
354
- );
355
-
356
- echo Cartflows_Admin_Fields::title_field(
357
- array(
358
- 'title' => __( 'Enable Events:', 'cartflows' ),
359
- )
360
- );
361
-
362
- echo Cartflows_Admin_Fields::checkobox_field(
363
- array(
364
- 'id' => 'enable_begin_checkout',
365
- 'name' => '_cartflows_google_analytics[enable_begin_checkout]',
366
- 'title' => __( 'Begin Checkout', 'cartflows' ),
367
- 'value' => $google_analytics_settings['enable_begin_checkout'],
368
- )
369
- );
370
-
371
- echo Cartflows_Admin_Fields::checkobox_field(
372
- array(
373
- 'id' => 'enable_add_to_cart',
374
- 'name' => '_cartflows_google_analytics[enable_add_to_cart]',
375
- 'title' => __( 'Add To Cart', 'cartflows' ),
376
- 'value' => $google_analytics_settings['enable_add_to_cart'],
377
- )
378
- );
379
-
380
- echo Cartflows_Admin_Fields::checkobox_field(
381
- array(
382
- 'id' => 'enable_add_payment_info',
383
- 'name' => '_cartflows_google_analytics[enable_add_payment_info]',
384
- 'title' => __( 'Add Payment Info', 'cartflows' ),
385
- 'value' => $google_analytics_settings['enable_add_payment_info'],
386
- )
387
- );
388
-
389
- echo Cartflows_Admin_Fields::checkobox_field(
390
- array(
391
- 'id' => 'enable_purchase_event',
392
- 'name' => '_cartflows_google_analytics[enable_purchase_event]',
393
- 'title' => __( 'Purchase', 'cartflows' ),
394
- 'value' => $google_analytics_settings['enable_purchase_event'],
395
- )
396
- );
397
-
398
- echo Cartflows_Admin_Fields::title_field(
399
- array(
400
- 'title' => '',
401
- 'description' => __( 'Google Analytics not working correctly? <a href="https://cartflows.com/docs/troubleshooting-google-analytics-tracking-issues/" > Click here </a> to know more. ', 'cartflows' ),
402
- )
403
- );
404
-
405
- do_action( 'cartflows_google_analytics_admin_fields', $google_analytics_settings );
406
-
407
- echo '</div>';
408
- ?>
409
-
410
-
411
- </div>
412
- <p>
413
- <?php submit_button( __( 'Save Changes', 'cartflows' ), 'cartflows-common-setting-save-btn button-primary button', 'submit', false ); ?>
414
- <?php wp_nonce_field( 'cartflows-google-analytics-settings', 'cartflows-google-analytics-settings-nonce' ); ?>
415
- </p>
416
-
417
-
418
- </form>
419
- </div>
420
- </div>
421
- <!-- Google Analytics Tracking -->
422
-
423
- <?php do_action( 'cartflows_register_general_settings' ); ?>
424
-
425
- </div>
426
-
427
- <!-- Right Sidebar -->
428
- <div class="postbox-container" id="postbox-container-1">
429
- <div id="side-sortables">
430
-
431
- <div class="postbox">
432
- <h2 class="hndle">
433
- <span class="dashicons dashicons-book"></span>
434
- <span><?php esc_html_e( 'Knowledge Base', 'cartflows' ); ?></span>
435
- </h2>
436
- <div class="inside">
437
- <p>
438
- <?php esc_html_e( 'Not sure how something works? Take a peek at the knowledge base and learn.', 'cartflows' ); ?>
439
- </p>
440
- <p>
441
- <a href="<?php echo esc_url( 'https://cartflows.com/docs' ); ?>" target="_blank" rel="noopener"><?php esc_html_e( 'Visit Knowledge Base »', 'cartflows' ); ?></a>
442
- </p>
443
- </div>
444
- </div>
445
-
446
- <div class="postbox">
447
- <h2 class="hndle">
448
- <span class="dashicons dashicons-groups"></span>
449
- <span><?php esc_html_e( 'Community', 'cartflows' ); ?></span>
450
- </h2>
451
- <div class="inside">
452
- <p>
453
- <?php esc_html_e( 'Join the community of super helpful CartFlows users. Say hello, ask questions, give feedback and help each other!', 'cartflows' ); ?>
454
- </p>
455
- <p>
456
- <a href="<?php echo esc_url( 'https://www.facebook.com/groups/cartflows/' ); ?>" target="_blank" rel="noopener"><?php esc_html_e( 'Join Our Facebook Group »', 'cartflows' ); ?></a>
457
- </p>
458
- </div>
459
- </div>
460
-
461
- <div class="postbox">
462
- <h2 class="hndle">
463
- <span class="dashicons dashicons-sos"></span>
464
- <span><?php esc_html_e( 'Five Star Support', 'cartflows' ); ?></span>
465
- </h2>
466
- <div class="inside">
467
- <p>
468
- <?php esc_html_e( 'Got a question? Get in touch with CartFlows developers. We\'re happy to help!', 'cartflows' ); ?>
469
- </p>
470
- <p>
471
- <a href="<?php echo esc_url( 'https://cartflows.com/contact' ); ?>" target="_blank" rel="noopener"><?php esc_html_e( 'Submit a Ticket »', 'cartflows' ); ?></a>
472
- </p>
473
- </div>
474
- </div>
475
- <?php
476
- if ( 'true' == $debug_on ) {
477
- ?>
478
- <div class="postbox">
479
- <h2 class="hndle">
480
- <span class="dashicons dashicons-editor-code"></span>
481
- <span><?php esc_html_e( 'Load Minified CSS', 'cartflows' ); ?></span>
482
- </h2>
483
- <div class="inside">
484
- <form method="post" class="wrap wcf-clear" action="">
485
- <p>
486
- <?php esc_html_e( 'Load the Minified CSS from here. Just Enable it by checking the below given checkbox.', 'cartflows' ); ?>
487
- </p>
488
- <?php
489
- echo Cartflows_Admin_Fields::checkobox_field(
490
- array(
491
- 'id' => 'allow_minified_files',
492
- 'name' => '_cartflows_debug_data[allow_minified_files]',
493
- 'title' => __( 'Load minified CSS & JS Files', 'cartflows' ),
494
- 'value' => $debug_data['allow_minified_files'],
495
- )
496
- );
497
- ?>
498
- <?php submit_button( __( 'Save', 'cartflows' ), 'button-primary button', 'submit', false ); ?>
499
- <?php wp_nonce_field( 'cartflows-debug-settings', 'cartflows-debug-settings-nonce' ); ?>
500
- </form>
501
- </div>
502
- </div>
503
- <?php
504
- }
505
- ?>
506
- </div>
507
- </div>
508
- <!-- Right Sidebar -->
509
-
510
- </div>
511
- <!-- /post-body -->
512
- <br class="clear">
513
- </div>
514
- </div>
515
- <?php endif; ?>
516
-
517
- <?php
518
- /**
519
- * Loads Zapier settings admin view.
520
- */
521
- do_action( 'cartflows_after_general_settings' );
522
- ?>
 
 
 
1
+ <?php
2
+ /**
3
+ * General settings
4
+ *
5
+ * @package CartFlows
6
+ */
7
+
8
+ $settings = Cartflows_Helper::get_common_settings();
9
+
10
+ $debug_data = Cartflows_Helper::get_debug_settings();
11
+
12
+ $permalink_settings = Cartflows_Helper::get_permalink_settings();
13
+
14
+ $google_analytics_settings = Cartflows_Helper::get_google_analytics_settings();
15
+
16
+ $facebook_settings = Cartflows_Helper::get_facebook_settings();
17
+
18
+ $debug_on = ( isset( $_GET['debug'] ) ) ? sanitize_text_field( wp_unslash( $_GET['debug'] ) ) : 'false'; //phpcs:ignore
19
+
20
+ $error_log = filter_input( INPUT_GET, 'cartflows-error-log', FILTER_VALIDATE_BOOLEAN );
21
+ ?>
22
+
23
+
24
+ <?php if ( $error_log ) : ?>
25
+ <div class="wrap wcf-addon-wrap wcf-clear wcf-container">
26
+ <?php Cartflows_Logger::status_logs_file(); ?>
27
+ </div>
28
+ <?php else : ?>
29
+ <div class="wrap wcf-addon-wrap wcf-clear wcf-container">
30
+ <input type="hidden" name="action" value="wcf_save_common_settings">
31
+ <h1 class="screen-reader-text"><?php esc_html_e( 'General Settings', 'cartflows' ); ?></h1>
32
+
33
+ <div id="poststuff">
34
+ <div id="post-body" class="columns-2">
35
+ <div id="post-body-content">
36
+
37
+ <!-- Getting Started -->
38
+ <div class="postbox introduction">
39
+ <h2 class="hndle wcf-normal-cusror ui-sortable-handle">
40
+ <span><?php esc_html_e( 'Getting Started', 'cartflows' ); ?></span>
41
+ </h2>
42
+ <div class="inside">
43
+ <div class="iframe-wrap">
44
+ <iframe width="560" height="315" src="https://www.youtube.com/embed/SlE0moPKjMY" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
45
+ </div>
46
+ <p>
47
+ <?php
48
+ esc_attr_e( 'Modernizing WordPress eCommerce!', 'cartflows' );
49
+ ?>
50
+ </p>
51
+ </div>
52
+ </div>
53
+ <!-- Getting Started -->
54
+
55
+ <!-- General Settings -->
56
+ <div class="general-settings-form postbox">
57
+ <h2 class="hndle wcf-normal-cusror ui-sortable-handle">
58
+ <span><?php esc_html_e( 'General Settings', 'cartflows' ); ?></span>
59
+ </h2>
60
+ <div class="inside">
61
+ <form method="post" class="wrap wcf-clear" action="" >
62
+ <div class="form-wrap">
63
+ <?php
64
+
65
+ do_action( 'cartflows_before_settings_fields', $settings );
66
+
67
+ echo Cartflows_Admin_Fields::checkobox_field(
68
+ array(
69
+ 'id' => 'wcf_disallow_indexing',
70
+ 'name' => '_cartflows_common[disallow_indexing]',
71
+ 'title' => __( 'Disallow search engines from indexing flows', 'cartflows' ),
72
+ 'value' => $settings['disallow_indexing'],
73
+ )
74
+ );
75
+
76
+ if ( wcf()->is_woo_active ) {
77
+ echo Cartflows_Admin_Fields::flow_checkout_selection_field(
78
+ array(
79
+ 'id' => 'wcf_global_checkout',
80
+ 'name' => '_cartflows_common[global_checkout]',
81
+ 'title' => __( 'Global Checkout', 'cartflows' ),
82
+ 'value' => $settings['global_checkout'],
83
+ )
84
+ );
85
+ }
86
+ echo Cartflows_Admin_Fields::select_field(
87
+ array(
88
+ 'id' => 'wcf_default_page_builder',
89
+ 'name' => '_cartflows_common[default_page_builder]',
90
+ 'title' => __( 'Show Templates designed with', 'cartflows' ),
91
+ 'description' => __( 'CartFlows offers flow templates that can be imported in one click. These templates are available in few different page builders. Please choose your preferred page builder from the list so you will only see templates that are made using that page builder..', 'cartflows' ),
92
+ 'value' => $settings['default_page_builder'],
93
+ 'options' => array(
94
+ 'elementor' => __( 'Elementor', 'cartflows' ),
95
+ 'beaver-builder' => __( 'Beaver Builder', 'cartflows' ),
96
+ 'divi' => __( 'Divi', 'cartflows' ),
97
+ 'gutenberg' => __( 'Gutenberg', 'cartflows' ),
98
+ 'other' => __( 'Other', 'cartflows' ),
99
+ ),
100
+ )
101
+ );
102
+
103
+ do_action( 'cartflows_after_settings_fields', $settings );
104
+
105
+ ?>
106
+ </div>
107
+ <?php submit_button( __( 'Save Changes', 'cartflows' ), 'cartflows-common-setting-save-btn button-primary button', 'submit', false ); ?>
108
+ <?php wp_nonce_field( 'cartflows-common-settings', 'cartflows-common-settings-nonce' ); ?>
109
+ </form>
110
+ </div>
111
+ </div>
112
+ <!-- General Settings -->
113
+
114
+ <?php do_action( 'cartflows_after_general_settings' ); ?>
115
+
116
+ <!-- Permalink Settings -->
117
+ <div class="general-settingss-form postbox">
118
+ <h2 class="hndle wcf-normal-cusror ui-sortable-handle">
119
+ <span><?php esc_html_e( 'Permalink Settings', 'cartflows' ); ?></span>
120
+ </h2>
121
+ <div class="inside">
122
+ <form method="post" class="wrap wcf-clear" action="" >
123
+ <div class="form-wrap wcf_permalink_settings">
124
+ <?php
125
+
126
+ echo Cartflows_Admin_Fields::radio_field(
127
+ array(
128
+ 'id' => 'permalink_structure',
129
+ 'name' => '_cartflows_permalink[permalink_structure]',
130
+ 'value' => $permalink_settings['permalink_structure'],
131
+ 'options' => array(
132
+ '' =>
133
+ array(
134
+ 'label' => __( 'Default', 'cartflows' ),
135
+ 'description' => 'Default WordPress Permalink',
136
+ ),
137
+
138
+ '/' . CARTFLOWS_FLOW_POST_TYPE . '/%flowname%/' . CARTFLOWS_STEP_POST_TYPE =>
139
+ array(
140
+ 'label' => __( 'Flow and Step Slug', 'cartflows' ),
141
+ 'description' => get_site_url() . '/<code>' . CARTFLOWS_FLOW_POST_TYPE . '</code>/%flowname%/<code>' . CARTFLOWS_STEP_POST_TYPE . '</code>/%stepname%/',
142
+ ),
143
+
144
+ '/' . CARTFLOWS_FLOW_POST_TYPE . '/%flowname%' =>
145
+ array(
146
+ 'label' => __( 'Flow Slug', 'cartflows' ),
147
+ 'description' => get_site_url() . '/<code>' . CARTFLOWS_FLOW_POST_TYPE . '</code>/%flowname%/%stepname%/',
148
+ ),
149
+
150
+ '/%flowname%/' . CARTFLOWS_STEP_POST_TYPE =>
151
+ array(
152
+ 'label' => __( 'Step Slug', 'cartflows' ),
153
+ 'description' => get_site_url() . '/%flowname%/<code>' . CARTFLOWS_STEP_POST_TYPE . '</code>/%stepname%/',
154
+ ),
155
+ ),
156
+ )
157
+ );
158
+ ?>
159
+ <hr/>
160
+ <?php
161
+
162
+ echo Cartflows_Admin_Fields::title_field(
163
+ array(
164
+ 'title' => __( 'Post Type Permalink Base', 'cartflows' ),
165
+ )
166
+ );
167
+
168
+ echo Cartflows_Admin_Fields::text_field(
169
+ array(
170
+ 'id' => 'wcf_permalink_step_base',
171
+ 'name' => '_cartflows_permalink[permalink]',
172
+ 'title' => __( 'Step Base', 'cartflows' ),
173
+ 'value' => $permalink_settings['permalink'],
174
+ 'placeholder' => CARTFLOWS_STEP_POST_TYPE,
175
+ )
176
+ );
177
+
178
+ echo Cartflows_Admin_Fields::text_field(
179
+ array(
180
+ 'id' => 'wcf_permalink_flow_base',
181
+ 'name' => '_cartflows_permalink[permalink_flow_base]',
182
+ 'title' => __( 'Flow Base', 'cartflows' ),
183
+ 'value' => $permalink_settings['permalink_flow_base'],
184
+ 'placeholder' => CARTFLOWS_FLOW_POST_TYPE,
185
+ )
186
+ );
187
+
188
+ ?>
189
+
190
+
191
+ </div>
192
+ <p>
193
+ <?php submit_button( __( 'Save Changes', 'cartflows' ), 'cartflows-common-setting-save-btn button-primary button', 'submit', false ); ?>
194
+ <?php submit_button( __( 'Set Default', 'cartflows' ), 'cartflows-common-setting-save-btn button-primary button', 'reset', false ); ?>
195
+ <?php wp_nonce_field( 'cartflows-permalink-settings', 'cartflows-permalink-settings-nonce' ); ?>
196
+ </p>
197
+
198
+
199
+ </form>
200
+ </div>
201
+ </div>
202
+ <!-- Permalink Settings -->
203
+
204
+ <!-- Facebook Pixel Tracking -->
205
+ <div class="general-settingss-form postbox">
206
+ <h2 class="wcf-facebook-hndle wcf-normal-cusror ui-sortable-handle hndle">
207
+
208
+ <span><?php esc_html_e( 'Facebook Pixel Settings', 'cartflows' ); ?></span>
209
+ </h2>
210
+
211
+ <form method="post" class="wrap wcf-clear" action="">
212
+ <div class="form-wrap">
213
+ <input type="hidden" name="action" value="wcf_save_facebook_pixel_settings">
214
+ <div id="post-body">
215
+
216
+ <div class="inside">
217
+ <div class="form-wrap">
218
+ <?php
219
+ echo Cartflows_Admin_Fields::checkobox_field(
220
+ array(
221
+ 'id' => 'wcf_facebook_pixel_tracking',
222
+ 'name' => '_cartflows_facebook[facebook_pixel_tracking]',
223
+ 'title' => __( 'Enable Facebook Pixel Tracking', 'cartflows' ),
224
+ 'value' => $facebook_settings['facebook_pixel_tracking'],
225
+ )
226
+ );
227
+
228
+ echo "<div class='wcf-fb-pixel-wrapper'>";
229
+ ?>
230
+ <hr/>
231
+ <?php
232
+ echo Cartflows_Admin_Fields::checkobox_field(
233
+ array(
234
+ 'id' => 'wcf_facebook_pixel_tracking_for_site',
235
+ 'name' => '_cartflows_facebook[facebook_pixel_tracking_for_site]',
236
+ 'title' => __( 'Enable for the whole site', 'cartflows' ),
237
+ 'value' => $facebook_settings['facebook_pixel_tracking_for_site'],
238
+ )
239
+ );
240
+
241
+ echo Cartflows_Admin_Fields::title_field(
242
+ array(
243
+ 'title' => '',
244
+ 'description' => __( 'If this option is unchecked, it will only apply to CartFlows steps.', 'cartflows' ),
245
+ )
246
+ );
247
+ ?>
248
+ <hr/>
249
+ <?php
250
+ echo Cartflows_Admin_Fields::text_field(
251
+ array(
252
+ 'id' => 'wcf_facebook_pixel_id',
253
+ 'name' => '_cartflows_facebook[facebook_pixel_id]',
254
+ 'title' => __( 'Enter Facebook pixel ID', 'cartflows' ),
255
+ 'value' => $facebook_settings['facebook_pixel_id'],
256
+ )
257
+ );
258
+
259
+
260
+ echo Cartflows_Admin_Fields::title_field(
261
+ array(
262
+ 'title' => __( 'Enable Events:', 'cartflows' ),
263
+ )
264
+ );
265
+
266
+
267
+ echo Cartflows_Admin_Fields::checkobox_field(
268
+ array(
269
+ 'id' => 'wcf_facebook_pixel_initiate_checkout',
270
+ 'name' => '_cartflows_facebook[facebook_pixel_initiate_checkout]',
271
+ 'title' => __( 'Initiate Checkout', 'cartflows' ),
272
+ 'value' => $facebook_settings['facebook_pixel_initiate_checkout'],
273
+ )
274
+ );
275
+
276
+ echo Cartflows_Admin_Fields::checkobox_field(
277
+ array(
278
+ 'id' => 'wcf_facebook_pixel_add_payment_info',
279
+ 'name' => '_cartflows_facebook[facebook_pixel_add_payment_info]',
280
+ 'title' => __( 'Add Payment Info', 'cartflows' ),
281
+ 'value' => $facebook_settings['facebook_pixel_add_payment_info'],
282
+ )
283
+ );
284
+
285
+ echo Cartflows_Admin_Fields::checkobox_field(
286
+ array(
287
+ 'id' => 'wcf_facebook_pixel_purchase_complete',
288
+ 'name' => '_cartflows_facebook[facebook_pixel_purchase_complete]',
289
+ 'title' => __( 'Purchase Complete', 'cartflows' ),
290
+ 'value' => $facebook_settings['facebook_pixel_purchase_complete'],
291
+ )
292
+ );
293
+
294
+ echo '</div>';
295
+
296
+ ?>
297
+ </div>
298
+
299
+ <?php submit_button( __( 'Save Changes', 'cartflows' ), 'cartflows-facebook-setting-save-btn button-primary button', 'submit', false ); ?>
300
+ <?php wp_nonce_field( 'cartflows-facebook-settings', 'cartflows-facebook-settings-nonce' ); ?>
301
+ </div>
302
+ </div>
303
+ </div>
304
+ </form>
305
+ </div>
306
+ <!-- Facebook Pixel Tracking -->
307
+
308
+ <!-- Google Analytics Tracking -->
309
+ <div class="general-settingss-form postbox">
310
+ <h2 class="hndle wcf-normal-cusror ui-sortable-handle">
311
+ <span><?php esc_html_e( 'Google Analytics Settings', 'cartflows' ); ?></span>
312
+ </h2>
313
+ <div class="inside">
314
+ <form method="post" class="wrap wcf-clear" action="" >
315
+ <div class="form-wrap">
316
+ <?php
317
+
318
+ echo Cartflows_Admin_Fields::checkobox_field(
319
+ array(
320
+ 'id' => 'enable_google-analytics-id',
321
+ 'name' => '_cartflows_google_analytics[enable_google_analytics]',
322
+ 'title' => __( 'Enable Google Analytics Tracking', 'cartflows' ),
323
+ 'value' => $google_analytics_settings['enable_google_analytics'],
324
+ )
325
+ );
326
+
327
+ echo "<div class='wcf-google-analytics-wrapper'>";
328
+ ?>
329
+ <hr/>
330
+ <?php
331
+ echo Cartflows_Admin_Fields::checkobox_field(
332
+ array(
333
+ 'id' => 'enable_google_analytics_for_site',
334
+ 'name' => '_cartflows_google_analytics[enable_google_analytics_for_site]',
335
+ 'title' => __( 'Enable for the whole website', 'cartflows' ),
336
+ 'value' => $google_analytics_settings['enable_google_analytics_for_site'],
337
+ )
338
+ );
339
+
340
+ echo Cartflows_Admin_Fields::title_field(
341
+ array(
342
+ 'title' => '',
343
+ 'description' => __( 'If this option is unchecked, it will only apply to CartFlows steps.', 'cartflows' ),
344
+ )
345
+ );
346
+ ?>
347
+ <hr/>
348
+ <?php
349
+ echo Cartflows_Admin_Fields::text_field(
350
+ array(
351
+ 'id' => 'google-analytics-id',
352
+ 'name' => '_cartflows_google_analytics[google_analytics_id]',
353
+ 'title' => __( 'Google Analytics ID', 'cartflows' ),
354
+ 'value' => $google_analytics_settings['google_analytics_id'],
355
+ 'description' => __( 'Log into your <a href="https://analytics.google.com/" target="_blank">google analytics account</a> to find your ID. eg: UA-XXXXXX-X&period;', 'cartflows' ),
356
+ )
357
+ );
358
+
359
+ echo Cartflows_Admin_Fields::title_field(
360
+ array(
361
+ 'title' => __( 'Enable Events:', 'cartflows' ),
362
+ )
363
+ );
364
+
365
+ echo Cartflows_Admin_Fields::checkobox_field(
366
+ array(
367
+ 'id' => 'enable_begin_checkout',
368
+ 'name' => '_cartflows_google_analytics[enable_begin_checkout]',
369
+ 'title' => __( 'Begin Checkout', 'cartflows' ),
370
+ 'value' => $google_analytics_settings['enable_begin_checkout'],
371
+ )
372
+ );
373
+
374
+ echo Cartflows_Admin_Fields::checkobox_field(
375
+ array(
376
+ 'id' => 'enable_add_to_cart',
377
+ 'name' => '_cartflows_google_analytics[enable_add_to_cart]',
378
+ 'title' => __( 'Add To Cart', 'cartflows' ),
379
+ 'value' => $google_analytics_settings['enable_add_to_cart'],
380
+ )
381
+ );
382
+
383
+ echo Cartflows_Admin_Fields::checkobox_field(
384
+ array(
385
+ 'id' => 'enable_add_payment_info',
386
+ 'name' => '_cartflows_google_analytics[enable_add_payment_info]',
387
+ 'title' => __( 'Add Payment Info', 'cartflows' ),
388
+ 'value' => $google_analytics_settings['enable_add_payment_info'],
389
+ )
390
+ );
391
+
392
+ echo Cartflows_Admin_Fields::checkobox_field(
393
+ array(
394
+ 'id' => 'enable_purchase_event',
395
+ 'name' => '_cartflows_google_analytics[enable_purchase_event]',
396
+ 'title' => __( 'Purchase', 'cartflows' ),
397
+ 'value' => $google_analytics_settings['enable_purchase_event'],
398
+ )
399
+ );
400
+
401
+ echo Cartflows_Admin_Fields::title_field(
402
+ array(
403
+ 'title' => '',
404
+ 'description' => __( 'Google Analytics not working correctly? <a href="https://cartflows.com/docs/troubleshooting-google-analytics-tracking-issues/" > Click here </a> to know more. ', 'cartflows' ),
405
+ )
406
+ );
407
+
408
+ do_action( 'cartflows_google_analytics_admin_fields', $google_analytics_settings );
409
+
410
+ echo '</div>';
411
+ ?>
412
+
413
+
414
+ </div>
415
+ <p>
416
+ <?php submit_button( __( 'Save Changes', 'cartflows' ), 'cartflows-common-setting-save-btn button-primary button', 'submit', false ); ?>
417
+ <?php wp_nonce_field( 'cartflows-google-analytics-settings', 'cartflows-google-analytics-settings-nonce' ); ?>
418
+ </p>
419
+
420
+
421
+ </form>
422
+ </div>
423
+ </div>
424
+ <!-- Google Analytics Tracking -->
425
+
426
+ <?php do_action( 'cartflows_register_general_settings' ); ?>
427
+
428
+ </div>
429
+
430
+ <!-- Right Sidebar -->
431
+ <div class="postbox-container" id="postbox-container-1">
432
+ <div id="side-sortables">
433
+
434
+ <div class="postbox">
435
+ <h2 class="hndle">
436
+ <span class="dashicons dashicons-book"></span>
437
+ <span><?php esc_html_e( 'Knowledge Base', 'cartflows' ); ?></span>
438
+ </h2>
439
+ <div class="inside">
440
+ <p>
441
+ <?php esc_html_e( 'Not sure how something works? Take a peek at the knowledge base and learn.', 'cartflows' ); ?>
442
+ </p>
443
+ <p>
444
+ <a href="<?php echo esc_url( 'https://cartflows.com/docs' ); ?>" target="_blank" rel="noopener"><?php esc_html_e( 'Visit Knowledge Base »', 'cartflows' ); ?></a>
445
+ </p>
446
+ </div>
447
+ </div>
448
+
449
+ <div class="postbox">
450
+ <h2 class="hndle">
451
+ <span class="dashicons dashicons-groups"></span>
452
+ <span><?php esc_html_e( 'Community', 'cartflows' ); ?></span>
453
+ </h2>
454
+ <div class="inside">
455
+ <p>
456
+ <?php esc_html_e( 'Join the community of super helpful CartFlows users. Say hello, ask questions, give feedback and help each other!', 'cartflows' ); ?>
457
+ </p>
458
+ <p>
459
+ <a href="<?php echo esc_url( 'https://www.facebook.com/groups/cartflows/' ); ?>" target="_blank" rel="noopener"><?php esc_html_e( 'Join Our Facebook Group »', 'cartflows' ); ?></a>
460
+ </p>
461
+ </div>
462
+ </div>
463
+
464
+ <div class="postbox">
465
+ <h2 class="hndle">
466
+ <span class="dashicons dashicons-sos"></span>
467
+ <span><?php esc_html_e( 'Five Star Support', 'cartflows' ); ?></span>
468
+ </h2>
469
+ <div class="inside">
470
+ <p>
471
+ <?php esc_html_e( 'Got a question? Get in touch with CartFlows developers. We\'re happy to help!', 'cartflows' ); ?>
472
+ </p>
473
+ <p>
474
+ <a href="<?php echo esc_url( 'https://cartflows.com/contact' ); ?>" target="_blank" rel="noopener"><?php esc_html_e( 'Submit a Ticket »', 'cartflows' ); ?></a>
475
+ </p>
476
+ </div>
477
+ </div>
478
+ <?php
479
+ if ( 'true' == $debug_on ) {
480
+ ?>
481
+ <div class="postbox">
482
+ <h2 class="hndle">
483
+ <span class="dashicons dashicons-editor-code"></span>
484
+ <span><?php esc_html_e( 'Load Minified CSS', 'cartflows' ); ?></span>
485
+ </h2>
486
+ <div class="inside">
487
+ <form method="post" class="wrap wcf-clear" action="">
488
+ <p>
489
+ <?php esc_html_e( 'Load the Minified CSS from here. Just Enable it by checking the below given checkbox.', 'cartflows' ); ?>
490
+ </p>
491
+ <?php
492
+ echo Cartflows_Admin_Fields::checkobox_field(
493
+ array(
494
+ 'id' => 'allow_minified_files',
495
+ 'name' => '_cartflows_debug_data[allow_minified_files]',
496
+ 'title' => __( 'Load minified CSS & JS Files', 'cartflows' ),
497
+ 'value' => $debug_data['allow_minified_files'],
498
+ )
499
+ );
500
+ ?>
501
+ <?php submit_button( __( 'Save', 'cartflows' ), 'button-primary button', 'submit', false ); ?>
502
+ <?php wp_nonce_field( 'cartflows-debug-settings', 'cartflows-debug-settings-nonce' ); ?>
503
+ </form>
504
+ </div>
505
+ </div>
506
+ <?php
507
+ }
508
+ ?>
509
+ </div>
510
+ </div>
511
+ <!-- Right Sidebar -->
512
+
513
+ </div>
514
+ <!-- /post-body -->
515
+ <br class="clear">
516
+ </div>
517
+ </div>
518
+ <?php endif; ?>
519
+
520
+ <?php
521
+ /**
522
+ * Loads Zapier settings admin view.
523
+ */
524
+ do_action( 'cartflows_after_general_settings' );
525
+ ?>
includes/meta-fields/generate-product-repeater.php CHANGED
@@ -1,99 +1,99 @@
1
- <?php
2
- /**
3
- * Generate product repeater.
4
- *
5
- * @package CartFlows
6
- */
7
-
8
- $hide_advance = 'wcf-hide-advance';
9
-
10
- if ( empty( $selected_data ) ) {
11
-
12
- $selected_data = array(
13
- 'quantity' => 1,
14
- 'discount_type' => '',
15
- 'discount_value' => '',
16
- 'unique_id' => '',
17
- );
18
- }
19
-
20
- ?>
21
-
22
- <div class="wcf-repeatable-row" data-key="<?php echo $id; ?>">
23
- <div class="wcf_display_advance_fields wcf-repeater-fields-head-wrap">
24
- <div class="wcf-repeatable-row-standard-fields">
25
- <div class="wcf-checkout-products-dashicon dashicons dashicons-menu"></div>
26
-
27
- <!-- Product Name -->
28
- <div class="wcf-repeatable-fields wcf-sel-product">
29
- <span class="wcf-repeatable-row-setting-field">
30
- <select name="wcf-checkout-products[<?php echo $id; ?>][product]" class="wcf-product-search" data-allow_clear="allow_clear" data-placeholder="<?php echo __( 'Search for a product&hellip;', 'cartflows' ); ?>" data-action="woocommerce_json_search_products_and_variations"><?php echo $options; ?></select>
31
- </span>
32
-
33
- <span class="wcf-repeatable-row-actions">
34
- <a class="wcf-remove-row wcf-repeatable-remove button" data-type="product">
35
- <span class="dashicons dashicons-trash"></span>
36
- <span class="wcf-repeatable-remove-button"><?php echo __( 'Remove', 'cartflows' ); ?></span>
37
- </a>
38
- </span>
39
- </div>
40
-
41
- <div class="wcf_toggle_advance_fields"><i class="dashicons dashicons-arrow-down"></i></div>
42
- </div>
43
- </div>
44
-
45
- <div class="wcf-repeatable-row-advance-fields <?php echo $hide_advance; ?>">
46
-
47
- <!-- Qty field. -->
48
- <div class="wcf-repeatable-row-qty-field wcf-checkout-products-qty-<?php echo $id; ?>">
49
- <div class="wcf-field-row">
50
- <div class="wcf-field-row-heading">
51
- <label><?php echo __( 'Product Quantity', 'cartflows' ); ?></label>
52
- </div>
53
-
54
- <div class="wcf-field-row-content wcf-field-row-advance-content">
55
- <input type="number" class="input-text qty text" step="1" min="1" max="" name="wcf-checkout-products[<?php echo $id; ?>][quantity]" value="<?php echo $selected_data['quantity']; ?>" title="Qty" inputmode="numeric">
56
- </div>
57
- </div>
58
- </div>
59
- <!-- Qty field end -->
60
-
61
- <!-- Type field. -->
62
- <div class="wcf-repeatable-discount-type-field">
63
- <div class="wcf-field-row">
64
- <div class="wcf-field-row-heading">
65
- <label><?php echo __( 'Discount Type', 'cartflows' ); ?></label>
66
- </div>
67
-
68
- <div class="wcf-field-row-content wcf-field-row-advance-content">
69
- <select name="wcf-checkout-products[<?php echo $id; ?>][discount_type]" data-allow_clear="allow_clear" data-placeholder="<?php echo __( 'Select Discount Type', 'cartflows' ); ?>">
70
- <option value="" <?php selected( $selected_data['discount_type'], '', true ); ?>><?php echo __( 'Original', 'cartflows' ); ?></option>
71
- <option value="discount_percent" <?php selected( $selected_data['discount_type'], 'discount_percent', true ); ?>><?php echo __( 'Percentage', 'cartflows' ); ?></option>
72
- <option value="discount_price" <?php selected( $selected_data['discount_type'], 'discount_price', true ); ?>><?php echo __( 'Price', 'cartflows' ); ?></option>
73
- </select>
74
- </div>
75
- </div>
76
- </div>
77
- <!-- Type field end -->
78
-
79
- <!-- Discount field -->
80
- <div class="wcf-repeatable-row-discount-field <?php echo $hide_advance; ?> wcf-checkout-products-discount-<?php echo $id; ?>">
81
- <div class="wcf-field-row">
82
- <div class="wcf-field-row-heading">
83
- <label><?php echo __( 'Discount Value', 'cartflows' ); ?></label>
84
- <i class="wcf-field-heading-help dashicons dashicons-editor-help"></i>
85
- <span class="wcf-tooltip-text"><?php echo __( 'Discount value will apply for each quantity of product.', 'cartflows' ); ?></span>
86
- </div>
87
- <div class="wcf-field-row-content wcf-field-row-advance-content">
88
- <input type="text" class="input-text text" name="wcf-checkout-products[<?php echo $id; ?>][discount_value]" value="<?php echo $selected_data['discount_value']; ?>" title="" inputmode="numeric">
89
- </div>
90
- </div>
91
- </div>
92
-
93
- <div class="wcf-repeatable-row-unique-id-field">
94
- <input name="wcf-checkout-products[<?php echo $id; ?>][unique_id]" type="hidden" class="wcf-checkout-product-unique" value="<?php echo $selected_data['unique_id']; ?>">
95
- </div>
96
-
97
- <?php do_action( 'cartflows_repeatable_row_advance_fields', $id ); ?>
98
- </div>
99
- </div>
1
+ <?php
2
+ /**
3
+ * Generate product repeater.
4
+ *
5
+ * @package CartFlows
6
+ */
7
+
8
+ $hide_advance = 'wcf-hide-advance';
9
+
10
+ if ( empty( $selected_data ) ) {
11
+
12
+ $selected_data = array(
13
+ 'quantity' => 1,
14
+ 'discount_type' => '',
15
+ 'discount_value' => '',
16
+ 'unique_id' => '',
17
+ );
18
+ }
19
+
20
+ ?>
21
+
22
+ <div class="wcf-repeatable-row" data-key="<?php echo $id; ?>">
23
+ <div class="wcf_display_advance_fields wcf-repeater-fields-head-wrap">
24
+ <div class="wcf-repeatable-row-standard-fields">
25
+ <div class="wcf-checkout-products-dashicon dashicons dashicons-menu"></div>
26
+
27
+ <!-- Product Name -->
28
+ <div class="wcf-repeatable-fields wcf-sel-product">
29
+ <span class="wcf-repeatable-row-setting-field">
30
+ <select name="wcf-checkout-products[<?php echo $id; ?>][product]" class="wcf-product-search" data-allow_clear="allow_clear" data-placeholder="<?php echo __( 'Search for a product&hellip;', 'cartflows' ); ?>" data-action="woocommerce_json_search_products_and_variations"><?php echo $options; ?></select>
31
+ </span>
32
+
33
+ <span class="wcf-repeatable-row-actions">
34
+ <a class="wcf-remove-row wcf-repeatable-remove button" data-type="product">
35
+ <span class="dashicons dashicons-trash"></span>
36
+ <span class="wcf-repeatable-remove-button"><?php echo __( 'Remove', 'cartflows' ); ?></span>
37
+ </a>
38
+ </span>
39
+ </div>
40
+
41
+ <div class="wcf_toggle_advance_fields"><i class="dashicons dashicons-arrow-down"></i></div>
42
+ </div>
43
+ </div>
44
+
45
+ <div class="wcf-repeatable-row-advance-fields <?php echo $hide_advance; ?>">
46
+
47
+ <!-- Qty field. -->
48
+ <div class="wcf-repeatable-row-qty-field wcf-checkout-products-qty-<?php echo $id; ?>">
49
+ <div class="wcf-field-row">
50
+ <div class="wcf-field-row-heading">
51
+ <label><?php echo __( 'Product Quantity', 'cartflows' ); ?></label>
52
+ </div>
53
+
54
+ <div class="wcf-field-row-content wcf-field-row-advance-content">
55
+ <input type="number" class="input-text qty text" step="1" min="1" max="" name="wcf-checkout-products[<?php echo $id; ?>][quantity]" value="<?php echo $selected_data['quantity']; ?>" title="Qty" inputmode="numeric">
56
+ </div>
57
+ </div>
58
+ </div>
59
+ <!-- Qty field end -->
60
+
61
+ <!-- Type field. -->
62
+ <div class="wcf-repeatable-discount-type-field">
63
+ <div class="wcf-field-row">
64
+ <div class="wcf-field-row-heading">
65
+ <label><?php echo __( 'Discount Type', 'cartflows' ); ?></label>
66
+ </div>
67
+
68
+ <div class="wcf-field-row-content wcf-field-row-advance-content">
69
+ <select name="wcf-checkout-products[<?php echo $id; ?>][discount_type]" data-allow_clear="allow_clear" data-placeholder="<?php echo __( 'Select Discount Type', 'cartflows' ); ?>">
70
+ <option value="" <?php selected( $selected_data['discount_type'], '', true ); ?>><?php echo __( 'Original', 'cartflows' ); ?></option>
71
+ <option value="discount_percent" <?php selected( $selected_data['discount_type'], 'discount_percent', true ); ?>><?php echo __( 'Percentage', 'cartflows' ); ?></option>
72
+ <option value="discount_price" <?php selected( $selected_data['discount_type'], 'discount_price', true ); ?>><?php echo __( 'Price', 'cartflows' ); ?></option>
73
+ </select>
74
+ </div>
75
+ </div>
76
+ </div>
77
+ <!-- Type field end -->
78
+
79
+ <!-- Discount field -->
80
+ <div class="wcf-repeatable-row-discount-field <?php echo $hide_advance; ?> wcf-checkout-products-discount-<?php echo $id; ?>">
81
+ <div class="wcf-field-row">
82
+ <div class="wcf-field-row-heading">
83
+ <label><?php echo __( 'Discount Value', 'cartflows' ); ?></label>
84
+ <i class="wcf-field-heading-help dashicons dashicons-editor-help"></i>
85
+ <span class="wcf-tooltip-text"><?php echo __( 'Discount value will apply for each quantity of product.', 'cartflows' ); ?></span>
86
+ </div>
87
+ <div class="wcf-field-row-content wcf-field-row-advance-content">
88
+ <input type="text" class="input-text text" name="wcf-checkout-products[<?php echo $id; ?>][discount_value]" value="<?php echo $selected_data['discount_value']; ?>" title="" inputmode="numeric">
89
+ </div>
90
+ </div>
91
+ </div>
92
+
93
+ <div class="wcf-repeatable-row-unique-id-field">
94
+ <input name="wcf-checkout-products[<?php echo $id; ?>][unique_id]" type="hidden" class="wcf-checkout-product-unique" value="<?php echo $selected_data['unique_id']; ?>">
95
+ </div>
96
+
97
+ <?php do_action( 'cartflows_repeatable_row_advance_fields', $id ); ?>
98
+ </div>
99
+ </div>
includes/meta-fields/get-field.php CHANGED
@@ -1,42 +1,42 @@
1
- <?php
2
- /**
3
- * Get Field.
4
- *
5
- * @package CartFlows
6
- */
7
-
8
- $label = isset( $field_data['label'] ) ? $field_data['label'] : '';
9
- $help = isset( $field_data['help'] ) ? $field_data['help'] : '';
10
- $after_html = isset( $field_data['after_html'] ) ? $field_data['after_html'] : '';
11
-
12
- $name_class = 'field-' . $field_data['name'];
13
-
14
- if ( isset( $field_data['field_type'] ) ) {
15
- $name_class .= ' wcf-field-' . $field_data['field_type'];
16
- }
17
- ?>
18
-
19
- <div class="wcf-field-row <?php echo $name_class; ?>">
20
-
21
- <?php if ( ! empty( $label ) || ! empty( $help ) ) { ?>
22
- <div class="wcf-field-row-heading">
23
-
24
- <?php if ( ! empty( $label ) ) { ?>
25
- <label><?php echo esc_html( $label ); ?></label>
26
- <?php } ?>
27
-
28
- <?php if ( ! empty( $help ) ) { ?>
29
- <i class="wcf-field-heading-help dashicons dashicons-editor-help"></i>
30
- <span class="wcf-tooltip-text"><?php echo $help; ?></span>
31
- <?php } ?>
32
- </div>
33
- <?php } ?>
34
-
35
- <div class="wcf-field-row-content"><?php echo $field_data['generated_content']; ?>
36
- <?php
37
- if ( ! empty( $after_html ) ) {
38
- echo $after_html;
39
- }
40
- ?>
41
- </div>
42
- </div>
1
+ <?php
2
+ /**
3
+ * Get Field.
4
+ *
5
+ * @package CartFlows
6
+ */
7
+
8
+ $label = isset( $field_data['label'] ) ? $field_data['label'] : '';
9
+ $help = isset( $field_data['help'] ) ? $field_data['help'] : '';
10
+ $after_html = isset( $field_data['after_html'] ) ? $field_data['after_html'] : '';
11
+
12
+ $name_class = 'field-' . $field_data['name'];
13
+
14
+ if ( isset( $field_data['field_type'] ) ) {
15
+ $name_class .= ' wcf-field-' . $field_data['field_type'];
16
+ }
17
+ ?>
18
+
19
+ <div class="wcf-field-row <?php echo $name_class; ?>">
20
+
21
+ <?php if ( ! empty( $label ) || ! empty( $help ) ) { ?>
22
+ <div class="wcf-field-row-heading">
23
+
24
+ <?php if ( ! empty( $label ) ) { ?>
25
+ <label><?php echo esc_html( $label ); ?></label>
26
+ <?php } ?>
27
+
28
+ <?php if ( ! empty( $help ) ) { ?>
29
+ <i class="wcf-field-heading-help dashicons dashicons-editor-help"></i>
30
+ <span class="wcf-tooltip-text"><?php echo $help; ?></span>
31
+ <?php } ?>
32
+ </div>
33
+ <?php } ?>
34
+
35
+ <div class="wcf-field-row-content"><?php echo $field_data['generated_content']; ?>
36
+ <?php
37
+ if ( ! empty( $after_html ) ) {
38
+ echo $after_html;
39
+ }
40
+ ?>
41
+ </div>
42
+ </div>
includes/meta-fields/get-product-selection-repeater.php CHANGED
@@ -1,117 +1,117 @@
1
- <?php
2
- /**
3
- * Get product selection repeater.
4
- *
5
- * @package CartFlows
6
- */
7
-
8
- $value = $field_data['value'];
9
-
10
- if ( ! is_array( $value ) ) {
11
-
12
- $value[0] = array(
13
- 'product' => '',
14
- );
15
- } else {
16
-
17
- if ( ! isset( $value[0] ) ) {
18
-
19
- $value[0] = array(
20
- 'product' => '',
21
- );
22
- }
23
- }
24
-
25
- $name_class = 'field-' . $field_data['name'];
26
-
27
- ?>
28
-
29
- <!-- Repeater template -->
30
- <script type="text/html" id="tmpl-wcf-product-repeater">
31
- <?php
32
- $template_data = array(
33
- 'quantity' => 1,
34
- 'discount_type' => '',
35
- 'discount_value' => '',
36
- 'unique_id' => '{{unique_id}}',
37
- );
38
- echo $this->generate_product_repeater_html( '{{id}}', '', $template_data );
39
- ?>
40
- </script>
41
- <!-- Repeater template end -->
42
-
43
- <div class="wcf-field-row wcf-product-repeater-field-row <?php echo $name_class; ?>">
44
- <div class="wcf-field-row-content">
45
- <div class="wcf-repeatables-wrap">
46
- <?php
47
-
48
- if ( is_array( $value ) ) {
49
-
50
- $repeater_html = '';
51
- $product_data_new = array();
52
-
53
- foreach ( $value as $p_key => $p_data ) {
54
-
55
- $selected_options = '';
56
- $selected_data = array(
57
- 'product' => 0,
58
- 'quantity' => 1,
59
- 'discount_type' => '',
60
- 'discount_value' => '',
61
- 'unique_id' => wcf()->utils->get_unique_id(),
62
- );
63
-
64
- if ( isset( $p_data['product'] ) ) {
65
-
66
- $product = wc_get_product( $p_data['product'] );
67
-
68
-
69
- // posts.
70
- if ( ! empty( $product ) ) {
71
-
72
- $post_title = $product->get_name() . ' (#' . $p_data['product'] . ')';
73
- $selected_options = '<option value="' . $p_data['product'] . '" selected="selected" >' . $post_title . '</option>';
74
- }
75
-
76
- $selected_data['product'] = $p_data['product'];
77
- }
78
-
79
- if ( isset( $p_data['quantity'] ) ) {
80
- $selected_data['quantity'] = $p_data['quantity'];
81
- }
82
-
83
-
84
- if ( isset( $p_data['discount_type'] ) ) {
85
- $selected_data['discount_type'] = $p_data['discount_type'];
86
-
87
- }
88
-
89
- if ( isset( $p_data['discount_value'] ) ) {
90
- $selected_data['discount_value'] = $p_data['discount_value'];
91
- }
92
-
93
- if ( isset( $p_data['unique_id'] ) && ! empty( $p_data['unique_id'] ) ) {
94
- $selected_data['unique_id'] = $p_data['unique_id'];
95
- }
96
-
97
- $repeater_html .= $this->generate_product_repeater_html( $p_key, $selected_options, $selected_data );
98
-
99
- $product_data_new[] = $selected_data;
100
- }
101
-
102
- wcf()->utils->set_selcted_checkout_products( '', $product_data_new );
103
-
104
- echo $repeater_html;
105
- }
106
- ?>
107
-
108
- <div class="wcf-add-fields"></div>
109
- </div>
110
- <div class="wcf-add-repeatable-row">
111
- <div class="submit wcf-add-repeatable-wrap">
112
- <button class="button-primary wcf-add-repeatable" data-name="wcf-checkout-products"><?php echo __( 'Add New Product', 'cartflows' ); ?></button>
113
- <a href="#!" class="button button-primary wcf-create-woo-product" data-name="wcf-create-woo-product"><?php echo __( 'Create Product', 'cartflows' ); ?></a>
114
- </div>
115
- </div>
116
- </div>
117
- </div>
1
+ <?php
2
+ /**
3
+ * Get product selection repeater.
4
+ *
5
+ * @package CartFlows
6
+ */
7
+
8
+ $value = $field_data['value'];
9
+
10
+ if ( ! is_array( $value ) ) {
11
+
12
+ $value[0] = array(
13
+ 'product' => '',
14
+ );
15
+ } else {
16
+
17
+ if ( ! isset( $value[0] ) ) {
18
+
19
+ $value[0] = array(
20
+ 'product' => '',
21
+ );
22
+ }
23
+ }
24
+
25
+ $name_class = 'field-' . $field_data['name'];
26
+
27
+ ?>
28
+
29
+ <!-- Repeater template -->
30
+ <script type="text/html" id="tmpl-wcf-product-repeater">
31
+ <?php
32
+ $template_data = array(
33
+ 'quantity' => 1,
34
+ 'discount_type' => '',
35
+ 'discount_value' => '',
36
+ 'unique_id' => '{{unique_id}}',
37
+ );
38
+ echo $this->generate_product_repeater_html( '{{id}}', '', $template_data );
39
+ ?>
40
+ </script>
41
+ <!-- Repeater template end -->
42
+
43
+ <div class="wcf-field-row wcf-product-repeater-field-row <?php echo $name_class; ?>">
44
+ <div class="wcf-field-row-content">
45
+ <div class="wcf-repeatables-wrap">
46
+ <?php
47
+
48
+ if ( is_array( $value ) ) {
49
+
50
+ $repeater_html = '';
51
+ $product_data_new = array();
52
+
53
+ foreach ( $value as $p_key => $p_data ) {
54
+
55
+ $selected_options = '';
56
+ $selected_data = array(
57
+ 'product' => 0,
58
+ 'quantity' => 1,
59
+ 'discount_type' => '',
60
+ 'discount_value' => '',
61
+ 'unique_id' => wcf()->utils->get_unique_id(),
62
+ );
63
+
64
+ if ( isset( $p_data['product'] ) ) {
65
+
66
+ $product = wc_get_product( $p_data['product'] );
67
+
68
+
69
+ // posts.
70
+ if ( ! empty( $product ) ) {
71
+
72
+ $post_title = $product->get_name() . ' (#' . $p_data['product'] . ')';
73
+ $selected_options = '<option value="' . $p_data['product'] . '" selected="selected" >' . $post_title . '</option>';
74
+ }
75
+
76
+ $selected_data['product'] = $p_data['product'];
77
+ }
78
+
79
+ if ( isset( $p_data['quantity'] ) ) {
80
+ $selected_data['quantity'] = $p_data['quantity'];
81
+ }
82
+
83
+
84
+ if ( isset( $p_data['discount_type'] ) ) {
85
+ $selected_data['discount_type'] = $p_data['discount_type'];
86
+
87
+ }
88
+
89
+ if ( isset( $p_data['discount_value'] ) ) {
90
+ $selected_data['discount_value'] = $p_data['discount_value'];
91
+ }
92
+
93
+ if ( isset( $p_data['unique_id'] ) && ! empty( $p_data['unique_id'] ) ) {
94
+ $selected_data['unique_id'] = $p_data['unique_id'];
95
+ }
96
+
97
+ $repeater_html .= $this->generate_product_repeater_html( $p_key, $selected_options, $selected_data );
98
+
99
+ $product_data_new[] = $selected_data;
100
+ }
101
+
102
+ wcf()->utils->set_selcted_checkout_products( '', $product_data_new );
103
+
104
+ echo $repeater_html;
105
+ }
106
+ ?>
107
+
108
+ <div class="wcf-add-fields"></div>
109
+ </div>
110
+ <div class="wcf-add-repeatable-row">
111
+ <div class="submit wcf-add-repeatable-wrap">
112
+ <button class="button-primary wcf-add-repeatable" data-name="wcf-checkout-products"><?php echo __( 'Add New Product', 'cartflows' ); ?></button>
113
+ <a href="#!" class="button button-primary wcf-create-woo-product" data-name="wcf-create-woo-product"><?php echo __( 'Create Product', 'cartflows' ); ?></a>
114
+ </div>
115
+ </div>
116
+ </div>
117
+ </div>
languages/cartflows.pot CHANGED
@@ -1,2046 +1,2051 @@
1
- # Copyright (C) 2020 CartFlows Inc
2
- # This file is distributed under the same license as the CartFlows package.
3
- msgid ""
4
- msgstr ""
5
- "Project-Id-Version: CartFlows 1.5.9\n"
6
- "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/cartflows\n"
7
- "POT-Creation-Date: 2020-05-14 10:01:55+00:00\n"
8
- "MIME-Version: 1.0\n"
9
- "Content-Type: text/plain; charset=utf-8\n"
10
- "Content-Transfer-Encoding: 8bit\n"
11
- "PO-Revision-Date: 2020-MO-DA HO:MI+ZONE\n"
12
- "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13
- "Language-Team: LANGUAGE <LL@li.org>\n"
14
- "Language: en\n"
15
- "Plural-Forms: nplurals=2; plural=(n != 1);\n"
16
- "X-Poedit-Country: United States\n"
17
- "X-Poedit-SourceCharset: UTF-8\n"
18
- "X-Poedit-KeywordsList: "
19
- "__;_e;_x:1,2c;_ex:1,2c;_n:1,2;_nx:1,2,4c;_n_noop:1,2;_nx_noop:1,2,3c;esc_"
20
- "attr__;esc_html__;esc_attr_e;esc_html_e;esc_attr_x:1,2c;esc_html_x:1,2c;\n"
21
- "X-Poedit-Basepath: ../\n"
22
- "X-Poedit-SearchPath-0: .\n"
23
- "X-Poedit-Bookmarks: \n"
24
- "X-Textdomain-Support: yes\n"
25
- "X-Generator: grunt-wp-i18n 1.0.3\n"
26
-
27
- #: classes/batch-process/class-cartflows-importer-elementor.php:44
28
- msgid "Invalid content."
29
- msgstr ""
30
-
31
- #: classes/batch-process/class-cartflows-importer-elementor.php:52
32
- msgid "Invalid content. Expected an array."
33
- msgstr ""
34
-
35
- #: classes/batch-process/helpers/class-wp-background-process.php:435
36
- msgid "Every %d Minutes"
37
- msgstr ""
38
-
39
- #: classes/class-cartflows-admin-fields.php:231
40
- msgid "Select"
41
- msgstr ""
42
-
43
- #: classes/class-cartflows-admin-fields.php:234
44
- msgid "No Checkout Steps"
45
- msgstr ""
46
-
47
- #: classes/class-cartflows-admin-fields.php:260
48
- #. translators: %s: link
49
- msgid ""
50
- "Be sure not to add any product in above selected Global Checkout step. "
51
- "Please read information about how to set up Global Checkout %1$shere%2$s."
52
- msgstr ""
53
-
54
- #: classes/class-cartflows-admin.php:153 classes/class-cartflows-admin.php:154
55
- #: includes/admin/cartflows-general-bck.php:34
56
- #: modules/optin/classes/class-cartflows-optin-meta.php:150
57
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:148
58
- msgid "Settings"
59
- msgstr ""
60
-
61
- #: classes/class-cartflows-admin.php:436
62
- msgid "Installing and activating.."
63
- msgstr ""
64
-
65
- #: classes/class-cartflows-admin.php:437
66
- msgid "There was an error with the installation of plugin."
67
- msgstr ""
68
-
69
- #: classes/class-cartflows-admin.php:491
70
- msgid "Flows Library"
71
- msgstr ""
72
-
73
- #: classes/class-cartflows-admin.php:498
74
- #: modules/flow/view/meta-flow-steps.php:156
75
- msgid "Ready Templates"
76
- msgstr ""
77
-
78
- #: classes/class-cartflows-admin.php:501
79
- #: modules/flow/view/meta-flow-steps.php:159
80
- msgid "Create Your Own"
81
- msgstr ""
82
-
83
- #: classes/class-cartflows-admin.php:512
84
- #: modules/flow/view/meta-flow-steps.php:171
85
- msgid "Search Sites"
86
- msgstr ""
87
-
88
- #: classes/class-cartflows-admin.php:513
89
- #: modules/flow/view/meta-flow-steps.php:172
90
- msgid "Search Flow..."
91
- msgstr ""
92
-
93
- #: classes/class-cartflows-admin.php:530
94
- msgid "Design Your Flow"
95
- msgstr ""
96
-
97
- #: classes/class-cartflows-admin.php:531
98
- #: classes/class-cartflows-importer.php:637
99
- #: classes/class-cartflows-importer.php:736
100
- #: modules/flow/view/meta-flow-steps.php:202
101
- msgid "Learn How"
102
- msgstr ""
103
-
104
- #: classes/class-cartflows-api.php:368
105
- msgid "Request successfully processed!"
106
- msgstr ""
107
-
108
- #: classes/class-cartflows-cloning.php:423
109
- msgid "Clone this flow"
110
- msgstr ""
111
-
112
- #: classes/class-cartflows-cloning.php:423
113
- #: modules/flow/view/meta-flow-steps.php:115
114
- msgid "Clone"
115
- msgstr ""
116
-
117
- #: classes/class-cartflows-default-meta.php:741
118
- #: modules/optin/classes/class-cartflows-optin-meta.php:487
119
- msgid "Submit"
120
- msgstr ""
121
-
122
- #: classes/class-cartflows-flow-frontend.php:53
123
- msgid ""
124
- "Test mode is active — which displays random products for previewing. It can "
125
- "be deactivated from the flow settings in the admin dashboard."
126
- msgstr ""
127
-
128
- #: classes/class-cartflows-flow-frontend.php:58
129
- msgid "Click here to disable it"
130
- msgstr ""
131
-
132
- #: classes/class-cartflows-importer.php:81
133
- msgid "Export this flow"
134
- msgstr ""
135
-
136
- #: classes/class-cartflows-importer.php:81 includes/exporter.php:18
137
- msgid "Export"
138
- msgstr ""
139
-
140
- #: classes/class-cartflows-importer.php:92
141
- msgid "Flow Export"
142
- msgstr ""
143
-
144
- #: classes/class-cartflows-importer.php:93
145
- msgid "Flow Import"
146
- msgstr ""
147
-
148
- #: classes/class-cartflows-importer.php:104
149
- msgid "No post to export has been supplied!"
150
- msgstr ""
151
-
152
- #: classes/class-cartflows-importer.php:295
153
- msgid "Please upload a valid .json file"
154
- msgstr ""
155
-
156
- #: classes/class-cartflows-importer.php:301
157
- msgid "Please upload a file to import"
158
- msgstr ""
159
-
160
- #: classes/class-cartflows-importer.php:478
161
- msgid "Successfully imported flows."
162
- msgstr ""
163
-
164
- #: classes/class-cartflows-importer.php:510
165
- msgid "Loading Steps"
166
- msgstr ""
167
-
168
- #: classes/class-cartflows-importer.php:512
169
- msgid "Getting steps from the cloud. Please wait for the moment."
170
- msgstr ""
171
-
172
- #: classes/class-cartflows-importer.php:523
173
- msgid "Searching Template.."
174
- msgstr ""
175
-
176
- #: classes/class-cartflows-importer.php:525
177
- msgid "Getting templates from the cloud. Please wait for the moment."
178
- msgstr ""
179
-
180
- #: classes/class-cartflows-importer.php:534
181
- msgid "Importing.."
182
- msgstr ""
183
-
184
- #: classes/class-cartflows-importer.php:543
185
- #: classes/class-cartflows-importer.php:583
186
- msgid "Imported"
187
- msgstr ""
188
-
189
- #: classes/class-cartflows-importer.php:544
190
- #: classes/class-cartflows-importer.php:584
191
- msgid "Thanks for patience"
192
- msgstr ""
193
-
194
- #: classes/class-cartflows-importer.php:553
195
- #: classes/class-cartflows-importer.php:565
196
- msgid "Coming Soon!"
197
- msgstr ""
198
-
199
- #: classes/class-cartflows-importer.php:584
200
- msgid "Redirecting to the Elementor edit window."
201
- msgstr ""
202
-
203
- #: classes/class-cartflows-importer.php:630
204
- #: classes/class-cartflows-importer.php:746
205
- msgid "Pro"
206
- msgstr ""
207
-
208
- #: classes/class-cartflows-importer.php:671
209
- #: classes/class-cartflows-importer.php:778
210
- msgid "Activate License"
211
- msgstr ""
212
-
213
- #: classes/class-cartflows-importer.php:673
214
- #: classes/class-cartflows-importer.php:780
215
- #: modules/flow/classes/class-cartflows-flow-meta.php:474
216
- msgid "Get Pro"
217
- msgstr ""
218
-
219
- #: classes/class-cartflows-importer.php:698
220
- msgid "Create"
221
- msgstr ""
222
-
223
- #: classes/class-cartflows-importer.php:797
224
- msgid "Under Maintenance.."
225
- msgstr ""
226
-
227
- #: classes/class-cartflows-importer.php:798
228
- msgid ""
229
- "If you are seeing this message, most likely our servers are under routine "
230
- "maintenance and we will be back shortly."
231
- msgstr ""
232
-
233
- #: classes/class-cartflows-importer.php:799
234
- msgid ""
235
- "In rare case, it is possible your website is having trouble connecting with "
236
- "ours. If you need help, please feel free to get in touch with us from our "
237
- "website.."
238
- msgstr ""
239
-
240
- #: classes/class-cartflows-importer.php:829
241
- #. translators: %s: Plugin string
242
- msgid ""
243
- "%1$s to see CartFlows templates. If you prefer another page builder tool, "
244
- "you can <a href=\"%2$s\" target=\"blank\">select it here</a>."
245
- msgstr ""
246
-
247
- #: classes/class-cartflows-importer.php:844
248
- msgid "All"
249
- msgstr ""
250
-
251
- #: classes/class-cartflows-importer.php:847
252
- msgid "Select Step Type"
253
- msgstr ""
254
-
255
- #: classes/class-cartflows-importer.php:931
256
- msgid "Import from Cloud"
257
- msgstr ""
258
-
259
- #: classes/class-cartflows-importer.php:1230
260
- msgid "Sales Landing"
261
- msgstr ""
262
-
263
- #: classes/class-cartflows-importer.php:1234
264
- #: modules/flow/classes/class-cartflows-step-post-type.php:253
265
- #: modules/flow/view/meta-flow-steps.php:12
266
- msgid "Checkout (Woo)"
267
- msgstr ""
268
-
269
- #: classes/class-cartflows-importer.php:1238
270
- #: modules/flow/classes/class-cartflows-step-post-type.php:260
271
- #: modules/flow/view/meta-flow-steps.php:13
272
- msgid "Thank You (Woo)"
273
- msgstr ""
274
-
275
- #: classes/class-cartflows-importer.php:1246
276
- #: modules/flow/classes/class-cartflows-step-post-type.php:239
277
- #: modules/flow/view/meta-flow-steps.php:11
278
- msgid "Landing"
279
- msgstr ""
280
-
281
- #: classes/class-cartflows-importer.php:1250
282
- msgid "Thank You"
283
- msgstr ""
284
-
285
- #: classes/class-cartflows-importer.php:1360
286
- #. translators: %s: template ID
287
- msgid "Invalid template id %1$s or post id %2$s."
288
- msgstr ""
289
-
290
- #: classes/class-cartflows-importer.php:1422
291
- #. translators: %s: flow ID
292
- msgid "Invalid flow id %1$s OR step type %2$s."
293
- msgstr ""
294
-
295
- #: classes/class-cartflows-importer.php:1547
296
- msgid ""
297
- "Elementor is not activated. Please activate plugin Elementor Page Builder "
298
- "to import the step."
299
- msgstr ""
300
-
301
- #: classes/class-cartflows-importer.php:1650
302
- msgid "Action failed. Invalid Security Nonce."
303
- msgstr ""
304
-
305
- #: classes/class-cartflows-importer.php:1657
306
- msgid "User have not plugin install permissions."
307
- msgstr ""
308
-
309
- #: classes/class-cartflows-importer.php:1679
310
- msgid "Plugin Successfully Activated"
311
- msgstr ""
312
-
313
- #: classes/class-cartflows-learndash-compatibility.php:86
314
- msgid "None"
315
- msgstr ""
316
-
317
- #: classes/class-cartflows-learndash-compatibility.php:113
318
- #. translators: 1: anchor start, 2: anchor close
319
- msgid ""
320
- "Non-enrolled students will redirect to the selected CartFlows template. If "
321
- "you have not created any Flow already, add new Flow from %1$shere%2$s."
322
- msgstr ""
323
-
324
- #: classes/class-cartflows-learndash-compatibility.php:119
325
- msgid "Select CartFlows Template for this Course"
326
- msgstr ""
327
-
328
- #: classes/class-cartflows-loader.php:222
329
- #. translators: %s: html tags
330
- msgid ""
331
- "You are using an older version of %1$sCartFlows Pro%2$s. Please update "
332
- "%1$sCartFlows Pro%2$s plugin to version %1$s%3$s%2$s or higher."
333
- msgstr ""
334
-
335
- #: classes/class-cartflows-loader.php:464
336
- #. translators: %s: html tags
337
- msgid ""
338
- "This %1$sCartFlows%2$s page requires %1$sWooCommerce%2$s plugin installed & "
339
- "activated."
340
- msgstr ""
341
-
342
- #: classes/class-cartflows-loader.php:474
343
- msgid "Activate WooCommerce"
344
- msgstr ""
345
-
346
- #: classes/class-cartflows-loader.php:482
347
- msgid "Install WooCommerce"
348
- msgstr ""
349
-
350
- #: classes/class-cartflows-logger.php:161
351
- msgid "Action failed. Please refresh the page and retry."
352
- msgstr ""
353
-
354
- #: classes/class-cartflows-meta-fields.php:82
355
- msgid "Thin 100"
356
- msgstr ""
357
-
358
- #: classes/class-cartflows-meta-fields.php:83
359
- msgid "Extra-Light 200"
360
- msgstr ""
361
-
362
- #: classes/class-cartflows-meta-fields.php:84
363
- msgid "Light 300"
364
- msgstr ""
365
-
366
- #: classes/class-cartflows-meta-fields.php:85
367
- msgid "Normal 400"
368
- msgstr ""
369
-
370
- #: classes/class-cartflows-meta-fields.php:86
371
- msgid "Medium 500"
372
- msgstr ""
373
-
374
- #: classes/class-cartflows-meta-fields.php:87
375
- msgid "Semi-Bold 600"
376
- msgstr ""
377
-
378
- #: classes/class-cartflows-meta-fields.php:88
379
- msgid "Bold 700"
380
- msgstr ""
381
-
382
- #: classes/class-cartflows-meta-fields.php:89
383
- msgid "Extra-Bold 800"
384
- msgstr ""
385
-
386
- #: classes/class-cartflows-meta-fields.php:90
387
- msgid "Ultra-Bold 900"
388
- msgstr ""
389
-
390
- #: classes/class-cartflows-meta-fields.php:642
391
- #: includes/meta-fields/generate-product-repeater.php:30
392
- msgid "Search for a product&hellip;"
393
- msgstr ""
394
-
395
- #: classes/class-cartflows-meta-fields.php:690
396
- msgid "Search for a coupon&hellip;"
397
- msgstr ""
398
-
399
- #: classes/class-cartflows-meta.php:34
400
- msgid "Update"
401
- msgstr ""
402
-
403
- #: classes/class-cartflows-meta.php:42
404
- #: modules/flow/classes/class-cartflows-flow-meta.php:95
405
- #: modules/flow/classes/class-cartflows-flow-meta.php:733
406
- msgid "Back to edit Flow"
407
- msgstr ""
408
-
409
- #: classes/class-cartflows-meta.php:63
410
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:198
411
- #: modules/landing/classes/class-cartflows-landing-meta.php:136
412
- #: modules/optin/classes/class-cartflows-optin-meta.php:156
413
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:154
414
- msgid "Custom Script"
415
- msgstr ""
416
-
417
- #: classes/class-cartflows-meta.php:66
418
- msgid ""
419
- "Custom script lets you add your own custom script on front end of this flow "
420
- "page."
421
- msgstr ""
422
-
423
- #: classes/class-cartflows-metabox.php:59
424
- msgid "Flow Details"
425
- msgstr ""
426
-
427
- #: classes/class-cartflows-wizard.php:83
428
- msgid "Thanks for installing and using CartFlows!"
429
- msgstr ""
430
-
431
- #: classes/class-cartflows-wizard.php:84
432
- msgid ""
433
- "It is easy to use the CartFlows. Please use the setup wizard to quick start "
434
- "setup."
435
- msgstr ""
436
-
437
- #: classes/class-cartflows-wizard.php:86
438
- msgid "Start Wizard"
439
- msgstr ""
440
-
441
- #: classes/class-cartflows-wizard.php:87
442
- msgid "Skip Setup"
443
- msgstr ""
444
-
445
- #: classes/class-cartflows-wizard.php:117
446
- #: includes/admin/cartflows-general-bck.php:24
447
- msgid "Welcome"
448
- msgstr ""
449
-
450
- #: classes/class-cartflows-wizard.php:122
451
- msgid "Page Builder"
452
- msgstr ""
453
-
454
- #: classes/class-cartflows-wizard.php:126
455
- msgid "Checkout"
456
- msgstr ""
457
-
458
- #: classes/class-cartflows-wizard.php:130
459
- msgid "Training"
460
- msgstr ""
461
-
462
- #: classes/class-cartflows-wizard.php:134
463
- msgid "Ready!"
464
- msgstr ""
465
-
466
- #: classes/class-cartflows-wizard.php:209
467
- msgid "CartFlows Setup"
468
- msgstr ""
469
-
470
- #: classes/class-cartflows-wizard.php:235
471
- msgid "Exit Setup Wizard"
472
- msgstr ""
473
-
474
- #: classes/class-cartflows-wizard.php:288
475
- msgid "Welcome to CartFlows!"
476
- msgstr ""
477
-
478
- #: classes/class-cartflows-wizard.php:289
479
- msgid ""
480
- "Thank you for choosing CartFlows to get more leads, increase conversions, & "
481
- "maximize profits. This short setup wizard will guide you though configuring "
482
- "CartFlows and creating your first funnel."
483
- msgstr ""
484
-
485
- #: classes/class-cartflows-wizard.php:295
486
- msgid "Lets Go »"
487
- msgstr ""
488
-
489
- #: classes/class-cartflows-wizard.php:322
490
- msgid "Page Builder Setup"
491
- msgstr ""
492
-
493
- #: classes/class-cartflows-wizard.php:323
494
- msgid "Please select a page builder you would like to use with CartFlows."
495
- msgstr ""
496
-
497
- #: classes/class-cartflows-wizard.php:328
498
- msgid "Select Page Builder"
499
- msgstr ""
500
-
501
- #: classes/class-cartflows-wizard.php:335
502
- #: includes/admin/cartflows-general.php:94
503
- msgid "Elementor"
504
- msgstr ""
505
-
506
- #: classes/class-cartflows-wizard.php:345
507
- msgid "Beaver Builder Plugin (Lite Version)"
508
- msgstr ""
509
-
510
- #: classes/class-cartflows-wizard.php:355
511
- #: includes/admin/cartflows-general.php:96
512
- msgid "Divi"
513
- msgstr ""
514
-
515
- #: classes/class-cartflows-wizard.php:365
516
- #: includes/admin/cartflows-general.php:97
517
- msgid "Other"
518
- msgstr ""
519
-
520
- #: classes/class-cartflows-wizard.php:387
521
- msgid ""
522
- "While CartFlows Should work with most page builders, we offer templates for "
523
- "the above page builders."
524
- msgstr ""
525
-
526
- #: classes/class-cartflows-wizard.php:390
527
- #: classes/class-cartflows-wizard.php:435
528
- #: classes/class-cartflows-wizard.php:622
529
- msgid "« Previous"
530
- msgstr ""
531
-
532
- #: classes/class-cartflows-wizard.php:393
533
- msgid "Skip this step"
534
- msgstr ""
535
-
536
- #: classes/class-cartflows-wizard.php:394
537
- msgid "Next »"
538
- msgstr ""
539
-
540
- #: classes/class-cartflows-wizard.php:413
541
- msgid "Choose a checkout"
542
- msgstr ""
543
-
544
- #: classes/class-cartflows-wizard.php:416
545
- msgid ""
546
- "While CartFlows is designed to use WooCommerce sell digital and physical "
547
- "products, not all funnels need a checkout system."
548
- msgstr ""
549
-
550
- #: classes/class-cartflows-wizard.php:418
551
- msgid ""
552
- "Would you like to install WooCommerce to sell digital and physical products "
553
- "in your funnels?"
554
- msgstr ""
555
-
556
- #: classes/class-cartflows-wizard.php:425
557
- msgid "The following plugin will be installed and activated for you:"
558
- msgstr ""
559
-
560
- #: classes/class-cartflows-wizard.php:426
561
- msgid "WooCommerce"
562
- msgstr ""
563
-
564
- #: classes/class-cartflows-wizard.php:427
565
- msgid "WooCommerce Cart Abandonment Recovery"
566
- msgstr ""
567
-
568
- #: classes/class-cartflows-wizard.php:438
569
- #: classes/class-cartflows-wizard.php:625
570
- msgid "No thanks"
571
- msgstr ""
572
-
573
- #: classes/class-cartflows-wizard.php:439
574
- msgid "Yes"
575
- msgstr ""
576
-
577
- #: classes/class-cartflows-wizard.php:558
578
- msgid "Congratulations, You Did It!"
579
- msgstr ""
580
-
581
- #: classes/class-cartflows-wizard.php:565
582
- msgid ""
583
- "CartFlows is ready to use on your website. You've successfully completed "
584
- "the setup process and all that is left for you to do is create your first "
585
- "flow."
586
- msgstr ""
587
-
588
- #: classes/class-cartflows-wizard.php:579
589
- msgid "Create a flow"
590
- msgstr ""
591
-
592
- #: classes/class-cartflows-wizard.php:596
593
- msgid "Exclusive CartFlows Training Course Offer"
594
- msgstr ""
595
-
596
- #: classes/class-cartflows-wizard.php:607
597
- msgid ""
598
- "We want you to get off to a great start using CartFlows, so we would like "
599
- "to give access to our exclusive training course."
600
- msgstr ""
601
-
602
- #: classes/class-cartflows-wizard.php:608
603
- msgid "Get access to this couse, for free, by entering your email below."
604
- msgstr ""
605
-
606
- #: classes/class-cartflows-wizard.php:610
607
- msgid "Enter Email address"
608
- msgstr ""
609
-
610
- #: classes/class-cartflows-wizard.php:626
611
- msgid "Allow"
612
- msgstr ""
613
-
614
- #: classes/logger/class-cartflows-log-handler-file.php:351
615
- #: classes/logger/class-cartflows-log-handler-file.php:371
616
- msgid "This method should not be called before plugins_loaded."
617
- msgstr ""
618
-
619
- #: classes/logger/class-cartflows-wc-logger.php:58
620
- #. translators: 1: class name 2: Cartflows_Log_Handler_Interface
621
- msgid "The provided handler %1$s does not implement %2$s."
622
- msgstr ""
623
-
624
- #: classes/logger/class-cartflows-wc-logger.php:136
625
- #. translators: 1: Cartflows_WC_Logger::log 2: level
626
- msgid "%1$s was called with an invalid level \"%2$s\"."
627
- msgstr ""
628
-
629
- #: includes/admin/cartflows-admin.php:19
630
- #: includes/admin/cartflows-general.php:48
631
- msgid "Modernizing WordPress eCommerce!"
632
- msgstr ""
633
-
634
- #: includes/admin/cartflows-admin.php:29
635
- msgid "Settings saved successfully."
636
- msgstr ""
637
-
638
- #: includes/admin/cartflows-error-log.php:36
639
- msgid "%1$s at %2$s"
640
- msgstr ""
641
-
642
- #: includes/admin/cartflows-error-log.php:41
643
- #: modules/flow/classes/class-cartflows-flow-post-type.php:225
644
- #: modules/flow/view/meta-flow-steps.php:104
645
- msgid "View"
646
- msgstr ""
647
-
648
- #: includes/admin/cartflows-error-log.php:65
649
- msgid "Delete log"
650
- msgstr ""
651
-
652
- #: includes/admin/cartflows-error-log.php:70
653
- msgid "There are currently no logs to view."
654
- msgstr ""
655
-
656
- #: includes/admin/cartflows-general-bck.php:10
657
- msgid "Selec"
658
- msgstr ""
659
-
660
- #: includes/admin/cartflows-general-bck.php:22
661
- msgid "General"
662
- msgstr ""
663
-
664
- #: includes/admin/cartflows-general.php:31
665
- #: includes/admin/cartflows-general.php:58
666
- msgid "General Settings"
667
- msgstr ""
668
-
669
- #: includes/admin/cartflows-general.php:40
670
- msgid "Getting Started"
671
- msgstr ""
672
-
673
- #: includes/admin/cartflows-general.php:71
674
- msgid "Disallow search engines from indexing flows"
675
- msgstr ""
676
-
677
- #: includes/admin/cartflows-general.php:81
678
- #: modules/flow/view/meta-flow-steps.php:93
679
- msgid "Global Checkout"
680
- msgstr ""
681
-
682
- #: includes/admin/cartflows-general.php:90
683
- msgid "Show Templates designed with"
684
- msgstr ""
685
-
686
- #: includes/admin/cartflows-general.php:91
687
- msgid ""
688
- "CartFlows offers flow templates that can be imported in one click. These "
689
- "templates are available in few different page builders. Please choose your "
690
- "preferred page builder from the list so you will only see templates that "
691
- "are made using that page builder.."
692
- msgstr ""
693
-
694
- #: includes/admin/cartflows-general.php:95
695
- msgid "Beaver Builder"
696
- msgstr ""
697
-
698
- #: includes/admin/cartflows-general.php:106
699
- #: includes/admin/cartflows-general.php:190
700
- #: includes/admin/cartflows-general.php:296
701
- #: includes/admin/cartflows-general.php:413
702
- msgid "Save Changes"
703
- msgstr ""
704
-
705
- #: includes/admin/cartflows-general.php:116
706
- msgid "Permalink Settings"
707
- msgstr ""
708
-
709
- #: includes/admin/cartflows-general.php:131
710
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:647
711
- #: modules/optin/classes/class-cartflows-optin-meta.php:380
712
- msgid "Default"
713
- msgstr ""
714
-
715
- #: includes/admin/cartflows-general.php:137
716
- msgid "Flow and Step Slug"
717
- msgstr ""
718
-
719
- #: includes/admin/cartflows-general.php:143
720
- msgid "Flow Slug"
721
- msgstr ""
722
-
723
- #: includes/admin/cartflows-general.php:149
724
- msgid "Step Slug"
725
- msgstr ""
726
-
727
- #: includes/admin/cartflows-general.php:161
728
- msgid "Post Type Permalink Base"
729
- msgstr ""
730
-
731
- #: includes/admin/cartflows-general.php:169
732
- msgid "Step Base"
733
- msgstr ""
734
-
735
- #: includes/admin/cartflows-general.php:179
736
- msgid "Flow Base"
737
- msgstr ""
738
-
739
- #: includes/admin/cartflows-general.php:191
740
- msgid "Set Default"
741
- msgstr ""
742
-
743
- #: includes/admin/cartflows-general.php:205
744
- msgid "Facebook Pixel Settings"
745
- msgstr ""
746
-
747
- #: includes/admin/cartflows-general.php:220
748
- msgid "Enable Facebook Pixel Tracking"
749
- msgstr ""
750
-
751
- #: includes/admin/cartflows-general.php:233
752
- msgid "Enable for the whole site"
753
- msgstr ""
754
-
755
- #: includes/admin/cartflows-general.php:241
756
- #: includes/admin/cartflows-general.php:340
757
- msgid "If this option is unchecked, it will only apply to CartFlows steps."
758
- msgstr ""
759
-
760
- #: includes/admin/cartflows-general.php:251
761
- msgid "Enter Facebook pixel ID"
762
- msgstr ""
763
-
764
- #: includes/admin/cartflows-general.php:259
765
- #: includes/admin/cartflows-general.php:358
766
- msgid "Enable Events:"
767
- msgstr ""
768
-
769
- #: includes/admin/cartflows-general.php:268
770
- msgid "Initiate Checkout"
771
- msgstr ""
772
-
773
- #: includes/admin/cartflows-general.php:277
774
- #: includes/admin/cartflows-general.php:384
775
- msgid "Add Payment Info"
776
- msgstr ""
777
-
778
- #: includes/admin/cartflows-general.php:286
779
- msgid "Purchase Complete"
780
- msgstr ""
781
-
782
- #: includes/admin/cartflows-general.php:308
783
- msgid "Google Analytics Settings"
784
- msgstr ""
785
-
786
- #: includes/admin/cartflows-general.php:319
787
- msgid "Enable Google Analytics Tracking"
788
- msgstr ""
789
-
790
- #: includes/admin/cartflows-general.php:332
791
- msgid "Enable for the whole website"
792
- msgstr ""
793
-
794
- #: includes/admin/cartflows-general.php:350
795
- msgid "Google Analytics ID"
796
- msgstr ""
797
-
798
- #: includes/admin/cartflows-general.php:352
799
- msgid ""
800
- "Log into your <a href=\"https://analytics.google.com/\" "
801
- "target=\"_blank\">google analytics account</a> to find your ID. eg: "
802
- "UA-XXXXXX-X&period;"
803
- msgstr ""
804
-
805
- #: includes/admin/cartflows-general.php:366
806
- msgid "Begin Checkout"
807
- msgstr ""
808
-
809
- #: includes/admin/cartflows-general.php:375
810
- msgid "Add To Cart"
811
- msgstr ""
812
-
813
- #: includes/admin/cartflows-general.php:393
814
- msgid "Purchase"
815
- msgstr ""
816
-
817
- #: includes/admin/cartflows-general.php:401
818
- msgid ""
819
- "Google Analytics not working correctly? <a "
820
- "href=\"https://cartflows.com/docs/troubleshooting-google-analytics-tracking-"
821
- "issues/\" > Click here </a> to know more. "
822
- msgstr ""
823
-
824
- #: includes/admin/cartflows-general.php:434
825
- msgid "Knowledge Base"
826
- msgstr ""
827
-
828
- #: includes/admin/cartflows-general.php:438
829
- msgid "Not sure how something works? Take a peek at the knowledge base and learn."
830
- msgstr ""
831
-
832
- #: includes/admin/cartflows-general.php:441
833
- msgid "Visit Knowledge Base »"
834
- msgstr ""
835
-
836
- #: includes/admin/cartflows-general.php:449
837
- msgid "Community"
838
- msgstr ""
839
-
840
- #: includes/admin/cartflows-general.php:453
841
- msgid ""
842
- "Join the community of super helpful CartFlows users. Say hello, ask "
843
- "questions, give feedback and help each other!"
844
- msgstr ""
845
-
846
- #: includes/admin/cartflows-general.php:456
847
- msgid "Join Our Facebook Group »"
848
- msgstr ""
849
-
850
- #: includes/admin/cartflows-general.php:464
851
- msgid "Five Star Support"
852
- msgstr ""
853
-
854
- #: includes/admin/cartflows-general.php:468
855
- msgid "Got a question? Get in touch with CartFlows developers. We're happy to help!"
856
- msgstr ""
857
-
858
- #: includes/admin/cartflows-general.php:471
859
- msgid "Submit a Ticket »"
860
- msgstr ""
861
-
862
- #: includes/admin/cartflows-general.php:481
863
- msgid "Load Minified CSS"
864
- msgstr ""
865
-
866
- #: includes/admin/cartflows-general.php:486
867
- msgid ""
868
- "Load the Minified CSS from here. Just Enable it by checking the below given "
869
- "checkbox."
870
- msgstr ""
871
-
872
- #: includes/admin/cartflows-general.php:493
873
- msgid "Load minified CSS & JS Files"
874
- msgstr ""
875
-
876
- #: includes/admin/cartflows-general.php:498
877
- msgid "Save"
878
- msgstr ""
879
-
880
- #: includes/exporter.php:12
881
- msgid "Export Flows to a JSON file"
882
- msgstr ""
883
-
884
- #: includes/exporter.php:13
885
- msgid ""
886
- "This tool allows you to generate and download a JSON file containing a list "
887
- "of all flows."
888
- msgstr ""
889
-
890
- #: includes/importer.php:12
891
- msgid "Import Flows to a JSON file"
892
- msgstr ""
893
-
894
- #: includes/importer.php:13
895
- msgid "This tool allows you to import the flows from the JSON file."
896
- msgstr ""
897
-
898
- #: includes/importer.php:21
899
- msgid "Import"
900
- msgstr ""
901
-
902
- #: includes/meta-fields/generate-product-repeater.php:36
903
- msgid "Remove"
904
- msgstr ""
905
-
906
- #: includes/meta-fields/generate-product-repeater.php:51
907
- msgid "Product Quantity"
908
- msgstr ""
909
-
910
- #: includes/meta-fields/generate-product-repeater.php:65
911
- msgid "Discount Type"
912
- msgstr ""
913
-
914
- #: includes/meta-fields/generate-product-repeater.php:69
915
- msgid "Select Discount Type"
916
- msgstr ""
917
-
918
- #: includes/meta-fields/generate-product-repeater.php:70
919
- msgid "Original"
920
- msgstr ""
921
-
922
- #: includes/meta-fields/generate-product-repeater.php:71
923
- msgid "Percentage"
924
- msgstr ""
925
-
926
- #: includes/meta-fields/generate-product-repeater.php:72
927
- msgid "Price"
928
- msgstr ""
929
-
930
- #: includes/meta-fields/generate-product-repeater.php:83
931
- msgid "Discount Value"
932
- msgstr ""
933
-
934
- #: includes/meta-fields/generate-product-repeater.php:85
935
- msgid "Discount value will apply for each quantity of product."
936
- msgstr ""
937
-
938
- #: includes/meta-fields/get-product-selection-repeater.php:112
939
- msgid "Add New Product"
940
- msgstr ""
941
-
942
- #: includes/meta-fields/get-product-selection-repeater.php:113
943
- msgid "Create Product"
944
- msgstr ""
945
-
946
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:256
947
- #: modules/optin/classes/class-cartflows-optin-markup.php:146
948
- #: modules/thankyou/classes/class-cartflows-thankyou-markup.php:90
949
- msgid ""
950
- "WooCommerce functions do not exist. If you are in an IFrame, please reload "
951
- "it."
952
- msgstr ""
953
-
954
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:257
955
- #: modules/optin/classes/class-cartflows-optin-markup.php:147
956
- #: modules/thankyou/classes/class-cartflows-thankyou-markup.php:91
957
- msgid "Click Here to Reload"
958
- msgstr ""
959
-
960
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:275
961
- msgid "Checkout ID not found"
962
- msgstr ""
963
-
964
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:338
965
- #: modules/checkout/templates/embed/checkout-template-simple.php:25
966
- #: modules/checkout/templates/wcf-template.php:36
967
- #: modules/optin/templates/optin-template-simple.php:25
968
- msgid "Your cart is currently empty."
969
- msgstr ""
970
-
971
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:404
972
- msgid ""
973
- "No product is selected. Please select products from the checkout meta "
974
- "settings to continue."
975
- msgstr ""
976
-
977
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:493
978
- msgid "Variations Not set"
979
- msgstr ""
980
-
981
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:501
982
- msgid "This product can't be purchased"
983
- msgstr ""
984
-
985
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:946
986
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:989
987
- msgid "Coupon Code"
988
- msgstr ""
989
-
990
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:947
991
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:998
992
- msgid "Apply"
993
- msgstr ""
994
-
995
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:1154
996
- msgid "Sorry there was a problem removing this coupon."
997
- msgstr ""
998
-
999
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:1157
1000
- msgid "Coupon has been removed."
1001
- msgstr ""
1002
-
1003
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:1176
1004
- msgid "Sorry there was a problem removing "
1005
- msgstr ""
1006
-
1007
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:1179
1008
- msgid " has been removed."
1009
- msgstr ""
1010
-
1011
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:65
1012
- msgid "Checkout Layout"
1013
- msgstr ""
1014
-
1015
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:150
1016
- #: modules/landing/classes/class-cartflows-landing-meta.php:130
1017
- #: modules/optin/classes/class-cartflows-optin-meta.php:126
1018
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:130
1019
- msgid "Shortcodes"
1020
- msgstr ""
1021
-
1022
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:156
1023
- #: modules/optin/classes/class-cartflows-optin-meta.php:132
1024
- msgid "Select Product"
1025
- msgstr ""
1026
-
1027
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:162
1028
- msgid "Product Options"
1029
- msgstr ""
1030
-
1031
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:168
1032
- msgid "Order Bump"
1033
- msgstr ""
1034
-
1035
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:174
1036
- msgid "Checkout Offer"
1037
- msgstr ""
1038
-
1039
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:180
1040
- msgid "Checkout Design"
1041
- msgstr ""
1042
-
1043
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:186
1044
- msgid "Checkout Fields"
1045
- msgstr ""
1046
-
1047
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:192
1048
- msgid "Checkout Settings"
1049
- msgstr ""
1050
-
1051
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:209
1052
- msgid "Logo (Optional)"
1053
- msgstr ""
1054
-
1055
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:270
1056
- #. translators: %s: link
1057
- msgid "Upgrade to %1$sCartFlows Pro%2$s for Product Options feature."
1058
- msgstr ""
1059
-
1060
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:281
1061
- #. translators: %s: link.
1062
- msgid "Update %1$sCartFlows Pro%2$s to %3$s or above for Product Options"
1063
- msgstr ""
1064
-
1065
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:309
1066
- msgid "Add this shortcode to your checkout page"
1067
- msgstr ""
1068
-
1069
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:345
1070
- #. translators: %s: link
1071
- msgid "Upgrade to %1$sCartFlows Pro%2$s for Pre-applied Coupon."
1072
- msgstr ""
1073
-
1074
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:372
1075
- #. translators: %s: link
1076
- msgid "Upgrade to %1$sCartFlows Pro%2$s for Checkout Offer feature"
1077
- msgstr ""
1078
-
1079
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:382
1080
- #. translators: %s: link
1081
- msgid "Update to %1$sCartFlows Pro%2$s to %3$s or above for Checkout Offer feature"
1082
- msgstr ""
1083
-
1084
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:409
1085
- #. translators: %s: link
1086
- msgid "Upgrade to %1$sCartFlows Pro%2$s for animate browser tab feature"
1087
- msgstr ""
1088
-
1089
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:419
1090
- #. translators: %s: link
1091
- msgid ""
1092
- "Update to %1$sCartFlows Pro%2$s to %3$s or above for animate browser tab "
1093
- "feature"
1094
- msgstr ""
1095
-
1096
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:442
1097
- #. translators: %s: link
1098
- msgid "Upgrade to %1$sCartFlows Pro%2$s for Order Bump feature."
1099
- msgstr ""
1100
-
1101
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:469
1102
- #: modules/optin/classes/class-cartflows-optin-meta.php:267
1103
- #. translators: %s: link
1104
- msgid "Upgrade to %1$sCartFlows Pro%2$s for Custom Fields feature."
1105
- msgstr ""
1106
-
1107
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:492
1108
- msgid "Place Order Button Text"
1109
- msgstr ""
1110
-
1111
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:496
1112
- msgid "Place order"
1113
- msgstr ""
1114
-
1115
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:498
1116
- msgid "It will change the Place Order Button text on checkout page."
1117
- msgstr ""
1118
-
1119
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:508
1120
- msgid "Enable cart editing on checkout"
1121
- msgstr ""
1122
-
1123
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:516
1124
- #. translators: %s: link
1125
- msgid "Users will able to remove products from the checkout page."
1126
- msgstr ""
1127
-
1128
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:546
1129
- msgid "One Column (Available in CartFlows Pro) "
1130
- msgstr ""
1131
-
1132
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:547
1133
- msgid "Two Step (Available in CartFlows Pro) "
1134
- msgstr ""
1135
-
1136
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:553
1137
- msgid "Checkout Skin"
1138
- msgstr ""
1139
-
1140
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:557
1141
- msgid "One Column"
1142
- msgstr ""
1143
-
1144
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:558
1145
- msgid "Two Column"
1146
- msgstr ""
1147
-
1148
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:559
1149
- msgid "Two Step"
1150
- msgstr ""
1151
-
1152
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:568
1153
- #: modules/optin/classes/class-cartflows-optin-meta.php:343
1154
- msgid "Primary Color"
1155
- msgstr ""
1156
-
1157
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:577
1158
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:612
1159
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:658
1160
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:750
1161
- #: modules/optin/classes/class-cartflows-optin-meta.php:352
1162
- #: modules/optin/classes/class-cartflows-optin-meta.php:391
1163
- #: modules/optin/classes/class-cartflows-optin-meta.php:503
1164
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:209
1165
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:240
1166
- msgid "Font Family"
1167
- msgstr ""
1168
-
1169
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:585
1170
- msgid "Advance Options"
1171
- msgstr ""
1172
-
1173
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:597
1174
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:225
1175
- msgid "Heading"
1176
- msgstr ""
1177
-
1178
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:603
1179
- msgid "Heading Color"
1180
- msgstr ""
1181
-
1182
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:621
1183
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:667
1184
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:759
1185
- #: modules/optin/classes/class-cartflows-optin-meta.php:400
1186
- #: modules/optin/classes/class-cartflows-optin-meta.php:512
1187
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:249
1188
- msgid "Font Weight"
1189
- msgstr ""
1190
-
1191
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:629
1192
- #: modules/optin/classes/class-cartflows-optin-meta.php:363
1193
- msgid "Input Fields"
1194
- msgstr ""
1195
-
1196
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:637
1197
- #: modules/optin/classes/class-cartflows-optin-meta.php:370
1198
- msgid "Floating Labels (Available in CartFlows Pro)"
1199
- msgstr ""
1200
-
1201
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:643
1202
- #: modules/optin/classes/class-cartflows-optin-meta.php:376
1203
- msgid "Style"
1204
- msgstr ""
1205
-
1206
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:648
1207
- #: modules/optin/classes/class-cartflows-optin-meta.php:381
1208
- msgid "Floating Labels"
1209
- msgstr ""
1210
-
1211
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:675
1212
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:767
1213
- #: modules/optin/classes/class-cartflows-optin-meta.php:408
1214
- #: modules/optin/classes/class-cartflows-optin-meta.php:520
1215
- msgid "Size"
1216
- msgstr ""
1217
-
1218
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:679
1219
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:771
1220
- #: modules/optin/classes/class-cartflows-optin-meta.php:412
1221
- #: modules/optin/classes/class-cartflows-optin-meta.php:524
1222
- msgid "Extra Small"
1223
- msgstr ""
1224
-
1225
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:680
1226
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:772
1227
- #: modules/optin/classes/class-cartflows-optin-meta.php:413
1228
- #: modules/optin/classes/class-cartflows-optin-meta.php:525
1229
- msgid "Small"
1230
- msgstr ""
1231
-
1232
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:681
1233
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:773
1234
- #: modules/optin/classes/class-cartflows-optin-meta.php:414
1235
- #: modules/optin/classes/class-cartflows-optin-meta.php:526
1236
- msgid "Medium"
1237
- msgstr ""
1238
-
1239
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:682
1240
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:774
1241
- #: modules/optin/classes/class-cartflows-optin-meta.php:415
1242
- #: modules/optin/classes/class-cartflows-optin-meta.php:527
1243
- msgid "Large"
1244
- msgstr ""
1245
-
1246
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:683
1247
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:775
1248
- #: modules/optin/classes/class-cartflows-optin-meta.php:416
1249
- #: modules/optin/classes/class-cartflows-optin-meta.php:528
1250
- msgid "Extra Large"
1251
- msgstr ""
1252
-
1253
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:684
1254
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:776
1255
- #: modules/optin/classes/class-cartflows-optin-meta.php:417
1256
- #: modules/optin/classes/class-cartflows-optin-meta.php:529
1257
- msgid "Custom"
1258
- msgstr ""
1259
-
1260
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:691
1261
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:783
1262
- #: modules/optin/classes/class-cartflows-optin-meta.php:424
1263
- #: modules/optin/classes/class-cartflows-optin-meta.php:536
1264
- msgid "Top Bottom Spacing"
1265
- msgstr ""
1266
-
1267
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:699
1268
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:791
1269
- #: modules/optin/classes/class-cartflows-optin-meta.php:432
1270
- #: modules/optin/classes/class-cartflows-optin-meta.php:544
1271
- msgid "Left Right Spacing"
1272
- msgstr ""
1273
-
1274
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:707
1275
- #: modules/optin/classes/class-cartflows-optin-meta.php:448
1276
- msgid "Text / Placeholder Color"
1277
- msgstr ""
1278
-
1279
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:715
1280
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:815
1281
- #: modules/optin/classes/class-cartflows-optin-meta.php:456
1282
- #: modules/optin/classes/class-cartflows-optin-meta.php:581
1283
- msgid "Background Color"
1284
- msgstr ""
1285
-
1286
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:723
1287
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:831
1288
- #: modules/optin/classes/class-cartflows-optin-meta.php:464
1289
- #: modules/optin/classes/class-cartflows-optin-meta.php:597
1290
- msgid "Border Color"
1291
- msgstr ""
1292
-
1293
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:730
1294
- #: modules/optin/classes/class-cartflows-optin-meta.php:440
1295
- msgid "Label Color"
1296
- msgstr ""
1297
-
1298
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:743
1299
- msgid "Buttons"
1300
- msgstr ""
1301
-
1302
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:799
1303
- #: modules/optin/classes/class-cartflows-optin-meta.php:565
1304
- msgid "Text Color"
1305
- msgstr ""
1306
-
1307
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:807
1308
- #: modules/optin/classes/class-cartflows-optin-meta.php:573
1309
- msgid "Text Hover Color"
1310
- msgstr ""
1311
-
1312
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:823
1313
- #: modules/optin/classes/class-cartflows-optin-meta.php:589
1314
- msgid "Background Hover Color"
1315
- msgstr ""
1316
-
1317
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:839
1318
- #: modules/optin/classes/class-cartflows-optin-meta.php:605
1319
- msgid "Border Hover Color"
1320
- msgstr ""
1321
-
1322
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:852
1323
- msgid "Sections"
1324
- msgstr ""
1325
-
1326
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:858
1327
- msgid "Highlight Area Background Color"
1328
- msgstr ""
1329
-
1330
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:897
1331
- msgid "Header Logo"
1332
- msgstr ""
1333
-
1334
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:905
1335
- msgid "Logo Width (In px)"
1336
- msgstr ""
1337
-
1338
- #: modules/checkout/templates/wcf-template.php:46
1339
- msgid "Copyright &copy;"
1340
- msgstr ""
1341
-
1342
- #: modules/checkout/templates/wcf-template.php:50
1343
- msgid "All Rights Reserved"
1344
- msgstr ""
1345
-
1346
- #: modules/flow/classes/class-cartflows-flow-meta.php:263
1347
- #. translators: %s flow id
1348
- msgid "Step not deleted for flow - %s"
1349
- msgstr ""
1350
-
1351
- #: modules/flow/classes/class-cartflows-flow-meta.php:294
1352
- #. translators: %s flow id
1353
- msgid "Step deleted for flow - %s"
1354
- msgstr ""
1355
-
1356
- #: modules/flow/classes/class-cartflows-flow-meta.php:322
1357
- #. translators: %s flow id
1358
- msgid "Steps not sorted for flow - %s"
1359
- msgstr ""
1360
-
1361
- #: modules/flow/classes/class-cartflows-flow-meta.php:345
1362
- #. translators: %s flow id
1363
- msgid "Steps sorted for flow - %s"
1364
- msgstr ""
1365
-
1366
- #: modules/flow/classes/class-cartflows-flow-meta.php:456
1367
- msgid "Analytics"
1368
- msgstr ""
1369
-
1370
- #: modules/flow/classes/class-cartflows-flow-meta.php:473
1371
- #. translators: %s: link
1372
- msgid "Upgrade to %1$sCartFlows Pro%2$s for Analytics feature"
1373
- msgstr ""
1374
-
1375
- #: modules/flow/classes/class-cartflows-flow-meta.php:491
1376
- msgid "Flow Settings"
1377
- msgstr ""
1378
-
1379
- #: modules/flow/classes/class-cartflows-flow-meta.php:576
1380
- msgid "Enable Test Mode"
1381
- msgstr ""
1382
-
1383
- #: modules/flow/classes/class-cartflows-flow-meta.php:583
1384
- msgid ""
1385
- "If you are using WooCommerce plugin then test mode will add random products "
1386
- "in your flow, so you can preview it easily while testing."
1387
- msgstr ""
1388
-
1389
- #: modules/flow/classes/class-cartflows-flow-meta.php:702
1390
- #: modules/flow/view/meta-flow-steps.php:133
1391
- msgid "Add New Step"
1392
- msgstr ""
1393
-
1394
- #: modules/flow/classes/class-cartflows-flow-post-type.php:69
1395
- msgid "Flow: "
1396
- msgstr ""
1397
-
1398
- #: modules/flow/classes/class-cartflows-flow-post-type.php:69
1399
- msgid "Name: "
1400
- msgstr ""
1401
-
1402
- #: modules/flow/classes/class-cartflows-flow-post-type.php:101
1403
- msgid "Search Flows"
1404
- msgstr ""
1405
-
1406
- #: modules/flow/classes/class-cartflows-flow-post-type.php:102
1407
- msgid "All Flows"
1408
- msgstr ""
1409
-
1410
- #: modules/flow/classes/class-cartflows-flow-post-type.php:103
1411
- msgid "Edit Flow"
1412
- msgstr ""
1413
-
1414
- #: modules/flow/classes/class-cartflows-flow-post-type.php:104
1415
- msgid "View Flow"
1416
- msgstr ""
1417
-
1418
- #: modules/flow/classes/class-cartflows-flow-post-type.php:105
1419
- #: modules/flow/classes/class-cartflows-flow-post-type.php:107
1420
- #: modules/flow/classes/class-cartflows-step-post-type.php:167
1421
- #: modules/flow/classes/class-cartflows-step-post-type.php:169
1422
- msgid "Add New"
1423
- msgstr ""
1424
-
1425
- #: modules/flow/classes/class-cartflows-flow-post-type.php:106
1426
- msgid "Update Flow"
1427
- msgstr ""
1428
-
1429
- #: modules/flow/classes/class-cartflows-flow-post-type.php:108
1430
- msgid "New Flow Name"
1431
- msgstr ""
1432
-
1433
- #: modules/flow/classes/class-cartflows-flow-post-type.php:190
1434
- msgid "Upgrade to CartFlows Pro"
1435
- msgstr ""
1436
-
1437
- #: modules/flow/classes/class-cartflows-flow-post-type.php:209
1438
- msgid "Slug"
1439
- msgstr ""
1440
-
1441
- #: modules/flow/classes/class-cartflows-flow-post-type.php:332
1442
- msgid "Flows"
1443
- msgstr ""
1444
-
1445
- #: modules/flow/classes/class-cartflows-flow-post-type.php:354
1446
- #: modules/flow/classes/class-cartflows-flow-post-type.php:360
1447
- #: modules/flow/classes/class-cartflows-step-post-type.php:397
1448
- #: modules/flow/classes/class-cartflows-step-post-type.php:403
1449
- #. translators: %s: singular custom post type name
1450
- msgid "%s updated."
1451
- msgstr ""
1452
-
1453
- #: modules/flow/classes/class-cartflows-flow-post-type.php:356
1454
- #: modules/flow/classes/class-cartflows-step-post-type.php:399
1455
- #. translators: %s: singular custom post type name
1456
- msgid "Custom %s updated."
1457
- msgstr ""
1458
-
1459
- #: modules/flow/classes/class-cartflows-flow-post-type.php:358
1460
- #: modules/flow/classes/class-cartflows-step-post-type.php:401
1461
- #. translators: %s: singular custom post type name
1462
- msgid "Custom %s deleted."
1463
- msgstr ""
1464
-
1465
- #: modules/flow/classes/class-cartflows-flow-post-type.php:362
1466
- #: modules/flow/classes/class-cartflows-step-post-type.php:405
1467
- #. translators: %1$s: singular custom post type name ,%2$s: date and time of
1468
- #. the revision
1469
- msgid "%1$s restored to revision from %2$s"
1470
- msgstr ""
1471
-
1472
- #: modules/flow/classes/class-cartflows-flow-post-type.php:364
1473
- #: modules/flow/classes/class-cartflows-step-post-type.php:407
1474
- #. translators: %s: singular custom post type name
1475
- msgid "%s published."
1476
- msgstr ""
1477
-
1478
- #: modules/flow/classes/class-cartflows-flow-post-type.php:366
1479
- #: modules/flow/classes/class-cartflows-step-post-type.php:409
1480
- #. translators: %s: singular custom post type name
1481
- msgid "%s saved."
1482
- msgstr ""
1483
-
1484
- #: modules/flow/classes/class-cartflows-flow-post-type.php:368
1485
- #: modules/flow/classes/class-cartflows-step-post-type.php:411
1486
- #. translators: %s: singular custom post type name
1487
- msgid "%s submitted."
1488
- msgstr ""
1489
-
1490
- #: modules/flow/classes/class-cartflows-flow-post-type.php:370
1491
- #: modules/flow/classes/class-cartflows-step-post-type.php:413
1492
- #. translators: %s: singular custom post type name
1493
- msgid "%s scheduled for."
1494
- msgstr ""
1495
-
1496
- #: modules/flow/classes/class-cartflows-flow-post-type.php:372
1497
- #: modules/flow/classes/class-cartflows-step-post-type.php:415
1498
- #. translators: %s: singular custom post type name
1499
- msgid "%s draft updated."
1500
- msgstr ""
1501
-
1502
- #: modules/flow/classes/class-cartflows-flow-shortcodes.php:148
1503
- #: modules/widgets/class-cartflows-next-step.php:78
1504
- msgid "Next Step"
1505
- msgstr ""
1506
-
1507
- #: modules/flow/classes/class-cartflows-step-post-type.php:163
1508
- msgid "Search Steps"
1509
- msgstr ""
1510
-
1511
- #: modules/flow/classes/class-cartflows-step-post-type.php:164
1512
- msgid "All Steps"
1513
- msgstr ""
1514
-
1515
- #: modules/flow/classes/class-cartflows-step-post-type.php:165
1516
- #: modules/flow/view/meta-flow-steps.php:106
1517
- msgid "Edit Step"
1518
- msgstr ""
1519
-
1520
- #: modules/flow/classes/class-cartflows-step-post-type.php:166
1521
- #: modules/flow/view/meta-flow-steps.php:102
1522
- msgid "View Step"
1523
- msgstr ""
1524
-
1525
- #: modules/flow/classes/class-cartflows-step-post-type.php:168
1526
- msgid "Update Step"
1527
- msgstr ""
1528
-
1529
- #: modules/flow/classes/class-cartflows-step-post-type.php:170
1530
- msgid "New Step Name"
1531
- msgstr ""
1532
-
1533
- #: modules/flow/classes/class-cartflows-step-post-type.php:211
1534
- msgid "Step Type"
1535
- msgstr ""
1536
-
1537
- #: modules/flow/classes/class-cartflows-step-post-type.php:221
1538
- msgid "Step Flow"
1539
- msgstr ""
1540
-
1541
- #: modules/flow/classes/class-cartflows-step-post-type.php:246
1542
- #: modules/flow/view/meta-flow-steps.php:16
1543
- msgid "Optin (Woo)"
1544
- msgstr ""
1545
-
1546
- #: modules/flow/classes/class-cartflows-step-post-type.php:267
1547
- #: modules/flow/view/meta-flow-steps.php:14
1548
- msgid "Upsell (Woo)"
1549
- msgstr ""
1550
-
1551
- #: modules/flow/classes/class-cartflows-step-post-type.php:274
1552
- #: modules/flow/view/meta-flow-steps.php:15
1553
- msgid "Downsell (Woo)"
1554
- msgstr ""
1555
-
1556
- #: modules/flow/view/meta-flow-steps.php:85
1557
- msgid "No Product Assigned"
1558
- msgstr ""
1559
-
1560
- #: modules/flow/view/meta-flow-steps.php:89
1561
- msgid "Global Checkout - Remove selected checkout product"
1562
- msgstr ""
1563
-
1564
- #: modules/flow/view/meta-flow-steps.php:108
1565
- msgid "Edit"
1566
- msgstr ""
1567
-
1568
- #: modules/flow/view/meta-flow-steps.php:113
1569
- msgid "Clone Step"
1570
- msgstr ""
1571
-
1572
- #: modules/flow/view/meta-flow-steps.php:118
1573
- msgid "Delete Step"
1574
- msgstr ""
1575
-
1576
- #: modules/flow/view/meta-flow-steps.php:120
1577
- msgid "Delete"
1578
- msgstr ""
1579
-
1580
- #: modules/flow/view/meta-flow-steps.php:149
1581
- msgid "Steps Library"
1582
- msgstr ""
1583
-
1584
- #: modules/flow/view/meta-flow-steps.php:198
1585
- msgid "Create Step"
1586
- msgstr ""
1587
-
1588
- #: modules/flow/view/meta-flow-steps.php:200
1589
- msgid "You need a Cartflows Pro version to import Upsell / Downsell"
1590
- msgstr ""
1591
-
1592
- #: modules/landing/classes/class-cartflows-landing-meta.php:66
1593
- msgid "Landing Page Settings"
1594
- msgstr ""
1595
-
1596
- #: modules/landing/classes/class-cartflows-landing-meta.php:169
1597
- msgid "Next Step Link"
1598
- msgstr ""
1599
-
1600
- #: modules/optin/classes/class-cartflows-optin-markup.php:165
1601
- msgid "Please place shortcode on Optin step-type only."
1602
- msgstr ""
1603
-
1604
- #: modules/optin/classes/class-cartflows-optin-markup.php:225
1605
- msgid ""
1606
- "No product is selected. Please select a Simple, Virtual and Free product "
1607
- "from the meta settings."
1608
- msgstr ""
1609
-
1610
- #: modules/optin/classes/class-cartflows-optin-markup.php:242
1611
- msgid "Please update the selected product's price to zero (0)."
1612
- msgstr ""
1613
-
1614
- #: modules/optin/classes/class-cartflows-optin-markup.php:251
1615
- #: modules/optin/classes/class-cartflows-optin-markup.php:255
1616
- msgid "Please select a Simple, Virtual and Free product."
1617
- msgstr ""
1618
-
1619
- #: modules/optin/classes/class-cartflows-optin-meta.php:65
1620
- msgid "Optin Settings"
1621
- msgstr ""
1622
-
1623
- #: modules/optin/classes/class-cartflows-optin-meta.php:138
1624
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:136
1625
- msgid "Design"
1626
- msgstr ""
1627
-
1628
- #: modules/optin/classes/class-cartflows-optin-meta.php:144
1629
- msgid "Form Fields"
1630
- msgstr ""
1631
-
1632
- #: modules/optin/classes/class-cartflows-optin-meta.php:213
1633
- msgid "Add this shortcode to your optin page"
1634
- msgstr ""
1635
-
1636
- #: modules/optin/classes/class-cartflows-optin-meta.php:238
1637
- msgid "Select Free Product"
1638
- msgstr ""
1639
-
1640
- #: modules/optin/classes/class-cartflows-optin-meta.php:239
1641
- msgid "Select Free and Virtual product only."
1642
- msgstr ""
1643
-
1644
- #: modules/optin/classes/class-cartflows-optin-meta.php:290
1645
- msgid "Pass Fields as URL Parameters"
1646
- msgstr ""
1647
-
1648
- #: modules/optin/classes/class-cartflows-optin-meta.php:293
1649
- msgid "Enable"
1650
- msgstr ""
1651
-
1652
- #: modules/optin/classes/class-cartflows-optin-meta.php:294
1653
- msgid ""
1654
- "You can pass specific fields from the form to next step as URL query "
1655
- "parameters."
1656
- msgstr ""
1657
-
1658
- #: modules/optin/classes/class-cartflows-optin-meta.php:305
1659
- msgid "Enter form field"
1660
- msgstr ""
1661
-
1662
- #: modules/optin/classes/class-cartflows-optin-meta.php:308
1663
- #: modules/optin/classes/class-cartflows-optin-meta.php:318
1664
- msgid "Enter comma seprated field name. E.g. first_name, last_name"
1665
- msgstr ""
1666
-
1667
- #: modules/optin/classes/class-cartflows-optin-meta.php:310
1668
- msgid "Fields to pass, separated by commas"
1669
- msgstr ""
1670
-
1671
- #: modules/optin/classes/class-cartflows-optin-meta.php:320
1672
- #. translators: %s: link
1673
- msgid ""
1674
- "You can pass field value as a URL parameter to the next step. %1$sClick "
1675
- "here%2$s for more information."
1676
- msgstr ""
1677
-
1678
- #: modules/optin/classes/class-cartflows-optin-meta.php:477
1679
- msgid "Submit Button"
1680
- msgstr ""
1681
-
1682
- #: modules/optin/classes/class-cartflows-optin-meta.php:483
1683
- msgid "Button Text"
1684
- msgstr ""
1685
-
1686
- #: modules/optin/classes/class-cartflows-optin-meta.php:494
1687
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:217
1688
- msgid "Font Size"
1689
- msgstr ""
1690
-
1691
- #: modules/optin/classes/class-cartflows-optin-meta.php:552
1692
- msgid "Position"
1693
- msgstr ""
1694
-
1695
- #: modules/optin/classes/class-cartflows-optin-meta.php:556
1696
- msgid "Left"
1697
- msgstr ""
1698
-
1699
- #: modules/optin/classes/class-cartflows-optin-meta.php:557
1700
- msgid "Center"
1701
- msgstr ""
1702
-
1703
- #: modules/optin/classes/class-cartflows-optin-meta.php:558
1704
- msgid "Right"
1705
- msgstr ""
1706
-
1707
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:65
1708
- msgid "Thank You Page Settings"
1709
- msgstr ""
1710
-
1711
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:142
1712
- msgid "Edit Fields"
1713
- msgstr ""
1714
-
1715
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:182
1716
- msgid "Order Details"
1717
- msgstr ""
1718
-
1719
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:194
1720
- msgid "Text"
1721
- msgstr ""
1722
-
1723
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:200
1724
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:231
1725
- msgid "Color"
1726
- msgstr ""
1727
-
1728
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:257
1729
- msgid "Advanced Options"
1730
- msgstr ""
1731
-
1732
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:267
1733
- msgid "Container Width (In px)"
1734
- msgstr ""
1735
-
1736
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:275
1737
- msgid "Section Background Color"
1738
- msgstr ""
1739
-
1740
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:289
1741
- msgid "Enable Order Overview "
1742
- msgstr ""
1743
-
1744
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:297
1745
- msgid "Enable Order Details "
1746
- msgstr ""
1747
-
1748
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:305
1749
- msgid "Enable Billing Details "
1750
- msgstr ""
1751
-
1752
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:313
1753
- msgid "Enable Shipping Details "
1754
- msgstr ""
1755
-
1756
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:329
1757
- msgid "Thank You Page Text"
1758
- msgstr ""
1759
-
1760
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:333
1761
- #: woocommerce/template/checkout/thankyou.php:41
1762
- #: woocommerce/template/checkout/thankyou.php:83
1763
- msgid "Thank you. Your order has been received."
1764
- msgstr ""
1765
-
1766
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:335
1767
- msgid "It will change the default text on thank you page."
1768
- msgstr ""
1769
-
1770
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:343
1771
- msgid "Redirect After Purchase"
1772
- msgstr ""
1773
-
1774
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:352
1775
- msgid "Redirect Link"
1776
- msgstr ""
1777
-
1778
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:356
1779
- msgid "https://"
1780
- msgstr ""
1781
-
1782
- #: modules/widgets/class-cartflows-next-step.php:24
1783
- msgid "CartFlows Next Step"
1784
- msgstr ""
1785
-
1786
- #: modules/widgets/class-cartflows-next-step.php:26
1787
- msgid "Next Step Widgets"
1788
- msgstr ""
1789
-
1790
- #: modules/widgets/class-cartflows-next-step.php:106
1791
- msgid "New title"
1792
- msgstr ""
1793
-
1794
- #: modules/widgets/class-cartflows-next-step.php:123
1795
- msgid "Title:"
1796
- msgstr ""
1797
-
1798
- #: modules/widgets/class-cartflows-next-step.php:127
1799
- msgid "Flow ID:"
1800
- msgstr ""
1801
-
1802
- #: modules/widgets/class-cartflows-next-step.php:131
1803
- msgid "Step ID:"
1804
- msgstr ""
1805
-
1806
- #: woocommerce/template/cart/cart-shipping.php:51
1807
- #. Translators: $s shipping destination.
1808
- msgid "Estimate for %s."
1809
- msgstr ""
1810
-
1811
- #: woocommerce/template/cart/cart-shipping.php:52
1812
- msgid "Change address"
1813
- msgstr ""
1814
-
1815
- #: woocommerce/template/cart/cart-shipping.php:54
1816
- msgid "This is only an estimate. Prices will be updated during checkout."
1817
- msgstr ""
1818
-
1819
- #: woocommerce/template/cart/cart-shipping.php:61
1820
- msgid "Enter your address to view shipping options."
1821
- msgstr ""
1822
-
1823
- #: woocommerce/template/cart/cart-shipping.php:63
1824
- msgid ""
1825
- "There are no shipping methods available. Please ensure that your address "
1826
- "has been entered correctly, or contact us if you need any help."
1827
- msgstr ""
1828
-
1829
- #: woocommerce/template/cart/cart-shipping.php:66
1830
- #. Translators: $s shipping destination.
1831
- msgid "No shipping options were found for %s."
1832
- msgstr ""
1833
-
1834
- #: woocommerce/template/cart/cart-shipping.php:67
1835
- msgid "Enter a different address"
1836
- msgstr ""
1837
-
1838
- #: woocommerce/template/checkout/form-billing.php:27
1839
- msgid "Billing &amp; Shipping"
1840
- msgstr ""
1841
-
1842
- #: woocommerce/template/checkout/form-billing.php:31
1843
- msgid "Billing details"
1844
- msgstr ""
1845
-
1846
- #: woocommerce/template/checkout/form-billing.php:59
1847
- msgid "Create an account?"
1848
- msgstr ""
1849
-
1850
- #: woocommerce/template/checkout/form-checkout.php:26
1851
- msgid "You must be logged in to checkout."
1852
- msgstr ""
1853
-
1854
- #: woocommerce/template/checkout/form-checkout.php:52
1855
- msgid "Your order"
1856
- msgstr ""
1857
-
1858
- #: woocommerce/template/checkout/form-coupon.php:26
1859
- msgid "Have a coupon?"
1860
- msgstr ""
1861
-
1862
- #: woocommerce/template/checkout/form-coupon.php:26
1863
- msgid "Click here to enter your code"
1864
- msgstr ""
1865
-
1866
- #: woocommerce/template/checkout/form-coupon.php:31
1867
- msgid "If you have a coupon code, please apply it below."
1868
- msgstr ""
1869
-
1870
- #: woocommerce/template/checkout/form-coupon.php:34
1871
- msgid "Coupon code"
1872
- msgstr ""
1873
-
1874
- #: woocommerce/template/checkout/form-coupon.php:38
1875
- msgid "Apply coupon"
1876
- msgstr ""
1877
-
1878
- #: woocommerce/template/checkout/form-login.php:26
1879
- msgid "Returning customer?"
1880
- msgstr ""
1881
-
1882
- #: woocommerce/template/checkout/form-login.php:26
1883
- msgid "Click here to login"
1884
- msgstr ""
1885
-
1886
- #: woocommerce/template/checkout/form-login.php:32
1887
- msgid ""
1888
- "If you have shopped with us before, please enter your details below. If you "
1889
- "are a new customer, please proceed to the Billing &amp; Shipping section."
1890
- msgstr ""
1891
-
1892
- #: woocommerce/template/checkout/form-shipping.php:26
1893
- msgid "Ship to a different address?"
1894
- msgstr ""
1895
-
1896
- #: woocommerce/template/checkout/form-shipping.php:57
1897
- msgid "Additional information"
1898
- msgstr ""
1899
-
1900
- #: woocommerce/template/checkout/payment.php:33
1901
- msgid ""
1902
- "Sorry, it seems that there are no available payment methods for your state. "
1903
- "Please contact us if you require assistance or wish to make alternate "
1904
- "arrangements."
1905
- msgstr ""
1906
-
1907
- #: woocommerce/template/checkout/payment.php:33
1908
- msgid "Please fill in your details above to see available payment methods."
1909
- msgstr ""
1910
-
1911
- #: woocommerce/template/checkout/payment.php:42
1912
- #. translators: $1 and $2 opening and closing emphasis tags respectively
1913
- msgid ""
1914
- "Since your browser does not support JavaScript, or it is disabled, please "
1915
- "ensure you click the %1$sUpdate Totals%2$s button before placing your "
1916
- "order. You may be charged more than the amount stated above if you fail to "
1917
- "do so."
1918
- msgstr ""
1919
-
1920
- #: woocommerce/template/checkout/payment.php:44
1921
- msgid "Update totals"
1922
- msgstr ""
1923
-
1924
- #: woocommerce/template/checkout/review-order.php:26
1925
- #: woocommerce/template/order/order-details.php:51
1926
- msgid "Product"
1927
- msgstr ""
1928
-
1929
- #: woocommerce/template/checkout/review-order.php:27
1930
- #: woocommerce/template/checkout/review-order.php:107
1931
- #: woocommerce/template/order/order-details.php:52
1932
- msgid "Total"
1933
- msgstr ""
1934
-
1935
- #: woocommerce/template/checkout/review-order.php:60
1936
- msgid "Subtotal"
1937
- msgstr ""
1938
-
1939
- #: woocommerce/template/checkout/thankyou.php:30
1940
- msgid ""
1941
- "Unfortunately your order cannot be processed as the originating "
1942
- "bank/merchant has declined your transaction. Please attempt your purchase "
1943
- "again."
1944
- msgstr ""
1945
-
1946
- #: woocommerce/template/checkout/thankyou.php:33
1947
- msgid "Pay"
1948
- msgstr ""
1949
-
1950
- #: woocommerce/template/checkout/thankyou.php:35
1951
- msgid "My account"
1952
- msgstr ""
1953
-
1954
- #: woocommerce/template/checkout/thankyou.php:46
1955
- msgid "Order number:"
1956
- msgstr ""
1957
-
1958
- #: woocommerce/template/checkout/thankyou.php:51
1959
- msgid "Date:"
1960
- msgstr ""
1961
-
1962
- #: woocommerce/template/checkout/thankyou.php:57
1963
- msgid "Email:"
1964
- msgstr ""
1965
-
1966
- #: woocommerce/template/checkout/thankyou.php:63
1967
- msgid "Total:"
1968
- msgstr ""
1969
-
1970
- #: woocommerce/template/checkout/thankyou.php:69
1971
- msgid "Payment method:"
1972
- msgstr ""
1973
-
1974
- #: woocommerce/template/global/form-login.php:34
1975
- msgid "Username or email"
1976
- msgstr ""
1977
-
1978
- #: woocommerce/template/global/form-login.php:38
1979
- msgid "Password"
1980
- msgstr ""
1981
-
1982
- #: woocommerce/template/global/form-login.php:48
1983
- msgid "Login"
1984
- msgstr ""
1985
-
1986
- #: woocommerce/template/global/form-login.php:53
1987
- msgid "Remember me"
1988
- msgstr ""
1989
-
1990
- #: woocommerce/template/global/form-login.php:57
1991
- msgid "Lost your password?"
1992
- msgstr ""
1993
-
1994
- #: woocommerce/template/order/order-details.php:45
1995
- msgid "Order details"
1996
- msgstr ""
1997
-
1998
- #: woocommerce/template/order/order-details.php:93
1999
- msgid "Note:"
2000
- msgstr ""
2001
-
2002
- #. Plugin Name of the plugin/theme
2003
- msgid "CartFlows"
2004
- msgstr ""
2005
-
2006
- #. Author URI of the plugin/theme
2007
- msgid "https://cartflows.com/"
2008
- msgstr ""
2009
-
2010
- #. Description of the plugin/theme
2011
- msgid "Create beautiful checkout pages & sales flows for WooCommerce."
2012
- msgstr ""
2013
-
2014
- #. Author of the plugin/theme
2015
- msgid "CartFlows Inc"
2016
- msgstr ""
2017
-
2018
- #: modules/flow/classes/class-cartflows-flow-post-type.php:99
2019
- msgctxt "flow general name"
2020
- msgid "Flows"
2021
- msgstr ""
2022
-
2023
- #: modules/flow/classes/class-cartflows-flow-post-type.php:100
2024
- msgctxt "flow singular name"
2025
- msgid "Flow"
2026
- msgstr ""
2027
-
2028
- #: modules/flow/classes/class-cartflows-step-post-type.php:161
2029
- msgctxt "flow step general name"
2030
- msgid "Steps"
2031
- msgstr ""
2032
-
2033
- #: modules/flow/classes/class-cartflows-step-post-type.php:162
2034
- msgctxt "flow step singular name"
2035
- msgid "Step"
2036
- msgstr ""
2037
-
2038
- #: modules/flow/classes/class-cartflows-step-post-type.php:315
2039
- msgctxt "cartflows"
2040
- msgid "CartFlows — Boxed"
2041
- msgstr ""
2042
-
2043
- #: modules/flow/classes/class-cartflows-step-post-type.php:316
2044
- msgctxt "cartflows"
2045
- msgid "Template for Page Builders"
 
 
 
 
 
2046
  msgstr ""
1
+ # Copyright (C) 2020 CartFlows Inc
2
+ # This file is distributed under the same license as the CartFlows package.
3
+ msgid ""
4
+ msgstr ""
5
+ "Project-Id-Version: CartFlows 1.5.10\n"
6
+ "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/cartflows\n"
7
+ "POT-Creation-Date: 2020-06-03 09:23:29+00:00\n"
8
+ "MIME-Version: 1.0\n"
9
+ "Content-Type: text/plain; charset=utf-8\n"
10
+ "Content-Transfer-Encoding: 8bit\n"
11
+ "PO-Revision-Date: 2020-MO-DA HO:MI+ZONE\n"
12
+ "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13
+ "Language-Team: LANGUAGE <LL@li.org>\n"
14
+ "Language: en\n"
15
+ "Plural-Forms: nplurals=2; plural=(n != 1);\n"
16
+ "X-Poedit-Country: United States\n"
17
+ "X-Poedit-SourceCharset: UTF-8\n"
18
+ "X-Poedit-KeywordsList: "
19
+ "__;_e;_x:1,2c;_ex:1,2c;_n:1,2;_nx:1,2,4c;_n_noop:1,2;_nx_noop:1,2,3c;esc_"
20
+ "attr__;esc_html__;esc_attr_e;esc_html_e;esc_attr_x:1,2c;esc_html_x:1,2c;\n"
21
+ "X-Poedit-Basepath: ../\n"
22
+ "X-Poedit-SearchPath-0: .\n"
23
+ "X-Poedit-Bookmarks: \n"
24
+ "X-Textdomain-Support: yes\n"
25
+ "X-Generator: grunt-wp-i18n 1.0.3\n"
26
+
27
+ #: classes/batch-process/class-cartflows-importer-elementor.php:44
28
+ msgid "Invalid content."
29
+ msgstr ""
30
+
31
+ #: classes/batch-process/class-cartflows-importer-elementor.php:56
32
+ msgid "Invalid content. Expected an array."
33
+ msgstr ""
34
+
35
+ #: classes/batch-process/helpers/class-wp-background-process.php:435
36
+ msgid "Every %d Minutes"
37
+ msgstr ""
38
+
39
+ #: classes/class-cartflows-admin-fields.php:235
40
+ msgid "Select"
41
+ msgstr ""
42
+
43
+ #: classes/class-cartflows-admin-fields.php:238
44
+ msgid "No Checkout Steps"
45
+ msgstr ""
46
+
47
+ #: classes/class-cartflows-admin-fields.php:264
48
+ #. translators: %s: link
49
+ msgid ""
50
+ "Be sure not to add any product in above selected Global Checkout step. "
51
+ "Please read information about how to set up Global Checkout %1$shere%2$s."
52
+ msgstr ""
53
+
54
+ #: classes/class-cartflows-admin.php:153 classes/class-cartflows-admin.php:154
55
+ #: includes/admin/cartflows-general-bck.php:34
56
+ #: modules/optin/classes/class-cartflows-optin-meta.php:150
57
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:148
58
+ msgid "Settings"
59
+ msgstr ""
60
+
61
+ #: classes/class-cartflows-admin.php:440
62
+ msgid "Installing and activating.."
63
+ msgstr ""
64
+
65
+ #: classes/class-cartflows-admin.php:441
66
+ msgid "There was an error with the installation of plugin."
67
+ msgstr ""
68
+
69
+ #: classes/class-cartflows-admin.php:495
70
+ msgid "Flows Library"
71
+ msgstr ""
72
+
73
+ #: classes/class-cartflows-admin.php:502
74
+ #: modules/flow/view/meta-flow-steps.php:156
75
+ msgid "Ready Templates"
76
+ msgstr ""
77
+
78
+ #: classes/class-cartflows-admin.php:505
79
+ #: modules/flow/view/meta-flow-steps.php:159
80
+ msgid "Create Your Own"
81
+ msgstr ""
82
+
83
+ #: classes/class-cartflows-admin.php:516
84
+ #: modules/flow/view/meta-flow-steps.php:171
85
+ msgid "Search Sites"
86
+ msgstr ""
87
+
88
+ #: classes/class-cartflows-admin.php:517
89
+ #: modules/flow/view/meta-flow-steps.php:172
90
+ msgid "Search Flow..."
91
+ msgstr ""
92
+
93
+ #: classes/class-cartflows-admin.php:534
94
+ msgid "Design Your Flow"
95
+ msgstr ""
96
+
97
+ #: classes/class-cartflows-admin.php:535
98
+ #: classes/class-cartflows-importer.php:665
99
+ #: classes/class-cartflows-importer.php:764
100
+ #: modules/flow/view/meta-flow-steps.php:202
101
+ msgid "Learn How"
102
+ msgstr ""
103
+
104
+ #: classes/class-cartflows-api.php:369
105
+ msgid "Request successfully processed!"
106
+ msgstr ""
107
+
108
+ #: classes/class-cartflows-cloning.php:423
109
+ msgid "Clone this flow"
110
+ msgstr ""
111
+
112
+ #: classes/class-cartflows-cloning.php:423
113
+ #: modules/flow/view/meta-flow-steps.php:115
114
+ msgid "Clone"
115
+ msgstr ""
116
+
117
+ #: classes/class-cartflows-default-meta.php:741
118
+ #: modules/optin/classes/class-cartflows-optin-meta.php:487
119
+ msgid "Submit"
120
+ msgstr ""
121
+
122
+ #: classes/class-cartflows-flow-frontend.php:53
123
+ msgid ""
124
+ "Test mode is active — which displays random products for previewing. It can "
125
+ "be deactivated from the flow settings in the admin dashboard."
126
+ msgstr ""
127
+
128
+ #: classes/class-cartflows-flow-frontend.php:58
129
+ msgid "Click here to disable it"
130
+ msgstr ""
131
+
132
+ #: classes/class-cartflows-importer.php:81
133
+ msgid "Export this flow"
134
+ msgstr ""
135
+
136
+ #: classes/class-cartflows-importer.php:81 includes/exporter.php:18
137
+ msgid "Export"
138
+ msgstr ""
139
+
140
+ #: classes/class-cartflows-importer.php:92
141
+ msgid "Flow Export"
142
+ msgstr ""
143
+
144
+ #: classes/class-cartflows-importer.php:93
145
+ msgid "Flow Import"
146
+ msgstr ""
147
+
148
+ #: classes/class-cartflows-importer.php:104
149
+ msgid "No post to export has been supplied!"
150
+ msgstr ""
151
+
152
+ #: classes/class-cartflows-importer.php:278
153
+ msgid "Please upload a valid .json file"
154
+ msgstr ""
155
+
156
+ #: classes/class-cartflows-importer.php:284
157
+ msgid "Please upload a file to import"
158
+ msgstr ""
159
+
160
+ #: classes/class-cartflows-importer.php:506
161
+ msgid "Successfully imported flows."
162
+ msgstr ""
163
+
164
+ #: classes/class-cartflows-importer.php:538
165
+ msgid "Loading Steps"
166
+ msgstr ""
167
+
168
+ #: classes/class-cartflows-importer.php:540
169
+ msgid "Getting steps from the cloud. Please wait for the moment."
170
+ msgstr ""
171
+
172
+ #: classes/class-cartflows-importer.php:551
173
+ msgid "Searching Template.."
174
+ msgstr ""
175
+
176
+ #: classes/class-cartflows-importer.php:553
177
+ msgid "Getting templates from the cloud. Please wait for the moment."
178
+ msgstr ""
179
+
180
+ #: classes/class-cartflows-importer.php:562
181
+ msgid "Importing.."
182
+ msgstr ""
183
+
184
+ #: classes/class-cartflows-importer.php:571
185
+ #: classes/class-cartflows-importer.php:611
186
+ msgid "Imported"
187
+ msgstr ""
188
+
189
+ #: classes/class-cartflows-importer.php:572
190
+ #: classes/class-cartflows-importer.php:612
191
+ msgid "Thanks for patience"
192
+ msgstr ""
193
+
194
+ #: classes/class-cartflows-importer.php:581
195
+ #: classes/class-cartflows-importer.php:593
196
+ msgid "Coming Soon!"
197
+ msgstr ""
198
+
199
+ #: classes/class-cartflows-importer.php:612
200
+ msgid "Redirecting to the Elementor edit window."
201
+ msgstr ""
202
+
203
+ #: classes/class-cartflows-importer.php:658
204
+ #: classes/class-cartflows-importer.php:774
205
+ msgid "Pro"
206
+ msgstr ""
207
+
208
+ #: classes/class-cartflows-importer.php:699
209
+ #: classes/class-cartflows-importer.php:806
210
+ msgid "Activate License"
211
+ msgstr ""
212
+
213
+ #: classes/class-cartflows-importer.php:701
214
+ #: classes/class-cartflows-importer.php:808
215
+ #: modules/flow/classes/class-cartflows-flow-meta.php:474
216
+ msgid "Get Pro"
217
+ msgstr ""
218
+
219
+ #: classes/class-cartflows-importer.php:726
220
+ msgid "Create"
221
+ msgstr ""
222
+
223
+ #: classes/class-cartflows-importer.php:825
224
+ msgid "Under Maintenance.."
225
+ msgstr ""
226
+
227
+ #: classes/class-cartflows-importer.php:826
228
+ msgid ""
229
+ "If you are seeing this message, most likely our servers are under routine "
230
+ "maintenance and we will be back shortly."
231
+ msgstr ""
232
+
233
+ #: classes/class-cartflows-importer.php:827
234
+ msgid ""
235
+ "In rare case, it is possible your website is having trouble connecting with "
236
+ "ours. If you need help, please feel free to get in touch with us from our "
237
+ "website.."
238
+ msgstr ""
239
+
240
+ #: classes/class-cartflows-importer.php:857
241
+ #. translators: %s: Plugin string
242
+ msgid ""
243
+ "%1$s to see CartFlows templates. If you prefer another page builder tool, "
244
+ "you can <a href=\"%2$s\" target=\"blank\">select it here</a>."
245
+ msgstr ""
246
+
247
+ #: classes/class-cartflows-importer.php:872
248
+ msgid "All"
249
+ msgstr ""
250
+
251
+ #: classes/class-cartflows-importer.php:875
252
+ msgid "Select Step Type"
253
+ msgstr ""
254
+
255
+ #: classes/class-cartflows-importer.php:959
256
+ msgid "Import from Cloud"
257
+ msgstr ""
258
+
259
+ #: classes/class-cartflows-importer.php:1264
260
+ msgid "Sales Landing"
261
+ msgstr ""
262
+
263
+ #: classes/class-cartflows-importer.php:1268
264
+ #: modules/flow/classes/class-cartflows-step-post-type.php:253
265
+ #: modules/flow/view/meta-flow-steps.php:12
266
+ msgid "Checkout (Woo)"
267
+ msgstr ""
268
+
269
+ #: classes/class-cartflows-importer.php:1272
270
+ #: modules/flow/classes/class-cartflows-step-post-type.php:260
271
+ #: modules/flow/view/meta-flow-steps.php:13
272
+ msgid "Thank You (Woo)"
273
+ msgstr ""
274
+
275
+ #: classes/class-cartflows-importer.php:1280
276
+ #: modules/flow/classes/class-cartflows-step-post-type.php:239
277
+ #: modules/flow/view/meta-flow-steps.php:11
278
+ msgid "Landing"
279
+ msgstr ""
280
+
281
+ #: classes/class-cartflows-importer.php:1284
282
+ msgid "Thank You"
283
+ msgstr ""
284
+
285
+ #: classes/class-cartflows-importer.php:1394
286
+ #. translators: %s: template ID
287
+ msgid "Invalid template id %1$s or post id %2$s."
288
+ msgstr ""
289
+
290
+ #: classes/class-cartflows-importer.php:1469
291
+ #. translators: %s: flow ID
292
+ msgid "Invalid flow id %1$s OR step type %2$s."
293
+ msgstr ""
294
+
295
+ #: classes/class-cartflows-importer.php:1594
296
+ msgid ""
297
+ "Elementor is not activated. Please activate plugin Elementor Page Builder "
298
+ "to import the step."
299
+ msgstr ""
300
+
301
+ #: classes/class-cartflows-importer.php:1697
302
+ msgid "Action failed. Invalid Security Nonce."
303
+ msgstr ""
304
+
305
+ #: classes/class-cartflows-importer.php:1704
306
+ msgid "User have not plugin install permissions."
307
+ msgstr ""
308
+
309
+ #: classes/class-cartflows-importer.php:1726
310
+ msgid "Plugin Successfully Activated"
311
+ msgstr ""
312
+
313
+ #: classes/class-cartflows-learndash-compatibility.php:86
314
+ msgid "None"
315
+ msgstr ""
316
+
317
+ #: classes/class-cartflows-learndash-compatibility.php:113
318
+ #. translators: 1: anchor start, 2: anchor close
319
+ msgid ""
320
+ "Non-enrolled students will redirect to the selected CartFlows template. If "
321
+ "you have not created any Flow already, add new Flow from %1$shere%2$s."
322
+ msgstr ""
323
+
324
+ #: classes/class-cartflows-learndash-compatibility.php:119
325
+ msgid "Select CartFlows Template for this Course"
326
+ msgstr ""
327
+
328
+ #: classes/class-cartflows-loader.php:222
329
+ #. translators: %s: html tags
330
+ msgid ""
331
+ "You are using an older version of %1$sCartFlows Pro%2$s. Please update "
332
+ "%1$sCartFlows Pro%2$s plugin to version %1$s%3$s%2$s or higher."
333
+ msgstr ""
334
+
335
+ #: classes/class-cartflows-loader.php:464
336
+ #. translators: %s: html tags
337
+ msgid ""
338
+ "This %1$sCartFlows%2$s page requires %1$sWooCommerce%2$s plugin installed & "
339
+ "activated."
340
+ msgstr ""
341
+
342
+ #: classes/class-cartflows-loader.php:474
343
+ msgid "Activate WooCommerce"
344
+ msgstr ""
345
+
346
+ #: classes/class-cartflows-loader.php:482
347
+ msgid "Install WooCommerce"
348
+ msgstr ""
349
+
350
+ #: classes/class-cartflows-logger.php:161
351
+ msgid "Action failed. Please refresh the page and retry."
352
+ msgstr ""
353
+
354
+ #: classes/class-cartflows-meta-fields.php:82
355
+ msgid "Thin 100"
356
+ msgstr ""
357
+
358
+ #: classes/class-cartflows-meta-fields.php:83
359
+ msgid "Extra-Light 200"
360
+ msgstr ""
361
+
362
+ #: classes/class-cartflows-meta-fields.php:84
363
+ msgid "Light 300"
364
+ msgstr ""
365
+
366
+ #: classes/class-cartflows-meta-fields.php:85
367
+ msgid "Normal 400"
368
+ msgstr ""
369
+
370
+ #: classes/class-cartflows-meta-fields.php:86
371
+ msgid "Medium 500"
372
+ msgstr ""
373
+
374
+ #: classes/class-cartflows-meta-fields.php:87
375
+ msgid "Semi-Bold 600"
376
+ msgstr ""
377
+
378
+ #: classes/class-cartflows-meta-fields.php:88
379
+ msgid "Bold 700"
380
+ msgstr ""
381
+
382
+ #: classes/class-cartflows-meta-fields.php:89
383
+ msgid "Extra-Bold 800"
384
+ msgstr ""
385
+
386
+ #: classes/class-cartflows-meta-fields.php:90
387
+ msgid "Ultra-Bold 900"
388
+ msgstr ""
389
+
390
+ #: classes/class-cartflows-meta-fields.php:642
391
+ #: includes/meta-fields/generate-product-repeater.php:30
392
+ msgid "Search for a product&hellip;"
393
+ msgstr ""
394
+
395
+ #: classes/class-cartflows-meta-fields.php:690
396
+ msgid "Search for a coupon&hellip;"
397
+ msgstr ""
398
+
399
+ #: classes/class-cartflows-meta.php:34
400
+ msgid "Update"
401
+ msgstr ""
402
+
403
+ #: classes/class-cartflows-meta.php:42
404
+ #: modules/flow/classes/class-cartflows-flow-meta.php:95
405
+ #: modules/flow/classes/class-cartflows-flow-meta.php:733
406
+ msgid "Back to edit Flow"
407
+ msgstr ""
408
+
409
+ #: classes/class-cartflows-meta.php:63
410
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:198
411
+ #: modules/landing/classes/class-cartflows-landing-meta.php:136
412
+ #: modules/optin/classes/class-cartflows-optin-meta.php:156
413
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:154
414
+ msgid "Custom Script"
415
+ msgstr ""
416
+
417
+ #: classes/class-cartflows-meta.php:66
418
+ msgid ""
419
+ "Custom script lets you add your own custom script on front end of this flow "
420
+ "page."
421
+ msgstr ""
422
+
423
+ #: classes/class-cartflows-metabox.php:59
424
+ msgid "Flow Details"
425
+ msgstr ""
426
+
427
+ #: classes/class-cartflows-wizard.php:83
428
+ msgid "Thanks for installing and using CartFlows!"
429
+ msgstr ""
430
+
431
+ #: classes/class-cartflows-wizard.php:84
432
+ msgid ""
433
+ "It is easy to use the CartFlows. Please use the setup wizard to quick start "
434
+ "setup."
435
+ msgstr ""
436
+
437
+ #: classes/class-cartflows-wizard.php:86
438
+ msgid "Start Wizard"
439
+ msgstr ""
440
+
441
+ #: classes/class-cartflows-wizard.php:87
442
+ msgid "Skip Setup"
443
+ msgstr ""
444
+
445
+ #: classes/class-cartflows-wizard.php:117
446
+ #: includes/admin/cartflows-general-bck.php:24
447
+ msgid "Welcome"
448
+ msgstr ""
449
+
450
+ #: classes/class-cartflows-wizard.php:122
451
+ msgid "Page Builder"
452
+ msgstr ""
453
+
454
+ #: classes/class-cartflows-wizard.php:126
455
+ msgid "Checkout"
456
+ msgstr ""
457
+
458
+ #: classes/class-cartflows-wizard.php:130
459
+ msgid "Training"
460
+ msgstr ""
461
+
462
+ #: classes/class-cartflows-wizard.php:134
463
+ msgid "Ready!"
464
+ msgstr ""
465
+
466
+ #: classes/class-cartflows-wizard.php:209
467
+ msgid "CartFlows Setup"
468
+ msgstr ""
469
+
470
+ #: classes/class-cartflows-wizard.php:235
471
+ msgid "Exit Setup Wizard"
472
+ msgstr ""
473
+
474
+ #: classes/class-cartflows-wizard.php:288
475
+ msgid "Welcome to CartFlows!"
476
+ msgstr ""
477
+
478
+ #: classes/class-cartflows-wizard.php:289
479
+ msgid ""
480
+ "Thank you for choosing CartFlows to get more leads, increase conversions, & "
481
+ "maximize profits. This short setup wizard will guide you though configuring "
482
+ "CartFlows and creating your first funnel."
483
+ msgstr ""
484
+
485
+ #: classes/class-cartflows-wizard.php:295
486
+ msgid "Lets Go »"
487
+ msgstr ""
488
+
489
+ #: classes/class-cartflows-wizard.php:322
490
+ msgid "Page Builder Setup"
491
+ msgstr ""
492
+
493
+ #: classes/class-cartflows-wizard.php:323
494
+ msgid "Please select a page builder you would like to use with CartFlows."
495
+ msgstr ""
496
+
497
+ #: classes/class-cartflows-wizard.php:328
498
+ msgid "Select Page Builder"
499
+ msgstr ""
500
+
501
+ #: classes/class-cartflows-wizard.php:335
502
+ #: includes/admin/cartflows-general.php:94
503
+ msgid "Elementor"
504
+ msgstr ""
505
+
506
+ #: classes/class-cartflows-wizard.php:345
507
+ msgid "Beaver Builder Plugin (Lite Version)"
508
+ msgstr ""
509
+
510
+ #: classes/class-cartflows-wizard.php:355
511
+ #: includes/admin/cartflows-general.php:96
512
+ msgid "Divi"
513
+ msgstr ""
514
+
515
+ #: classes/class-cartflows-wizard.php:365
516
+ #: includes/admin/cartflows-general.php:97
517
+ msgid "Gutenberg"
518
+ msgstr ""
519
+
520
+ #: classes/class-cartflows-wizard.php:375
521
+ #: includes/admin/cartflows-general.php:98
522
+ msgid "Other"
523
+ msgstr ""
524
+
525
+ #: classes/class-cartflows-wizard.php:397
526
+ msgid ""
527
+ "While CartFlows Should work with most page builders, we offer templates for "
528
+ "the above page builders."
529
+ msgstr ""
530
+
531
+ #: classes/class-cartflows-wizard.php:400
532
+ #: classes/class-cartflows-wizard.php:445
533
+ #: classes/class-cartflows-wizard.php:632
534
+ msgid "« Previous"
535
+ msgstr ""
536
+
537
+ #: classes/class-cartflows-wizard.php:403
538
+ msgid "Skip this step"
539
+ msgstr ""
540
+
541
+ #: classes/class-cartflows-wizard.php:404
542
+ msgid "Next »"
543
+ msgstr ""
544
+
545
+ #: classes/class-cartflows-wizard.php:423
546
+ msgid "Choose a checkout"
547
+ msgstr ""
548
+
549
+ #: classes/class-cartflows-wizard.php:426
550
+ msgid ""
551
+ "While CartFlows is designed to use WooCommerce sell digital and physical "
552
+ "products, not all funnels need a checkout system."
553
+ msgstr ""
554
+
555
+ #: classes/class-cartflows-wizard.php:428
556
+ msgid ""
557
+ "Would you like to install WooCommerce to sell digital and physical products "
558
+ "in your funnels?"
559
+ msgstr ""
560
+
561
+ #: classes/class-cartflows-wizard.php:435
562
+ msgid "The following plugin will be installed and activated for you:"
563
+ msgstr ""
564
+
565
+ #: classes/class-cartflows-wizard.php:436
566
+ msgid "WooCommerce"
567
+ msgstr ""
568
+
569
+ #: classes/class-cartflows-wizard.php:437
570
+ msgid "WooCommerce Cart Abandonment Recovery"
571
+ msgstr ""
572
+
573
+ #: classes/class-cartflows-wizard.php:448
574
+ #: classes/class-cartflows-wizard.php:635
575
+ msgid "No thanks"
576
+ msgstr ""
577
+
578
+ #: classes/class-cartflows-wizard.php:449
579
+ msgid "Yes"
580
+ msgstr ""
581
+
582
+ #: classes/class-cartflows-wizard.php:568
583
+ msgid "Congratulations, You Did It!"
584
+ msgstr ""
585
+
586
+ #: classes/class-cartflows-wizard.php:575
587
+ msgid ""
588
+ "CartFlows is ready to use on your website. You've successfully completed "
589
+ "the setup process and all that is left for you to do is create your first "
590
+ "flow."
591
+ msgstr ""
592
+
593
+ #: classes/class-cartflows-wizard.php:589
594
+ msgid "Create a flow"
595
+ msgstr ""
596
+
597
+ #: classes/class-cartflows-wizard.php:606
598
+ msgid "Exclusive CartFlows Training Course Offer"
599
+ msgstr ""
600
+
601
+ #: classes/class-cartflows-wizard.php:617
602
+ msgid ""
603
+ "We want you to get off to a great start using CartFlows, so we would like "
604
+ "to give access to our exclusive training course."
605
+ msgstr ""
606
+
607
+ #: classes/class-cartflows-wizard.php:618
608
+ msgid "Get access to this couse, for free, by entering your email below."
609
+ msgstr ""
610
+
611
+ #: classes/class-cartflows-wizard.php:620
612
+ msgid "Enter Email address"
613
+ msgstr ""
614
+
615
+ #: classes/class-cartflows-wizard.php:636
616
+ msgid "Allow"
617
+ msgstr ""
618
+
619
+ #: classes/logger/class-cartflows-log-handler-file.php:351
620
+ #: classes/logger/class-cartflows-log-handler-file.php:371
621
+ msgid "This method should not be called before plugins_loaded."
622
+ msgstr ""
623
+
624
+ #: classes/logger/class-cartflows-wc-logger.php:58
625
+ #. translators: 1: class name 2: Cartflows_Log_Handler_Interface
626
+ msgid "The provided handler %1$s does not implement %2$s."
627
+ msgstr ""
628
+
629
+ #: classes/logger/class-cartflows-wc-logger.php:136
630
+ #. translators: 1: Cartflows_WC_Logger::log 2: level
631
+ msgid "%1$s was called with an invalid level \"%2$s\"."
632
+ msgstr ""
633
+
634
+ #: includes/admin/cartflows-admin.php:19
635
+ #: includes/admin/cartflows-general.php:48
636
+ msgid "Modernizing WordPress eCommerce!"
637
+ msgstr ""
638
+
639
+ #: includes/admin/cartflows-admin.php:29
640
+ msgid "Settings saved successfully."
641
+ msgstr ""
642
+
643
+ #: includes/admin/cartflows-error-log.php:36
644
+ msgid "%1$s at %2$s"
645
+ msgstr ""
646
+
647
+ #: includes/admin/cartflows-error-log.php:41
648
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:225
649
+ #: modules/flow/view/meta-flow-steps.php:104
650
+ msgid "View"
651
+ msgstr ""
652
+
653
+ #: includes/admin/cartflows-error-log.php:65
654
+ msgid "Delete log"
655
+ msgstr ""
656
+
657
+ #: includes/admin/cartflows-error-log.php:70
658
+ msgid "There are currently no logs to view."
659
+ msgstr ""
660
+
661
+ #: includes/admin/cartflows-general-bck.php:10
662
+ msgid "Selec"
663
+ msgstr ""
664
+
665
+ #: includes/admin/cartflows-general-bck.php:22
666
+ msgid "General"
667
+ msgstr ""
668
+
669
+ #: includes/admin/cartflows-general.php:31
670
+ #: includes/admin/cartflows-general.php:58
671
+ msgid "General Settings"
672
+ msgstr ""
673
+
674
+ #: includes/admin/cartflows-general.php:40
675
+ msgid "Getting Started"
676
+ msgstr ""
677
+
678
+ #: includes/admin/cartflows-general.php:71
679
+ msgid "Disallow search engines from indexing flows"
680
+ msgstr ""
681
+
682
+ #: includes/admin/cartflows-general.php:81
683
+ #: modules/flow/view/meta-flow-steps.php:93
684
+ msgid "Global Checkout"
685
+ msgstr ""
686
+
687
+ #: includes/admin/cartflows-general.php:90
688
+ msgid "Show Templates designed with"
689
+ msgstr ""
690
+
691
+ #: includes/admin/cartflows-general.php:91
692
+ msgid ""
693
+ "CartFlows offers flow templates that can be imported in one click. These "
694
+ "templates are available in few different page builders. Please choose your "
695
+ "preferred page builder from the list so you will only see templates that "
696
+ "are made using that page builder.."
697
+ msgstr ""
698
+
699
+ #: includes/admin/cartflows-general.php:95
700
+ msgid "Beaver Builder"
701
+ msgstr ""
702
+
703
+ #: includes/admin/cartflows-general.php:107
704
+ #: includes/admin/cartflows-general.php:193
705
+ #: includes/admin/cartflows-general.php:299
706
+ #: includes/admin/cartflows-general.php:416
707
+ msgid "Save Changes"
708
+ msgstr ""
709
+
710
+ #: includes/admin/cartflows-general.php:119
711
+ msgid "Permalink Settings"
712
+ msgstr ""
713
+
714
+ #: includes/admin/cartflows-general.php:134
715
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:647
716
+ #: modules/optin/classes/class-cartflows-optin-meta.php:380
717
+ msgid "Default"
718
+ msgstr ""
719
+
720
+ #: includes/admin/cartflows-general.php:140
721
+ msgid "Flow and Step Slug"
722
+ msgstr ""
723
+
724
+ #: includes/admin/cartflows-general.php:146
725
+ msgid "Flow Slug"
726
+ msgstr ""
727
+
728
+ #: includes/admin/cartflows-general.php:152
729
+ msgid "Step Slug"
730
+ msgstr ""
731
+
732
+ #: includes/admin/cartflows-general.php:164
733
+ msgid "Post Type Permalink Base"
734
+ msgstr ""
735
+
736
+ #: includes/admin/cartflows-general.php:172
737
+ msgid "Step Base"
738
+ msgstr ""
739
+
740
+ #: includes/admin/cartflows-general.php:182
741
+ msgid "Flow Base"
742
+ msgstr ""
743
+
744
+ #: includes/admin/cartflows-general.php:194
745
+ msgid "Set Default"
746
+ msgstr ""
747
+
748
+ #: includes/admin/cartflows-general.php:208
749
+ msgid "Facebook Pixel Settings"
750
+ msgstr ""
751
+
752
+ #: includes/admin/cartflows-general.php:223
753
+ msgid "Enable Facebook Pixel Tracking"
754
+ msgstr ""
755
+
756
+ #: includes/admin/cartflows-general.php:236
757
+ msgid "Enable for the whole site"
758
+ msgstr ""
759
+
760
+ #: includes/admin/cartflows-general.php:244
761
+ #: includes/admin/cartflows-general.php:343
762
+ msgid "If this option is unchecked, it will only apply to CartFlows steps."
763
+ msgstr ""
764
+
765
+ #: includes/admin/cartflows-general.php:254
766
+ msgid "Enter Facebook pixel ID"
767
+ msgstr ""
768
+
769
+ #: includes/admin/cartflows-general.php:262
770
+ #: includes/admin/cartflows-general.php:361
771
+ msgid "Enable Events:"
772
+ msgstr ""
773
+
774
+ #: includes/admin/cartflows-general.php:271
775
+ msgid "Initiate Checkout"
776
+ msgstr ""
777
+
778
+ #: includes/admin/cartflows-general.php:280
779
+ #: includes/admin/cartflows-general.php:387
780
+ msgid "Add Payment Info"
781
+ msgstr ""
782
+
783
+ #: includes/admin/cartflows-general.php:289
784
+ msgid "Purchase Complete"
785
+ msgstr ""
786
+
787
+ #: includes/admin/cartflows-general.php:311
788
+ msgid "Google Analytics Settings"
789
+ msgstr ""
790
+
791
+ #: includes/admin/cartflows-general.php:322
792
+ msgid "Enable Google Analytics Tracking"
793
+ msgstr ""
794
+
795
+ #: includes/admin/cartflows-general.php:335
796
+ msgid "Enable for the whole website"
797
+ msgstr ""
798
+
799
+ #: includes/admin/cartflows-general.php:353
800
+ msgid "Google Analytics ID"
801
+ msgstr ""
802
+
803
+ #: includes/admin/cartflows-general.php:355
804
+ msgid ""
805
+ "Log into your <a href=\"https://analytics.google.com/\" "
806
+ "target=\"_blank\">google analytics account</a> to find your ID. eg: "
807
+ "UA-XXXXXX-X&period;"
808
+ msgstr ""
809
+
810
+ #: includes/admin/cartflows-general.php:369
811
+ msgid "Begin Checkout"
812
+ msgstr ""
813
+
814
+ #: includes/admin/cartflows-general.php:378
815
+ msgid "Add To Cart"
816
+ msgstr ""
817
+
818
+ #: includes/admin/cartflows-general.php:396
819
+ msgid "Purchase"
820
+ msgstr ""
821
+
822
+ #: includes/admin/cartflows-general.php:404
823
+ msgid ""
824
+ "Google Analytics not working correctly? <a "
825
+ "href=\"https://cartflows.com/docs/troubleshooting-google-analytics-tracking-"
826
+ "issues/\" > Click here </a> to know more. "
827
+ msgstr ""
828
+
829
+ #: includes/admin/cartflows-general.php:437
830
+ msgid "Knowledge Base"
831
+ msgstr ""
832
+
833
+ #: includes/admin/cartflows-general.php:441
834
+ msgid "Not sure how something works? Take a peek at the knowledge base and learn."
835
+ msgstr ""
836
+
837
+ #: includes/admin/cartflows-general.php:444
838
+ msgid "Visit Knowledge Base »"
839
+ msgstr ""
840
+
841
+ #: includes/admin/cartflows-general.php:452
842
+ msgid "Community"
843
+ msgstr ""
844
+
845
+ #: includes/admin/cartflows-general.php:456
846
+ msgid ""
847
+ "Join the community of super helpful CartFlows users. Say hello, ask "
848
+ "questions, give feedback and help each other!"
849
+ msgstr ""
850
+
851
+ #: includes/admin/cartflows-general.php:459
852
+ msgid "Join Our Facebook Group »"
853
+ msgstr ""
854
+
855
+ #: includes/admin/cartflows-general.php:467
856
+ msgid "Five Star Support"
857
+ msgstr ""
858
+
859
+ #: includes/admin/cartflows-general.php:471
860
+ msgid "Got a question? Get in touch with CartFlows developers. We're happy to help!"
861
+ msgstr ""
862
+
863
+ #: includes/admin/cartflows-general.php:474
864
+ msgid "Submit a Ticket »"
865
+ msgstr ""
866
+
867
+ #: includes/admin/cartflows-general.php:484
868
+ msgid "Load Minified CSS"
869
+ msgstr ""
870
+
871
+ #: includes/admin/cartflows-general.php:489
872
+ msgid ""
873
+ "Load the Minified CSS from here. Just Enable it by checking the below given "
874
+ "checkbox."
875
+ msgstr ""
876
+
877
+ #: includes/admin/cartflows-general.php:496
878
+ msgid "Load minified CSS & JS Files"
879
+ msgstr ""
880
+
881
+ #: includes/admin/cartflows-general.php:501
882
+ msgid "Save"
883
+ msgstr ""
884
+
885
+ #: includes/exporter.php:12
886
+ msgid "Export Flows to a JSON file"
887
+ msgstr ""
888
+
889
+ #: includes/exporter.php:13
890
+ msgid ""
891
+ "This tool allows you to generate and download a JSON file containing a list "
892
+ "of all flows."
893
+ msgstr ""
894
+
895
+ #: includes/importer.php:12
896
+ msgid "Import Flows to a JSON file"
897
+ msgstr ""
898
+
899
+ #: includes/importer.php:13
900
+ msgid "This tool allows you to import the flows from the JSON file."
901
+ msgstr ""
902
+
903
+ #: includes/importer.php:21
904
+ msgid "Import"
905
+ msgstr ""
906
+
907
+ #: includes/meta-fields/generate-product-repeater.php:36
908
+ msgid "Remove"
909
+ msgstr ""
910
+
911
+ #: includes/meta-fields/generate-product-repeater.php:51
912
+ msgid "Product Quantity"
913
+ msgstr ""
914
+
915
+ #: includes/meta-fields/generate-product-repeater.php:65
916
+ msgid "Discount Type"
917
+ msgstr ""
918
+
919
+ #: includes/meta-fields/generate-product-repeater.php:69
920
+ msgid "Select Discount Type"
921
+ msgstr ""
922
+
923
+ #: includes/meta-fields/generate-product-repeater.php:70
924
+ msgid "Original"
925
+ msgstr ""
926
+
927
+ #: includes/meta-fields/generate-product-repeater.php:71
928
+ msgid "Percentage"
929
+ msgstr ""
930
+
931
+ #: includes/meta-fields/generate-product-repeater.php:72
932
+ msgid "Price"
933
+ msgstr ""
934
+
935
+ #: includes/meta-fields/generate-product-repeater.php:83
936
+ msgid "Discount Value"
937
+ msgstr ""
938
+
939
+ #: includes/meta-fields/generate-product-repeater.php:85
940
+ msgid "Discount value will apply for each quantity of product."
941
+ msgstr ""
942
+
943
+ #: includes/meta-fields/get-product-selection-repeater.php:112
944
+ msgid "Add New Product"
945
+ msgstr ""
946
+
947
+ #: includes/meta-fields/get-product-selection-repeater.php:113
948
+ msgid "Create Product"
949
+ msgstr ""
950
+
951
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:256
952
+ #: modules/optin/classes/class-cartflows-optin-markup.php:146
953
+ #: modules/thankyou/classes/class-cartflows-thankyou-markup.php:90
954
+ msgid ""
955
+ "WooCommerce functions do not exist. If you are in an IFrame, please reload "
956
+ "it."
957
+ msgstr ""
958
+
959
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:257
960
+ #: modules/optin/classes/class-cartflows-optin-markup.php:147
961
+ #: modules/thankyou/classes/class-cartflows-thankyou-markup.php:91
962
+ msgid "Click Here to Reload"
963
+ msgstr ""
964
+
965
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:275
966
+ msgid "Checkout ID not found"
967
+ msgstr ""
968
+
969
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:338
970
+ #: modules/checkout/templates/embed/checkout-template-simple.php:25
971
+ #: modules/checkout/templates/wcf-template.php:36
972
+ #: modules/optin/templates/optin-template-simple.php:25
973
+ msgid "Your cart is currently empty."
974
+ msgstr ""
975
+
976
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:404
977
+ msgid ""
978
+ "No product is selected. Please select products from the checkout meta "
979
+ "settings to continue."
980
+ msgstr ""
981
+
982
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:493
983
+ msgid "Variations Not set"
984
+ msgstr ""
985
+
986
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:501
987
+ msgid "This product can't be purchased"
988
+ msgstr ""
989
+
990
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:946
991
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:989
992
+ msgid "Coupon Code"
993
+ msgstr ""
994
+
995
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:947
996
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:998
997
+ msgid "Apply"
998
+ msgstr ""
999
+
1000
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:1154
1001
+ msgid "Sorry there was a problem removing this coupon."
1002
+ msgstr ""
1003
+
1004
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:1157
1005
+ msgid "Coupon has been removed."
1006
+ msgstr ""
1007
+
1008
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:1176
1009
+ msgid "Sorry there was a problem removing "
1010
+ msgstr ""
1011
+
1012
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:1179
1013
+ msgid " has been removed."
1014
+ msgstr ""
1015
+
1016
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:65
1017
+ msgid "Checkout Layout"
1018
+ msgstr ""
1019
+
1020
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:150
1021
+ #: modules/landing/classes/class-cartflows-landing-meta.php:130
1022
+ #: modules/optin/classes/class-cartflows-optin-meta.php:126
1023
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:130
1024
+ msgid "Shortcodes"
1025
+ msgstr ""
1026
+
1027
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:156
1028
+ #: modules/optin/classes/class-cartflows-optin-meta.php:132
1029
+ msgid "Select Product"
1030
+ msgstr ""
1031
+
1032
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:162
1033
+ msgid "Product Options"
1034
+ msgstr ""
1035
+
1036
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:168
1037
+ msgid "Order Bump"
1038
+ msgstr ""
1039
+
1040
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:174
1041
+ msgid "Checkout Offer"
1042
+ msgstr ""
1043
+
1044
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:180
1045
+ msgid "Checkout Design"
1046
+ msgstr ""
1047
+
1048
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:186
1049
+ msgid "Checkout Fields"
1050
+ msgstr ""
1051
+
1052
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:192
1053
+ msgid "Checkout Settings"
1054
+ msgstr ""
1055
+
1056
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:209
1057
+ msgid "Logo (Optional)"
1058
+ msgstr ""
1059
+
1060
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:270
1061
+ #. translators: %s: link
1062
+ msgid "Upgrade to %1$sCartFlows Pro%2$s for Product Options feature."
1063
+ msgstr ""
1064
+
1065
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:281
1066
+ #. translators: %s: link.
1067
+ msgid "Update %1$sCartFlows Pro%2$s to %3$s or above for Product Options"
1068
+ msgstr ""
1069
+
1070
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:309
1071
+ msgid "Add this shortcode to your checkout page"
1072
+ msgstr ""
1073
+
1074
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:345
1075
+ #. translators: %s: link
1076
+ msgid "Upgrade to %1$sCartFlows Pro%2$s for Pre-applied Coupon."
1077
+ msgstr ""
1078
+
1079
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:372
1080
+ #. translators: %s: link
1081
+ msgid "Upgrade to %1$sCartFlows Pro%2$s for Checkout Offer feature"
1082
+ msgstr ""
1083
+
1084
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:382
1085
+ #. translators: %s: link
1086
+ msgid "Update to %1$sCartFlows Pro%2$s to %3$s or above for Checkout Offer feature"
1087
+ msgstr ""
1088
+
1089
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:409
1090
+ #. translators: %s: link
1091
+ msgid "Upgrade to %1$sCartFlows Pro%2$s for animate browser tab feature"
1092
+ msgstr ""
1093
+
1094
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:419
1095
+ #. translators: %s: link
1096
+ msgid ""
1097
+ "Update to %1$sCartFlows Pro%2$s to %3$s or above for animate browser tab "
1098
+ "feature"
1099
+ msgstr ""
1100
+
1101
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:442
1102
+ #. translators: %s: link
1103
+ msgid "Upgrade to %1$sCartFlows Pro%2$s for Order Bump feature."
1104
+ msgstr ""
1105
+
1106
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:469
1107
+ #: modules/optin/classes/class-cartflows-optin-meta.php:267
1108
+ #. translators: %s: link
1109
+ msgid "Upgrade to %1$sCartFlows Pro%2$s for Custom Fields feature."
1110
+ msgstr ""
1111
+
1112
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:492
1113
+ msgid "Place Order Button Text"
1114
+ msgstr ""
1115
+
1116
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:496
1117
+ msgid "Place order"
1118
+ msgstr ""
1119
+
1120
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:498
1121
+ msgid "It will change the Place Order Button text on checkout page."
1122
+ msgstr ""
1123
+
1124
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:508
1125
+ msgid "Enable cart editing on checkout"
1126
+ msgstr ""
1127
+
1128
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:516
1129
+ #. translators: %s: link
1130
+ msgid "Users will able to remove products from the checkout page."
1131
+ msgstr ""
1132
+
1133
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:546
1134
+ msgid "One Column (Available in CartFlows Pro) "
1135
+ msgstr ""
1136
+
1137
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:547
1138
+ msgid "Two Step (Available in CartFlows Pro) "
1139
+ msgstr ""
1140
+
1141
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:553
1142
+ msgid "Checkout Skin"
1143
+ msgstr ""
1144
+
1145
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:557
1146
+ msgid "One Column"
1147
+ msgstr ""
1148
+
1149
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:558
1150
+ msgid "Two Column"
1151
+ msgstr ""
1152
+
1153
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:559
1154
+ msgid "Two Step"
1155
+ msgstr ""
1156
+
1157
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:568
1158
+ #: modules/optin/classes/class-cartflows-optin-meta.php:343
1159
+ msgid "Primary Color"
1160
+ msgstr ""
1161
+
1162
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:577
1163
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:612
1164
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:658
1165
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:750
1166
+ #: modules/optin/classes/class-cartflows-optin-meta.php:352
1167
+ #: modules/optin/classes/class-cartflows-optin-meta.php:391
1168
+ #: modules/optin/classes/class-cartflows-optin-meta.php:503
1169
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:209
1170
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:240
1171
+ msgid "Font Family"
1172
+ msgstr ""
1173
+
1174
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:585
1175
+ msgid "Advance Options"
1176
+ msgstr ""
1177
+
1178
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:597
1179
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:225
1180
+ msgid "Heading"
1181
+ msgstr ""
1182
+
1183
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:603
1184
+ msgid "Heading Color"
1185
+ msgstr ""
1186
+
1187
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:621
1188
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:667
1189
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:759
1190
+ #: modules/optin/classes/class-cartflows-optin-meta.php:400
1191
+ #: modules/optin/classes/class-cartflows-optin-meta.php:512
1192
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:249
1193
+ msgid "Font Weight"
1194
+ msgstr ""
1195
+
1196
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:629
1197
+ #: modules/optin/classes/class-cartflows-optin-meta.php:363
1198
+ msgid "Input Fields"
1199
+ msgstr ""
1200
+
1201
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:637
1202
+ #: modules/optin/classes/class-cartflows-optin-meta.php:370
1203
+ msgid "Floating Labels (Available in CartFlows Pro)"
1204
+ msgstr ""
1205
+
1206
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:643
1207
+ #: modules/optin/classes/class-cartflows-optin-meta.php:376
1208
+ msgid "Style"
1209
+ msgstr ""
1210
+
1211
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:648
1212
+ #: modules/optin/classes/class-cartflows-optin-meta.php:381
1213
+ msgid "Floating Labels"
1214
+ msgstr ""
1215
+
1216
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:675
1217
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:767
1218
+ #: modules/optin/classes/class-cartflows-optin-meta.php:408
1219
+ #: modules/optin/classes/class-cartflows-optin-meta.php:520
1220
+ msgid "Size"
1221
+ msgstr ""
1222
+
1223
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:679
1224
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:771
1225
+ #: modules/optin/classes/class-cartflows-optin-meta.php:412
1226
+ #: modules/optin/classes/class-cartflows-optin-meta.php:524
1227
+ msgid "Extra Small"
1228
+ msgstr ""
1229
+
1230
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:680
1231
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:772
1232
+ #: modules/optin/classes/class-cartflows-optin-meta.php:413
1233
+ #: modules/optin/classes/class-cartflows-optin-meta.php:525
1234
+ msgid "Small"
1235
+ msgstr ""
1236
+
1237
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:681
1238
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:773
1239
+ #: modules/optin/classes/class-cartflows-optin-meta.php:414
1240
+ #: modules/optin/classes/class-cartflows-optin-meta.php:526
1241
+ msgid "Medium"
1242
+ msgstr ""
1243
+
1244
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:682
1245
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:774
1246
+ #: modules/optin/classes/class-cartflows-optin-meta.php:415
1247
+ #: modules/optin/classes/class-cartflows-optin-meta.php:527
1248
+ msgid "Large"
1249
+ msgstr ""
1250
+
1251
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:683
1252
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:775
1253
+ #: modules/optin/classes/class-cartflows-optin-meta.php:416
1254
+ #: modules/optin/classes/class-cartflows-optin-meta.php:528
1255
+ msgid "Extra Large"
1256
+ msgstr ""
1257
+
1258
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:684
1259
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:776
1260
+ #: modules/optin/classes/class-cartflows-optin-meta.php:417
1261
+ #: modules/optin/classes/class-cartflows-optin-meta.php:529
1262
+ msgid "Custom"
1263
+ msgstr ""
1264
+
1265
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:691
1266
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:783
1267
+ #: modules/optin/classes/class-cartflows-optin-meta.php:424
1268
+ #: modules/optin/classes/class-cartflows-optin-meta.php:536
1269
+ msgid "Top Bottom Spacing"
1270
+ msgstr ""
1271
+
1272
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:699
1273
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:791
1274
+ #: modules/optin/classes/class-cartflows-optin-meta.php:432
1275
+ #: modules/optin/classes/class-cartflows-optin-meta.php:544
1276
+ msgid "Left Right Spacing"
1277
+ msgstr ""
1278
+
1279
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:707
1280
+ #: modules/optin/classes/class-cartflows-optin-meta.php:448
1281
+ msgid "Text / Placeholder Color"
1282
+ msgstr ""
1283
+
1284
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:715
1285
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:815
1286
+ #: modules/optin/classes/class-cartflows-optin-meta.php:456
1287
+ #: modules/optin/classes/class-cartflows-optin-meta.php:581
1288
+ msgid "Background Color"
1289
+ msgstr ""
1290
+
1291
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:723
1292
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:831
1293
+ #: modules/optin/classes/class-cartflows-optin-meta.php:464
1294
+ #: modules/optin/classes/class-cartflows-optin-meta.php:597
1295
+ msgid "Border Color"
1296
+ msgstr ""
1297
+
1298
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:730
1299
+ #: modules/optin/classes/class-cartflows-optin-meta.php:440
1300
+ msgid "Label Color"
1301
+ msgstr ""
1302
+
1303
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:743
1304
+ msgid "Buttons"
1305
+ msgstr ""
1306
+
1307
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:799
1308
+ #: modules/optin/classes/class-cartflows-optin-meta.php:565
1309
+ msgid "Text Color"
1310
+ msgstr ""
1311
+
1312
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:807
1313
+ #: modules/optin/classes/class-cartflows-optin-meta.php:573
1314
+ msgid "Text Hover Color"
1315
+ msgstr ""
1316
+
1317
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:823
1318
+ #: modules/optin/classes/class-cartflows-optin-meta.php:589
1319
+ msgid "Background Hover Color"
1320
+ msgstr ""
1321
+
1322
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:839
1323
+ #: modules/optin/classes/class-cartflows-optin-meta.php:605
1324
+ msgid "Border Hover Color"
1325
+ msgstr ""
1326
+
1327
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:852
1328
+ msgid "Sections"
1329
+ msgstr ""
1330
+
1331
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:858
1332
+ msgid "Highlight Area Background Color"
1333
+ msgstr ""
1334
+
1335
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:897
1336
+ msgid "Header Logo"
1337
+ msgstr ""
1338
+
1339
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:905
1340
+ msgid "Logo Width (In px)"
1341
+ msgstr ""
1342
+
1343
+ #: modules/checkout/templates/wcf-template.php:46
1344
+ msgid "Copyright &copy;"
1345
+ msgstr ""
1346
+
1347
+ #: modules/checkout/templates/wcf-template.php:50
1348
+ msgid "All Rights Reserved"
1349
+ msgstr ""
1350
+
1351
+ #: modules/flow/classes/class-cartflows-flow-meta.php:263
1352
+ #. translators: %s flow id
1353
+ msgid "Step not deleted for flow - %s"
1354
+ msgstr ""
1355
+
1356
+ #: modules/flow/classes/class-cartflows-flow-meta.php:294
1357
+ #. translators: %s flow id
1358
+ msgid "Step deleted for flow - %s"
1359
+ msgstr ""
1360
+
1361
+ #: modules/flow/classes/class-cartflows-flow-meta.php:322
1362
+ #. translators: %s flow id
1363
+ msgid "Steps not sorted for flow - %s"
1364
+ msgstr ""
1365
+
1366
+ #: modules/flow/classes/class-cartflows-flow-meta.php:345
1367
+ #. translators: %s flow id
1368
+ msgid "Steps sorted for flow - %s"
1369
+ msgstr ""
1370
+
1371
+ #: modules/flow/classes/class-cartflows-flow-meta.php:456
1372
+ msgid "Analytics"
1373
+ msgstr ""
1374
+
1375
+ #: modules/flow/classes/class-cartflows-flow-meta.php:473
1376
+ #. translators: %s: link
1377
+ msgid "Upgrade to %1$sCartFlows Pro%2$s for Analytics feature"
1378
+ msgstr ""
1379
+
1380
+ #: modules/flow/classes/class-cartflows-flow-meta.php:491
1381
+ msgid "Flow Settings"
1382
+ msgstr ""
1383
+
1384
+ #: modules/flow/classes/class-cartflows-flow-meta.php:576
1385
+ msgid "Enable Test Mode"
1386
+ msgstr ""
1387
+
1388
+ #: modules/flow/classes/class-cartflows-flow-meta.php:583
1389
+ msgid ""
1390
+ "If you are using WooCommerce plugin then test mode will add random products "
1391
+ "in your flow, so you can preview it easily while testing."
1392
+ msgstr ""
1393
+
1394
+ #: modules/flow/classes/class-cartflows-flow-meta.php:702
1395
+ #: modules/flow/view/meta-flow-steps.php:133
1396
+ msgid "Add New Step"
1397
+ msgstr ""
1398
+
1399
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:69
1400
+ msgid "Flow: "
1401
+ msgstr ""
1402
+
1403
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:69
1404
+ msgid "Name: "
1405
+ msgstr ""
1406
+
1407
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:101
1408
+ msgid "Search Flows"
1409
+ msgstr ""
1410
+
1411
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:102
1412
+ msgid "All Flows"
1413
+ msgstr ""
1414
+
1415
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:103
1416
+ msgid "Edit Flow"
1417
+ msgstr ""
1418
+
1419
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:104
1420
+ msgid "View Flow"
1421
+ msgstr ""
1422
+
1423
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:105
1424
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:107
1425
+ #: modules/flow/classes/class-cartflows-step-post-type.php:167
1426
+ #: modules/flow/classes/class-cartflows-step-post-type.php:169
1427
+ msgid "Add New"
1428
+ msgstr ""
1429
+
1430
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:106
1431
+ msgid "Update Flow"
1432
+ msgstr ""
1433
+
1434
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:108
1435
+ msgid "New Flow Name"
1436
+ msgstr ""
1437
+
1438
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:190
1439
+ msgid "Upgrade to CartFlows Pro"
1440
+ msgstr ""
1441
+
1442
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:209
1443
+ msgid "Slug"
1444
+ msgstr ""
1445
+
1446
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:332
1447
+ msgid "Flows"
1448
+ msgstr ""
1449
+
1450
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:354
1451
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:360
1452
+ #: modules/flow/classes/class-cartflows-step-post-type.php:397
1453
+ #: modules/flow/classes/class-cartflows-step-post-type.php:403
1454
+ #. translators: %s: singular custom post type name
1455
+ msgid "%s updated."
1456
+ msgstr ""
1457
+
1458
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:356
1459
+ #: modules/flow/classes/class-cartflows-step-post-type.php:399
1460
+ #. translators: %s: singular custom post type name
1461
+ msgid "Custom %s updated."
1462
+ msgstr ""
1463
+
1464
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:358
1465
+ #: modules/flow/classes/class-cartflows-step-post-type.php:401
1466
+ #. translators: %s: singular custom post type name
1467
+ msgid "Custom %s deleted."
1468
+ msgstr ""
1469
+
1470
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:362
1471
+ #: modules/flow/classes/class-cartflows-step-post-type.php:405
1472
+ #. translators: %1$s: singular custom post type name ,%2$s: date and time of
1473
+ #. the revision
1474
+ msgid "%1$s restored to revision from %2$s"
1475
+ msgstr ""
1476
+
1477
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:364
1478
+ #: modules/flow/classes/class-cartflows-step-post-type.php:407
1479
+ #. translators: %s: singular custom post type name
1480
+ msgid "%s published."
1481
+ msgstr ""
1482
+
1483
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:366
1484
+ #: modules/flow/classes/class-cartflows-step-post-type.php:409
1485
+ #. translators: %s: singular custom post type name
1486
+ msgid "%s saved."
1487
+ msgstr ""
1488
+
1489
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:368
1490
+ #: modules/flow/classes/class-cartflows-step-post-type.php:411
1491
+ #. translators: %s: singular custom post type name
1492
+ msgid "%s submitted."
1493
+ msgstr ""
1494
+
1495
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:370
1496
+ #: modules/flow/classes/class-cartflows-step-post-type.php:413
1497
+ #. translators: %s: singular custom post type name
1498
+ msgid "%s scheduled for."
1499
+ msgstr ""
1500
+
1501
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:372
1502
+ #: modules/flow/classes/class-cartflows-step-post-type.php:415
1503
+ #. translators: %s: singular custom post type name
1504
+ msgid "%s draft updated."
1505
+ msgstr ""
1506
+
1507
+ #: modules/flow/classes/class-cartflows-flow-shortcodes.php:148
1508
+ #: modules/widgets/class-cartflows-next-step.php:78
1509
+ msgid "Next Step"
1510
+ msgstr ""
1511
+
1512
+ #: modules/flow/classes/class-cartflows-step-post-type.php:163
1513
+ msgid "Search Steps"
1514
+ msgstr ""
1515
+
1516
+ #: modules/flow/classes/class-cartflows-step-post-type.php:164
1517
+ msgid "All Steps"
1518
+ msgstr ""
1519
+
1520
+ #: modules/flow/classes/class-cartflows-step-post-type.php:165
1521
+ #: modules/flow/view/meta-flow-steps.php:106
1522
+ msgid "Edit Step"
1523
+ msgstr ""
1524
+
1525
+ #: modules/flow/classes/class-cartflows-step-post-type.php:166
1526
+ #: modules/flow/view/meta-flow-steps.php:102
1527
+ msgid "View Step"
1528
+ msgstr ""
1529
+
1530
+ #: modules/flow/classes/class-cartflows-step-post-type.php:168
1531
+ msgid "Update Step"
1532
+ msgstr ""
1533
+
1534
+ #: modules/flow/classes/class-cartflows-step-post-type.php:170
1535
+ msgid "New Step Name"
1536
+ msgstr ""
1537
+
1538
+ #: modules/flow/classes/class-cartflows-step-post-type.php:211
1539
+ msgid "Step Type"
1540
+ msgstr ""
1541
+
1542
+ #: modules/flow/classes/class-cartflows-step-post-type.php:221
1543
+ msgid "Step Flow"
1544
+ msgstr ""
1545
+
1546
+ #: modules/flow/classes/class-cartflows-step-post-type.php:246
1547
+ #: modules/flow/view/meta-flow-steps.php:16
1548
+ msgid "Optin (Woo)"
1549
+ msgstr ""
1550
+
1551
+ #: modules/flow/classes/class-cartflows-step-post-type.php:267
1552
+ #: modules/flow/view/meta-flow-steps.php:14
1553
+ msgid "Upsell (Woo)"
1554
+ msgstr ""
1555
+
1556
+ #: modules/flow/classes/class-cartflows-step-post-type.php:274
1557
+ #: modules/flow/view/meta-flow-steps.php:15
1558
+ msgid "Downsell (Woo)"
1559
+ msgstr ""
1560
+
1561
+ #: modules/flow/view/meta-flow-steps.php:85
1562
+ msgid "No Product Assigned"
1563
+ msgstr ""
1564
+
1565
+ #: modules/flow/view/meta-flow-steps.php:89
1566
+ msgid "Global Checkout - Remove selected checkout product"
1567
+ msgstr ""
1568
+
1569
+ #: modules/flow/view/meta-flow-steps.php:108
1570
+ msgid "Edit"
1571
+ msgstr ""
1572
+
1573
+ #: modules/flow/view/meta-flow-steps.php:113
1574
+ msgid "Clone Step"
1575
+ msgstr ""
1576
+
1577
+ #: modules/flow/view/meta-flow-steps.php:118
1578
+ msgid "Delete Step"
1579
+ msgstr ""
1580
+
1581
+ #: modules/flow/view/meta-flow-steps.php:120
1582
+ msgid "Delete"
1583
+ msgstr ""
1584
+
1585
+ #: modules/flow/view/meta-flow-steps.php:149
1586
+ msgid "Steps Library"
1587
+ msgstr ""
1588
+
1589
+ #: modules/flow/view/meta-flow-steps.php:198
1590
+ msgid "Create Step"
1591
+ msgstr ""
1592
+
1593
+ #: modules/flow/view/meta-flow-steps.php:200
1594
+ msgid "You need a Cartflows Pro version to import Upsell / Downsell"
1595
+ msgstr ""
1596
+
1597
+ #: modules/landing/classes/class-cartflows-landing-meta.php:66
1598
+ msgid "Landing Page Settings"
1599
+ msgstr ""
1600
+
1601
+ #: modules/landing/classes/class-cartflows-landing-meta.php:169
1602
+ msgid "Next Step Link"
1603
+ msgstr ""
1604
+
1605
+ #: modules/optin/classes/class-cartflows-optin-markup.php:165
1606
+ msgid "Please place shortcode on Optin step-type only."
1607
+ msgstr ""
1608
+
1609
+ #: modules/optin/classes/class-cartflows-optin-markup.php:225
1610
+ msgid ""
1611
+ "No product is selected. Please select a Simple, Virtual and Free product "
1612
+ "from the meta settings."
1613
+ msgstr ""
1614
+
1615
+ #: modules/optin/classes/class-cartflows-optin-markup.php:242
1616
+ msgid "Please update the selected product's price to zero (0)."
1617
+ msgstr ""
1618
+
1619
+ #: modules/optin/classes/class-cartflows-optin-markup.php:251
1620
+ #: modules/optin/classes/class-cartflows-optin-markup.php:255
1621
+ msgid "Please select a Simple, Virtual and Free product."
1622
+ msgstr ""
1623
+
1624
+ #: modules/optin/classes/class-cartflows-optin-meta.php:65
1625
+ msgid "Optin Settings"
1626
+ msgstr ""
1627
+
1628
+ #: modules/optin/classes/class-cartflows-optin-meta.php:138
1629
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:136
1630
+ msgid "Design"
1631
+ msgstr ""
1632
+
1633
+ #: modules/optin/classes/class-cartflows-optin-meta.php:144
1634
+ msgid "Form Fields"
1635
+ msgstr ""
1636
+
1637
+ #: modules/optin/classes/class-cartflows-optin-meta.php:213
1638
+ msgid "Add this shortcode to your optin page"
1639
+ msgstr ""
1640
+
1641
+ #: modules/optin/classes/class-cartflows-optin-meta.php:238
1642
+ msgid "Select Free Product"
1643
+ msgstr ""
1644
+
1645
+ #: modules/optin/classes/class-cartflows-optin-meta.php:239
1646
+ msgid "Select Free and Virtual product only."
1647
+ msgstr ""
1648
+
1649
+ #: modules/optin/classes/class-cartflows-optin-meta.php:290
1650
+ msgid "Pass Fields as URL Parameters"
1651
+ msgstr ""
1652
+
1653
+ #: modules/optin/classes/class-cartflows-optin-meta.php:293
1654
+ msgid "Enable"
1655
+ msgstr ""
1656
+
1657
+ #: modules/optin/classes/class-cartflows-optin-meta.php:294
1658
+ msgid ""
1659
+ "You can pass specific fields from the form to next step as URL query "
1660
+ "parameters."
1661
+ msgstr ""
1662
+
1663
+ #: modules/optin/classes/class-cartflows-optin-meta.php:305
1664
+ msgid "Enter form field"
1665
+ msgstr ""
1666
+
1667
+ #: modules/optin/classes/class-cartflows-optin-meta.php:308
1668
+ #: modules/optin/classes/class-cartflows-optin-meta.php:318
1669
+ msgid "Enter comma seprated field name. E.g. first_name, last_name"
1670
+ msgstr ""
1671
+
1672
+ #: modules/optin/classes/class-cartflows-optin-meta.php:310
1673
+ msgid "Fields to pass, separated by commas"
1674
+ msgstr ""
1675
+
1676
+ #: modules/optin/classes/class-cartflows-optin-meta.php:320
1677
+ #. translators: %s: link
1678
+ msgid ""
1679
+ "You can pass field value as a URL parameter to the next step. %1$sClick "
1680
+ "here%2$s for more information."
1681
+ msgstr ""
1682
+
1683
+ #: modules/optin/classes/class-cartflows-optin-meta.php:477
1684
+ msgid "Submit Button"
1685
+ msgstr ""
1686
+
1687
+ #: modules/optin/classes/class-cartflows-optin-meta.php:483
1688
+ msgid "Button Text"
1689
+ msgstr ""
1690
+
1691
+ #: modules/optin/classes/class-cartflows-optin-meta.php:494
1692
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:217
1693
+ msgid "Font Size"
1694
+ msgstr ""
1695
+
1696
+ #: modules/optin/classes/class-cartflows-optin-meta.php:552
1697
+ msgid "Position"
1698
+ msgstr ""
1699
+
1700
+ #: modules/optin/classes/class-cartflows-optin-meta.php:556
1701
+ msgid "Left"
1702
+ msgstr ""
1703
+
1704
+ #: modules/optin/classes/class-cartflows-optin-meta.php:557
1705
+ msgid "Center"
1706
+ msgstr ""
1707
+
1708
+ #: modules/optin/classes/class-cartflows-optin-meta.php:558
1709
+ msgid "Right"
1710
+ msgstr ""
1711
+
1712
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:65
1713
+ msgid "Thank You Page Settings"
1714
+ msgstr ""
1715
+
1716
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:142
1717
+ msgid "Edit Fields"
1718
+ msgstr ""
1719
+
1720
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:182
1721
+ msgid "Order Details"
1722
+ msgstr ""
1723
+
1724
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:194
1725
+ msgid "Text"
1726
+ msgstr ""
1727
+
1728
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:200
1729
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:231
1730
+ msgid "Color"
1731
+ msgstr ""
1732
+
1733
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:257
1734
+ msgid "Advanced Options"
1735
+ msgstr ""
1736
+
1737
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:267
1738
+ msgid "Container Width (In px)"
1739
+ msgstr ""
1740
+
1741
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:275
1742
+ msgid "Section Background Color"
1743
+ msgstr ""
1744
+
1745
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:289
1746
+ msgid "Enable Order Overview "
1747
+ msgstr ""
1748
+
1749
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:297
1750
+ msgid "Enable Order Details "
1751
+ msgstr ""
1752
+
1753
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:305
1754
+ msgid "Enable Billing Details "
1755
+ msgstr ""
1756
+
1757
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:313
1758
+ msgid "Enable Shipping Details "
1759
+ msgstr ""
1760
+
1761
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:329
1762
+ msgid "Thank You Page Text"
1763
+ msgstr ""
1764
+
1765
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:333
1766
+ #: woocommerce/template/checkout/thankyou.php:41
1767
+ #: woocommerce/template/checkout/thankyou.php:83
1768
+ msgid "Thank you. Your order has been received."
1769
+ msgstr ""
1770
+
1771
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:335
1772
+ msgid "It will change the default text on thank you page."
1773
+ msgstr ""
1774
+
1775
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:343
1776
+ msgid "Redirect After Purchase"
1777
+ msgstr ""
1778
+
1779
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:352
1780
+ msgid "Redirect Link"
1781
+ msgstr ""
1782
+
1783
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:356
1784
+ msgid "https://"
1785
+ msgstr ""
1786
+
1787
+ #: modules/widgets/class-cartflows-next-step.php:24
1788
+ msgid "CartFlows Next Step"
1789
+ msgstr ""
1790
+
1791
+ #: modules/widgets/class-cartflows-next-step.php:26
1792
+ msgid "Next Step Widgets"
1793
+ msgstr ""
1794
+
1795
+ #: modules/widgets/class-cartflows-next-step.php:106
1796
+ msgid "New title"
1797
+ msgstr ""
1798
+
1799
+ #: modules/widgets/class-cartflows-next-step.php:123
1800
+ msgid "Title:"
1801
+ msgstr ""
1802
+
1803
+ #: modules/widgets/class-cartflows-next-step.php:127
1804
+ msgid "Flow ID:"
1805
+ msgstr ""
1806
+
1807
+ #: modules/widgets/class-cartflows-next-step.php:131
1808
+ msgid "Step ID:"
1809
+ msgstr ""
1810
+
1811
+ #: woocommerce/template/cart/cart-shipping.php:51
1812
+ #. Translators: $s shipping destination.
1813
+ msgid "Estimate for %s."
1814
+ msgstr ""
1815
+
1816
+ #: woocommerce/template/cart/cart-shipping.php:52
1817
+ msgid "Change address"
1818
+ msgstr ""
1819
+
1820
+ #: woocommerce/template/cart/cart-shipping.php:54
1821
+ msgid "This is only an estimate. Prices will be updated during checkout."
1822
+ msgstr ""
1823
+
1824
+ #: woocommerce/template/cart/cart-shipping.php:61
1825
+ msgid "Enter your address to view shipping options."
1826
+ msgstr ""
1827
+
1828
+ #: woocommerce/template/cart/cart-shipping.php:63
1829
+ msgid ""
1830
+ "There are no shipping methods available. Please ensure that your address "
1831
+ "has been entered correctly, or contact us if you need any help."
1832
+ msgstr ""
1833
+
1834
+ #: woocommerce/template/cart/cart-shipping.php:66
1835
+ #. Translators: $s shipping destination.
1836
+ msgid "No shipping options were found for %s."
1837
+ msgstr ""
1838
+
1839
+ #: woocommerce/template/cart/cart-shipping.php:67
1840
+ msgid "Enter a different address"
1841
+ msgstr ""
1842
+
1843
+ #: woocommerce/template/checkout/form-billing.php:27
1844
+ msgid "Billing &amp; Shipping"
1845
+ msgstr ""
1846
+
1847
+ #: woocommerce/template/checkout/form-billing.php:31
1848
+ msgid "Billing details"
1849
+ msgstr ""
1850
+
1851
+ #: woocommerce/template/checkout/form-billing.php:59
1852
+ msgid "Create an account?"
1853
+ msgstr ""
1854
+
1855
+ #: woocommerce/template/checkout/form-checkout.php:26
1856
+ msgid "You must be logged in to checkout."
1857
+ msgstr ""
1858
+
1859
+ #: woocommerce/template/checkout/form-checkout.php:52
1860
+ msgid "Your order"
1861
+ msgstr ""
1862
+
1863
+ #: woocommerce/template/checkout/form-coupon.php:26
1864
+ msgid "Have a coupon?"
1865
+ msgstr ""
1866
+
1867
+ #: woocommerce/template/checkout/form-coupon.php:26
1868
+ msgid "Click here to enter your code"
1869
+ msgstr ""
1870
+
1871
+ #: woocommerce/template/checkout/form-coupon.php:31
1872
+ msgid "If you have a coupon code, please apply it below."
1873
+ msgstr ""
1874
+
1875
+ #: woocommerce/template/checkout/form-coupon.php:34
1876
+ msgid "Coupon code"
1877
+ msgstr ""
1878
+
1879
+ #: woocommerce/template/checkout/form-coupon.php:38
1880
+ msgid "Apply coupon"
1881
+ msgstr ""
1882
+
1883
+ #: woocommerce/template/checkout/form-login.php:26
1884
+ msgid "Returning customer?"
1885
+ msgstr ""
1886
+
1887
+ #: woocommerce/template/checkout/form-login.php:26
1888
+ msgid "Click here to login"
1889
+ msgstr ""
1890
+
1891
+ #: woocommerce/template/checkout/form-login.php:32
1892
+ msgid ""
1893
+ "If you have shopped with us before, please enter your details below. If you "
1894
+ "are a new customer, please proceed to the Billing &amp; Shipping section."
1895
+ msgstr ""
1896
+
1897
+ #: woocommerce/template/checkout/form-shipping.php:26
1898
+ msgid "Ship to a different address?"
1899
+ msgstr ""
1900
+
1901
+ #: woocommerce/template/checkout/form-shipping.php:57
1902
+ msgid "Additional information"
1903
+ msgstr ""
1904
+
1905
+ #: woocommerce/template/checkout/payment.php:33
1906
+ msgid ""
1907
+ "Sorry, it seems that there are no available payment methods for your state. "
1908
+ "Please contact us if you require assistance or wish to make alternate "
1909
+ "arrangements."
1910
+ msgstr ""
1911
+
1912
+ #: woocommerce/template/checkout/payment.php:33
1913
+ msgid "Please fill in your details above to see available payment methods."
1914
+ msgstr ""
1915
+
1916
+ #: woocommerce/template/checkout/payment.php:42
1917
+ #. translators: $1 and $2 opening and closing emphasis tags respectively
1918
+ msgid ""
1919
+ "Since your browser does not support JavaScript, or it is disabled, please "
1920
+ "ensure you click the %1$sUpdate Totals%2$s button before placing your "
1921
+ "order. You may be charged more than the amount stated above if you fail to "
1922
+ "do so."
1923
+ msgstr ""
1924
+
1925
+ #: woocommerce/template/checkout/payment.php:44
1926
+ msgid "Update totals"
1927
+ msgstr ""
1928
+
1929
+ #: woocommerce/template/checkout/review-order.php:26
1930
+ #: woocommerce/template/order/order-details.php:51
1931
+ msgid "Product"
1932
+ msgstr ""
1933
+
1934
+ #: woocommerce/template/checkout/review-order.php:27
1935
+ #: woocommerce/template/checkout/review-order.php:107
1936
+ #: woocommerce/template/order/order-details.php:52
1937
+ msgid "Total"
1938
+ msgstr ""
1939
+
1940
+ #: woocommerce/template/checkout/review-order.php:60
1941
+ msgid "Subtotal"
1942
+ msgstr ""
1943
+
1944
+ #: woocommerce/template/checkout/thankyou.php:30
1945
+ msgid ""
1946
+ "Unfortunately your order cannot be processed as the originating "
1947
+ "bank/merchant has declined your transaction. Please attempt your purchase "
1948
+ "again."
1949
+ msgstr ""
1950
+
1951
+ #: woocommerce/template/checkout/thankyou.php:33
1952
+ msgid "Pay"
1953
+ msgstr ""
1954
+
1955
+ #: woocommerce/template/checkout/thankyou.php:35
1956
+ msgid "My account"
1957
+ msgstr ""
1958
+
1959
+ #: woocommerce/template/checkout/thankyou.php:46
1960
+ msgid "Order number:"
1961
+ msgstr ""
1962
+
1963
+ #: woocommerce/template/checkout/thankyou.php:51
1964
+ msgid "Date:"
1965
+ msgstr ""
1966
+
1967
+ #: woocommerce/template/checkout/thankyou.php:57
1968
+ msgid "Email:"
1969
+ msgstr ""
1970
+
1971
+ #: woocommerce/template/checkout/thankyou.php:63
1972
+ msgid "Total:"
1973
+ msgstr ""
1974
+
1975
+ #: woocommerce/template/checkout/thankyou.php:69
1976
+ msgid "Payment method:"
1977
+ msgstr ""
1978
+
1979
+ #: woocommerce/template/global/form-login.php:34
1980
+ msgid "Username or email"
1981
+ msgstr ""
1982
+
1983
+ #: woocommerce/template/global/form-login.php:38
1984
+ msgid "Password"
1985
+ msgstr ""
1986
+
1987
+ #: woocommerce/template/global/form-login.php:48
1988
+ msgid "Login"
1989
+ msgstr ""
1990
+
1991
+ #: woocommerce/template/global/form-login.php:53
1992
+ msgid "Remember me"
1993
+ msgstr ""
1994
+
1995
+ #: woocommerce/template/global/form-login.php:57
1996
+ msgid "Lost your password?"
1997
+ msgstr ""
1998
+
1999
+ #: woocommerce/template/order/order-details.php:45
2000
+ msgid "Order details"
2001
+ msgstr ""
2002
+
2003
+ #: woocommerce/template/order/order-details.php:93
2004
+ msgid "Note:"
2005
+ msgstr ""
2006
+
2007
+ #. Plugin Name of the plugin/theme
2008
+ msgid "CartFlows"
2009
+ msgstr ""
2010
+
2011
+ #. Author URI of the plugin/theme
2012
+ msgid "https://cartflows.com/"
2013
+ msgstr ""
2014
+
2015
+ #. Description of the plugin/theme
2016
+ msgid "Create beautiful checkout pages & sales flows for WooCommerce."
2017
+ msgstr ""
2018
+
2019
+ #. Author of the plugin/theme
2020
+ msgid "CartFlows Inc"
2021
+ msgstr ""
2022
+
2023
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:99
2024
+ msgctxt "flow general name"
2025
+ msgid "Flows"
2026
+ msgstr ""
2027
+
2028
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:100
2029
+ msgctxt "flow singular name"
2030
+ msgid "Flow"
2031
+ msgstr ""
2032
+
2033
+ #: modules/flow/classes/class-cartflows-step-post-type.php:161
2034
+ msgctxt "flow step general name"
2035
+ msgid "Steps"
2036
+ msgstr ""
2037
+
2038
+ #: modules/flow/classes/class-cartflows-step-post-type.php:162
2039
+ msgctxt "flow step singular name"
2040
+ msgid "Step"
2041
+ msgstr ""
2042
+
2043
+ #: modules/flow/classes/class-cartflows-step-post-type.php:315
2044
+ msgctxt "cartflows"
2045
+ msgid "CartFlows Boxed"
2046
+ msgstr ""
2047
+
2048
+ #: modules/flow/classes/class-cartflows-step-post-type.php:316
2049
+ msgctxt "cartflows"
2050
+ msgid "Template for Page Builders"
2051
  msgstr ""
modules/checkout/classes/class-cartflows-checkout-markup.php CHANGED
@@ -1,1260 +1,1260 @@
1
- <?php
2
- /**
3
- * Checkout markup.
4
- *
5
- * @package CartFlows
6
- */
7
-
8
- /**
9
- * Checkout Markup
10
- *
11
- * @since 1.0.0
12
- */
13
- class Cartflows_Checkout_Markup {
14
-
15
- /**
16
- * Member Variable
17
- *
18
- * @var object instance
19
- */
20
- private static $instance;
21
-
22
- /**
23
- * Initiator
24
- */
25
- public static function get_instance() {
26
- if ( ! isset( self::$instance ) ) {
27
- self::$instance = new self();
28
- }
29
- return self::$instance;
30
- }
31
-
32
- /**
33
- * Constructor
34
- */
35
- public function __construct() {
36
-
37
- /* Set is checkout flag */
38
- add_filter( 'woocommerce_is_checkout', array( $this, 'woo_checkout_flag' ), 9999 );
39
-
40
- add_action( 'woocommerce_checkout_update_order_meta', array( $this, 'save_checkout_fields' ), 10, 2 );
41
-
42
- /* Show notice if cart is empty */
43
- add_action( 'cartflows_checkout_cart_empty', array( $this, 'display_woo_notices' ) );
44
-
45
- /* Checkout Shortcode */
46
- add_shortcode( 'cartflows_checkout', array( $this, 'checkout_shortcode_markup' ) );
47
-
48
- /* Preconfigured cart data */
49
- add_action( 'wp', array( $this, 'preconfigured_cart_data' ), 1 );
50
-
51
- /* Embed Checkout */
52
- add_action( 'wp', array( $this, 'shortcode_load_data' ), 999 );
53
-
54
- /* Ajax Endpoint */
55
- add_filter( 'woocommerce_ajax_get_endpoint', array( $this, 'get_ajax_endpoint' ), 10, 2 );
56
-
57
- add_filter( 'cartflows_add_before_main_section', array( $this, 'enable_logo_in_header' ) );
58
-
59
- add_filter( 'cartflows_primary_container_bottom', array( $this, 'show_cartflows_copyright_message' ) );
60
-
61
- add_filter( 'woocommerce_login_redirect', array( $this, 'after_login_redirect' ), 10, 2 );
62
-
63
- add_action( 'wp_ajax_wcf_woo_apply_coupon', array( $this, 'apply_coupon' ) );
64
- add_action( 'wp_ajax_nopriv_wcf_woo_apply_coupon', array( $this, 'apply_coupon' ) );
65
-
66
- add_filter( 'global_cartflows_js_localize', array( $this, 'add_localize_vars' ) );
67
-
68
- /* Global Checkout */
69
- add_action( 'template_redirect', array( $this, 'global_checkout_template_redirect' ), 1 );
70
-
71
- add_action( 'wp_ajax_wcf_woo_remove_coupon', array( $this, 'remove_coupon' ) );
72
- add_action( 'wp_ajax_nopriv_wcf_woo_remove_coupon', array( $this, 'remove_coupon' ) );
73
-
74
- add_action( 'wp_ajax_wcf_woo_remove_cart_product', array( $this, 'wcf_woo_remove_cart_product' ) );
75
- add_action( 'wp_ajax_nopriv_wcf_woo_remove_cart_product', array( $this, 'wcf_woo_remove_cart_product' ) );
76
-
77
- add_filter( 'woocommerce_paypal_args', array( $this, 'modify_paypal_args' ), 10, 2 );
78
-
79
- add_filter( 'woocommerce_cart_item_name', array( $this, 'wcf_add_remove_label' ), 10, 3 );
80
-
81
- add_action( 'woocommerce_before_calculate_totals', array( $this, 'custom_price_to_cart_item' ), 9999 );
82
- }
83
-
84
- /**
85
- * Modify WooCommerce paypal arguments.
86
- *
87
- * @param array $args argumenets for payment.
88
- * @param WC_Order $order order data.
89
- * @return array
90
- */
91
- public function modify_paypal_args( $args, $order ) {
92
-
93
- $checkout_id = wcf()->utils->get_checkout_id_from_post_data();
94
-
95
- if ( ! $checkout_id ) {
96
- return $args;
97
- }
98
-
99
- // Set cancel return URL.
100
- $args['cancel_return'] = esc_url_raw( $order->get_cancel_order_url_raw( get_permalink( $checkout_id ) ) );
101
-
102
- return $args;
103
- }
104
-
105
- /**
106
- * Modify WooCommerce paypal arguments.
107
- *
108
- * @param string $product_name product name.
109
- * @param object $cart_item cart item.
110
- * @param string $cart_item_key cart item key.
111
- * @return string
112
- */
113
- public function wcf_add_remove_label( $product_name, $cart_item, $cart_item_key ) {
114
-
115
- $checkout_id = get_the_ID();
116
- if ( ! $checkout_id ) {
117
- $checkout_id = ( isset( $_POST['option']['checkout_id'] ) ) ? wp_unslash( $_POST['option']['checkout_id'] ) : '';//phpcs:ignore
118
- }
119
-
120
- if ( ! empty( $checkout_id ) ) {
121
- $is_remove_product_option = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-remove-product-field' );
122
- if ( 'checkout' === get_post_meta( $checkout_id, 'wcf-step-type', true ) && ( 'yes' === $is_remove_product_option ) ) {
123
- $remove_label = apply_filters(
124
- 'woocommerce_cart_item_remove_link',
125
- sprintf(
126
- '<a href="#" rel="nofollow" class="remove cartflows-icon-close" data-id="%s" data-item-key="%s" ></a>',
127
- esc_attr( $cart_item['product_id'] ),
128
- $cart_item_key
129
- ),
130
- $cart_item_key
131
- );
132
-
133
- $product_name = $remove_label . $product_name;
134
- }
135
- }
136
-
137
- return $product_name;
138
-
139
- }
140
-
141
- /**
142
- * Change order button text .
143
- *
144
- * @param string $woo_button_text place order.
145
- * @return string
146
- */
147
- public function place_order_button_text( $woo_button_text ) {
148
-
149
- $checkout_id = get_the_ID();
150
- if ( ! $checkout_id ) {
151
- $checkout_id = ( isset( $_POST['option']['checkout_id'] ) ) ? intval( $_POST['option']['checkout_id'] ) : 0; //phpcs:ignore
152
- }
153
-
154
- $wcf_order_button_text = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-checkout-place-order-button-text' );
155
-
156
- if ( ! empty( $wcf_order_button_text ) ) {
157
- $woo_button_text = $wcf_order_button_text;
158
- }
159
-
160
- return $woo_button_text;
161
- }
162
-
163
- /**
164
- * Display all WooCommerce notices.
165
- *
166
- * @since 1.1.5
167
- */
168
- public function display_woo_notices() {
169
-
170
- if ( null != WC()->session && function_exists( 'woocommerce_output_all_notices' ) ) {
171
- woocommerce_output_all_notices();
172
- }
173
- }
174
-
175
-
176
- /**
177
- * Redirect from default to the global checkout page
178
- *
179
- * @since 1.0.0
180
- */
181
- public function global_checkout_template_redirect() {
182
-
183
- if ( ! is_checkout() ) {
184
- return;
185
- }
186
-
187
- if ( wcf()->utils->is_step_post_type() ) {
188
- return;
189
- }
190
-
191
- // Return if the key OR Order paramater is found in the URL for certain Payment gateways.
192
- if ( isset( $_GET['key'] ) || isset( $_GET['order'] ) ) { //phpcs:ignore
193
- return;
194
- }
195
-
196
- // redirect only for cartflows checkout pages.
197
- $order_pay_endpoint = get_option( 'woocommerce_checkout_pay_endpoint', 'order-pay' );
198
- $order_received_endpoint = get_option( 'woocommerce_checkout_order_received_endpoint', 'order-received' );
199
-
200
- $common = Cartflows_Helper::get_common_settings();
201
-
202
- $global_checkout = $common['global_checkout'];
203
-
204
- if (
205
- isset( $_SERVER['REQUEST_URI'] ) &&
206
- // ignore on order-pay.
207
- false === wcf_mb_strpos( esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ), '/' . $order_pay_endpoint . '/' ) &&
208
- // ignore on TY page.
209
- false === wcf_mb_strpos( esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ), '/' . $order_received_endpoint . '/' ) &&
210
- // ignore if order-pay in query param.
211
- false === wcf_mb_strpos( esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ), $order_pay_endpoint . '=' )
212
- ) {
213
-
214
- if ( '' !== $global_checkout ) {
215
-
216
- $link = apply_filters( 'cartflows_global_checkout_url', get_permalink( $global_checkout ) );
217
-
218
- if ( ! empty( $link ) ) {
219
-
220
- wp_safe_redirect( $link );
221
- die();
222
- }
223
- }
224
- }
225
- }
226
-
227
- /**
228
- * Check for checkout flag
229
- *
230
- * @param bool $is_checkout is checkout.
231
- *
232
- * @return bool
233
- */
234
- public function woo_checkout_flag( $is_checkout ) {
235
-
236
- if ( ! is_admin() ) {
237
-
238
- if ( _is_wcf_checkout_type() || _is_wcf_checkout_shortcode() ) {
239
-
240
- $is_checkout = true;
241
- }
242
- }
243
-
244
- return $is_checkout;
245
- }
246
-
247
- /**
248
- * Render checkout shortcode markup.
249
- *
250
- * @param array $atts attributes.
251
- * @return string
252
- */
253
- public function checkout_shortcode_markup( $atts ) {
254
-
255
- if ( ! function_exists( 'wc_print_notices' ) ) {
256
- $notice_out = '<p class="woocommerce-notice">' . __( 'WooCommerce functions do not exist. If you are in an IFrame, please reload it.', 'cartflows' ) . '</p>';
257
- $notice_out .= '<button onClick="location.reload()">' . __( 'Click Here to Reload', 'cartflows' ) . '</button>';
258
-
259
- return $notice_out;
260
- }
261
-
262
- $atts = shortcode_atts(
263
- array(
264
- 'id' => 0,
265
- ),
266
- $atts
267
- );
268
-
269
- $checkout_id = intval( $atts['id'] );
270
-
271
- if ( empty( $checkout_id ) ) {
272
-
273
- if ( ! _is_wcf_checkout_type() ) {
274
-
275
- return '<h4>' . __( 'Checkout ID not found', 'cartflows' ) . '</h4>';
276
- }
277
-
278
- global $post;
279
-
280
- $checkout_id = intval( $post->ID );
281
- }
282
-
283
- $output = '';
284
-
285
- ob_start();
286
-
287
- do_action( 'cartflows_checkout_form_before', $checkout_id );
288
-
289
- $checkout_layout = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-checkout-layout' );
290
-
291
- $template_default = CARTFLOWS_CHECKOUT_DIR . 'templates/embed/checkout-template-simple.php';
292
-
293
- $template_layout = apply_filters( 'cartflows_checkout_layout_template', $checkout_layout );
294
-
295
- if ( file_exists( $template_layout ) ) {
296
- include $template_layout;
297
- } else {
298
- include $template_default;
299
- }
300
-
301
- $output .= ob_get_clean();
302
-
303
- return $output;
304
- }
305
-
306
- /**
307
- * Configure Cart Data.
308
- *
309
- * @since 1.0.0
310
- *
311
- * @return void
312
- */
313
- public function preconfigured_cart_data() {
314
-
315
- if ( is_admin() ) {
316
- return;
317
- }
318
-
319
- global $post;
320
-
321
- if ( _is_wcf_checkout_type() || _is_wcf_checkout_shortcode() ) {
322
-
323
- if ( wp_doing_ajax() ) {
324
- return;
325
- } else {
326
-
327
- if ( _is_wcf_checkout_type() ) {
328
- $checkout_id = $post->ID;
329
- } else {
330
- $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
331
- }
332
-
333
- $global_checkout = intval( Cartflows_Helper::get_common_setting( 'global_checkout' ) );
334
-
335
- if ( ! empty( $global_checkout ) && $checkout_id === $global_checkout ) {
336
-
337
- if ( WC()->cart->is_empty() ) {
338
- wc_add_notice( __( 'Your cart is currently empty.', 'cartflows' ), 'error' );
339
- }
340
-
341
- return;
342
- }
343
-
344
- if ( apply_filters( 'cartflows_skip_configure_cart', false, $checkout_id ) ) {
345
- return;
346
- }
347
-
348
- do_action( 'cartflows_checkout_before_configure_cart', $checkout_id );
349
-
350
- $flow_id = wcf()->utils->get_flow_id_from_step_id( $checkout_id );
351
-
352
- if ( wcf()->flow->is_flow_testmode( $flow_id ) ) {
353
- $products = 'dummy';
354
- } else {
355
- $products = wcf()->utils->get_selected_checkout_products( $checkout_id );
356
- }
357
-
358
- if ( ! is_array( $products ) ) {
359
-
360
- if ( 'dummy' === $products ) {
361
-
362
- $args = array(
363
- 'posts_per_page' => 1,
364
- 'orderby' => 'rand',
365
- 'post_type' => 'product',
366
- 'meta_query' => array( //phpcs:ignore
367
- // Exclude out of stock products.
368
- array(
369
- 'key' => '_stock_status',
370
- 'value' => 'outofstock',
371
- 'compare' => 'NOT IN',
372
- ),
373
- ),
374
- 'tax_query' => array( //phpcs:ignore
375
- array(
376
- 'taxonomy' => 'product_type',
377
- 'field' => 'slug',
378
- 'terms' => 'simple',
379
- ),
380
- ),
381
- );
382
-
383
- $random_product = get_posts( $args );
384
-
385
- if ( isset( $random_product[0]->ID ) ) {
386
- $products = array(
387
- array(
388
- 'product' => $random_product[0]->ID,
389
- 'add_to_cart' => true,
390
- ),
391
- );
392
- } else {
393
- return;
394
- }
395
- } else {
396
- return;
397
- }
398
- }
399
-
400
- /* Empty the current cart */
401
- WC()->cart->empty_cart();
402
-
403
- if ( is_array( $products ) && empty( $products[0]['product'] ) ) {
404
- wc_add_notice( __( 'No product is selected. Please select products from the checkout meta settings to continue.', 'cartflows' ), 'error' );
405
- return;
406
- }
407
-
408
- /* Set customer session if not set */
409
- if ( ! is_user_logged_in() && WC()->cart->is_empty() ) {
410
- WC()->session->set_customer_session_cookie( true );
411
- }
412
-
413
- $cart_product_count = 0;
414
- $cart_key = '';
415
- $products_new = array();
416
-
417
- $products = apply_filters( 'cartflows_selected_checkout_products', $products, $checkout_id );
418
-
419
- foreach ( $products as $index => $data ) {
420
-
421
- if ( ! isset( $data['product'] ) ) {
422
- continue;
423
- }
424
-
425
- if ( empty( $data['add_to_cart'] ) ) {
426
- continue;
427
- }
428
-
429
- if ( apply_filters( 'cartflows_skip_other_products', false, $cart_product_count ) ) {
430
- break;
431
- }
432
-
433
- $product_id = $data['product'];
434
- $_product = wc_get_product( $product_id );
435
-
436
- if ( ! empty( $_product ) ) {
437
-
438
- $quantity = 1;
439
-
440
- if ( isset( $data['quantity'] ) && ! empty( $data['quantity'] ) ) {
441
- $quantity = $data['quantity'];
442
- }
443
-
444
- $discount_type = isset( $data['discount_type'] ) ? $data['discount_type'] : '';
445
- $discount_value = ! empty( $data['discount_value'] ) ? $data['discount_value'] : '';
446
- $_product_price = $_product->get_price( $data['product'] );
447
-
448
- $custom_price = $this->calculate_discount( '', $discount_type, $discount_value, $_product_price );
449
-
450
- $cart_item_data = array();
451
-
452
- if ( ! empty( $custom_price ) ) {
453
-
454
- $cart_item_data = array(
455
- 'custom_price' => $custom_price,
456
- );
457
- }
458
-
459
- if ( ! $_product->is_type( 'grouped' ) && ! $_product->is_type( 'external' ) ) {
460
-
461
- if ( $_product->is_type( 'variable' ) ) {
462
-
463
- $default_attributes = $_product->get_default_attributes();
464
-
465
- if ( ! empty( $default_attributes ) ) {
466
-
467
- foreach ( $_product->get_children() as $variation_id ) {
468
-
469
- $single_variation = new WC_Product_Variation( $variation_id );
470
-
471
- if ( $default_attributes == $single_variation->get_attributes() ) {
472
- $cart_key = WC()->cart->add_to_cart( $variation_id, $quantity, 0, array(), $cart_item_data );
473
- $cart_product_count++;
474
- }
475
- }
476
- } else {
477
-
478
- $product_childrens = $_product->get_children();
479
-
480
- if ( isset( $product_childrens[0] ) ) {
481
- $variation = wc_get_product( $product_childrens[0] );
482
- $_product_price = $variation->get_price();
483
- $custom_price = $this->calculate_discount( '', $discount_type, $discount_value, $_product_price );
484
- if ( ! empty( $custom_price ) ) {
485
- $cart_item_data = array(
486
- 'custom_price' => $custom_price,
487
- 'data' => $data,
488
- );
489
- }
490
- $cart_key = WC()->cart->add_to_cart( $product_childrens[0], $quantity, 0, array(), $cart_item_data );
491
- $cart_product_count++;
492
- } else {
493
- echo '<p>' . esc_html__( 'Variations Not set', 'cartflows' ) . '</p>';
494
- }
495
- }
496
- } else {
497
- $cart_key = WC()->cart->add_to_cart( $product_id, $quantity, 0, array(), $cart_item_data );
498
- $cart_product_count++;
499
- }
500
- } else {
501
- $wrong_product_notice = __( 'This product can\'t be purchased', 'cartflows' );
502
- wc_add_notice( $wrong_product_notice );
503
- /**
504
- WC()->cart->add_to_cart( $product_id, $quantity );.
505
- */
506
- }
507
- }
508
- $products_new[ $index ] = array(
509
- 'cart_item_key' => $cart_key,
510
- );
511
- }
512
-
513
- /* Set checkout products data */
514
- wcf()->utils->set_selcted_checkout_products( $checkout_id, $products_new );
515
-
516
- /* Since 1.2.2 */
517
- wcf_do_action_deprecated( 'cartflows_checkout_aftet_configure_cart', array( $checkout_id ), '1.2.2', 'cartflows_checkout_after_configure_cart' );
518
- do_action( 'cartflows_checkout_after_configure_cart', $checkout_id );
519
- }
520
- }
521
- }
522
-
523
- /**
524
- * Load shortcode data.
525
- *
526
- * @return void
527
- */
528
- public function shortcode_load_data() {
529
-
530
- if ( _is_wcf_checkout_type() || _is_wcf_checkout_shortcode() ) {
531
-
532
- add_action( 'wp_enqueue_scripts', array( $this, 'shortcode_scripts' ), 21 );
533
-
534
- add_action( 'wp_enqueue_scripts', array( $this, 'compatibility_scripts' ), 101 );
535
-
536
- /* Show notices if cart has errors */
537
- add_action( 'woocommerce_cart_has_errors', 'woocommerce_output_all_notices' );
538
-
539
- add_action( 'woocommerce_checkout_after_customer_details', array( $this, 'order_wrap_div_start' ), 99 );
540
-
541
- add_action( 'woocommerce_checkout_after_order_review', array( $this, 'order_wrap_div_end' ), 99 );
542
-
543
- // Outputting the hidden field in checkout page.
544
- add_action( 'woocommerce_after_order_notes', array( $this, 'checkout_shortcode_post_id' ), 99 );
545
- add_action( 'woocommerce_login_form_end', array( $this, 'checkout_shortcode_post_id' ), 99 );
546
-
547
- remove_all_actions( 'woocommerce_checkout_billing' );
548
- remove_all_actions( 'woocommerce_checkout_shipping' );
549
-
550
- // Hook in actions once.
551
- add_action( 'woocommerce_checkout_billing', array( WC()->checkout, 'checkout_form_billing' ) );
552
- add_action( 'woocommerce_checkout_shipping', array( WC()->checkout, 'checkout_form_shipping' ) );
553
-
554
- remove_action( 'woocommerce_before_checkout_form', 'woocommerce_checkout_coupon_form' );
555
-
556
- add_action( 'woocommerce_checkout_order_review', array( $this, 'display_custom_coupon_field' ) );
557
-
558
- add_filter( 'woocommerce_checkout_fields', array( $this, 'add_three_column_layout_fields' ) );
559
-
560
- add_filter( 'woocommerce_cart_totals_coupon_html', array( $this, 'remove_coupon_text' ) );
561
-
562
- add_filter( 'woocommerce_order_button_text', array( $this, 'place_order_button_text' ), 10, 1 );
563
-
564
- global $post;
565
-
566
- if ( _is_wcf_checkout_type() ) {
567
- $checkout_id = $post->ID;
568
- } else {
569
- $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
570
- }
571
-
572
- do_action( 'cartflows_checkout_before_shortcode', $checkout_id );
573
- }
574
- }
575
-
576
- /**
577
- * Render checkout ID hidden field.
578
- *
579
- * @param array $checkout checkout session data.
580
- * @return void
581
- */
582
- public function checkout_shortcode_post_id( $checkout ) {
583
-
584
- global $post;
585
-
586
- if ( _is_wcf_checkout_type() ) {
587
- $checkout_id = $post->ID;
588
- } else {
589
- $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
590
- }
591
-
592
- $flow_id = get_post_meta( $checkout_id, 'wcf-flow-id', true );
593
-
594
- echo '<input type="hidden" class="input-hidden _wcf_flow_id" name="_wcf_flow_id" value="' . intval( $flow_id ) . '">';
595
- echo '<input type="hidden" class="input-hidden _wcf_checkout_id" name="_wcf_checkout_id" value="' . intval( $checkout_id ) . '">';
596
- }
597
-
598
- /**
599
- * Load shortcode scripts.
600
- *
601
- * @return void
602
- */
603
- public function shortcode_scripts() {
604
-
605
- wp_enqueue_style( 'wcf-checkout-template', wcf()->utils->get_css_url( 'checkout-template' ), '', CARTFLOWS_VER );
606
-
607
- wp_enqueue_script(
608
- 'wcf-checkout-template',
609
- wcf()->utils->get_js_url( 'checkout-template' ),
610
- array( 'jquery' ),
611
- CARTFLOWS_VER,
612
- true
613
- );
614
-
615
- do_action( 'cartflows_checkout_scripts' );
616
-
617
- $style = $this->generate_style();
618
-
619
- wp_add_inline_style( 'wcf-checkout-template', $style );
620
-
621
- }
622
-
623
- /**
624
- * Load compatibility scripts.
625
- *
626
- * @return void
627
- */
628
- public function compatibility_scripts() {
629
-
630
- global $post;
631
-
632
- if ( _is_wcf_checkout_type() ) {
633
- $checkout_id = $post->ID;
634
- } else {
635
- $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
636
- }
637
-
638
- // Add DIVI Compatibility css if DIVI theme is enabled.
639
- if ( Cartflows_Compatibility::get_instance()->is_divi_enabled() ||
640
- Cartflows_Compatibility::get_instance()->is_divi_builder_enabled( $checkout_id )
641
- ) {
642
- wp_enqueue_style( 'wcf-checkout-template-divi', wcf()->utils->get_css_url( 'checkout-template-divi' ), '', CARTFLOWS_VER );
643
- }
644
-
645
- // Add Flatsome Compatibility css if Flatsome theme is enabled.
646
- if ( Cartflows_Compatibility::get_instance()->is_flatsome_enabled() ) {
647
- wp_enqueue_style( 'wcf-checkout-template-flatsome', wcf()->utils->get_css_url( 'checkout-template-flatsome' ), '', CARTFLOWS_VER );
648
- }
649
-
650
- // Add The7 Compatibility css if The7 theme is enabled.
651
- if ( Cartflows_Compatibility::get_instance()->is_the_seven_enabled() ) {
652
- wp_enqueue_style( 'wcf-checkout-template-the-seven', wcf()->utils->get_css_url( 'checkout-template-the-seven' ), '', CARTFLOWS_VER );
653
- }
654
- }
655
-
656
- /**
657
- * Generate styles.
658
- *
659
- * @return string
660
- */
661
- public function generate_style() {
662
-
663
- global $post;
664
-
665
- if ( _is_wcf_checkout_type() ) {
666
- $checkout_id = $post->ID;
667
- } else {
668
- $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
669
- }
670
-
671
- /*Output css variable */
672
- $output = '';
673
-
674
- CartFlows_Font_Families::render_fonts( $checkout_id );
675
-
676
- $primary_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-primary-color' );
677
-
678
- $base_font_family = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-base-font-family' );
679
-
680
- $header_logo_width = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-header-logo-width' );
681
-
682
- /**
683
- $base_font_weight = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-base-font-weight' );*/
684
- $r = '';
685
- $g = '';
686
- $b = '';
687
-
688
- $field_tb_padding = '';
689
- $field_lr_padding = '';
690
-
691
- $field_heading_color = '';
692
- $field_color = '';
693
- $field_bg_color = '';
694
- $field_border_color = '';
695
- $field_label_color = '';
696
- $submit_tb_padding = '';
697
- $submit_lr_padding = '';
698
- $hl_bg_color = '';
699
- $field_input_size = '';
700
- $box_border_color = '';
701
- $section_bg_color = '';
702
- $submit_button_height = '';
703
- $submit_color = '';
704
- $submit_bg_color = $primary_color;
705
- $submit_border_color = $primary_color;
706
-
707
- $submit_hover_color = '';
708
- $submit_bg_hover_color = $primary_color;
709
- $submit_border_hover_color = $primary_color;
710
-
711
- $section_heading_color = '';
712
-
713
- $is_advance_option = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-advance-options-fields' );
714
-
715
- $button_font_family = '';
716
- $button_font_weight = '';
717
- $input_font_family = '';
718
- $input_font_weight = '';
719
- $heading_font_family = '';
720
- $heading_font_weight = '';
721
- $base_font_family = $base_font_family;
722
- /**
723
- $base_font_weight = $base_font_weight;*/
724
-
725
- if ( 'yes' == $is_advance_option ) {
726
-
727
- /**
728
- * Get Font Family and Font Weight weight values
729
- */
730
- $section_bg_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-section-bg-color' );
731
-
732
- $heading_font_family = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-heading-font-family' );
733
- $heading_font_weight = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-heading-font-weight' );
734
- $section_heading_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-heading-color' );
735
- $button_font_family = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-button-font-family' );
736
- $button_font_weight = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-button-font-weight' );
737
- $input_font_family = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-input-font-family' );
738
- $input_font_weight = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-input-font-weight' );
739
- $field_tb_padding = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-tb-padding' );
740
- $field_lr_padding = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-lr-padding' );
741
- $field_input_size = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-input-field-size' );
742
-
743
- $field_heading_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-heading-color' );
744
-
745
- $field_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-color' );
746
-
747
- $field_bg_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-bg-color' );
748
-
749
- $field_border_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-border-color' );
750
-
751
- $field_label_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-label-color' );
752
-
753
- $submit_tb_padding = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-tb-padding' );
754
-
755
- $submit_lr_padding = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-lr-padding' );
756
-
757
- $submit_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-color' );
758
-
759
- $submit_bg_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-bg-color', $primary_color );
760
-
761
- $submit_border_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-border-color', $primary_color );
762
-
763
- $submit_border_hover_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-border-hover-color', $primary_color );
764
-
765
- $submit_hover_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-hover-color' );
766
-
767
- $submit_bg_hover_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-bg-hover-color', $primary_color );
768
-
769
- $hl_bg_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-hl-bg-color' );
770
-
771
- $box_border_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-box-border-color' );
772
-
773
- $submit_button_height = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-input-button-size' );
774
-
775
- /**
776
- * Get font values
777
- */
778
-
779
- if ( 'custom' == $submit_button_height ) {
780
- $submit_button_height = '38px';
781
- }
782
-
783
- if ( 'custom' == $field_input_size ) {
784
- $field_input_size = '38px';
785
- }
786
- }
787
- if ( isset( $primary_color ) ) {
788
-
789
- list($r, $g, $b) = sscanf( $primary_color, '#%02x%02x%02x' );
790
- }
791
-
792
- if ( Cartflows_Compatibility::get_instance()->is_divi_enabled() ||
793
- Cartflows_Compatibility::get_instance()->is_divi_builder_enabled( $checkout_id ) ) {
794
-
795
- include CARTFLOWS_CHECKOUT_DIR . 'includes/checkout-dynamic-divi-css.php';
796
-
797
- } else {
798
- include CARTFLOWS_CHECKOUT_DIR . 'includes/checkout-dynamic-css.php';
799
- }
800
-
801
- return $output;
802
- }
803
-
804
- /**
805
- * Get ajax end points.
806
- *
807
- * @param string $endpoint_url end point URL.
808
- * @param string $request end point request.
809
- * @return string
810
- */
811
- public function get_ajax_endpoint( $endpoint_url, $request ) {
812
-
813
- global $post;
814
-
815
- if ( ! empty( $post ) && ! empty( $_SERVER['REQUEST_URI'] ) ) {
816
-
817
- if ( _is_wcf_checkout_type() ) {
818
-
819
- if ( mb_strpos( $endpoint_url, 'checkout', 0, 'utf-8' ) === false ) {
820
-
821
- if ( '' === $request ) {
822
- $query_args = array(
823
- 'wc-ajax' => '%%endpoint%%',
824
- );
825
- } else {
826
- $query_args = array(
827
- 'wc-ajax' => $request,
828
- );
829
- }
830
-
831
- $uri = explode( '?', $_SERVER['REQUEST_URI'], 2 ); //phpcs:ignore
832
- $uri = $uri[0];
833
-
834
- $endpoint_url = esc_url( add_query_arg( $query_args, $uri ) );
835
- }
836
- }
837
- }
838
-
839
- return $endpoint_url;
840
- }
841
-
842
-
843
- /**
844
- * Save checkout fields.
845
- *
846
- * @param int $order_id order id.
847
- * @param array $posted posted data.
848
- * @return void
849
- */
850
- public function save_checkout_fields( $order_id, $posted ) {
851
-
852
- if ( isset( $_POST['_wcf_checkout_id'] ) ) { //phpcs:ignore
853
-
854
- $checkout_id = wc_clean( intval( $_POST['_wcf_checkout_id'] ) ); //phpcs:ignore
855
-
856
- update_post_meta( $order_id, '_wcf_checkout_id', $checkout_id );
857
-
858
- if ( isset( $_POST['_wcf_flow_id'] ) ) { //phpcs:ignore
859
-
860
- $flow_id = wc_clean( intval( $_POST['_wcf_flow_id'] ) ); //phpcs:ignore
861
-
862
- update_post_meta( $order_id, '_wcf_flow_id', $flow_id );
863
- }
864
- }
865
-
866
- }
867
-
868
- /**
869
- * Enable Logo In Header Of Checkout Page
870
- *
871
- * @return void
872
- */
873
- public function enable_logo_in_header() {
874
- global $post;
875
-
876
- if ( _is_wcf_checkout_type() ) {
877
- $checkout_id = $post->ID;
878
- } else {
879
- $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
880
- }
881
-
882
- $header_logo_image = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-header-logo-image' );
883
- $add_image_markup = '';
884
-
885
- if ( isset( $header_logo_image ) && ! empty( $header_logo_image ) ) {
886
- $add_image_markup = '<div class="wcf-checkout-header-image">';
887
- $add_image_markup .= '<img src="' . $header_logo_image . '" />';
888
- $add_image_markup .= '</div>';
889
- }
890
-
891
- echo $add_image_markup;
892
- }
893
-
894
- /**
895
- * Add text to the bootom of the checkout page.
896
- *
897
- * @return void
898
- */
899
- public function show_cartflows_copyright_message() {
900
- $output_string = '';
901
-
902
- $output_string .= '<div class="wcf-footer-primary">';
903
- $output_string .= '<div class="wcf-footer-content">';
904
- $output_string .= '<p class="wcf-footer-message">';
905
- $output_string .= 'Checkout powered by CartFlows';
906
- $output_string .= '</p>';
907
- $output_string .= '</div>';
908
- $output_string .= '</div>';
909
-
910
- echo $output_string;
911
- }
912
-
913
- /**
914
- * Redirect users to our checkout if hidden param
915
- *
916
- * @param string $redirect redirect url.
917
- * @param object $user user.
918
- * @return string
919
- */
920
- public function after_login_redirect( $redirect, $user ) {
921
-
922
- if ( isset( $_POST['_wcf_checkout_id'] ) ) { //phpcs:ignore
923
-
924
- $checkout_id = intval( $_POST['_wcf_checkout_id'] ); //phpcs:ignore
925
-
926
- $redirect = get_permalink( $checkout_id );
927
- }
928
-
929
- return $redirect;
930
- }
931
-
932
- /**
933
- * Display coupon code field after review order fields.
934
- */
935
- public function display_custom_coupon_field() {
936
-
937
- $coupon_enabled = apply_filters( 'woocommerce_coupons_enabled', true );
938
- $show_coupon = apply_filters( 'cartflows_show_coupon_field', true );
939
-
940
- if ( ! ( $coupon_enabled && $show_coupon ) ) {
941
- return;
942
-
943
- }
944
-
945
- $coupon_field = array(
946
- 'field_text' => __( 'Coupon Code', 'cartflows' ),
947
- 'button_text' => __( 'Apply', 'cartflows' ),
948
- 'class' => '',
949
- );
950
-
951
- $coupon_field = apply_filters( 'cartflows_coupon_field_options', $coupon_field );
952
-
953
- ob_start();
954
- ?>
955
- <div class="wcf-custom-coupon-field <?php echo $coupon_field['class']; ?>" id="wcf_custom_coupon_field">
956
- <div class="wcf-coupon-col-1">
957
- <span>
958
- <input type="text" name="coupon_code" class="input-text wcf-coupon-code-input" placeholder="<?php echo $coupon_field['field_text']; ?>" id="coupon_code" value="">
959
- </span>
960
- </div>
961
- <div class="wcf-coupon-col-2">
962
- <span>
963
- <button type="button" class="button wcf-submit-coupon wcf-btn-small" name="apply_coupon" value="Apply"><?php echo $coupon_field['button_text']; ?></button>
964
- </span>
965
- </div>
966
- </div>
967
- <?php
968
- echo ob_get_clean();
969
- }
970
-
971
- /**
972
- * Apply filter to change class of remove coupon field.
973
- *
974
- * @param string $coupon coupon.
975
- * @return string
976
- */
977
- public function remove_coupon_text( $coupon ) {
978
-
979
- $coupon = str_replace( 'woocommerce-remove-coupon', 'wcf-remove-coupon', $coupon );
980
- return $coupon;
981
-
982
- }
983
- /**
984
- * Apply filter to change the placeholder text of coupon field.
985
- *
986
- * @return string
987
- */
988
- public function coupon_field_placeholder() {
989
- return apply_filters( 'cartflows_coupon_field_placeholder', __( 'Coupon Code', 'cartflows' ) );
990
- }
991
-
992
- /**
993
- * Apply filter to change the button text of coupon field.
994
- *
995
- * @return string
996
- */
997
- public function coupon_button_text() {
998
- return apply_filters( 'cartflows_coupon_button_text', __( 'Apply', 'cartflows' ) );
999
- }
1000
-
1001
- /**
1002
- * Apply coupon on submit of custom coupon form.
1003
- */
1004
- public function apply_coupon() {
1005
-
1006
- $response = '';
1007
-
1008
- check_ajax_referer( 'wcf-apply-coupon', 'security' );
1009
- if ( ! empty( $_POST['coupon_code'] ) ) {
1010
- $result = WC()->cart->add_discount( sanitize_text_field( wp_unslash( $_POST['coupon_code'] ) ) );
1011
- } else {
1012
- wc_add_notice( WC_Coupon::get_generic_coupon_error( WC_Coupon::E_WC_COUPON_PLEASE_ENTER ), 'error' );
1013
- }
1014
-
1015
- $response = array(
1016
- 'status' => $result,
1017
- 'msg' => wc_print_notices( true ),
1018
- );
1019
-
1020
- echo wp_json_encode( $response );
1021
-
1022
- die();
1023
- }
1024
-
1025
-
1026
- /**
1027
- * Added ajax nonce to localize variable.
1028
- *
1029
- * @param array $vars localize variables.
1030
- */
1031
- public function add_localize_vars( $vars ) {
1032
-
1033
- $vars['wcf_validate_coupon_nonce'] = wp_create_nonce( 'wcf-apply-coupon' );
1034
-
1035
- $vars['wcf_validate_remove_coupon_nonce'] = wp_create_nonce( 'wcf-remove-coupon' );
1036
-
1037
- $vars['wcf_validate_remove_cart_product_nonce'] = wp_create_nonce( 'wcf-remove-cart-product' );
1038
-
1039
- $vars['allow_persistance'] = apply_filters( 'cartflows_allow_persistace', 'yes' );
1040
-
1041
- return $vars;
1042
- }
1043
-
1044
- /**
1045
- * Add custom class to the fields to change the UI to three column.
1046
- *
1047
- * @param array $fields fields.
1048
- */
1049
- public function add_three_column_layout_fields( $fields ) {
1050
-
1051
- if ( empty( $fields['billing']['billing_address_2'] ) ) {
1052
-
1053
- if ( isset( $fields['billing']['billing_address_1'] ) && is_array( $fields['billing']['billing_address_1'] ) ) {
1054
- $fields['billing']['billing_address_1']['class'][] = 'form-row-full';
1055
- }
1056
- }
1057
-
1058
- if ( ! empty( $fields['billing']['billing_company'] ) ) {
1059
-
1060
- if ( isset( $fields['billing']['billing_company'] ) && is_array( $fields['billing']['billing_company'] ) ) {
1061
- $fields['billing']['billing_company']['class'][] = 'form-row-full';
1062
- }
1063
- }
1064
-
1065
- if ( ! empty( $fields['shipping']['shipping_company'] ) ) {
1066
-
1067
- if ( isset( $fields['shipping']['shipping_company'] ) && is_array( $fields['shipping']['shipping_company'] ) ) {
1068
- $fields['shipping']['shipping_company']['class'][] = 'form-row-full';
1069
- }
1070
- }
1071
-
1072
- if ( ! empty( $fields['billing']['billing_country'] ) ) {
1073
-
1074
- if ( isset( $fields['billing']['billing_country'] ) && is_array( $fields['billing']['billing_country'] ) ) {
1075
- $fields['billing']['billing_country']['class'][] = 'form-row-full';
1076
- }
1077
- }
1078
-
1079
- if ( ! empty( $fields['shipping']['shipping_country'] ) ) {
1080
-
1081
- if ( isset( $fields['shipping']['shipping_country'] ) && is_array( $fields['shipping']['shipping_country'] ) ) {
1082
- $fields['shipping']['shipping_country']['class'][] = 'form-row-full';
1083
- }
1084
- }
1085
-
1086
- if ( ! empty( $fields['billing']['billing_phone'] ) ) {
1087
-
1088
- if ( isset( $fields['billing']['billing_phone'] ) && is_array( $fields['billing']['billing_phone'] ) ) {
1089
- $fields['billing']['billing_phone']['class'][] = 'form-row-full';
1090
- }
1091
- }
1092
-
1093
- if ( ! empty( $fields['billing']['billing_email'] ) ) {
1094
-
1095
- if ( isset( $fields['billing']['billing_email'] ) && is_array( $fields['billing']['billing_email'] ) ) {
1096
- $fields['billing']['billing_email']['class'][] = 'form-row-full';
1097
- }
1098
- }
1099
-
1100
- if ( empty( $fields['shipping']['shipping_address_2'] ) ) {
1101
-
1102
- if ( isset( $fields['shipping']['shipping_address_1'] ) && is_array( $fields['shipping']['shipping_address_1'] ) ) {
1103
- $fields['shipping']['shipping_address_1']['class'][] = 'form-row-full';
1104
- }
1105
- }
1106
-
1107
- if ( isset( $fields['billing']['billing_city'] ) &&
1108
- isset( $fields['billing']['billing_state'] ) && isset( $fields['billing']['billing_postcode'] ) ) {
1109
-
1110
- $fields['billing']['billing_city']['class'][] = 'wcf-column-33';
1111
- $fields['billing']['billing_state']['class'][] = 'wcf-column-33';
1112
- $fields['billing']['billing_postcode']['class'][] = 'wcf-column-33';
1113
- }
1114
-
1115
- if ( isset( $fields['shipping']['shipping_city'] ) &&
1116
- isset( $fields['shipping']['shipping_state'] ) && isset( $fields['shipping']['shipping_postcode'] ) ) {
1117
-
1118
- $fields['shipping']['shipping_city']['class'][] = 'wcf-column-33';
1119
- $fields['shipping']['shipping_state']['class'][] = 'wcf-column-33';
1120
- $fields['shipping']['shipping_postcode']['class'][] = 'wcf-column-33';
1121
- }
1122
-
1123
- return $fields;
1124
- }
1125
-
1126
- /**
1127
- * Add opening dev
1128
- *
1129
- * @since 1.0.0
1130
- */
1131
- public function order_wrap_div_start() {
1132
-
1133
- echo "<div class='wcf-order-wrap'> ";
1134
- }
1135
-
1136
- /**
1137
- * Add closing dev
1138
- *
1139
- * @since 1.0.0
1140
- */
1141
- public function order_wrap_div_end() {
1142
-
1143
- echo '</div> ';
1144
- }
1145
- /**
1146
- * Remove coupon.
1147
- */
1148
- public function remove_coupon() {
1149
-
1150
- check_ajax_referer( 'wcf-remove-coupon', 'security' );
1151
- $coupon = isset( $_POST['coupon_code'] ) ? wc_clean( wp_unslash( $_POST['coupon_code'] ) ) : false; //phpcs:ignore
1152
-
1153
- if ( empty( $coupon ) ) {
1154
- echo "<div class='woocommerce-error'>" . esc_html__( 'Sorry there was a problem removing this coupon.', 'cartflows' );
1155
- } else {
1156
- WC()->cart->remove_coupon( $coupon );
1157
- echo "<div class='woocommerce-error'>" . esc_html__( 'Coupon has been removed.', 'cartflows' ) . '</div>';
1158
- }
1159
- wc_print_notices();
1160
- wp_die();
1161
- }
1162
-
1163
- /**
1164
- * Remove cart item.
1165
- */
1166
- public function wcf_woo_remove_cart_product() {
1167
-
1168
- check_ajax_referer( 'wcf-remove-cart-product', 'security' );
1169
- $product_key = isset( $_POST['p_key'] ) ? wc_clean( wp_unslash( $_POST['p_key'] ) ) : false; //phpcs:ignore
1170
- $product_id = isset( $_POST['p_id'] ) ? wc_clean( wp_unslash( $_POST['p_id'] ) ) : ''; //phpcs:ignore
1171
- $product_title = get_the_title( $product_id );
1172
-
1173
- $needs_shipping = false;
1174
-
1175
- if ( empty( $product_key ) ) {
1176
- $msg = "<div class='woocommerce-message'>" . __( 'Sorry there was a problem removing ', 'cartflows' ) . $product_title;
1177
- } else {
1178
- WC()->cart->remove_cart_item( $product_key );
1179
- $msg = "<div class='woocommerce-message'>" . $product_title . __( ' has been removed.', 'cartflows' ) . '</div>';
1180
- }
1181
-
1182
- foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
1183
- if ( $values['data']->needs_shipping() ) {
1184
- $needs_shipping = true;
1185
- break;
1186
- }
1187
- }
1188
-
1189
- $response = array(
1190
- 'need_shipping' => $needs_shipping,
1191
- 'msg' => $msg,
1192
- );
1193
-
1194
- echo wp_json_encode( $response );
1195
- wp_die();
1196
- }
1197
-
1198
- /**
1199
- * Calculate discount for product.
1200
- *
1201
- * @param string $discount_coupon discount coupon.
1202
- * @param string $discount_type discount type.
1203
- * @param int $discount_value discount value.
1204
- * @param int $_product_price product price.
1205
- * @return int
1206
- * @since 1.1.5
1207
- */
1208
- public function calculate_discount( $discount_coupon, $discount_type, $discount_value, $_product_price ) {
1209
-
1210
- $custom_price = '';
1211
-
1212
- if ( ! empty( $discount_type ) ) {
1213
- if ( 'discount_percent' === $discount_type ) {
1214
-
1215
- if ( $discount_value > 0 ) {
1216
- $custom_price = $_product_price - ( ( $_product_price * $discount_value ) / 100 );
1217
- }
1218
- } elseif ( 'discount_price' === $discount_type ) {
1219
-
1220
- if ( $discount_value > 0 ) {
1221
- $custom_price = $_product_price - $discount_value;
1222
- }
1223
- } elseif ( 'coupon' === $discount_type ) {
1224
-
1225
- if ( ! empty( $discount_coupon ) ) {
1226
- WC()->cart->add_discount( $discount_coupon );
1227
- }
1228
- }
1229
- }
1230
-
1231
- return $custom_price;
1232
- }
1233
-
1234
- /**
1235
- * Preserve the custom item price added by Variations & Quantity feature
1236
- *
1237
- * @param array $cart_object cart object.
1238
- * @since 1.0.0
1239
- */
1240
- public function custom_price_to_cart_item( $cart_object ) {
1241
-
1242
- if ( wp_doing_ajax() && ! WC()->session->__isset( 'reload_checkout' ) ) {
1243
-
1244
- foreach ( $cart_object->cart_contents as $key => $value ) {
1245
-
1246
- if ( isset( $value['custom_price'] ) ) {
1247
-
1248
- $custom_price = floatval( $value['custom_price'] );
1249
- $value['data']->set_price( $custom_price );
1250
- }
1251
- }
1252
- }
1253
- }
1254
-
1255
- }
1256
-
1257
- /**
1258
- * Kicking this off by calling 'get_instance()' method
1259
- */
1260
- Cartflows_Checkout_Markup::get_instance();
1
+ <?php
2
+ /**
3
+ * Checkout markup.
4
+ *
5
+ * @package CartFlows
6
+ */
7
+
8
+ /**
9
+ * Checkout Markup
10
+ *
11
+ * @since 1.0.0
12
+ */
13
+ class Cartflows_Checkout_Markup {
14
+
15
+ /**
16
+ * Member Variable
17
+ *
18
+ * @var object instance
19
+ */
20
+ private static $instance;
21
+
22
+ /**
23
+ * Initiator
24
+ */
25
+ public static function get_instance() {
26
+ if ( ! isset( self::$instance ) ) {
27
+ self::$instance = new self();
28
+ }
29
+ return self::$instance;
30
+ }
31
+
32
+ /**
33
+ * Constructor
34
+ */
35
+ public function __construct() {
36
+
37
+ /* Set is checkout flag */
38
+ add_filter( 'woocommerce_is_checkout', array( $this, 'woo_checkout_flag' ), 9999 );
39
+
40
+ add_action( 'woocommerce_checkout_update_order_meta', array( $this, 'save_checkout_fields' ), 10, 2 );
41
+
42
+ /* Show notice if cart is empty */
43
+ add_action( 'cartflows_checkout_cart_empty', array( $this, 'display_woo_notices' ) );
44
+
45
+ /* Checkout Shortcode */
46
+ add_shortcode( 'cartflows_checkout', array( $this, 'checkout_shortcode_markup' ) );
47
+
48
+ /* Preconfigured cart data */
49
+ add_action( 'wp', array( $this, 'preconfigured_cart_data' ), 1 );
50
+
51
+ /* Embed Checkout */
52
+ add_action( 'wp', array( $this, 'shortcode_load_data' ), 999 );
53
+
54
+ /* Ajax Endpoint */
55
+ add_filter( 'woocommerce_ajax_get_endpoint', array( $this, 'get_ajax_endpoint' ), 10, 2 );
56
+
57
+ add_filter( 'cartflows_add_before_main_section', array( $this, 'enable_logo_in_header' ) );
58
+
59
+ add_filter( 'cartflows_primary_container_bottom', array( $this, 'show_cartflows_copyright_message' ) );
60
+
61
+ add_filter( 'woocommerce_login_redirect', array( $this, 'after_login_redirect' ), 10, 2 );
62
+
63
+ add_action( 'wp_ajax_wcf_woo_apply_coupon', array( $this, 'apply_coupon' ) );
64
+ add_action( 'wp_ajax_nopriv_wcf_woo_apply_coupon', array( $this, 'apply_coupon' ) );
65
+
66
+ add_filter( 'global_cartflows_js_localize', array( $this, 'add_localize_vars' ) );
67
+
68
+ /* Global Checkout */
69
+ add_action( 'template_redirect', array( $this, 'global_checkout_template_redirect' ), 1 );
70
+
71
+ add_action( 'wp_ajax_wcf_woo_remove_coupon', array( $this, 'remove_coupon' ) );
72
+ add_action( 'wp_ajax_nopriv_wcf_woo_remove_coupon', array( $this, 'remove_coupon' ) );
73
+
74
+ add_action( 'wp_ajax_wcf_woo_remove_cart_product', array( $this, 'wcf_woo_remove_cart_product' ) );
75
+ add_action( 'wp_ajax_nopriv_wcf_woo_remove_cart_product', array( $this, 'wcf_woo_remove_cart_product' ) );
76
+
77
+ add_filter( 'woocommerce_paypal_args', array( $this, 'modify_paypal_args' ), 10, 2 );
78
+
79
+ add_filter( 'woocommerce_cart_item_name', array( $this, 'wcf_add_remove_label' ), 10, 3 );
80
+
81
+ add_action( 'woocommerce_before_calculate_totals', array( $this, 'custom_price_to_cart_item' ), 9999 );
82
+ }
83
+
84
+ /**
85
+ * Modify WooCommerce paypal arguments.
86
+ *
87
+ * @param array $args argumenets for payment.
88
+ * @param WC_Order $order order data.
89
+ * @return array
90
+ */
91
+ public function modify_paypal_args( $args, $order ) {
92
+
93
+ $checkout_id = wcf()->utils->get_checkout_id_from_post_data();
94
+
95
+ if ( ! $checkout_id ) {
96
+ return $args;
97
+ }
98
+
99
+ // Set cancel return URL.
100
+ $args['cancel_return'] = esc_url_raw( $order->get_cancel_order_url_raw( get_permalink( $checkout_id ) ) );
101
+
102
+ return $args;
103
+ }
104
+
105
+ /**
106
+ * Modify WooCommerce paypal arguments.
107
+ *
108
+ * @param string $product_name product name.
109
+ * @param object $cart_item cart item.
110
+ * @param string $cart_item_key cart item key.
111
+ * @return string
112
+ */
113
+ public function wcf_add_remove_label( $product_name, $cart_item, $cart_item_key ) {
114
+
115
+ $checkout_id = get_the_ID();
116
+ if ( ! $checkout_id ) {
117
+ $checkout_id = ( isset( $_POST['option']['checkout_id'] ) ) ? wp_unslash( $_POST['option']['checkout_id'] ) : '';//phpcs:ignore
118
+ }
119
+
120
+ if ( ! empty( $checkout_id ) ) {
121
+ $is_remove_product_option = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-remove-product-field' );
122
+ if ( 'checkout' === get_post_meta( $checkout_id, 'wcf-step-type', true ) && ( 'yes' === $is_remove_product_option ) ) {
123
+ $remove_label = apply_filters(
124
+ 'woocommerce_cart_item_remove_link',
125
+ sprintf(
126
+ '<a href="#" rel="nofollow" class="remove cartflows-icon-close" data-id="%s" data-item-key="%s" ></a>',
127
+ esc_attr( $cart_item['product_id'] ),
128
+ $cart_item_key
129
+ ),
130
+ $cart_item_key
131
+ );
132
+
133
+ $product_name = $remove_label . $product_name;
134
+ }
135
+ }
136
+
137
+ return $product_name;
138
+
139
+ }
140
+
141
+ /**
142
+ * Change order button text .
143
+ *
144
+ * @param string $woo_button_text place order.
145
+ * @return string
146
+ */
147
+ public function place_order_button_text( $woo_button_text ) {
148
+
149
+ $checkout_id = get_the_ID();
150
+ if ( ! $checkout_id ) {
151
+ $checkout_id = ( isset( $_POST['option']['checkout_id'] ) ) ? intval( $_POST['option']['checkout_id'] ) : 0; //phpcs:ignore
152
+ }
153
+
154
+ $wcf_order_button_text = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-checkout-place-order-button-text' );
155
+
156
+ if ( ! empty( $wcf_order_button_text ) ) {
157
+ $woo_button_text = $wcf_order_button_text;
158
+ }
159
+
160
+ return $woo_button_text;
161
+ }
162
+
163
+ /**
164
+ * Display all WooCommerce notices.
165
+ *
166
+ * @since 1.1.5
167
+ */
168
+ public function display_woo_notices() {
169
+
170
+ if ( null != WC()->session && function_exists( 'woocommerce_output_all_notices' ) ) {
171
+ woocommerce_output_all_notices();
172
+ }
173
+ }
174
+
175
+
176
+ /**
177
+ * Redirect from default to the global checkout page
178
+ *
179
+ * @since 1.0.0
180
+ */
181
+ public function global_checkout_template_redirect() {
182
+
183
+ if ( ! is_checkout() ) {
184
+ return;
185
+ }
186
+
187
+ if ( wcf()->utils->is_step_post_type() ) {
188
+ return;
189
+ }
190
+
191
+ // Return if the key OR Order paramater is found in the URL for certain Payment gateways.
192
+ if ( isset( $_GET['key'] ) || isset( $_GET['order'] ) ) { //phpcs:ignore
193
+ return;
194
+ }
195
+
196
+ // redirect only for cartflows checkout pages.
197
+ $order_pay_endpoint = get_option( 'woocommerce_checkout_pay_endpoint', 'order-pay' );
198
+ $order_received_endpoint = get_option( 'woocommerce_checkout_order_received_endpoint', 'order-received' );
199
+
200
+ $common = Cartflows_Helper::get_common_settings();
201
+
202
+ $global_checkout = $common['global_checkout'];
203
+
204
+ if (
205
+ isset( $_SERVER['REQUEST_URI'] ) &&
206
+ // ignore on order-pay.
207
+ false === wcf_mb_strpos( esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ), '/' . $order_pay_endpoint . '/' ) &&
208
+ // ignore on TY page.
209
+ false === wcf_mb_strpos( esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ), '/' . $order_received_endpoint . '/' ) &&
210
+ // ignore if order-pay in query param.
211
+ false === wcf_mb_strpos( esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ), $order_pay_endpoint . '=' )
212
+ ) {
213
+
214
+ if ( '' !== $global_checkout ) {
215
+
216
+ $link = apply_filters( 'cartflows_global_checkout_url', get_permalink( $global_checkout ) );
217
+
218
+ if ( ! empty( $link ) ) {
219
+
220
+ wp_safe_redirect( $link );
221
+ die();
222
+ }
223
+ }
224
+ }
225
+ }
226
+
227
+ /**
228
+ * Check for checkout flag
229
+ *
230
+ * @param bool $is_checkout is checkout.
231
+ *
232
+ * @return bool
233
+ */
234
+ public function woo_checkout_flag( $is_checkout ) {
235
+
236
+ if ( ! is_admin() ) {
237
+
238
+ if ( _is_wcf_checkout_type() || _is_wcf_checkout_shortcode() ) {
239
+
240
+ $is_checkout = true;
241
+ }
242
+ }
243
+
244
+ return $is_checkout;
245
+ }
246
+
247
+ /**
248
+ * Render checkout shortcode markup.
249
+ *
250
+ * @param array $atts attributes.
251
+ * @return string
252
+ */
253
+ public function checkout_shortcode_markup( $atts ) {
254
+
255
+ if ( ! function_exists( 'wc_print_notices' ) ) {
256
+ $notice_out = '<p class="woocommerce-notice">' . __( 'WooCommerce functions do not exist. If you are in an IFrame, please reload it.', 'cartflows' ) . '</p>';
257
+ $notice_out .= '<button onClick="location.reload()">' . __( 'Click Here to Reload', 'cartflows' ) . '</button>';
258
+
259
+ return $notice_out;
260
+ }
261
+
262
+ $atts = shortcode_atts(
263
+ array(
264
+ 'id' => 0,
265
+ ),
266
+ $atts
267
+ );
268
+
269
+ $checkout_id = intval( $atts['id'] );
270
+
271
+ if ( empty( $checkout_id ) ) {
272
+
273
+ if ( ! _is_wcf_checkout_type() ) {
274
+
275
+ return '<h4>' . __( 'Checkout ID not found', 'cartflows' ) . '</h4>';
276
+ }
277
+
278
+ global $post;
279
+
280
+ $checkout_id = intval( $post->ID );
281
+ }
282
+
283
+ $output = '';
284
+
285
+ ob_start();
286
+
287
+ do_action( 'cartflows_checkout_form_before', $checkout_id );
288
+
289
+ $checkout_layout = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-checkout-layout' );
290
+
291
+ $template_default = CARTFLOWS_CHECKOUT_DIR . 'templates/embed/checkout-template-simple.php';
292
+
293
+ $template_layout = apply_filters( 'cartflows_checkout_layout_template', $checkout_layout );
294
+
295
+ if ( file_exists( $template_layout ) ) {
296
+ include $template_layout;
297
+ } else {
298
+ include $template_default;
299
+ }
300
+
301
+ $output .= ob_get_clean();
302
+
303
+ return $output;
304
+ }
305
+
306
+ /**
307
+ * Configure Cart Data.
308
+ *
309
+ * @since 1.0.0
310
+ *
311
+ * @return void
312
+ */
313
+ public function preconfigured_cart_data() {
314
+
315
+ if ( is_admin() ) {
316
+ return;
317
+ }
318
+
319
+ global $post;
320
+
321
+ if ( _is_wcf_checkout_type() || _is_wcf_checkout_shortcode() ) {
322
+
323
+ if ( wp_doing_ajax() ) {
324
+ return;
325
+ } else {
326
+
327
+ if ( _is_wcf_checkout_type() ) {
328
+ $checkout_id = $post->ID;
329
+ } else {
330
+ $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
331
+ }
332
+
333
+ $global_checkout = intval( Cartflows_Helper::get_common_setting( 'global_checkout' ) );
334
+
335
+ if ( ! empty( $global_checkout ) && $checkout_id === $global_checkout ) {
336
+
337
+ if ( WC()->cart->is_empty() ) {
338
+ wc_add_notice( __( 'Your cart is currently empty.', 'cartflows' ), 'error' );
339
+ }
340
+
341
+ return;
342
+ }
343
+
344
+ if ( apply_filters( 'cartflows_skip_configure_cart', false, $checkout_id ) ) {
345
+ return;
346
+ }
347
+
348
+ do_action( 'cartflows_checkout_before_configure_cart', $checkout_id );
349
+
350
+ $flow_id = wcf()->utils->get_flow_id_from_step_id( $checkout_id );
351
+
352
+ if ( wcf()->flow->is_flow_testmode( $flow_id ) ) {
353
+ $products = 'dummy';
354
+ } else {
355
+ $products = wcf()->utils->get_selected_checkout_products( $checkout_id );
356
+ }
357
+
358
+ if ( ! is_array( $products ) ) {
359
+
360
+ if ( 'dummy' === $products ) {
361
+
362
+ $args = array(
363
+ 'posts_per_page' => 1,
364
+ 'orderby' => 'rand',
365
+ 'post_type' => 'product',
366
+ 'meta_query' => array( //phpcs:ignore
367
+ // Exclude out of stock products.
368
+ array(
369
+ 'key' => '_stock_status',
370
+ 'value' => 'outofstock',
371
+ 'compare' => 'NOT IN',
372
+ ),
373
+ ),
374
+ 'tax_query' => array( //phpcs:ignore
375
+ array(
376
+ 'taxonomy' => 'product_type',
377
+ 'field' => 'slug',
378
+ 'terms' => 'simple',
379
+ ),
380
+ ),
381
+ );
382
+
383
+ $random_product = get_posts( $args );
384
+
385
+ if ( isset( $random_product[0]->ID ) ) {
386
+ $products = array(
387
+ array(
388
+ 'product' => $random_product[0]->ID,
389
+ 'add_to_cart' => true,
390
+ ),
391
+ );
392
+ } else {
393
+ return;
394
+ }
395
+ } else {
396
+ return;
397
+ }
398
+ }
399
+
400
+ /* Empty the current cart */
401
+ WC()->cart->empty_cart();
402
+
403
+ if ( is_array( $products ) && empty( $products[0]['product'] ) ) {
404
+ wc_add_notice( __( 'No product is selected. Please select products from the checkout meta settings to continue.', 'cartflows' ), 'error' );
405
+ return;
406
+ }
407
+
408
+ /* Set customer session if not set */
409
+ if ( ! is_user_logged_in() && WC()->cart->is_empty() ) {
410
+ WC()->session->set_customer_session_cookie( true );
411
+ }
412
+
413
+ $cart_product_count = 0;
414
+ $cart_key = '';
415
+ $products_new = array();
416
+
417
+ $products = apply_filters( 'cartflows_selected_checkout_products', $products, $checkout_id );
418
+
419
+ foreach ( $products as $index => $data ) {
420
+
421
+ if ( ! isset( $data['product'] ) ) {
422
+ continue;
423
+ }
424
+
425
+ if ( empty( $data['add_to_cart'] ) ) {
426
+ continue;
427
+ }
428
+
429
+ if ( apply_filters( 'cartflows_skip_other_products', false, $cart_product_count ) ) {
430
+ break;
431
+ }
432
+
433
+ $product_id = $data['product'];
434
+ $_product = wc_get_product( $product_id );
435
+
436
+ if ( ! empty( $_product ) ) {
437
+
438
+ $quantity = 1;
439
+
440
+ if ( isset( $data['quantity'] ) && ! empty( $data['quantity'] ) ) {
441
+ $quantity = $data['quantity'];
442
+ }
443
+
444
+ $discount_type = isset( $data['discount_type'] ) ? $data['discount_type'] : '';
445
+ $discount_value = ! empty( $data['discount_value'] ) ? $data['discount_value'] : '';
446
+ $_product_price = $_product->get_price( $data['product'] );
447
+
448
+ $custom_price = $this->calculate_discount( '', $discount_type, $discount_value, $_product_price );
449
+
450
+ $cart_item_data = array();
451
+
452
+ if ( ! empty( $custom_price ) ) {
453
+
454
+ $cart_item_data = array(
455
+ 'custom_price' => $custom_price,
456
+ );
457
+ }
458
+
459
+ if ( ! $_product->is_type( 'grouped' ) && ! $_product->is_type( 'external' ) ) {
460
+
461
+ if ( $_product->is_type( 'variable' ) ) {
462
+
463
+ $default_attributes = $_product->get_default_attributes();
464
+
465
+ if ( ! empty( $default_attributes ) ) {
466
+
467
+ foreach ( $_product->get_children() as $variation_id ) {
468
+
469
+ $single_variation = new WC_Product_Variation( $variation_id );
470
+
471
+ if ( $default_attributes == $single_variation->get_attributes() ) {
472
+ $cart_key = WC()->cart->add_to_cart( $variation_id, $quantity, 0, array(), $cart_item_data );
473
+ $cart_product_count++;
474
+ }
475
+ }
476
+ } else {
477
+
478
+ $product_childrens = $_product->get_children();
479
+
480
+ if ( isset( $product_childrens[0] ) ) {
481
+ $variation = wc_get_product( $product_childrens[0] );
482
+ $_product_price = $variation->get_price();
483
+ $custom_price = $this->calculate_discount( '', $discount_type, $discount_value, $_product_price );
484
+ if ( ! empty( $custom_price ) ) {
485
+ $cart_item_data = array(
486
+ 'custom_price' => $custom_price,
487
+ 'data' => $data,
488
+ );
489
+ }
490
+ $cart_key = WC()->cart->add_to_cart( $product_childrens[0], $quantity, 0, array(), $cart_item_data );
491
+ $cart_product_count++;
492
+ } else {
493
+ echo '<p>' . esc_html__( 'Variations Not set', 'cartflows' ) . '</p>';
494
+ }
495
+ }
496
+ } else {
497
+ $cart_key = WC()->cart->add_to_cart( $product_id, $quantity, 0, array(), $cart_item_data );
498
+ $cart_product_count++;
499
+ }
500
+ } else {
501
+ $wrong_product_notice = __( 'This product can\'t be purchased', 'cartflows' );
502
+ wc_add_notice( $wrong_product_notice );
503
+ /**
504
+ WC()->cart->add_to_cart( $product_id, $quantity );.
505
+ */
506
+ }
507
+ }
508
+ $products_new[ $index ] = array(
509
+ 'cart_item_key' => $cart_key,
510
+ );
511
+ }
512
+
513
+ /* Set checkout products data */
514
+ wcf()->utils->set_selcted_checkout_products( $checkout_id, $products_new );
515
+
516
+ /* Since 1.2.2 */
517
+ wcf_do_action_deprecated( 'cartflows_checkout_aftet_configure_cart', array( $checkout_id ), '1.2.2', 'cartflows_checkout_after_configure_cart' );
518
+ do_action( 'cartflows_checkout_after_configure_cart', $checkout_id );
519
+ }
520
+ }
521
+ }
522
+
523
+ /**
524
+ * Load shortcode data.
525
+ *
526
+ * @return void
527
+ */
528
+ public function shortcode_load_data() {
529
+
530
+ if ( _is_wcf_checkout_type() || _is_wcf_checkout_shortcode() ) {
531
+
532
+ add_action( 'wp_enqueue_scripts', array( $this, 'shortcode_scripts' ), 21 );
533
+
534
+ add_action( 'wp_enqueue_scripts', array( $this, 'compatibility_scripts' ), 101 );
535
+
536
+ /* Show notices if cart has errors */
537
+ add_action( 'woocommerce_cart_has_errors', 'woocommerce_output_all_notices' );
538
+
539
+ add_action( 'woocommerce_checkout_after_customer_details', array( $this, 'order_wrap_div_start' ), 99 );
540
+
541
+ add_action( 'woocommerce_checkout_after_order_review', array( $this, 'order_wrap_div_end' ), 99 );
542
+
543
+ // Outputting the hidden field in checkout page.
544
+ add_action( 'woocommerce_after_order_notes', array( $this, 'checkout_shortcode_post_id' ), 99 );
545
+ add_action( 'woocommerce_login_form_end', array( $this, 'checkout_shortcode_post_id' ), 99 );
546
+
547
+ remove_all_actions( 'woocommerce_checkout_billing' );
548
+ remove_all_actions( 'woocommerce_checkout_shipping' );
549
+
550
+ // Hook in actions once.
551
+ add_action( 'woocommerce_checkout_billing', array( WC()->checkout, 'checkout_form_billing' ) );
552
+ add_action( 'woocommerce_checkout_shipping', array( WC()->checkout, 'checkout_form_shipping' ) );
553
+
554
+ remove_action( 'woocommerce_before_checkout_form', 'woocommerce_checkout_coupon_form' );
555
+
556
+ add_action( 'woocommerce_checkout_order_review', array( $this, 'display_custom_coupon_field' ) );
557
+
558
+ add_filter( 'woocommerce_checkout_fields', array( $this, 'add_three_column_layout_fields' ) );
559
+
560
+ add_filter( 'woocommerce_cart_totals_coupon_html', array( $this, 'remove_coupon_text' ) );
561
+
562
+ add_filter( 'woocommerce_order_button_text', array( $this, 'place_order_button_text' ), 10, 1 );
563
+
564
+ global $post;
565
+
566
+ if ( _is_wcf_checkout_type() ) {
567
+ $checkout_id = $post->ID;
568
+ } else {
569
+ $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
570
+ }
571
+
572
+ do_action( 'cartflows_checkout_before_shortcode', $checkout_id );
573
+ }
574
+ }
575
+
576
+ /**
577
+ * Render checkout ID hidden field.
578
+ *
579
+ * @param array $checkout checkout session data.
580
+ * @return void
581
+ */
582
+ public function checkout_shortcode_post_id( $checkout ) {
583
+
584
+ global $post;
585
+
586
+ if ( _is_wcf_checkout_type() ) {
587
+ $checkout_id = $post->ID;
588
+ } else {
589
+ $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
590
+ }
591
+
592
+ $flow_id = get_post_meta( $checkout_id, 'wcf-flow-id', true );
593
+
594
+ echo '<input type="hidden" class="input-hidden _wcf_flow_id" name="_wcf_flow_id" value="' . intval( $flow_id ) . '">';
595
+ echo '<input type="hidden" class="input-hidden _wcf_checkout_id" name="_wcf_checkout_id" value="' . intval( $checkout_id ) . '">';
596
+ }
597
+
598
+ /**
599
+ * Load shortcode scripts.
600
+ *
601
+ * @return void
602
+ */
603
+ public function shortcode_scripts() {
604
+
605
+ wp_enqueue_style( 'wcf-checkout-template', wcf()->utils->get_css_url( 'checkout-template' ), '', CARTFLOWS_VER );
606
+
607
+ wp_enqueue_script(
608
+ 'wcf-checkout-template',
609
+ wcf()->utils->get_js_url( 'checkout-template' ),
610
+ array( 'jquery' ),
611
+ CARTFLOWS_VER,
612
+ true
613
+ );
614
+
615
+ do_action( 'cartflows_checkout_scripts' );
616
+
617
+ $style = $this->generate_style();
618
+
619
+ wp_add_inline_style( 'wcf-checkout-template', $style );
620
+
621
+ }
622
+
623
+ /**
624
+ * Load compatibility scripts.
625
+ *
626
+ * @return void
627
+ */
628
+ public function compatibility_scripts() {
629
+
630
+ global $post;
631
+
632
+ if ( _is_wcf_checkout_type() ) {
633
+ $checkout_id = $post->ID;
634
+ } else {
635
+ $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
636
+ }
637
+
638
+ // Add DIVI Compatibility css if DIVI theme is enabled.
639
+ if ( Cartflows_Compatibility::get_instance()->is_divi_enabled() ||
640
+ Cartflows_Compatibility::get_instance()->is_divi_builder_enabled( $checkout_id )
641
+ ) {
642
+ wp_enqueue_style( 'wcf-checkout-template-divi', wcf()->utils->get_css_url( 'checkout-template-divi' ), '', CARTFLOWS_VER );
643
+ }
644
+
645
+ // Add Flatsome Compatibility css if Flatsome theme is enabled.
646
+ if ( Cartflows_Compatibility::get_instance()->is_flatsome_enabled() ) {
647
+ wp_enqueue_style( 'wcf-checkout-template-flatsome', wcf()->utils->get_css_url( 'checkout-template-flatsome' ), '', CARTFLOWS_VER );
648
+ }
649
+
650
+ // Add The7 Compatibility css if The7 theme is enabled.
651
+ if ( Cartflows_Compatibility::get_instance()->is_the_seven_enabled() ) {
652
+ wp_enqueue_style( 'wcf-checkout-template-the-seven', wcf()->utils->get_css_url( 'checkout-template-the-seven' ), '', CARTFLOWS_VER );
653
+ }
654
+ }
655
+
656
+ /**
657
+ * Generate styles.
658
+ *
659
+ * @return string
660
+ */
661
+ public function generate_style() {
662
+
663
+ global $post;
664
+
665
+ if ( _is_wcf_checkout_type() ) {
666
+ $checkout_id = $post->ID;
667
+ } else {
668
+ $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
669
+ }
670
+
671
+ /*Output css variable */
672
+ $output = '';
673
+
674
+ CartFlows_Font_Families::render_fonts( $checkout_id );
675
+
676
+ $primary_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-primary-color' );
677
+
678
+ $base_font_family = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-base-font-family' );
679
+
680
+ $header_logo_width = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-header-logo-width' );
681
+
682
+ /**
683
+ $base_font_weight = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-base-font-weight' );*/
684
+ $r = '';
685
+ $g = '';
686
+ $b = '';
687
+
688
+ $field_tb_padding = '';
689
+ $field_lr_padding = '';
690
+
691
+ $field_heading_color = '';
692
+ $field_color = '';
693
+ $field_bg_color = '';
694
+ $field_border_color = '';
695
+ $field_label_color = '';
696
+ $submit_tb_padding = '';
697
+ $submit_lr_padding = '';
698
+ $hl_bg_color = '';
699
+ $field_input_size = '';
700
+ $box_border_color = '';
701
+ $section_bg_color = '';
702
+ $submit_button_height = '';
703
+ $submit_color = '';
704
+ $submit_bg_color = $primary_color;
705
+ $submit_border_color = $primary_color;
706
+
707
+ $submit_hover_color = '';
708
+ $submit_bg_hover_color = $primary_color;
709
+ $submit_border_hover_color = $primary_color;
710
+
711
+ $section_heading_color = '';
712
+
713
+ $is_advance_option = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-advance-options-fields' );
714
+
715
+ $button_font_family = '';
716
+ $button_font_weight = '';
717
+ $input_font_family = '';
718
+ $input_font_weight = '';
719
+ $heading_font_family = '';
720
+ $heading_font_weight = '';
721
+ $base_font_family = $base_font_family;
722
+ /**
723
+ $base_font_weight = $base_font_weight;*/
724
+
725
+ if ( 'yes' == $is_advance_option ) {
726
+
727
+ /**
728
+ * Get Font Family and Font Weight weight values
729
+ */
730
+ $section_bg_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-section-bg-color' );
731
+
732
+ $heading_font_family = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-heading-font-family' );
733
+ $heading_font_weight = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-heading-font-weight' );
734
+ $section_heading_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-heading-color' );
735
+ $button_font_family = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-button-font-family' );
736
+ $button_font_weight = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-button-font-weight' );
737
+ $input_font_family = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-input-font-family' );
738
+ $input_font_weight = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-input-font-weight' );
739
+ $field_tb_padding = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-tb-padding' );
740
+ $field_lr_padding = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-lr-padding' );
741
+ $field_input_size = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-input-field-size' );
742
+
743
+ $field_heading_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-heading-color' );
744
+
745
+ $field_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-color' );
746
+
747
+ $field_bg_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-bg-color' );
748
+
749
+ $field_border_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-border-color' );
750
+
751
+ $field_label_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-label-color' );
752
+
753
+ $submit_tb_padding = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-tb-padding' );
754
+
755
+ $submit_lr_padding = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-lr-padding' );
756
+
757
+ $submit_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-color' );
758
+
759
+ $submit_bg_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-bg-color', $primary_color );
760
+
761
+ $submit_border_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-border-color', $primary_color );
762
+
763
+ $submit_border_hover_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-border-hover-color', $primary_color );
764
+
765
+ $submit_hover_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-hover-color' );
766
+
767
+ $submit_bg_hover_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-bg-hover-color', $primary_color );
768
+
769
+ $hl_bg_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-hl-bg-color' );
770
+
771
+ $box_border_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-box-border-color' );
772
+
773
+ $submit_button_height = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-input-button-size' );
774
+
775
+ /**
776
+ * Get font values
777
+ */
778
+
779
+ if ( 'custom' == $submit_button_height ) {
780
+ $submit_button_height = '38px';
781
+ }
782
+
783
+ if ( 'custom' == $field_input_size ) {
784
+ $field_input_size = '38px';
785
+ }
786
+ }
787
+ if ( isset( $primary_color ) ) {
788
+
789
+ list($r, $g, $b) = sscanf( $primary_color, '#%02x%02x%02x' );
790
+ }
791
+
792
+ if ( Cartflows_Compatibility::get_instance()->is_divi_enabled() ||
793
+ Cartflows_Compatibility::get_instance()->is_divi_builder_enabled( $checkout_id ) ) {
794
+
795
+ include CARTFLOWS_CHECKOUT_DIR . 'includes/checkout-dynamic-divi-css.php';
796
+
797
+ } else {
798
+ include CARTFLOWS_CHECKOUT_DIR . 'includes/checkout-dynamic-css.php';
799
+ }
800
+
801
+ return $output;
802
+ }
803
+
804
+ /**
805
+ * Get ajax end points.
806
+ *
807
+ * @param string $endpoint_url end point URL.
808
+ * @param string $request end point request.
809
+ * @return string
810
+ */
811
+ public function get_ajax_endpoint( $endpoint_url, $request ) {
812
+
813
+ global $post;
814
+
815
+ if ( ! empty( $post ) && ! empty( $_SERVER['REQUEST_URI'] ) ) {
816
+
817
+ if ( _is_wcf_checkout_type() ) {
818
+
819
+ if ( mb_strpos( $endpoint_url, 'checkout', 0, 'utf-8' ) === false ) {
820
+
821
+ if ( '' === $request ) {
822
+ $query_args = array(
823
+ 'wc-ajax' => '%%endpoint%%',
824
+ );
825
+ } else {
826
+ $query_args = array(
827
+ 'wc-ajax' => $request,
828
+ );
829
+ }
830
+
831
+ $uri = explode( '?', $_SERVER['REQUEST_URI'], 2 ); //phpcs:ignore
832
+ $uri = $uri[0];
833
+
834
+ $endpoint_url = esc_url( add_query_arg( $query_args, $uri ) );
835
+ }
836
+ }
837
+ }
838
+
839
+ return $endpoint_url;
840
+ }
841
+
842
+
843
+ /**
844
+ * Save checkout fields.
845
+ *
846
+ * @param int $order_id order id.
847
+ * @param array $posted posted data.
848
+ * @return void
849
+ */
850
+ public function save_checkout_fields( $order_id, $posted ) {
851
+
852
+ if ( isset( $_POST['_wcf_checkout_id'] ) ) { //phpcs:ignore
853
+
854
+ $checkout_id = wc_clean( intval( $_POST['_wcf_checkout_id'] ) ); //phpcs:ignore
855
+
856
+ update_post_meta( $order_id, '_wcf_checkout_id', $checkout_id );
857
+
858
+ if ( isset( $_POST['_wcf_flow_id'] ) ) { //phpcs:ignore
859
+
860
+ $flow_id = wc_clean( intval( $_POST['_wcf_flow_id'] ) ); //phpcs:ignore
861
+
862
+ update_post_meta( $order_id, '_wcf_flow_id', $flow_id );
863
+ }
864
+ }
865
+
866
+ }
867
+
868
+ /**
869
+ * Enable Logo In Header Of Checkout Page
870
+ *
871
+ * @return void
872
+ */
873
+ public function enable_logo_in_header() {
874
+ global $post;
875
+
876
+ if ( _is_wcf_checkout_type() ) {
877
+ $checkout_id = $post->ID;
878
+ } else {
879
+ $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
880
+ }
881
+
882
+ $header_logo_image = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-header-logo-image' );
883
+ $add_image_markup = '';
884
+
885
+ if ( isset( $header_logo_image ) && ! empty( $header_logo_image ) ) {
886
+ $add_image_markup = '<div class="wcf-checkout-header-image">';
887
+ $add_image_markup .= '<img src="' . $header_logo_image . '" />';
888
+ $add_image_markup .= '</div>';
889
+ }
890
+
891
+ echo $add_image_markup;
892
+ }
893
+
894
+ /**
895
+ * Add text to the bootom of the checkout page.
896
+ *
897
+ * @return void
898
+ */
899
+ public function show_cartflows_copyright_message() {
900
+ $output_string = '';
901
+
902
+ $output_string .= '<div class="wcf-footer-primary">';
903
+ $output_string .= '<div class="wcf-footer-content">';
904
+ $output_string .= '<p class="wcf-footer-message">';
905
+ $output_string .= 'Checkout powered by CartFlows';
906
+ $output_string .= '</p>';
907
+ $output_string .= '</div>';
908
+ $output_string .= '</div>';
909
+
910
+ echo $output_string;
911
+ }
912
+
913
+ /**
914
+ * Redirect users to our checkout if hidden param
915
+ *
916
+ * @param string $redirect redirect url.
917
+ * @param object $user user.
918
+ * @return string
919
+ */
920
+ public function after_login_redirect( $redirect, $user ) {
921
+
922
+ if ( isset( $_POST['_wcf_checkout_id'] ) ) { //phpcs:ignore
923
+
924
+ $checkout_id = intval( $_POST['_wcf_checkout_id'] ); //phpcs:ignore
925
+
926
+ $redirect = get_permalink( $checkout_id );
927
+ }
928
+
929
+ return $redirect;
930
+ }
931
+
932
+ /**
933
+ * Display coupon code field after review order fields.
934
+ */
935
+ public function display_custom_coupon_field() {
936
+
937
+ $coupon_enabled = apply_filters( 'woocommerce_coupons_enabled', true );
938
+ $show_coupon = apply_filters( 'cartflows_show_coupon_field', true );
939
+
940
+ if ( ! ( $coupon_enabled && $show_coupon ) ) {
941
+ return;
942
+
943
+ }
944
+
945
+ $coupon_field = array(
946
+ 'field_text' => __( 'Coupon Code', 'cartflows' ),
947
+ 'button_text' => __( 'Apply', 'cartflows' ),
948
+ 'class' => '',
949
+ );
950
+
951
+ $coupon_field = apply_filters( 'cartflows_coupon_field_options', $coupon_field );
952
+
953
+ ob_start();
954
+ ?>
955
+ <div class="wcf-custom-coupon-field <?php echo $coupon_field['class']; ?>" id="wcf_custom_coupon_field">
956
+ <div class="wcf-coupon-col-1">
957
+ <span>
958
+ <input type="text" name="coupon_code" class="input-text wcf-coupon-code-input" placeholder="<?php echo $coupon_field['field_text']; ?>" id="coupon_code" value="">
959
+ </span>
960
+ </div>
961
+ <div class="wcf-coupon-col-2">
962
+ <span>
963
+ <button type="button" class="button wcf-submit-coupon wcf-btn-small" name="apply_coupon" value="Apply"><?php echo $coupon_field['button_text']; ?></button>
964
+ </span>
965
+ </div>
966
+ </div>
967
+ <?php
968
+ echo ob_get_clean();
969
+ }
970
+
971
+ /**
972
+ * Apply filter to change class of remove coupon field.
973
+ *
974
+ * @param string $coupon coupon.
975
+ * @return string
976
+ */
977
+ public function remove_coupon_text( $coupon ) {
978
+
979
+ $coupon = str_replace( 'woocommerce-remove-coupon', 'wcf-remove-coupon', $coupon );
980
+ return $coupon;
981
+
982
+ }
983
+ /**
984
+ * Apply filter to change the placeholder text of coupon field.
985
+ *
986
+ * @return string
987
+ */
988
+ public function coupon_field_placeholder() {
989
+ return apply_filters( 'cartflows_coupon_field_placeholder', __( 'Coupon Code', 'cartflows' ) );
990
+ }
991
+
992
+ /**
993
+ * Apply filter to change the button text of coupon field.
994
+ *
995
+ * @return string
996
+ */
997
+ public function coupon_button_text() {
998
+ return apply_filters( 'cartflows_coupon_button_text', __( 'Apply', 'cartflows' ) );
999
+ }
1000
+
1001
+ /**
1002
+ * Apply coupon on submit of custom coupon form.
1003
+ */
1004
+ public function apply_coupon() {
1005
+
1006
+ $response = '';
1007
+
1008
+ check_ajax_referer( 'wcf-apply-coupon', 'security' );
1009
+ if ( ! empty( $_POST['coupon_code'] ) ) {
1010
+ $result = WC()->cart->add_discount( sanitize_text_field( wp_unslash( $_POST['coupon_code'] ) ) );
1011
+ } else {
1012
+ wc_add_notice( WC_Coupon::get_generic_coupon_error( WC_Coupon::E_WC_COUPON_PLEASE_ENTER ), 'error' );
1013
+ }
1014
+
1015
+ $response = array(
1016
+ 'status' => $result,
1017
+ 'msg' => wc_print_notices( true ),
1018
+ );
1019
+
1020
+ echo wp_json_encode( $response );
1021
+
1022
+ die();
1023
+ }
1024
+
1025
+
1026
+ /**
1027
+ * Added ajax nonce to localize variable.
1028
+ *
1029
+ * @param array $vars localize variables.
1030
+ */
1031
+ public function add_localize_vars( $vars ) {
1032
+
1033
+ $vars['wcf_validate_coupon_nonce'] = wp_create_nonce( 'wcf-apply-coupon' );
1034
+
1035
+ $vars['wcf_validate_remove_coupon_nonce'] = wp_create_nonce( 'wcf-remove-coupon' );
1036
+
1037
+ $vars['wcf_validate_remove_cart_product_nonce'] = wp_create_nonce( 'wcf-remove-cart-product' );
1038
+
1039
+ $vars['allow_persistance'] = apply_filters( 'cartflows_allow_persistace', 'yes' );
1040
+
1041
+ return $vars;
1042
+ }
1043
+
1044
+ /**
1045
+ * Add custom class to the fields to change the UI to three column.
1046
+ *
1047
+ * @param array $fields fields.
1048
+ */
1049
+ public function add_three_column_layout_fields( $fields ) {
1050
+
1051
+ if ( empty( $fields['billing']['billing_address_2'] ) ) {
1052
+
1053
+ if ( isset( $fields['billing']['billing_address_1'] ) && is_array( $fields['billing']['billing_address_1'] ) ) {
1054
+ $fields['billing']['billing_address_1']['class'][] = 'form-row-full';
1055
+ }
1056
+ }
1057
+
1058
+ if ( ! empty( $fields['billing']['billing_company'] ) ) {
1059
+
1060
+ if ( isset( $fields['billing']['billing_company'] ) && is_array( $fields['billing']['billing_company'] ) ) {
1061
+ $fields['billing']['billing_company']['class'][] = 'form-row-full';
1062
+ }
1063
+ }
1064
+
1065
+ if ( ! empty( $fields['shipping']['shipping_company'] ) ) {
1066
+
1067
+ if ( isset( $fields['shipping']['shipping_company'] ) && is_array( $fields['shipping']['shipping_company'] ) ) {
1068
+ $fields['shipping']['shipping_company']['class'][] = 'form-row-full';
1069
+ }
1070
+ }
1071
+
1072
+ if ( ! empty( $fields['billing']['billing_country'] ) ) {
1073
+
1074
+ if ( isset( $fields['billing']['billing_country'] ) && is_array( $fields['billing']['billing_country'] ) ) {
1075
+ $fields['billing']['billing_country']['class'][] = 'form-row-full';
1076
+ }
1077
+ }
1078
+
1079
+ if ( ! empty( $fields['shipping']['shipping_country'] ) ) {
1080
+
1081
+ if ( isset( $fields['shipping']['shipping_country'] ) && is_array( $fields['shipping']['shipping_country'] ) ) {
1082
+ $fields['shipping']['shipping_country']['class'][] = 'form-row-full';
1083
+ }
1084
+ }
1085
+
1086
+ if ( ! empty( $fields['billing']['billing_phone'] ) ) {
1087
+
1088
+ if ( isset( $fields['billing']['billing_phone'] ) && is_array( $fields['billing']['billing_phone'] ) ) {
1089
+ $fields['billing']['billing_phone']['class'][] = 'form-row-full';
1090
+ }
1091
+ }
1092
+
1093
+ if ( ! empty( $fields['billing']['billing_email'] ) ) {
1094
+
1095
+ if ( isset( $fields['billing']['billing_email'] ) && is_array( $fields['billing']['billing_email'] ) ) {
1096
+ $fields['billing']['billing_email']['class'][] = 'form-row-full';
1097
+ }
1098
+ }
1099
+
1100
+ if ( empty( $fields['shipping']['shipping_address_2'] ) ) {
1101
+
1102
+ if ( isset( $fields['shipping']['shipping_address_1'] ) && is_array( $fields['shipping']['shipping_address_1'] ) ) {
1103
+ $fields['shipping']['shipping_address_1']['class'][] = 'form-row-full';
1104
+ }
1105
+ }
1106
+
1107
+ if ( isset( $fields['billing']['billing_city'] ) &&
1108
+ isset( $fields['billing']['billing_state'] ) && isset( $fields['billing']['billing_postcode'] ) ) {
1109
+
1110
+ $fields['billing']['billing_city']['class'][] = 'wcf-column-33';
1111
+ $fields['billing']['billing_state']['class'][] = 'wcf-column-33';
1112
+ $fields['billing']['billing_postcode']['class'][] = 'wcf-column-33';
1113
+ }
1114
+
1115
+ if ( isset( $fields['shipping']['shipping_city'] ) &&
1116
+ isset( $fields['shipping']['shipping_state'] ) && isset( $fields['shipping']['shipping_postcode'] ) ) {
1117
+
1118
+ $fields['shipping']['shipping_city']['class'][] = 'wcf-column-33';
1119
+ $fields['shipping']['shipping_state']['class'][] = 'wcf-column-33';
1120
+ $fields['shipping']['shipping_postcode']['class'][] = 'wcf-column-33';
1121
+ }
1122
+
1123
+ return $fields;
1124
+ }
1125
+
1126
+ /**
1127
+ * Add opening dev
1128
+ *
1129
+ * @since 1.0.0
1130
+ */
1131
+ public function order_wrap_div_start() {
1132
+
1133
+ echo "<div class='wcf-order-wrap'> ";
1134
+ }
1135
+
1136
+ /**
1137
+ * Add closing dev
1138
+ *
1139
+ * @since 1.0.0
1140
+ */
1141
+ public function order_wrap_div_end() {
1142
+
1143
+ echo '</div> ';
1144
+ }
1145
+ /**
1146
+ * Remove coupon.
1147
+ */
1148
+ public function remove_coupon() {
1149
+
1150
+ check_ajax_referer( 'wcf-remove-coupon', 'security' );
1151
+ $coupon = isset( $_POST['coupon_code'] ) ? wc_clean( wp_unslash( $_POST['coupon_code'] ) ) : false; //phpcs:ignore
1152
+
1153
+ if ( empty( $coupon ) ) {
1154
+ echo "<div class='woocommerce-error'>" . esc_html__( 'Sorry there was a problem removing this coupon.', 'cartflows' );
1155
+ } else {
1156
+ WC()->cart->remove_coupon( $coupon );
1157
+ echo "<div class='woocommerce-error'>" . esc_html__( 'Coupon has been removed.', 'cartflows' ) . '</div>';
1158
+ }
1159
+ wc_print_notices();
1160
+ wp_die();
1161
+ }
1162
+
1163
+ /**
1164
+ * Remove cart item.
1165
+ */
1166
+ public function wcf_woo_remove_cart_product() {
1167
+
1168
+ check_ajax_referer( 'wcf-remove-cart-product', 'security' );
1169
+ $product_key = isset( $_POST['p_key'] ) ? wc_clean( wp_unslash( $_POST['p_key'] ) ) : false; //phpcs:ignore
1170
+ $product_id = isset( $_POST['p_id'] ) ? wc_clean( wp_unslash( $_POST['p_id'] ) ) : ''; //phpcs:ignore
1171
+ $product_title = get_the_title( $product_id );
1172
+
1173
+ $needs_shipping = false;
1174
+
1175
+ if ( empty( $product_key ) ) {
1176
+ $msg = "<div class='woocommerce-message'>" . __( 'Sorry there was a problem removing ', 'cartflows' ) . $product_title;
1177
+ } else {
1178
+ WC()->cart->remove_cart_item( $product_key );
1179
+ $msg = "<div class='woocommerce-message'>" . $product_title . __( ' has been removed.', 'cartflows' ) . '</div>';
1180
+ }
1181
+
1182
+ foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
1183
+ if ( $values['data']->needs_shipping() ) {
1184
+ $needs_shipping = true;
1185
+ break;
1186
+ }
1187
+ }
1188
+
1189
+ $response = array(
1190
+ 'need_shipping' => $needs_shipping,
1191
+ 'msg' => $msg,
1192
+ );
1193
+
1194
+ echo wp_json_encode( $response );
1195
+ wp_die();
1196
+ }
1197
+
1198
+ /**
1199
+ * Calculate discount for product.
1200
+ *
1201
+ * @param string $discount_coupon discount coupon.
1202
+ * @param string $discount_type discount type.
1203
+ * @param int $discount_value discount value.
1204
+ * @param int $_product_price product price.
1205
+ * @return int
1206
+ * @since 1.1.5
1207
+ */
1208
+ public function calculate_discount( $discount_coupon, $discount_type, $discount_value, $_product_price ) {
1209
+
1210
+ $custom_price = '';
1211
+
1212
+ if ( ! empty( $discount_type ) ) {
1213
+ if ( 'discount_percent' === $discount_type ) {
1214
+
1215
+ if ( $discount_value > 0 ) {
1216
+ $custom_price = $_product_price - ( ( $_product_price * $discount_value ) / 100 );
1217
+ }
1218
+ } elseif ( 'discount_price' === $discount_type ) {
1219
+
1220
+ if ( $discount_value > 0 ) {
1221
+ $custom_price = $_product_price - $discount_value;
1222
+ }
1223
+ } elseif ( 'coupon' === $discount_type ) {
1224
+
1225
+ if ( ! empty( $discount_coupon ) ) {
1226
+ WC()->cart->add_discount( $discount_coupon );
1227
+ }
1228
+ }
1229
+ }
1230
+
1231
+ return $custom_price;
1232
+ }
1233
+
1234
+ /**
1235
+ * Preserve the custom item price added by Variations & Quantity feature
1236
+ *
1237
+ * @param array $cart_object cart object.
1238
+ * @since 1.0.0
1239
+ */
1240
+ public function custom_price_to_cart_item( $cart_object ) {
1241
+
1242
+ if ( wp_doing_ajax() && ! WC()->session->__isset( 'reload_checkout' ) ) {
1243
+
1244
+ foreach ( $cart_object->cart_contents as $key => $value ) {
1245
+
1246
+ if ( isset( $value['custom_price'] ) ) {
1247
+
1248
+ $custom_price = floatval( $value['custom_price'] );
1249
+ $value['data']->set_price( $custom_price );
1250
+ }
1251
+ }
1252
+ }
1253
+ }
1254
+
1255
+ }
1256
+
1257
+ /**
1258
+ * Kicking this off by calling 'get_instance()' method
1259
+ */
1260
+ Cartflows_Checkout_Markup::get_instance();
modules/checkout/classes/class-cartflows-checkout-meta.php CHANGED
@@ -1,959 +1,959 @@
1
- <?php
2
- /**
3
- * Checkout post meta
4
- *
5
- * @package CartFlows
6
- */
7
-
8
- /**
9
- * Meta Boxes setup
10
- */
11
- class Cartflows_Checkout_Meta extends Cartflows_Meta {
12
-
13
-
14
- /**
15
- * Instance
16
- *
17
- * @var $instance
18
- */
19
- private static $instance;
20
-
21
- /**
22
- * Meta Option
23
- *
24
- * @var $meta_option
25
- */
26
- private static $meta_option = null;
27
-
28
- /**
29
- * Initiator
30
- */
31
- public static function get_instance() {
32
- if ( ! isset( self::$instance ) ) {
33
- self::$instance = new self();
34
- }
35
-
36
- return self::$instance;
37
- }
38
-
39
- /**
40
- * Constructor
41
- */
42
- public function __construct() {
43
-
44
- /* Init Metabox */
45
- add_action( 'load-post.php', array( $this, 'init_metabox' ) );
46
- add_action( 'load-post-new.php', array( $this, 'init_metabox' ) );
47
- }
48
- /**
49
- * Init Metabox
50
- */
51
- public function init_metabox() {
52
-
53
- add_action( 'add_meta_boxes', array( $this, 'setup_meta_box' ) );
54
- add_action( 'save_post', array( $this, 'save_meta_box' ) );
55
- }
56
-
57
- /**
58
- * Setup Metabox
59
- */
60
- public function setup_meta_box() {
61
-
62
- if ( _is_wcf_checkout_type() ) {
63
- add_meta_box(
64
- 'wcf-checkout-settings', // Id.
65
- __( 'Checkout Layout', 'cartflows' ), // Title.
66
- array( $this, 'markup_meta_box' ), // Callback.
67
- wcf()->utils->get_step_post_type(), // Post_type.
68
- 'normal', // Context.
69
- 'high' // Priority.
70
- );
71
- }
72
- }
73
-
74
- /**
75
- * Metabox Markup
76
- *
77
- * @param object $post Post object.
78
- * @return void
79
- */
80
- public function markup_meta_box( $post ) {
81
-
82
- wp_nonce_field( 'save-nonce-checkout-step-meta', 'nonce-checkout-step-meta' );
83
-
84
- $stored = get_post_meta( $post->ID );
85
-
86
- $checkout_meta = self::get_meta_option( $post->ID );
87
-
88
- // Set stored and override defaults.
89
- foreach ( $stored as $key => $value ) {
90
- if ( array_key_exists( $key, $checkout_meta ) ) {
91
- self::$meta_option[ $key ]['default'] = ( isset( $stored[ $key ][0] ) ) ? maybe_unserialize( $stored[ $key ][0] ) : '';
92
- } else {
93
- self::$meta_option[ $key ]['default'] = ( isset( $stored[ $key ][0] ) ) ? $stored[ $key ][0] : '';
94
- }
95
- }
96
-
97
- // Get defaults.
98
- $meta = self::get_meta_option( $post->ID );
99
- $checkout_data = array();
100
-
101
- foreach ( $meta as $key => $value ) {
102
- $checkout_data[ $key ] = $meta[ $key ]['default'];
103
- }
104
-
105
- /**
106
- $billing_fields = Cartflows_Helper::get_checkout_fields( 'billing', $post->ID );
107
-
108
- // For loop
109
- foreach ( $billing_fields as $key => $value ) {
110
-
111
- $checkout_data[ 'wcf-' . $key ] = $meta[ 'wcf-' . $key ]['default'];
112
- }
113
-
114
- $shipping_fields = Cartflows_Helper::get_checkout_fields( 'shipping', $post->ID );
115
-
116
- foreach ( $shipping_fields as $key => $value ) {
117
-
118
- $checkout_data[ 'wcf-' . $key ] = $meta[ 'wcf-' . $key ]['default'];
119
- }
120
-
121
- $additional_fields = Cartflows_Helper::get_checkout_fields( 'additional', $post->ID );
122
-
123
- foreach ( $additional_fields as $key => $value ) {
124
-
125
- $checkout_data[ 'wcf-' . $key ] = $meta[ 'wcf-' . $key ]['default'];
126
- }
127
- */
128
-
129
- do_action( 'wcf_checkout_settings_markup_before' );
130
- $this->tabs_markup( $checkout_data, $post->ID );
131
- do_action( 'wcf_checkout_settings_markup_after' );
132
- }
133
-
134
- /**
135
- * Page Header Tabs
136
- *
137
- * @param array $options options.
138
- * @param int $post_id post ID.
139
- */
140
- public function tabs_markup( $options, $post_id ) {
141
-
142
- $active_tab = get_post_meta( $post_id, 'wcf-active-tab', true );
143
-
144
- if ( empty( $active_tab ) ) {
145
- $active_tab = 'wcf-checkout-shortcodes';
146
- }
147
-
148
- $tab_array = array(
149
- array(
150
- 'title' => __( 'Shortcodes', 'cartflows' ),
151
- 'id' => 'wcf-checkout-shortcodes',
152
- 'class' => 'wcf-checkout-shortcodes' === $active_tab ? 'wcf-tab wp-ui-text-highlight active' : 'wcf-tab',
153
- 'icon' => 'dashicons-editor-code',
154
- ),
155
- array(
156
- 'title' => __( 'Select Product', 'cartflows' ),
157
- 'id' => 'wcf-checkout-general',
158
- 'class' => 'wcf-checkout-general' === $active_tab ? 'wcf-tab wp-ui-text-highlight active' : 'wcf-tab',
159
- 'icon' => 'dashicons-info',
160
- ),
161
- array(
162
- 'title' => __( 'Product Options', 'cartflows' ),
163
- 'id' => 'wcf-product-options',
164
- 'class' => 'wcf-product-options' === $active_tab ? 'wcf-tab wp-ui-text-highlight active' : 'wcf-tab',
165
- 'icon' => 'dashicons dashicons-screenoptions',
166
- ),
167
- array(
168
- 'title' => __( 'Order Bump', 'cartflows' ),
169
- 'id' => 'wcf-product-order-bump',
170
- 'class' => 'wcf-product-order-bump' === $active_tab ? 'wcf-tab wp-ui-text-highlight active' : 'wcf-tab',
171
- 'icon' => 'dashicons-cart',
172
- ),
173
- array(
174
- 'title' => __( 'Checkout Offer', 'cartflows' ),
175
- 'id' => 'wcf-pre-checkout-offer',
176
- 'class' => 'wcf-pre-checkout-offer' === $active_tab ? 'wcf-tab wp-ui-text-highlight active' : 'wcf-tab',
177
- 'icon' => 'dashicons-arrow-up-alt',
178
- ),
179
- array(
180
- 'title' => __( 'Checkout Design', 'cartflows' ),
181
- 'id' => 'wcf-checkout-style',
182
- 'class' => 'wcf-checkout-style' === $active_tab ? 'wcf-tab wp-ui-text-highlight active' : 'wcf-tab',
183
- 'icon' => 'dashicons-admin-customizer',
184
- ),
185
- array(
186
- 'title' => __( 'Checkout Fields', 'cartflows' ),
187
- 'id' => 'wcf-checkout-custom-fields',
188
- 'class' => 'wcf-checkout-custom-fields' === $active_tab ? 'wcf-tab wp-ui-text-highlight active' : 'wcf-tab',
189
- 'icon' => 'dashicons-welcome-widgets-menus',
190
- ),
191
- array(
192
- 'title' => __( 'Checkout Settings', 'cartflows' ),
193
- 'id' => 'wcf-checkout-custom-settings',
194
- 'class' => 'wcf-checkout-custom-settings' === $active_tab ? 'wcf-tab wp-ui-text-highlight active' : 'wcf-tab',
195
- 'icon' => 'dashicons-admin-generic',
196
- ),
197
- array(
198
- 'title' => __( 'Custom Script', 'cartflows' ),
199
- 'id' => 'wcf-checkout-custom-script-header',
200
- 'class' => 'wcf-checkout-custom-script-header' === $active_tab ? 'wcf-tab wp-ui-text-highlight active' : 'wcf-tab',
201
- 'icon' => 'dashicons-format-aside',
202
- ),
203
- );
204
-
205
- $show_logo = filter_input( INPUT_GET, 'logo-tab', FILTER_VALIDATE_BOOLEAN );
206
-
207
- if ( $show_logo ) {
208
- $logo_tab = array(
209
- 'title' => __( 'Logo (Optional)', 'cartflows' ),
210
- 'id' => 'wcf-checkout-header',
211
- 'class' => 'wcf-checkout-header' === $active_tab ? 'wcf-tab wp-ui-text-highlight active' : 'wcf-tab',
212
- 'icon' => 'dashicons-format-image',
213
- );
214
- array_push( $tab_array, $logo_tab );
215
- }
216
-
217
- $tabs = apply_filters( 'cartflows_checkout_tabs', $tab_array, $active_tab );
218
-
219
- ?>
220
- <div class="wcf-checkout-table wcf-metabox-wrap widefat">
221
- <div class="wcf-table-container">
222
- <div class="wcf-column-left">
223
- <div class="wcf-tab-wrapper">
224
-
225
- <?php foreach ( $tabs as $key => $tab ) { ?>
226
- <div class="<?php echo esc_attr( $tab['class'] ); ?>" data-tab="<?php echo esc_attr( $tab['id'] ); ?>">
227
- <span class="dashicons <?php echo esc_attr( $tab['icon'] ); ?>"></span>
228
- <span class="wcf-tab-title"><?php echo esc_html( $tab['title'] ); ?></span>
229
- </div>
230
- <?php } ?>
231
-
232
- <input type="hidden" id="wcf-active-tab" name="wcf-active-tab" value="<?php echo esc_attr( $active_tab ); ?>" />
233
- </div>
234
- </div>
235
- <div class="wcf-column-right">
236
- <?php $this->tab_shortcodes( $options, $post_id ); ?>
237
- <?php $this->tab_general( $options, $post_id ); ?>
238
- <?php $this->tab_product_options( $options, $post_id ); ?>
239
- <?php $this->tab_style( $options, $post_id ); ?>
240
- <?php $this->tab_pre_checkout_offer( $options, $post_id ); ?>
241
- <?php $this->tab_product_bump( $options, $post_id ); ?>
242
- <?php $this->tab_custom_fields( $options, $post_id ); ?>
243
- <?php $this->tab_custom_settings( $options, $post_id ); ?>
244
- <?php $this->tab_header_content( $options, $post_id ); ?>
245
- <?php $this->tab_custom_script( $options, $post_id ); ?>
246
- <?php do_action( 'cartflows_checkout_tabs_content', $options, $post_id ); ?>
247
- <?php $this->right_column_footer( $options, $post_id ); ?>
248
- </div>
249
- </div>
250
- </div>
251
-
252
- <?php
253
- }
254
-
255
- /**
256
- * Product options tab.
257
- *
258
- * @param array $options options.
259
- * @param int $post_id post ID.
260
- */
261
- public function tab_product_options( $options, $post_id ) {
262
- ?>
263
- <div class="wcf-product-options wcf-tab-content widefat">
264
- <?php
265
- if ( ! _is_cartflows_pro() ) {
266
- echo wcf()->meta->get_description_field(
267
- array(
268
- 'name' => 'wcf-upgrade-to-pro',
269
- /* translators: %s: link */
270
- 'content' => '<i>' . sprintf( esc_html__( 'Upgrade to %1$sCartFlows Pro%2$s for Product Options feature.', 'cartflows' ), '<a href="https://cartflows.com/" target="_blank">', '</a>' ) . '</i>',
271
- )
272
- );
273
- } elseif ( _is_cartflows_pro() && _is_cartflows_pro_ver_less_than( '1.5.4' ) ) {
274
- $version = '1.5.4';
275
- $file_path = 'cartflows-pro/cartflows-pro.php';
276
- $upgrade_link = wp_nonce_url( self_admin_url( 'update.php?action=upgrade-plugin&plugin=' ) . $file_path, 'upgrade-plugin_' . $file_path );
277
- echo wcf()->meta->get_description_field(
278
- array(
279
- 'name' => 'wcf-upgrade-to-pro',
280
- // translators: %s: link.
281
- 'content' => '<i>' . sprintf( esc_html__( 'Update %1$sCartFlows Pro%2$s to %3$s or above for Product Options', 'cartflows' ), '<a href="' . $upgrade_link . '" target="_blank">', '</a>', $version ) . '</i>',
282
- )
283
- );
284
- }
285
-
286
- do_action( 'cartflows_product_options_tab_content', $options, $post_id );
287
- ?>
288
- </div>
289
- <?php
290
- }
291
-
292
- /**
293
- * Shortcodes tab
294
- *
295
- * @param array $options options.
296
- * @param int $post_id post ID.
297
- */
298
- public function tab_shortcodes( $options, $post_id ) {
299
- ?>
300
- <div class="wcf-checkout-shortcodes wcf-tab-content widefat">
301
-
302
- <?php
303
-
304
- echo wcf()->meta->get_shortcode_field(
305
- array(
306
- 'label' => 'Checkout Page',
307
- 'name' => 'wcf-checkout-shortcode',
308
- 'content' => '[cartflows_checkout]',
309
- 'help' => esc_html__( 'Add this shortcode to your checkout page', 'cartflows' ),
310
- )
311
- );
312
- ?>
313
- </div>
314
- <?php
315
- }
316
-
317
-
318
- /**
319
- * General tab
320
- *
321
- * @param array $options options.
322
- * @param int $post_id post ID.
323
- */
324
- public function tab_general( $options, $post_id ) {
325
- ?>
326
- <div class="wcf-checkout-general wcf-tab-content widefat">
327
-
328
- <?php
329
-
330
- echo wcf()->meta->get_product_selection_repeater(
331
- array(
332
- 'name' => 'wcf-checkout-products',
333
- 'value' => $options['wcf-checkout-products'],
334
- 'allow_clear' => true,
335
- )
336
- );
337
-
338
- if ( ! _is_cartflows_pro() ) {
339
-
340
- echo wcf()->meta->get_hr_line_field( array() );
341
- echo wcf()->meta->get_description_field(
342
- array(
343
- 'name' => 'wcf-upgrade-to-pro',
344
- /* translators: %s: link */
345
- 'content' => '<i>' . sprintf( esc_html__( 'Upgrade to %1$sCartFlows Pro%2$s for Pre-applied Coupon.', 'cartflows' ), '<a href="https://cartflows.com/" target="_blank">', '</a>' ) . '</i>',
346
- )
347
- );
348
- }
349
-
350
- do_action( 'cartflows_checkout_general_tab_content', $options, $post_id );
351
-
352
- ?>
353
- </div>
354
- <?php
355
- }
356
-
357
- /**
358
- * Pre Checkout tab
359
- *
360
- * @param array $options options.
361
- * @param int $post_id post ID.
362
- */
363
- public function tab_pre_checkout_offer( $options, $post_id ) {
364
- ?>
365
- <div class="wcf-pre-checkout-offer wcf-tab-content widefat">
366
- <?php
367
- if ( ! _is_cartflows_pro() ) {
368
- echo wcf()->meta->get_description_field(
369
- array(
370
- 'name' => 'wcf-upgrade-to-pro',
371
- /* translators: %s: link */
372
- 'content' => '<i>' . sprintf( esc_html__( 'Upgrade to %1$sCartFlows Pro%2$s for Checkout Offer feature', 'cartflows' ), '<a href="https://cartflows.com/" target="_blank">', '</a>' ) . '</i>',
373
- )
374
- );
375
- } elseif ( _is_cartflows_pro_ver_less_than( '1.2.0' ) ) {
376
-
377
- $version = '1.2.0';
378
- echo wcf()->meta->get_description_field(
379
- array(
380
- 'name' => 'wcf-upgrade-to-pro',
381
- /* translators: %s: link */
382
- 'content' => '<i>' . sprintf( esc_html__( 'Update to %1$sCartFlows Pro%2$s to %3$s or above for Checkout Offer feature', 'cartflows' ), '<a href="https://cartflows.com/" target="_blank">', '</a>', $version ) . '</i>',
383
- )
384
- );
385
- }
386
- ?>
387
-
388
- <?php do_action( 'cartflows_pre_checkout_offer_tab_content', $options, $post_id ); ?>
389
- </div>
390
- <?php
391
- }
392
-
393
-
394
- /**
395
- * Pre Checkout tab
396
- *
397
- * @param array $options options.
398
- * @param int $post_id post ID.
399
- */
400
- public function animate_title_settings( $options, $post_id ) {
401
-
402
- echo wcf()->meta->get_hr_line_field( array() );
403
-
404
- if ( ! _is_cartflows_pro() ) {
405
- echo wcf()->meta->get_description_field(
406
- array(
407
- 'name' => 'wcf-upgrade-to-pro',
408
- /* translators: %s: link */
409
- 'content' => '<i>' . sprintf( __( 'Upgrade to %1$sCartFlows Pro%2$s for animate browser tab feature', 'cartflows' ), '<a href="https://cartflows.com/" target="_blank">', '</a>' ) . '</i>',
410
- )
411
- );
412
- } elseif ( _is_cartflows_pro_ver_less_than( '1.4.0' ) ) {
413
-
414
- $version = '1.4.0';
415
- echo wcf()->meta->get_description_field(
416
- array(
417
- 'name' => 'wcf-upgrade-to-pro',
418
- /* translators: %s: link */
419
- 'content' => '<i>' . sprintf( __( 'Update to %1$sCartFlows Pro%2$s to %3$s or above for animate browser tab feature', 'cartflows' ), '<a href="https://cartflows.com/" target="_blank">', '</a>', $version ) . '</i>',
420
- )
421
- );
422
- }
423
-
424
- do_action( 'cartflows_animate_browser_tab_settings', $options, $post_id );
425
- }
426
-
427
- /**
428
- * Product bump tab
429
- *
430
- * @param array $options options.
431
- * @param int $post_id post ID.
432
- */
433
- public function tab_product_bump( $options, $post_id ) {
434
- ?>
435
- <div class="wcf-product-order-bump wcf-tab-content widefat">
436
- <?php
437
- if ( ! _is_cartflows_pro() ) {
438
- echo wcf()->meta->get_description_field(
439
- array(
440
- 'name' => 'wcf-upgrade-to-pro',
441
- /* translators: %s: link */
442
- 'content' => '<i>' . sprintf( esc_html__( 'Upgrade to %1$sCartFlows Pro%2$s for Order Bump feature.', 'cartflows' ), '<a href="https://cartflows.com/" target="_blank">', '</a>' ) . '</i>',
443
- )
444
- );
445
- }
446
- ?>
447
-
448
- <?php do_action( 'cartflows_order_bump_tab_content', $options, $post_id ); ?>
449
- </div>
450
- <?php
451
- }
452
- /**
453
- * Tab custom fields
454
- *
455
- * @param array $options options.
456
- * @param int $post_id post ID.
457
- */
458
- public function tab_custom_fields( $options, $post_id ) {
459
- ?>
460
- <div class="wcf-checkout-custom-fields wcf-tab-content widefat">
461
- <?php
462
- /* Custom Checkout Fields Section */
463
-
464
- if ( ! _is_cartflows_pro() ) {
465
- echo wcf()->meta->get_description_field(
466
- array(
467
- 'name' => 'wcf-upgrade-to-pro',
468
- /* translators: %s: link */
469
- 'content' => '<i>' . sprintf( esc_html__( 'Upgrade to %1$sCartFlows Pro%2$s for Custom Fields feature.', 'cartflows' ), '<a href="https://cartflows.com/" target="_blank">', '</a>' ) . '</i>',
470
- )
471
- );
472
- }
473
- ?>
474
- <?php do_action( 'cartflows_custom_fields_tab_content', $options, $post_id ); ?>
475
- </div>
476
- <?php
477
- }
478
- /**
479
- * Tab custom settings
480
- *
481
- * @param array $options options.
482
- * @param int $post_id post ID.
483
- */
484
- public function tab_custom_settings( $options, $post_id ) {
485
- ?>
486
- <div class="wcf-checkout-custom-settings wcf-tab-content widefat">
487
- <div class="wcf-custom-settings-fields">
488
- <?php
489
-
490
- echo wcf()->meta->get_text_field(
491
- array(
492
- 'label' => __( 'Place Order Button Text', 'cartflows' ),
493
- 'name' => 'wcf-checkout-place-order-button-text',
494
- 'value' => $options['wcf-checkout-place-order-button-text'],
495
- 'attr' => array(
496
- 'placeholder' => __( 'Place order', 'cartflows' ),
497
- ),
498
- 'help' => __( 'It will change the Place Order Button text on checkout page.', 'cartflows' ),
499
- )
500
- );
501
-
502
- echo wcf()->meta->get_hr_line_field( array() );
503
-
504
- echo wcf()->meta->get_checkbox_field(
505
- array(
506
- 'name' => 'wcf-remove-product-field',
507
- 'value' => $options['wcf-remove-product-field'],
508
- 'after' => esc_html__( 'Enable cart editing on checkout', 'cartflows' ),
509
- )
510
- );
511
-
512
- echo wcf()->meta->get_description_field(
513
- array(
514
- 'name' => '',
515
- /* translators: %s: link */
516
- 'content' => '<i>' . sprintf( esc_html__( 'Users will able to remove products from the checkout page.', 'cartflows' ), '<a href="https://cartflows.com/" target="_blank">', '</a>' ) . '</i>',
517
- )
518
- );
519
-
520
- $this->animate_title_settings( $options, $post_id );
521
- ?>
522
- </div>
523
- <?php do_action( 'cartflows_custom_settings_tab_content', $options, $post_id ); ?>
524
- </div>
525
- <?php
526
- }
527
-
528
- /**
529
- * Tab style
530
- *
531
- * @param array $options options.
532
- * @param int $post_id post ID.
533
- */
534
- public function tab_style( $options, $post_id ) {
535
- ?>
536
-
537
- <div class="wcf-checkout-style wcf-tab-content widefat">
538
- <div class="wcf-cs-fields">
539
- <div class="wcf-cs-checkbox-field">
540
- <?php
541
-
542
- $layout_pro_option = array();
543
-
544
- if ( ! _is_cartflows_pro() ) {
545
- $layout_pro_option = array(
546
- 'one-column' => __( 'One Column (Available in CartFlows Pro) ', 'cartflows' ),
547
- 'two-step' => __( 'Two Step (Available in CartFlows Pro) ', 'cartflows' ),
548
- );
549
- }
550
-
551
- echo wcf()->meta->get_select_field(
552
- array(
553
- 'label' => __( 'Checkout Skin', 'cartflows' ),
554
- 'name' => 'wcf-checkout-layout',
555
- 'value' => $options['wcf-checkout-layout'],
556
- 'options' => array(
557
- 'one-column' => esc_html__( 'One Column', 'cartflows' ),
558
- 'two-column' => esc_html__( 'Two Column', 'cartflows' ),
559
- 'two-step' => esc_html__( 'Two Step', 'cartflows' ),
560
- ),
561
- 'pro-options' => $layout_pro_option,
562
-
563
- )
564
- );
565
-
566
- echo wcf()->meta->get_color_picker_field(
567
- array(
568
- 'label' => __( 'Primary Color', 'cartflows' ),
569
- 'name' => 'wcf-primary-color',
570
- 'value' => $options['wcf-primary-color'],
571
- )
572
- );
573
-
574
- echo wcf()->meta->get_font_family_field(
575
- array(
576
- 'for' => 'wcf-base',
577
- 'label' => esc_html__( 'Font Family', 'cartflows' ),
578
- 'name' => 'wcf-base-font-family',
579
- 'value' => $options['wcf-base-font-family'],
580
- )
581
- );
582
-
583
- echo wcf()->meta->get_checkbox_field(
584
- array(
585
- 'label' => __( 'Advance Options', 'cartflows' ),
586
- 'name' => 'wcf-advance-options-fields',
587
- 'value' => $options['wcf-advance-options-fields'],
588
- 'after' => 'Enable',
589
- )
590
- );
591
- ?>
592
- </div>
593
- <div class="wcf-cs-fields-options">
594
- <?php
595
- echo wcf()->meta->get_section(
596
- array(
597
- 'label' => __( 'Heading', 'cartflows' ),
598
- )
599
- );
600
-
601
- echo wcf()->meta->get_color_picker_field(
602
- array(
603
- 'label' => __( 'Heading Color', 'cartflows' ),
604
- 'name' => 'wcf-heading-color',
605
- 'value' => $options['wcf-heading-color'],
606
- )
607
- );
608
-
609
- echo wcf()->meta->get_font_family_field(
610
- array(
611
- 'for' => 'wcf-heading',
612
- 'label' => esc_html__( 'Font Family', 'cartflows' ),
613
- 'name' => 'wcf-heading-font-family',
614
- 'value' => $options['wcf-heading-font-family'],
615
- )
616
- );
617
-
618
- echo wcf()->meta->get_font_weight_field(
619
- array(
620
- 'for' => 'wcf-heading',
621
- 'label' => esc_html__( 'Font Weight', 'cartflows' ),
622
- 'name' => 'wcf-heading-font-weight',
623
- 'value' => $options['wcf-heading-font-weight'],
624
- )
625
- );
626
-
627
- echo wcf()->meta->get_section(
628
- array(
629
- 'label' => __( 'Input Fields', 'cartflows' ),
630
- )
631
- );
632
-
633
- $fields_skin_pro_option = array();
634
-
635
- if ( ! _is_cartflows_pro() ) {
636
- $fields_skin_pro_option = array(
637
- 'style-one' => __( 'Floating Labels (Available in CartFlows Pro)', 'cartflows' ),
638
- );
639
- }
640
-
641
- echo wcf()->meta->get_select_field(
642
- array(
643
- 'label' => __( 'Style', 'cartflows' ),
644
- 'name' => 'wcf-fields-skins',
645
- 'value' => $options['wcf-fields-skins'],
646
- 'options' => array(
647
- 'default' => esc_html__( 'Default', 'cartflows' ),
648
- 'style-one' => esc_html__( 'Floating Labels', 'cartflows' ),
649
- ),
650
- 'pro-options' => $fields_skin_pro_option,
651
-
652
- )
653
- );
654
-
655
- echo wcf()->meta->get_font_family_field(
656
- array(
657
- 'for' => 'wcf-input',
658
- 'label' => esc_html__( 'Font Family', 'cartflows' ),
659
- 'name' => 'wcf-input-font-family',
660
- 'value' => $options['wcf-input-font-family'],
661
- )
662
- );
663
-
664
- echo wcf()->meta->get_font_weight_field(
665
- array(
666
- 'for' => 'wcf-input',
667
- 'label' => esc_html__( 'Font Weight', 'cartflows' ),
668
- 'name' => 'wcf-input-font-weight',
669
- 'value' => $options['wcf-input-font-weight'],
670
- )
671
- );
672
-
673
- echo wcf()->meta->get_select_field(
674
- array(
675
- 'label' => __( 'Size', 'cartflows' ),
676
- 'name' => 'wcf-input-field-size',
677
- 'value' => $options['wcf-input-field-size'],
678
- 'options' => array(
679
- '33px' => esc_html__( 'Extra Small', 'cartflows' ),
680
- '38px' => esc_html__( 'Small', 'cartflows' ),
681
- '44px' => esc_html__( 'Medium', 'cartflows' ),
682
- '58px' => esc_html__( 'Large', 'cartflows' ),
683
- '68px' => esc_html__( 'Extra Large', 'cartflows' ),
684
- 'custom' => esc_html__( 'Custom', 'cartflows' ),
685
- ),
686
- )
687
- );
688
-
689
- echo wcf()->meta->get_number_field(
690
- array(
691
- 'label' => __( 'Top Bottom Spacing', 'cartflows' ),
692
- 'name' => 'wcf-field-tb-padding',
693
- 'value' => $options['wcf-field-tb-padding'],
694
- )
695
- );
696
-
697
- echo wcf()->meta->get_number_field(
698
- array(
699
- 'label' => __( 'Left Right Spacing', 'cartflows' ),
700
- 'name' => 'wcf-field-lr-padding',
701
- 'value' => $options['wcf-field-lr-padding'],
702
- )
703
- );
704
-
705
- echo wcf()->meta->get_color_picker_field(
706
- array(
707
- 'label' => __( 'Text / Placeholder Color', 'cartflows' ),
708
- 'name' => 'wcf-field-color',
709
- 'value' => $options['wcf-field-color'],
710
- )
711
- );
712
-
713
- echo wcf()->meta->get_color_picker_field(
714
- array(
715
- 'label' => __( 'Background Color', 'cartflows' ),
716
- 'name' => 'wcf-field-bg-color',
717
- 'value' => $options['wcf-field-bg-color'],
718
- )
719
- );
720
-
721
- echo wcf()->meta->get_color_picker_field(
722
- array(
723
- 'label' => __( 'Border Color', 'cartflows' ),
724
- 'name' => 'wcf-field-border-color',
725
- 'value' => $options['wcf-field-border-color'],
726
- )
727
- );
728
- echo wcf()->meta->get_color_picker_field(
729
- array(
730
- 'label' => __( 'Label Color', 'cartflows' ),
731
- 'name' => 'wcf-field-label-color',
732
- 'value' => $options['wcf-field-label-color'],
733
- )
734
- );
735
-
736
- ?>
737
- </div>
738
- <div class="wcf-cs-button-options">
739
- <?php
740
-
741
- echo wcf()->meta->get_section(
742
- array(
743
- 'label' => __( 'Buttons', 'cartflows' ),
744
- )
745
- );
746
-
747
- echo wcf()->meta->get_font_family_field(
748
- array(
749
- 'for' => 'wcf-button',
750
- 'label' => esc_html__( 'Font Family', 'cartflows' ),
751
- 'name' => 'wcf-button-font-family',
752
- 'value' => $options['wcf-button-font-family'],
753
- )
754
- );
755
-
756
- echo wcf()->meta->get_font_weight_field(
757
- array(
758
- 'for' => 'wcf-button',
759
- 'label' => esc_html__( 'Font Weight', 'cartflows' ),
760
- 'name' => 'wcf-button-font-weight',
761
- 'value' => $options['wcf-button-font-weight'],
762
- )
763
- );
764
-
765
- echo wcf()->meta->get_select_field(
766
- array(
767
- 'label' => __( 'Size', 'cartflows' ),
768
- 'name' => 'wcf-input-button-size',
769
- 'value' => $options['wcf-input-button-size'],
770
- 'options' => array(
771
- '33px' => esc_html__( 'Extra Small', 'cartflows' ),
772
- '38px' => esc_html__( 'Small', 'cartflows' ),
773
- '44px' => esc_html__( 'Medium', 'cartflows' ),
774
- '58px' => esc_html__( 'Large', 'cartflows' ),
775
- '68px' => esc_html__( 'Extra Large', 'cartflows' ),
776
- 'custom' => esc_html__( 'Custom', 'cartflows' ),
777
- ),
778
- )
779
- );
780
-
781
- echo wcf()->meta->get_number_field(
782
- array(
783
- 'label' => __( 'Top Bottom Spacing', 'cartflows' ),
784
- 'name' => 'wcf-submit-tb-padding',
785
- 'value' => $options['wcf-submit-tb-padding'],
786
- )
787
- );
788
-
789
- echo wcf()->meta->get_number_field(
790
- array(
791
- 'label' => __( 'Left Right Spacing', 'cartflows' ),
792
- 'name' => 'wcf-submit-lr-padding',
793
- 'value' => $options['wcf-submit-lr-padding'],
794
- )
795
- );
796
-
797
- echo wcf()->meta->get_color_picker_field(
798
- array(
799
- 'label' => __( 'Text Color', 'cartflows' ),
800
- 'name' => 'wcf-submit-color',
801
- 'value' => $options['wcf-submit-color'],
802
- )
803
- );
804
-
805
- echo wcf()->meta->get_color_picker_field(
806
- array(
807
- 'label' => __( 'Text Hover Color', 'cartflows' ),
808
- 'name' => 'wcf-submit-hover-color',
809
- 'value' => $options['wcf-submit-hover-color'],
810
- )
811
- );
812
-
813
- echo wcf()->meta->get_color_picker_field(
814
- array(
815
- 'label' => __( 'Background Color', 'cartflows' ),
816
- 'name' => 'wcf-submit-bg-color',
817
- 'value' => $options['wcf-submit-bg-color'],
818
- )
819
- );
820
-
821
- echo wcf()->meta->get_color_picker_field(
822
- array(
823
- 'label' => __( 'Background Hover Color', 'cartflows' ),
824
- 'name' => 'wcf-submit-bg-hover-color',
825
- 'value' => $options['wcf-submit-bg-hover-color'],
826
- )
827
- );
828
-
829
- echo wcf()->meta->get_color_picker_field(
830
- array(
831
- 'label' => __( 'Border Color', 'cartflows' ),
832
- 'name' => 'wcf-submit-border-color',
833
- 'value' => $options['wcf-submit-border-color'],
834
- )
835
- );
836
-
837
- echo wcf()->meta->get_color_picker_field(
838
- array(
839
- 'label' => __( 'Border Hover Color', 'cartflows' ),
840
- 'name' => 'wcf-submit-border-hover-color',
841
- 'value' => $options['wcf-submit-border-hover-color'],
842
- )
843
- );
844
-
845
- ?>
846
- </div>
847
- <div class="wcf-cs-section-options">
848
- <?php
849
-
850
- echo wcf()->meta->get_section(
851
- array(
852
- 'label' => __( 'Sections', 'cartflows' ),
853
- )
854
- );
855
-
856
- echo wcf()->meta->get_color_picker_field(
857
- array(
858
- 'label' => __( 'Highlight Area Background Color', 'cartflows' ),
859
- 'name' => 'wcf-hl-bg-color',
860
- 'value' => $options['wcf-hl-bg-color'],
861
- )
862
- );
863
-
864
- echo wcf()->meta->get_hidden_field(
865
- array(
866
- 'name' => 'wcf-field-google-font-url',
867
- 'value' => $options['wcf-field-google-font-url'],
868
- )
869
- );
870
- ?>
871
- </div>
872
- <?php do_action( 'cartflows_checkout_style_tab_content', $options, $post_id ); ?>
873
- </div>
874
- </div>
875
- <?php
876
- }
877
-
878
-
879
- /**
880
- * Tab Header (Used for add logo into header)
881
- *
882
- * @param array $options options.
883
- * @param int $post_id post ID.
884
- */
885
- public function tab_header_content( $options, $post_id ) {
886
- ?>
887
-
888
- <div class="wcf-checkout-header wcf-tab-content widefat">
889
- <?php
890
-
891
- $layout_pro_option = array();
892
-
893
- echo wcf()->meta->get_image_field(
894
- array(
895
- 'name' => 'wcf-header-logo-image',
896
- 'value' => $options['wcf-header-logo-image'],
897
- 'label' => esc_html__( 'Header Logo', 'cartflows' ),
898
- )
899
- );
900
-
901
- echo wcf()->meta->get_number_field(
902
- array(
903
- 'name' => 'wcf-header-logo-width',
904
- 'value' => $options['wcf-header-logo-width'],
905
- 'label' => esc_html__( 'Logo Width (In px)', 'cartflows' ),
906
- )
907
- );
908
- ?>
909
- <?php do_action( 'cartflows_checkout_header_tab_content', $options, $post_id ); ?>
910
- </div>
911
- <?php
912
- }
913
- /**
914
- * Get metabox options
915
- *
916
- * @param int $post_id post ID.
917
- */
918
- public static function get_meta_option( $post_id ) {
919
-
920
- if ( null === self::$meta_option ) {
921
-
922
- /**
923
- * Set metabox options
924
- *
925
- * @see http://php.net/manual/en/filter.filters.sanitize.php
926
- */
927
- self::$meta_option = wcf()->options->get_checkout_fields( $post_id );
928
- }
929
-
930
- return self::$meta_option;
931
- }
932
-
933
- /**
934
- * Metabox Save
935
- *
936
- * @param number $post_id Post ID.
937
- * @return void
938
- */
939
- public function save_meta_box( $post_id ) {
940
-
941
- // Checks save status.
942
- $is_autosave = wp_is_post_autosave( $post_id );
943
- $is_revision = wp_is_post_revision( $post_id );
944
-
945
- $is_valid_nonce = ( isset( $_POST['nonce-checkout-step-meta'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce-checkout-step-meta'] ) ), 'save-nonce-checkout-step-meta' ) ) ? true : false;
946
-
947
- // Exits script depending on save status.
948
- if ( $is_autosave || $is_revision || ! $is_valid_nonce ) {
949
- return;
950
- }
951
-
952
- wcf()->options->save_checkout_fields( $post_id );
953
- }
954
- }
955
-
956
- /**
957
- * Kicking this off by calling 'get_instance()' method
958
- */
959
- Cartflows_Checkout_Meta::get_instance();
1
+ <?php
2
+ /**
3
+ * Checkout post meta
4
+ *
5
+ * @package CartFlows
6
+ */
7
+
8
+ /**
9
+ * Meta Boxes setup
10
+ */
11
+ class Cartflows_Checkout_Meta extends Cartflows_Meta {
12
+
13
+
14
+ /**
15
+ * Instance
16
+ *
17
+ * @var $instance
18
+ */
19
+ private static $instance;
20
+
21
+ /**
22
+ * Meta Option
23
+ *
24
+ * @var $meta_option
25
+ */
26
+ private static $meta_option = null;
27
+
28
+ /**
29
+ * Initiator
30
+ */
31
+ public static function get_instance() {
32
+ if ( ! isset( self::$instance ) ) {
33
+ self::$instance = new self();
34
+ }
35
+
36
+ return self::$instance;
37
+ }
38
+
39
+ /**
40
+ * Constructor
41
+ */
42
+ public function __construct() {
43
+
44
+ /* Init Metabox */
45
+ add_action( 'load-post.php', array( $this, 'init_metabox' ) );
46
+ add_action( 'load-post-new.php', array( $this, 'init_metabox' ) );
47
+ }
48
+ /**
49
+ * Init Metabox
50
+ */
51
+ public function init_metabox() {
52
+
53
+ add_action( 'add_meta_boxes', array( $this, 'setup_meta_box' ) );
54
+ add_action( 'save_post', array( $this, 'save_meta_box' ) );
55
+ }
56
+
57
+ /**
58
+ * Setup Metabox
59
+ */
60
+ public function setup_meta_box() {
61
+
62
+ if ( _is_wcf_checkout_type() ) {
63
+ add_meta_box(
64
+ 'wcf-checkout-settings', // Id.
65
+ __( 'Checkout Layout', 'cartflows' ), // Title.
66
+ array( $this, 'markup_meta_box' ), // Callback.
67
+ wcf()->utils->get_step_post_type(), // Post_type.
68
+ 'normal', // Context.
69
+ 'high' // Priority.
70
+ );
71
+ }
72
+ }
73
+
74
+ /**
75
+ * Metabox Markup
76
+ *
77
+ * @param object $post Post object.
78
+ * @return void
79
+ */
80
+ public function markup_meta_box( $post ) {
81
+
82
+ wp_nonce_field( 'save-nonce-checkout-step-meta', 'nonce-checkout-step-meta' );
83
+
84
+ $stored = get_post_meta( $post->ID );
85
+
86
+ $checkout_meta = self::get_meta_option( $post->ID );
87
+
88
+ // Set stored and override defaults.
89
+ foreach ( $stored as $key => $value ) {
90
+ if ( array_key_exists( $key, $checkout_meta ) ) {
91
+ self::$meta_option[ $key ]['default'] = ( isset( $stored[ $key ][0] ) ) ? maybe_unserialize( $stored[ $key ][0] ) : '';
92
+ } else {
93
+ self::$meta_option[ $key ]['default'] = ( isset( $stored[ $key ][0] ) ) ? $stored[ $key ][0] : '';
94
+ }
95
+ }
96
+
97
+ // Get defaults.
98
+ $meta = self::get_meta_option( $post->ID );
99
+ $checkout_data = array();
100
+
101
+ foreach ( $meta as $key => $value ) {
102
+ $checkout_data[ $key ] = $meta[ $key ]['default'];
103
+ }
104
+
105
+ /**
106
+ $billing_fields = Cartflows_Helper::get_checkout_fields( 'billing', $post->ID );
107
+
108
+ // For loop
109
+ foreach ( $billing_fields as $key => $value ) {
110
+
111
+ $checkout_data[ 'wcf-' . $key ] = $meta[ 'wcf-' . $key ]['default'];
112
+ }
113
+
114
+ $shipping_fields = Cartflows_Helper::get_checkout_fields( 'shipping', $post->ID );
115
+
116
+ foreach ( $shipping_fields as $key => $value ) {
117
+
118
+ $checkout_data[ 'wcf-' . $key ] = $meta[ 'wcf-' . $key ]['default'];
119
+ }
120
+
121
+ $additional_fields = Cartflows_Helper::get_checkout_fields( 'additional', $post->ID );
122
+
123
+ foreach ( $additional_fields as $key => $value ) {
124
+
125
+ $checkout_data[ 'wcf-' . $key ] = $meta[ 'wcf-' . $key ]['default'];
126
+ }
127
+ */
128
+
129
+ do_action( 'wcf_checkout_settings_markup_before' );
130
+ $this->tabs_markup( $checkout_data, $post->ID );
131
+ do_action( 'wcf_checkout_settings_markup_after' );
132
+ }
133
+
134
+ /**
135
+ * Page Header Tabs
136
+ *
137
+ * @param array $options options.
138
+ * @param int $post_id post ID.
139
+ */
140
+ public function tabs_markup( $options, $post_id ) {
141
+
142
+ $active_tab = get_post_meta( $post_id, 'wcf-active-tab', true );
143
+
144
+ if ( empty( $active_tab ) ) {
145
+ $active_tab = 'wcf-checkout-shortcodes';
146
+ }
147
+
148
+ $tab_array = array(
149
+ array(
150
+ 'title' => __( 'Shortcodes', 'cartflows' ),
151
+ 'id' => 'wcf-checkout-shortcodes',
152
+ 'class' => 'wcf-checkout-shortcodes' === $active_tab ? 'wcf-tab wp-ui-text-highlight active' : 'wcf-tab',
153
+ 'icon' => 'dashicons-editor-code',
154
+ ),
155
+ array(
156
+ 'title' => __( 'Select Product', 'cartflows' ),
157
+ 'id' => 'wcf-checkout-general',
158
+ 'class' => 'wcf-checkout-general' === $active_tab ? 'wcf-tab wp-ui-text-highlight active' : 'wcf-tab',
159
+ 'icon' => 'dashicons-info',
160
+ ),
161
+ array(
162
+ 'title' => __( 'Product Options', 'cartflows' ),
163
+ 'id' => 'wcf-product-options',
164
+ 'class' => 'wcf-product-options' === $active_tab ? 'wcf-tab wp-ui-text-highlight active' : 'wcf-tab',
165
+ 'icon' => 'dashicons dashicons-screenoptions',
166
+ ),
167
+ array(
168
+ 'title' => __( 'Order Bump', 'cartflows' ),
169
+ 'id' => 'wcf-product-order-bump',
170
+ 'class' => 'wcf-product-order-bump' === $active_tab ? 'wcf-tab wp-ui-text-highlight active' : 'wcf-tab',
171
+ 'icon' => 'dashicons-cart',
172
+ ),
173
+ array(
174
+ 'title' => __( 'Checkout Offer', 'cartflows' ),
175
+ 'id' => 'wcf-pre-checkout-offer',
176
+ 'class' => 'wcf-pre-checkout-offer' === $active_tab ? 'wcf-tab wp-ui-text-highlight active' : 'wcf-tab',
177
+ 'icon' => 'dashicons-arrow-up-alt',
178
+ ),
179
+ array(
180
+ 'title' => __( 'Checkout Design', 'cartflows' ),
181
+ 'id' => 'wcf-checkout-style',
182
+ 'class' => 'wcf-checkout-style' === $active_tab ? 'wcf-tab wp-ui-text-highlight active' : 'wcf-tab',
183
+ 'icon' => 'dashicons-admin-customizer',
184
+ ),
185
+ array(
186
+ 'title' => __( 'Checkout Fields', 'cartflows' ),
187
+ 'id' => 'wcf-checkout-custom-fields',
188
+ 'class' => 'wcf-checkout-custom-fields' === $active_tab ? 'wcf-tab wp-ui-text-highlight active' : 'wcf-tab',
189
+ 'icon' => 'dashicons-welcome-widgets-menus',
190
+ ),
191
+ array(
192
+ 'title' => __( 'Checkout Settings', 'cartflows' ),
193
+ 'id' => 'wcf-checkout-custom-settings',
194
+ 'class' => 'wcf-checkout-custom-settings' === $active_tab ? 'wcf-tab wp-ui-text-highlight active' : 'wcf-tab',
195
+ 'icon' => 'dashicons-admin-generic',
196
+ ),
197
+ array(
198
+ 'title' => __( 'Custom Script', 'cartflows' ),
199
+ 'id' => 'wcf-checkout-custom-script-header',
200
+ 'class' => 'wcf-checkout-custom-script-header' === $active_tab ? 'wcf-tab wp-ui-text-highlight active' : 'wcf-tab',
201
+ 'icon' => 'dashicons-format-aside',
202
+ ),
203
+ );
204
+
205
+ $show_logo = filter_input( INPUT_GET, 'logo-tab', FILTER_VALIDATE_BOOLEAN );
206
+
207
+ if ( $show_logo ) {
208
+ $logo_tab = array(
209
+ 'title' => __( 'Logo (Optional)', 'cartflows' ),
210
+ 'id' => 'wcf-checkout-header',
211
+ 'class' => 'wcf-checkout-header' === $active_tab ? 'wcf-tab wp-ui-text-highlight active' : 'wcf-tab',
212
+ 'icon' => 'dashicons-format-image',
213
+ );
214
+ array_push( $tab_array, $logo_tab );
215
+ }
216
+
217
+ $tabs = apply_filters( 'cartflows_checkout_tabs', $tab_array, $active_tab );
218
+
219
+ ?>
220
+ <div class="wcf-checkout-table wcf-metabox-wrap widefat">
221
+ <div class="wcf-table-container">
222
+ <div class="wcf-column-left">
223
+ <div class="wcf-tab-wrapper">
224
+
225
+ <?php foreach ( $tabs as $key => $tab ) { ?>
226
+ <div class="<?php echo esc_attr( $tab['class'] ); ?>" data-tab="<?php echo esc_attr( $tab['id'] ); ?>">
227
+ <span class="dashicons <?php echo esc_attr( $tab['icon'] ); ?>"></span>
228
+ <span class="wcf-tab-title"><?php echo esc_html( $tab['title'] ); ?></span>
229
+ </div>
230
+ <?php } ?>
231
+
232
+ <input type="hidden" id="wcf-active-tab" name="wcf-active-tab" value="<?php echo esc_attr( $active_tab ); ?>" />
233
+ </div>
234
+ </div>
235
+ <div class="wcf-column-right">
236
+ <?php $this->tab_shortcodes( $options, $post_id ); ?>
237
+ <?php $this->tab_general( $options, $post_id ); ?>
238
+ <?php $this->tab_product_options( $options, $post_id ); ?>
239
+ <?php $this->tab_style( $options, $post_id ); ?>
240
+ <?php $this->tab_pre_checkout_offer( $options, $post_id ); ?>
241
+ <?php $this->tab_product_bump( $options, $post_id ); ?>
242
+ <?php $this->tab_custom_fields( $options, $post_id ); ?>
243
+ <?php $this->tab_custom_settings( $options, $post_id ); ?>
244
+ <?php $this->tab_header_content( $options, $post_id ); ?>
245
+ <?php $this->tab_custom_script( $options, $post_id ); ?>
246
+ <?php do_action( 'cartflows_checkout_tabs_content', $options, $post_id ); ?>
247
+ <?php $this->right_column_footer( $options, $post_id ); ?>
248
+ </div>
249
+ </div>
250
+ </div>
251
+
252
+ <?php
253
+ }
254
+
255
+ /**
256
+ * Product options tab.
257
+ *
258
+ * @param array $options options.
259
+ * @param int $post_id post ID.
260
+ */
261
+ public function tab_product_options( $options, $post_id ) {
262
+ ?>
263
+ <div class="wcf-product-options wcf-tab-content widefat">
264
+ <?php
265
+ if ( ! _is_cartflows_pro() ) {
266
+ echo wcf()->meta->get_description_field(
267
+ array(
268
+ 'name' => 'wcf-upgrade-to-pro',
269
+ /* translators: %s: link */
270
+ 'content' => '<i>' . sprintf( esc_html__( 'Upgrade to %1$sCartFlows Pro%2$s for Product Options feature.', 'cartflows' ), '<a href="https://cartflows.com/" target="_blank">', '</a>' ) . '</i>',
271
+ )
272
+ );
273
+ } elseif ( _is_cartflows_pro() && _is_cartflows_pro_ver_less_than( '1.5.4' ) ) {
274
+ $version = '1.5.4';
275
+ $file_path = 'cartflows-pro/cartflows-pro.php';
276
+ $upgrade_link = wp_nonce_url( self_admin_url( 'update.php?action=upgrade-plugin&plugin=' ) . $file_path, 'upgrade-plugin_' . $file_path );
277
+ echo wcf()->meta->get_description_field(
278
+ array(
279
+ 'name' => 'wcf-upgrade-to-pro',
280
+ // translators: %s: link.
281
+ 'content' => '<i>' . sprintf( esc_html__( 'Update %1$sCartFlows Pro%2$s to %3$s or above for Product Options', 'cartflows' ), '<a href="' . $upgrade_link . '" target="_blank">', '</a>', $version ) . '</i>',
282
+ )
283
+ );
284
+ }
285
+
286
+ do_action( 'cartflows_product_options_tab_content', $options, $post_id );
287
+ ?>
288
+ </div>
289
+ <?php
290
+ }
291
+
292
+ /**
293
+ * Shortcodes tab
294
+ *
295
+ * @param array $options options.
296
+ * @param int $post_id post ID.
297
+ */
298
+ public function tab_shortcodes( $options, $post_id ) {
299
+ ?>
300
+ <div class="wcf-checkout-shortcodes wcf-tab-content widefat">
301
+
302
+ <?php
303
+
304
+ echo wcf()->meta->get_shortcode_field(
305
+ array(
306
+ 'label' => 'Checkout Page',
307
+ 'name' => 'wcf-checkout-shortcode',
308
+ 'content' => '[cartflows_checkout]',
309
+ 'help' => esc_html__( 'Add this shortcode to your checkout page', 'cartflows' ),
310
+ )
311
+ );
312
+ ?>
313
+ </div>
314
+ <?php
315
+ }
316
+
317
+
318
+ /**
319
+ * General tab
320
+ *
321
+ * @param array $options options.
322
+ * @param int $post_id post ID.
323
+ */
324
+ public function tab_general( $options, $post_id ) {
325
+ ?>
326
+ <div class="wcf-checkout-general wcf-tab-content widefat">
327
+
328
+ <?php
329
+
330
+ echo wcf()->meta->get_product_selection_repeater(
331
+ array(
332
+ 'name' => 'wcf-checkout-products',
333
+ 'value' => $options['wcf-checkout-products'],
334
+ 'allow_clear' => true,
335
+ )
336
+ );
337
+
338
+ if ( ! _is_cartflows_pro() ) {
339
+
340
+ echo wcf()->meta->get_hr_line_field( array() );
341
+ echo wcf()->meta->get_description_field(
342
+ array(
343
+ 'name' => 'wcf-upgrade-to-pro',
344
+ /* translators: %s: link */
345
+ 'content' => '<i>' . sprintf( esc_html__( 'Upgrade to %1$sCartFlows Pro%2$s for Pre-applied Coupon.', 'cartflows' ), '<a href="https://cartflows.com/" target="_blank">', '</a>' ) . '</i>',
346
+ )
347
+ );
348
+ }
349
+
350
+ do_action( 'cartflows_checkout_general_tab_content', $options, $post_id );
351
+
352
+ ?>
353
+ </div>
354
+ <?php
355
+ }
356
+
357
+ /**
358
+ * Pre Checkout tab
359
+ *
360
+ * @param array $options options.
361
+ * @param int $post_id post ID.
362
+ */
363
+ public function tab_pre_checkout_offer( $options, $post_id ) {
364
+ ?>
365
+ <div class="wcf-pre-checkout-offer wcf-tab-content widefat">
366
+ <?php
367
+ if ( ! _is_cartflows_pro() ) {
368
+ echo wcf()->meta->get_description_field(
369
+ array(
370
+ 'name' => 'wcf-upgrade-to-pro',
371
+ /* translators: %s: link */
372
+ 'content' => '<i>' . sprintf( esc_html__( 'Upgrade to %1$sCartFlows Pro%2$s for Checkout Offer feature', 'cartflows' ), '<a href="https://cartflows.com/" target="_blank">', '</a>' ) . '</i>',
373
+ )
374
+ );
375
+ } elseif ( _is_cartflows_pro_ver_less_than( '1.2.0' ) ) {
376
+
377
+ $version = '1.2.0';
378
+ echo wcf()->meta->get_description_field(
379
+ array(
380
+ 'name' => 'wcf-upgrade-to-pro',
381
+ /* translators: %s: link */
382
+ 'content' => '<i>' . sprintf( esc_html__( 'Update to %1$sCartFlows Pro%2$s to %3$s or above for Checkout Offer feature', 'cartflows' ), '<a href="https://cartflows.com/" target="_blank">', '</a>', $version ) . '</i>',
383
+ )
384
+ );
385
+ }
386
+ ?>
387
+
388
+ <?php do_action( 'cartflows_pre_checkout_offer_tab_content', $options, $post_id ); ?>
389
+ </div>
390
+ <?php
391
+ }
392
+
393
+
394
+ /**
395
+ * Pre Checkout tab
396
+ *
397
+ * @param array $options options.
398
+ * @param int $post_id post ID.
399
+ */
400
+ public function animate_title_settings( $options, $post_id ) {
401
+
402
+ echo wcf()->meta->get_hr_line_field( array() );
403
+
404
+ if ( ! _is_cartflows_pro() ) {
405
+ echo wcf()->meta->get_description_field(
406
+ array(
407
+ 'name' => 'wcf-upgrade-to-pro',
408
+ /* translators: %s: link */
409
+ 'content' => '<i>' . sprintf( __( 'Upgrade to %1$sCartFlows Pro%2$s for animate browser tab feature', 'cartflows' ), '<a href="https://cartflows.com/" target="_blank">', '</a>' ) . '</i>',
410
+ )
411
+ );
412
+ } elseif ( _is_cartflows_pro_ver_less_than( '1.4.0' ) ) {
413
+
414
+ $version = '1.4.0';
415
+ echo wcf()->meta->get_description_field(
416
+ array(
417
+ 'name' => 'wcf-upgrade-to-pro',
418
+ /* translators: %s: link */
419
+ 'content' => '<i>' . sprintf( __( 'Update to %1$sCartFlows Pro%2$s to %3$s or above for animate browser tab feature', 'cartflows' ), '<a href="https://cartflows.com/" target="_blank">', '</a>', $version ) . '</i>',
420
+ )
421
+ );
422
+ }
423
+
424
+ do_action( 'cartflows_animate_browser_tab_settings', $options, $post_id );
425
+ }
426
+
427
+ /**
428
+ * Product bump tab
429
+ *
430
+ * @param array $options options.
431
+ * @param int $post_id post ID.
432
+ */
433
+ public function tab_product_bump( $options, $post_id ) {
434
+ ?>
435
+ <div class="wcf-product-order-bump wcf-tab-content widefat">
436
+ <?php
437
+ if ( ! _is_cartflows_pro() ) {
438
+ echo wcf()->meta->get_description_field(
439
+ array(
440
+ 'name' => 'wcf-upgrade-to-pro',
441
+ /* translators: %s: link */
442
+ 'content' => '<i>' . sprintf( esc_html__( 'Upgrade to %1$sCartFlows Pro%2$s for Order Bump feature.', 'cartflows' ), '<a href="https://cartflows.com/" target="_blank">', '</a>' ) . '</i>',
443
+ )
444
+ );
445
+ }
446
+ ?>
447
+
448
+ <?php do_action( 'cartflows_order_bump_tab_content', $options, $post_id ); ?>
449
+ </div>
450
+ <?php
451
+ }
452
+ /**
453
+ * Tab custom fields
454
+ *
455
+ * @param array $options options.
456
+ * @param int $post_id post ID.
457
+ */
458
+ public function tab_custom_fields( $options, $post_id ) {
459
+ ?>
460
+ <div class="wcf-checkout-custom-fields wcf-tab-content widefat">
461
+ <?php
462
+ /* Custom Checkout Fields Section */
463
+
464
+ if ( ! _is_cartflows_pro() ) {
465
+ echo wcf()->meta->get_description_field(
466
+ array(
467
+ 'name' => 'wcf-upgrade-to-pro',
468
+ /* translators: %s: link */
469
+ 'content' => '<i>' . sprintf( esc_html__( 'Upgrade to %1$sCartFlows Pro%2$s for Custom Fields feature.', 'cartflows' ), '<a href="https://cartflows.com/" target="_blank">', '</a>' ) . '</i>',
470
+ )
471
+ );
472
+ }
473
+ ?>
474
+ <?php do_action( 'cartflows_custom_fields_tab_content', $options, $post_id ); ?>
475
+ </div>
476
+ <?php
477
+ }
478
+ /**
479
+ * Tab custom settings
480
+ *
481
+ * @param array $options options.
482
+ * @param int $post_id post ID.
483
+ */
484
+ public function tab_custom_settings( $options, $post_id ) {
485
+ ?>
486
+ <div class="wcf-checkout-custom-settings wcf-tab-content widefat">
487
+ <div class="wcf-custom-settings-fields">
488
+ <?php
489
+
490
+ echo wcf()->meta->get_text_field(
491
+ array(
492
+ 'label' => __( 'Place Order Button Text', 'cartflows' ),
493
+ 'name' => 'wcf-checkout-place-order-button-text',
494
+ 'value' => $options['wcf-checkout-place-order-button-text'],
495
+ 'attr' => array(
496
+ 'placeholder' => __( 'Place order', 'cartflows' ),
497
+ ),
498
+ 'help' => __( 'It will change the Place Order Button text on checkout page.', 'cartflows' ),
499
+ )
500
+ );
501
+
502
+ echo wcf()->meta->get_hr_line_field( array() );
503
+
504
+ echo wcf()->meta->get_checkbox_field(
505
+ array(
506
+ 'name' => 'wcf-remove-product-field',
507
+ 'value' => $options['wcf-remove-product-field'],
508
+ 'after' => esc_html__( 'Enable cart editing on checkout', 'cartflows' ),
509
+ )
510
+ );
511
+
512
+ echo wcf()->meta->get_description_field(
513
+ array(
514
+ 'name' => '',
515
+ /* translators: %s: link */
516
+ 'content' => '<i>' . sprintf( esc_html__( 'Users will able to remove products from the checkout page.', 'cartflows' ), '<a href="https://cartflows.com/" target="_blank">', '</a>' ) . '</i>',
517
+ )
518
+ );
519
+
520
+ $this->animate_title_settings( $options, $post_id );
521
+ ?>
522
+ </div>
523
+ <?php do_action( 'cartflows_custom_settings_tab_content', $options, $post_id ); ?>
524
+ </div>
525
+ <?php
526
+ }
527
+
528
+ /**
529
+ * Tab style
530
+ *
531
+ * @param array $options options.
532
+ * @param int $post_id post ID.
533
+ */
534
+ public function tab_style( $options, $post_id ) {
535
+ ?>
536
+
537
+ <div class="wcf-checkout-style wcf-tab-content widefat">
538
+ <div class="wcf-cs-fields">
539
+ <div class="wcf-cs-checkbox-field">
540
+ <?php
541
+
542
+ $layout_pro_option = array();
543
+
544
+ if ( ! _is_cartflows_pro() ) {
545
+ $layout_pro_option = array(
546
+ 'one-column' => __( 'One Column (Available in CartFlows Pro) ', 'cartflows' ),
547
+ 'two-step' => __( 'Two Step (Available in CartFlows Pro) ', 'cartflows' ),
548
+ );
549
+ }
550
+
551
+ echo wcf()->meta->get_select_field(
552
+ array(
553
+ 'label' => __( 'Checkout Skin', 'cartflows' ),
554
+ 'name' => 'wcf-checkout-layout',
555
+ 'value' => $options['wcf-checkout-layout'],
556
+ 'options' => array(
557
+ 'one-column' => esc_html__( 'One Column', 'cartflows' ),
558
+ 'two-column' => esc_html__( 'Two Column', 'cartflows' ),
559
+ 'two-step' => esc_html__( 'Two Step', 'cartflows' ),
560
+ ),
561
+ 'pro-options' => $layout_pro_option,
562
+
563
+ )
564
+ );
565
+
566
+ echo wcf()->meta->get_color_picker_field(
567
+ array(
568
+ 'label' => __( 'Primary Color', 'cartflows' ),
569
+ 'name' => 'wcf-primary-color',
570
+ 'value' => $options['wcf-primary-color'],
571
+ )
572
+ );
573
+
574
+ echo wcf()->meta->get_font_family_field(
575
+ array(
576
+ 'for' => 'wcf-base',
577
+ 'label' => esc_html__( 'Font Family', 'cartflows' ),
578
+ 'name' => 'wcf-base-font-family',
579
+ 'value' => $options['wcf-base-font-family'],
580
+ )
581
+ );
582
+
583
+ echo wcf()->meta->get_checkbox_field(
584
+ array(
585
+ 'label' => __( 'Advance Options', 'cartflows' ),
586
+ 'name' => 'wcf-advance-options-fields',
587
+ 'value' => $options['wcf-advance-options-fields'],
588
+ 'after' => 'Enable',
589
+ )
590
+ );
591
+ ?>
592
+ </div>
593
+ <div class="wcf-cs-fields-options">
594
+ <?php
595
+ echo wcf()->meta->get_section(
596
+ array(
597
+ 'label' => __( 'Heading', 'cartflows' ),
598
+ )
599
+ );
600
+
601
+ echo wcf()->meta->get_color_picker_field(
602
+ array(
603
+ 'label' => __( 'Heading Color', 'cartflows' ),
604
+ 'name' => 'wcf-heading-color',
605
+ 'value' => $options['wcf-heading-color'],
606
+ )
607
+ );
608
+
609
+ echo wcf()->meta->get_font_family_field(
610
+ array(
611
+ 'for' => 'wcf-heading',
612
+ 'label' => esc_html__( 'Font Family', 'cartflows' ),
613
+ 'name' => 'wcf-heading-font-family',
614
+ 'value' => $options['wcf-heading-font-family'],
615
+ )
616
+ );
617
+
618
+ echo wcf()->meta->get_font_weight_field(
619
+ array(
620
+ 'for' => 'wcf-heading',
621
+ 'label' => esc_html__( 'Font Weight', 'cartflows' ),
622
+ 'name' => 'wcf-heading-font-weight',
623
+ 'value' => $options['wcf-heading-font-weight'],
624
+ )
625
+ );
626
+
627
+ echo wcf()->meta->get_section(
628
+ array(
629
+ 'label' => __( 'Input Fields', 'cartflows' ),
630
+ )
631
+ );
632
+
633
+ $fields_skin_pro_option = array();
634
+
635
+ if ( ! _is_cartflows_pro() ) {
636
+ $fields_skin_pro_option = array(
637
+ 'style-one' => __( 'Floating Labels (Available in CartFlows Pro)', 'cartflows' ),
638
+ );
639
+ }
640
+
641
+ echo wcf()->meta->get_select_field(
642
+ array(
643
+ 'label' => __( 'Style', 'cartflows' ),
644
+ 'name' => 'wcf-fields-skins',
645
+ 'value' => $options['wcf-fields-skins'],
646
+ 'options' => array(
647
+ 'default' => esc_html__( 'Default', 'cartflows' ),
648
+ 'style-one' => esc_html__( 'Floating Labels', 'cartflows' ),
649
+ ),
650
+ 'pro-options' => $fields_skin_pro_option,
651
+
652
+ )
653
+ );
654
+
655
+ echo wcf()->meta->get_font_family_field(
656
+ array(
657
+ 'for' => 'wcf-input',
658
+ 'label' => esc_html__( 'Font Family', 'cartflows' ),
659
+ 'name' => 'wcf-input-font-family',
660
+ 'value' => $options['wcf-input-font-family'],
661
+ )
662
+ );
663
+
664
+ echo wcf()->meta->get_font_weight_field(
665
+ array(
666
+ 'for' => 'wcf-input',
667
+ 'label' => esc_html__( 'Font Weight', 'cartflows' ),
668
+ 'name' => 'wcf-input-font-weight',
669
+ 'value' => $options['wcf-input-font-weight'],
670
+ )
671
+ );
672
+
673
+ echo wcf()->meta->get_select_field(
674
+ array(
675
+ 'label' => __( 'Size', 'cartflows' ),
676
+ 'name' => 'wcf-input-field-size',
677
+ 'value' => $options['wcf-input-field-size'],
678
+ 'options' => array(
679
+ '33px' => esc_html__( 'Extra Small', 'cartflows' ),
680
+ '38px' => esc_html__( 'Small', 'cartflows' ),
681
+ '44px' => esc_html__( 'Medium', 'cartflows' ),
682
+ '58px' => esc_html__( 'Large', 'cartflows' ),
683
+ '68px' => esc_html__( 'Extra Large', 'cartflows' ),
684
+ 'custom' => esc_html__( 'Custom', 'cartflows' ),
685
+ ),
686
+ )
687
+ );
688
+
689
+ echo wcf()->meta->get_number_field(
690
+ array(
691
+ 'label' => __( 'Top Bottom Spacing', 'cartflows' ),
692
+ 'name' => 'wcf-field-tb-padding',
693
+ 'value' => $options['wcf-field-tb-padding'],
694
+ )
695
+ );
696
+
697
+ echo wcf()->meta->get_number_field(
698
+ array(
699
+ 'label' => __( 'Left Right Spacing', 'cartflows' ),
700
+ 'name' => 'wcf-field-lr-padding',
701
+ 'value' => $options['wcf-field-lr-padding'],
702
+ )
703
+ );
704
+
705
+ echo wcf()->meta->get_color_picker_field(
706
+ array(
707
+ 'label' => __( 'Text / Placeholder Color', 'cartflows' ),
708
+ 'name' => 'wcf-field-color',
709
+ 'value' => $options['wcf-field-color'],
710
+ )
711
+ );
712
+
713
+ echo wcf()->meta->get_color_picker_field(
714
+ array(
715
+ 'label' => __( 'Background Color', 'cartflows' ),
716
+ 'name' => 'wcf-field-bg-color',
717
+ 'value' => $options['wcf-field-bg-color'],
718
+ )
719
+ );
720
+
721
+ echo wcf()->meta->get_color_picker_field(
722
+ array(
723
+ 'label' => __( 'Border Color', 'cartflows' ),
724
+ 'name' => 'wcf-field-border-color',
725
+ 'value' => $options['wcf-field-border-color'],
726
+ )
727
+ );
728
+ echo wcf()->meta->get_color_picker_field(
729
+ array(
730
+ 'label' => __( 'Label Color', 'cartflows' ),
731
+ 'name' => 'wcf-field-label-color',
732
+ 'value' => $options['wcf-field-label-color'],
733
+ )
734
+ );
735
+
736
+ ?>
737
+ </div>
738
+ <div class="wcf-cs-button-options">
739
+ <?php
740
+
741
+ echo wcf()->meta->get_section(
742
+ array(
743
+ 'label' => __( 'Buttons', 'cartflows' ),
744
+ )
745
+ );
746
+
747
+ echo wcf()->meta->get_font_family_field(
748
+ array(
749
+ 'for' => 'wcf-button',
750
+ 'label' => esc_html__( 'Font Family', 'cartflows' ),
751
+ 'name' => 'wcf-button-font-family',
752
+ 'value' => $options['wcf-button-font-family'],
753
+ )
754
+ );
755
+
756
+ echo wcf()->meta->get_font_weight_field(
757
+ array(
758
+ 'for' => 'wcf-button',
759
+ 'label' => esc_html__( 'Font Weight', 'cartflows' ),
760
+ 'name' => 'wcf-button-font-weight',
761
+ 'value' => $options['wcf-button-font-weight'],
762
+ )
763
+ );
764
+
765
+ echo wcf()->meta->get_select_field(
766
+ array(
767
+ 'label' => __( 'Size', 'cartflows' ),
768
+ 'name' => 'wcf-input-button-size',
769
+ 'value' => $options['wcf-input-button-size'],
770
+ 'options' => array(
771
+ '33px' => esc_html__( 'Extra Small', 'cartflows' ),
772
+ '38px' => esc_html__( 'Small', 'cartflows' ),
773
+ '44px' => esc_html__( 'Medium', 'cartflows' ),
774
+ '58px' => esc_html__( 'Large', 'cartflows' ),
775
+ '68px' => esc_html__( 'Extra Large', 'cartflows' ),
776
+ 'custom' => esc_html__( 'Custom', 'cartflows' ),
777
+ ),
778
+ )
779
+ );
780
+
781
+ echo wcf()->meta->get_number_field(
782
+ array(
783
+ 'label' => __( 'Top Bottom Spacing', 'cartflows' ),
784
+ 'name' => 'wcf-submit-tb-padding',
785
+ 'value' => $options['wcf-submit-tb-padding'],
786
+ )
787
+ );
788
+
789
+ echo wcf()->meta->get_number_field(
790
+ array(
791
+ 'label' => __( 'Left Right Spacing', 'cartflows' ),
792
+ 'name' => 'wcf-submit-lr-padding',
793
+ 'value' => $options['wcf-submit-lr-padding'],
794
+ )
795
+ );
796
+
797
+ echo wcf()->meta->get_color_picker_field(
798
+ array(
799
+ 'label' => __( 'Text Color', 'cartflows' ),
800
+ 'name' => 'wcf-submit-color',
801
+ 'value' => $options['wcf-submit-color'],
802
+ )
803
+ );
804
+
805
+ echo wcf()->meta->get_color_picker_field(
806
+ array(
807
+ 'label' => __( 'Text Hover Color', 'cartflows' ),
808
+ 'name' => 'wcf-submit-hover-color',
809
+ 'value' => $options['wcf-submit-hover-color'],
810
+ )
811
+ );
812
+
813
+ echo wcf()->meta->get_color_picker_field(
814
+ array(
815
+ 'label' => __( 'Background Color', 'cartflows' ),
816
+ 'name' => 'wcf-submit-bg-color',
817
+ 'value' => $options['wcf-submit-bg-color'],
818
+ )
819
+ );
820
+
821
+ echo wcf()->meta->get_color_picker_field(
822
+ array(
823
+ 'label' => __( 'Background Hover Color', 'cartflows' ),
824
+ 'name' => 'wcf-submit-bg-hover-color',
825
+ 'value' => $options['wcf-submit-bg-hover-color'],
826
+ )
827
+ );
828
+
829
+ echo wcf()->meta->get_color_picker_field(
830
+ array(
831
+ 'label' => __( 'Border Color', 'cartflows' ),
832
+ 'name' => 'wcf-submit-border-color',
833
+ 'value' => $options['wcf-submit-border-color'],
834
+ )
835
+ );
836
+
837
+ echo wcf()->meta->get_color_picker_field(
838
+ array(
839
+ 'label' => __( 'Border Hover Color', 'cartflows' ),
840
+ 'name' => 'wcf-submit-border-hover-color',
841
+ 'value' => $options['wcf-submit-border-hover-color'],
842
+ )
843
+ );
844
+
845
+ ?>
846
+ </div>
847
+ <div class="wcf-cs-section-options">
848
+ <?php
849
+
850
+ echo wcf()->meta->get_section(
851
+ array(
852
+ 'label' => __( 'Sections', 'cartflows' ),
853
+ )
854
+ );
855
+
856
+ echo wcf()->meta->get_color_picker_field(
857
+ array(
858
+ 'label' => __( 'Highlight Area Background Color', 'cartflows' ),
859
+ 'name' => 'wcf-hl-bg-color',
860
+ 'value' => $options['wcf-hl-bg-color'],
861
+ )
862
+ );
863
+
864
+ echo wcf()->meta->get_hidden_field(
865
+ array(
866
+ 'name' => 'wcf-field-google-font-url',
867
+ 'value' => $options['wcf-field-google-font-url'],
868
+ )
869
+ );
870
+ ?>
871
+ </div>
872
+ <?php do_action( 'cartflows_checkout_style_tab_content', $options, $post_id ); ?>
873
+ </div>
874
+ </div>
875
+ <?php
876
+ }
877
+
878
+
879
+ /**
880
+ * Tab Header (Used for add logo into header)
881
+ *
882
+ * @param array $options options.
883
+ * @param int $post_id post ID.
884
+ */
885
+ public function tab_header_content( $options, $post_id ) {
886
+ ?>
887
+
888
+ <div class="wcf-checkout-header wcf-tab-content widefat">
889
+ <?php
890
+
891
+ $layout_pro_option = array();
892
+
893
+ echo wcf()->meta->get_image_field(
894
+ array(
895
+ 'name' => 'wcf-header-logo-image',
896
+ 'value' => $options['wcf-header-logo-image'],
897
+ 'label' => esc_html__( 'Header Logo', 'cartflows' ),
898
+ )
899
+ );
900
+
901
+ echo wcf()->meta->get_number_field(
902
+ array(
903
+ 'name' => 'wcf-header-logo-width',
904
+ 'value' => $options['wcf-header-logo-width'],
905
+ 'label' => esc_html__( 'Logo Width (In px)', 'cartflows' ),
906
+ )
907
+ );
908
+ ?>
909
+ <?php do_action( 'cartflows_checkout_header_tab_content', $options, $post_id ); ?>
910
+ </div>
911
+ <?php
912
+ }
913
+ /**
914
+ * Get metabox options
915
+ *
916
+ * @param int $post_id post ID.
917
+ */
918
+ public static function get_meta_option( $post_id ) {
919
+
920
+ if ( null === self::$meta_option ) {
921
+
922
+ /**
923
+ * Set metabox options
924
+ *
925
+ * @see http://php.net/manual/en/filter.filters.sanitize.php
926
+ */
927
+ self::$meta_option = wcf()->options->get_checkout_fields( $post_id );
928
+ }
929
+
930
+ return self::$meta_option;
931
+ }
932
+
933
+ /**
934
+ * Metabox Save
935
+ *
936
+ * @param number $post_id Post ID.
937
+ * @return void
938
+ */
939
+ public function save_meta_box( $post_id ) {
940
+
941
+ // Checks save status.
942
+ $is_autosave = wp_is_post_autosave( $post_id );
943
+ $is_revision = wp_is_post_revision( $post_id );
944
+
945
+ $is_valid_nonce = ( isset( $_POST['nonce-checkout-step-meta'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce-checkout-step-meta'] ) ), 'save-nonce-checkout-step-meta' ) ) ? true : false;
946
+
947
+ // Exits script depending on save status.
948
+ if ( $is_autosave || $is_revision || ! $is_valid_nonce ) {
949
+ return;
950
+ }
951
+
952
+ wcf()->options->save_checkout_fields( $post_id );
953
+ }
954
+ }
955
+
956
+ /**
957
+ * Kicking this off by calling 'get_instance()' method
958
+ */
959
+ Cartflows_Checkout_Meta::get_instance();
modules/flow/classes/class-cartflows-flow-post-type.php CHANGED
@@ -1,383 +1,383 @@
1
- <?php
2
- /**
3
- * Flow post type
4
- *
5
- * @package CartFlows
6
- */
7
-
8
- /**
9
- * Initialization
10
- *
11
- * @since 1.0.0
12
- */
13
- class Cartflows_Flow_Post_Type {
14
-
15
-
16
- /**
17
- * Member Variable
18
- *
19
- * @var instance
20
- */
21
- private static $instance;
22
-
23
- /**
24
- * Initiator
25
- */
26
- public static function get_instance() {
27
- if ( ! isset( self::$instance ) ) {
28
- self::$instance = new self();
29
- }
30
- return self::$instance;
31
- }
32
-
33
- /**
34
- * Constructor
35
- */
36
- public function __construct() {
37
-
38
- add_action( 'init', array( $this, 'flow_post_type' ) );
39
- add_action( 'admin_menu', array( $this, 'register_as_submenu' ), 100 );
40
- add_action( 'do_meta_boxes', array( $this, 'wcf_change_metabox_position' ) );
41
-
42
- add_filter( 'post_updated_messages', array( $this, 'custom_post_type_post_update_messages' ) );
43
-
44
- add_filter( 'display_post_states', array( $this, 'add_cartflows_post_state' ), 15, 1 );
45
-
46
- add_filter( 'hidden_meta_boxes', array( $this, 'display_flow_slug_meta_box' ), 10, 2 );
47
-
48
- /* View Post URL */
49
- add_filter( 'post_row_actions', array( $this, 'post_row_actions' ), 10, 2 );
50
- add_filter( 'preview_post_link', array( $this, 'preview_post_link' ), 10, 2 );
51
- add_action( 'template_redirect', array( $this, 'redirect_to_step' ), 10 );
52
- }
53
-
54
- /**
55
- * Add CartFlows post status.
56
- *
57
- * @param array $post_states post data.
58
- * @return array
59
- */
60
- public function add_cartflows_post_state( $post_states ) {
61
-
62
- global $post;
63
-
64
- if ( isset( $post->post_type ) && CARTFLOWS_STEP_POST_TYPE === $post->post_type ) {
65
-
66
- $flow_id = get_post_meta( $post->ID, 'wcf-flow-id', true );
67
- $flow_title = get_the_title( $flow_id );
68
-
69
- $post_states['cartflows_step'] = '( ' . __( 'Flow: ', 'cartflows' ) . $flow_id . ' | ' . __( 'Name: ', 'cartflows' ) . $flow_title . ')';
70
-
71
- }
72
-
73
- return $post_states;
74
- }
75
-
76
- /**
77
- * Display slugdiv.
78
- *
79
- * @param array $hidden metaboxes.
80
- * @param obj $screen screen.
81
- * @return array
82
- */
83
- public function display_flow_slug_meta_box( $hidden, $screen ) {
84
- $post_type = $screen->id;
85
- if ( ! empty( $post_type ) && CARTFLOWS_FLOW_POST_TYPE === $post_type ) {
86
- $pos = array_search( 'slugdiv', $hidden, true );
87
- unset( $hidden[ $pos ] );
88
- }
89
-
90
- return $hidden;
91
- }
92
-
93
- /**
94
- * Create custom post type
95
- */
96
- public function flow_post_type() {
97
-
98
- $labels = array(
99
- 'name' => esc_html_x( 'Flows', 'flow general name', 'cartflows' ),
100
- 'singular_name' => esc_html_x( 'Flow', 'flow singular name', 'cartflows' ),
101
- 'search_items' => esc_html__( 'Search Flows', 'cartflows' ),
102
- 'all_items' => esc_html__( 'All Flows', 'cartflows' ),
103
- 'edit_item' => esc_html__( 'Edit Flow', 'cartflows' ),
104
- 'view_item' => esc_html__( 'View Flow', 'cartflows' ),
105
- 'add_new' => esc_html__( 'Add New', 'cartflows' ),
106
- 'update_item' => esc_html__( 'Update Flow', 'cartflows' ),
107
- 'add_new_item' => esc_html__( 'Add New', 'cartflows' ),
108
- 'new_item_name' => esc_html__( 'New Flow Name', 'cartflows' ),
109
- );
110
-
111
- $args = array(
112
- 'labels' => $labels,
113
- 'show_in_menu' => false,
114
- 'public' => false, // it's not public, not own permalink.
115
- 'publicly_queryable' => true, // you should be able to query it.
116
- 'show_ui' => true,
117
- 'query_var' => true,
118
- 'can_export' => true,
119
- 'show_in_admin_bar' => true,
120
- 'exclude_from_search' => true,
121
- 'has_archive' => false, // it shouldn't have archive page.
122
- 'rewrite' => false, // it shouldn't have rewrite rules.
123
- 'supports' => array( 'title', 'thumbnail', 'slug' ),
124
- 'capability_type' => 'post',
125
- );
126
-
127
- if ( ! _is_cartflows_pro() ) {
128
-
129
- $flow_posts = get_posts(
130
- array(
131
- 'posts_per_page' => 4,
132
- 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
133
- 'post_status' => array( 'publish', 'pending', 'draft', 'future', 'private', 'inherit', 'trash' ),
134
- )
135
- );
136
-
137
- if ( is_array( $flow_posts ) ) {
138
-
139
- $flow_count = count( $flow_posts );
140
-
141
- if ( $flow_count > 3 || 3 === $flow_count ) {
142
-
143
- $args['capabilities'] = array(
144
- 'create_posts' => 'do_not_allow',
145
- );
146
- $args['map_meta_cap'] = true;
147
-
148
- // Add new notice button.
149
- add_action( 'admin_print_footer_scripts', array( $this, 'add_new_notice_button' ) );
150
-
151
- // Add the notice popup HTML to admin footer.
152
- add_action( 'admin_footer', array( $this, 'upgrade_to_pro_notice_popup' ) );
153
- }
154
- }
155
- }
156
-
157
- register_post_type( CARTFLOWS_FLOW_POST_TYPE, $args );
158
- }
159
-
160
- /**
161
- * Show custom add new button.
162
- */
163
- public function add_new_notice_button() {
164
-
165
- $screen = get_current_screen();
166
-
167
- if ( is_object( $screen ) && CARTFLOWS_FLOW_POST_TYPE === $screen->post_type && 'edit-cartflows_flow' === $screen->id ) {
168
- ?>
169
- <script>
170
- jQuery('.wrap h1.wp-heading-inline').after('<a type="button" class="wcf-custom-add-new-button button">Add New</a>');
171
- </script>
172
- <?php
173
- }
174
- }
175
-
176
- /**
177
- * Upgrade to pro notice popup.
178
- *
179
- * @since 1.3.4
180
- *
181
- * @return void
182
- */
183
- public function upgrade_to_pro_notice_popup() {
184
-
185
- ?>
186
- <div id="cartflows-upgrade-notice-overlay" style="display:none;"></div>
187
- <div id="cartflows-upgrade-notice-popup" style="display:none;">
188
- <div class="inner">
189
- <div class="heading">
190
- <span><?php esc_html_e( 'Upgrade to CartFlows Pro', 'cartflows' ); ?></span>
191
- <span class="cartflows-close-popup-button tb-close-icon"></span>
192
- </div>
193
- <div class="contents">
194
- <div class="wcf-notice">
195
- <p>Upgrade to CartFlows Pro for adding more flows and other features. <a href ="https://cartflows.com/" target="_blank"> Click here</a> to upgrade.</p>
196
- </div>
197
- </div>
198
- </div>
199
- </div>
200
- <?php
201
- }
202
-
203
- /**
204
- * Change metabox position.
205
- */
206
- public function wcf_change_metabox_position() {
207
-
208
- remove_meta_box( 'slugdiv', CARTFLOWS_FLOW_POST_TYPE, 'normal' );
209
- add_meta_box( 'slugdiv', __( 'Slug', 'cartflows' ), 'post_slug_meta_box', CARTFLOWS_FLOW_POST_TYPE, 'side', 'high' );
210
- }
211
-
212
- /**
213
- * Add post raw actions
214
- *
215
- * @param array $actions actions.
216
- * @param array $post post data.
217
- * @return array
218
- */
219
- public function post_row_actions( $actions, $post ) {
220
-
221
- $first_step = $this->get_first_step_url( $post );
222
-
223
- if ( $first_step && isset( $actions['view'] ) ) {
224
-
225
- $actions['view'] = '<a href="' . $first_step . '">' . __( 'View', 'cartflows' ) . '</a>';
226
- }
227
-
228
- return $actions;
229
- }
230
-
231
- /**
232
- * Returns previous post link
233
- *
234
- * @param string $prev_link previous link.
235
- * @param array $post post data.
236
- * @return string
237
- */
238
- public function preview_post_link( $prev_link, $post ) {
239
-
240
- if ( $this->is_flow_post_type( $post ) ) {
241
-
242
- $first_step = $this->get_first_step_url( $post );
243
-
244
- if ( $first_step ) {
245
-
246
- return $first_step;
247
- }
248
-
249
- return '';
250
- }
251
-
252
- return $prev_link;
253
- }
254
-
255
- /**
256
- * Check if post type is flow
257
- *
258
- * @param array $post post data.
259
- * @return bool
260
- */
261
- public function is_flow_post_type( $post ) {
262
-
263
- if ( isset( $post ) && CARTFLOWS_FLOW_POST_TYPE === $post->post_type ) {
264
-
265
- return true;
266
- }
267
-
268
- return false;
269
- }
270
-
271
- /**
272
- * Redirect to first step
273
- *
274
- * @return void
275
- */
276
- public function redirect_to_step() {
277
-
278
- global $post;
279
-
280
- $first_step = $this->get_first_step_url( $post );
281
-
282
- if ( $first_step ) {
283
-
284
- wp_safe_redirect( $first_step );
285
- die;
286
- }
287
- }
288
-
289
- /**
290
- * Return first step URL
291
- *
292
- * @param array $post post data.
293
- * @return bool
294
- */
295
- public function get_first_step_url( $post ) {
296
-
297
- if ( $this->is_flow_post_type( $post ) ) {
298
-
299
- $flow_id = $post->ID;
300
- $title = $post->post_title;
301
- $steps = get_post_meta( $flow_id, 'wcf-steps', true );
302
-
303
- if ( is_array( $steps ) && ! empty( $steps ) && isset( $steps[0]['id'] ) ) {
304
-
305
- return get_permalink( $steps[0]['id'] );
306
- }
307
- }
308
-
309
- return false;
310
- }
311
-
312
- /**
313
- * Register the admin menu for Custom Layouts
314
- *
315
- * @since 1.0.0
316
- * Moved the menu under Appearance -> Custom Layouts
317
- public function register_admin_menu() {
318
- add_submenu_page(
319
- CARTFLOWS_SLUG,
320
- __( 'Flows', 'wcf' ),
321
- __( 'Flows', 'wcf' ),
322
- 'edit_pages',
323
- 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE
324
- );
325
- }
326
- */
327
- public function register_as_submenu() {
328
-
329
- global $submenu;
330
-
331
- $submenu[ CARTFLOWS_SLUG ][0] = array( //phpcs:ignore
332
- __( 'Flows', 'cartflows' ),
333
- 'edit_pages',
334
- 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE,
335
- );
336
- }
337
-
338
- /**
339
- * Add Update messages for any custom post type
340
- *
341
- * @param array $messages Array of default messages.
342
- */
343
- public function custom_post_type_post_update_messages( $messages ) {
344
-
345
- $custom_post_type = get_post_type( get_the_ID() );
346
-
347
- if ( CARTFLOWS_FLOW_POST_TYPE == $custom_post_type ) {
348
-
349
- $obj = get_post_type_object( $custom_post_type );
350
- $singular_name = $obj->labels->singular_name;
351
- $messages[ $custom_post_type ] = array(
352
- 0 => '', // Unused. Messages start at index 1.
353
- /* translators: %s: singular custom post type name */
354
- 1 => sprintf( __( '%s updated.', 'cartflows' ), $singular_name ),
355
- /* translators: %s: singular custom post type name */
356
- 2 => sprintf( __( 'Custom %s updated.', 'cartflows' ), $singular_name ),
357
- /* translators: %s: singular custom post type name */
358
- 3 => sprintf( __( 'Custom %s deleted.', 'cartflows' ), $singular_name ),
359
- /* translators: %s: singular custom post type name */
360
- 4 => sprintf( __( '%s updated.', 'cartflows' ), $singular_name ),
361
- /* translators: %1$s: singular custom post type name ,%2$s: date and time of the revision */
362
- 5 => isset( $_GET['revision'] ) ? sprintf( __( '%1$s restored to revision from %2$s', 'cartflows' ), $singular_name, wp_post_revision_title( (int) $_GET['revision'], false ) ) : false, //phpcs:ignore
363
- /* translators: %s: singular custom post type name */
364
- 6 => sprintf( __( '%s published.', 'cartflows' ), $singular_name ),
365
- /* translators: %s: singular custom post type name */
366
- 7 => sprintf( __( '%s saved.', 'cartflows' ), $singular_name ),
367
- /* translators: %s: singular custom post type name */
368
- 8 => sprintf( __( '%s submitted.', 'cartflows' ), $singular_name ),
369
- /* translators: %s: singular custom post type name */
370
- 9 => sprintf( __( '%s scheduled for.', 'cartflows' ), $singular_name ),
371
- /* translators: %s: singular custom post type name */
372
- 10 => sprintf( __( '%s draft updated.', 'cartflows' ), $singular_name ),
373
- );
374
- }
375
-
376
- return $messages;
377
- }
378
- }
379
-
380
- /**
381
- * Kicking this off by calling 'get_instance()' method
382
- */
383
- Cartflows_Flow_Post_Type::get_instance();
1
+ <?php
2
+ /**
3
+ * Flow post type
4
+ *
5
+ * @package CartFlows
6
+ */
7
+
8
+ /**
9
+ * Initialization
10
+ *
11
+ * @since 1.0.0
12
+ */
13
+ class Cartflows_Flow_Post_Type {
14
+
15
+
16
+ /**
17
+ * Member Variable
18
+ *
19
+ * @var instance
20
+ */
21
+ private static $instance;
22
+
23
+ /**
24
+ * Initiator
25
+ */
26
+ public static function get_instance() {
27
+ if ( ! isset( self::$instance ) ) {
28
+ self::$instance = new self();
29
+ }
30
+ return self::$instance;
31
+ }
32
+
33
+ /**
34
+ * Constructor
35
+ */
36
+ public function __construct() {
37
+
38
+ add_action( 'init', array( $this, 'flow_post_type' ) );
39
+ add_action( 'admin_menu', array( $this, 'register_as_submenu' ), 100 );
40
+ add_action( 'do_meta_boxes', array( $this, 'wcf_change_metabox_position' ) );
41
+
42
+ add_filter( 'post_updated_messages', array( $this, 'custom_post_type_post_update_messages' ) );
43
+
44
+ add_filter( 'display_post_states', array( $this, 'add_cartflows_post_state' ), 15, 1 );
45
+
46
+ add_filter( 'hidden_meta_boxes', array( $this, 'display_flow_slug_meta_box' ), 10, 2 );
47
+
48
+ /* View Post URL */
49
+ add_filter( 'post_row_actions', array( $this, 'post_row_actions' ), 10, 2 );
50
+ add_filter( 'preview_post_link', array( $this, 'preview_post_link' ), 10, 2 );
51
+ add_action( 'template_redirect', array( $this, 'redirect_to_step' ), 10 );
52
+ }
53
+
54
+ /**
55
+ * Add CartFlows post status.
56
+ *
57
+ * @param array $post_states post data.
58
+ * @return array
59
+ */
60
+ public function add_cartflows_post_state( $post_states ) {
61
+
62
+ global $post;
63
+
64
+ if ( isset( $post->post_type ) && CARTFLOWS_STEP_POST_TYPE === $post->post_type ) {
65
+
66
+ $flow_id = get_post_meta( $post->ID, 'wcf-flow-id', true );
67
+ $flow_title = get_the_title( $flow_id );
68
+
69
+ $post_states['cartflows_step'] = '( ' . __( 'Flow: ', 'cartflows' ) . $flow_id . ' | ' . __( 'Name: ', 'cartflows' ) . $flow_title . ')';
70
+
71
+ }
72
+
73
+ return $post_states;
74
+ }
75
+
76
+ /**
77
+ * Display slugdiv.
78
+ *
79
+ * @param array $hidden metaboxes.
80
+ * @param obj $screen screen.
81
+ * @return array
82
+ */
83
+ public function display_flow_slug_meta_box( $hidden, $screen ) {
84
+ $post_type = $screen->id;
85
+ if ( ! empty( $post_type ) && CARTFLOWS_FLOW_POST_TYPE === $post_type ) {
86
+ $pos = array_search( 'slugdiv', $hidden, true );
87
+ unset( $hidden[ $pos ] );
88
+ }
89
+
90
+ return $hidden;
91
+ }
92
+
93
+ /**
94
+ * Create custom post type
95
+ */
96
+ public function flow_post_type() {
97
+
98
+ $labels = array(
99
+ 'name' => esc_html_x( 'Flows', 'flow general name', 'cartflows' ),
100
+ 'singular_name' => esc_html_x( 'Flow', 'flow singular name', 'cartflows' ),
101
+ 'search_items' => esc_html__( 'Search Flows', 'cartflows' ),
102
+ 'all_items' => esc_html__( 'All Flows', 'cartflows' ),
103
+ 'edit_item' => esc_html__( 'Edit Flow', 'cartflows' ),
104
+ 'view_item' => esc_html__( 'View Flow', 'cartflows' ),
105
+ 'add_new' => esc_html__( 'Add New', 'cartflows' ),
106
+ 'update_item' => esc_html__( 'Update Flow', 'cartflows' ),
107
+ 'add_new_item' => esc_html__( 'Add New', 'cartflows' ),
108
+ 'new_item_name' => esc_html__( 'New Flow Name', 'cartflows' ),
109
+ );
110
+
111
+ $args = array(
112
+ 'labels' => $labels,
113
+ 'show_in_menu' => false,
114
+ 'public' => false, // it's not public, not own permalink.
115
+ 'publicly_queryable' => true, // you should be able to query it.
116
+ 'show_ui' => true,
117
+ 'query_var' => true,
118
+ 'can_export' => true,
119
+ 'show_in_admin_bar' => true,
120
+ 'exclude_from_search' => true,
121
+ 'has_archive' => false, // it shouldn't have archive page.
122
+ 'rewrite' => false, // it shouldn't have rewrite rules.
123
+ 'supports' => array( 'title', 'thumbnail', 'slug' ),
124
+ 'capability_type' => 'post',
125
+ );
126
+
127
+ if ( ! _is_cartflows_pro() ) {
128
+
129
+ $flow_posts = get_posts(
130
+ array(
131
+ 'posts_per_page' => 4,
132
+ 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
133
+ 'post_status' => array( 'publish', 'pending', 'draft', 'future', 'private' ),
134
+ )
135
+ );
136
+
137
+ if ( is_array( $flow_posts ) ) {
138
+
139
+ $flow_count = count( $flow_posts );
140
+
141
+ if ( $flow_count > 3 || 3 === $flow_count ) {
142
+
143
+ $args['capabilities'] = array(
144
+ 'create_posts' => 'do_not_allow',
145
+ );
146
+ $args['map_meta_cap'] = true;
147
+
148
+ // Add new notice button.
149
+ add_action( 'admin_print_footer_scripts', array( $this, 'add_new_notice_button' ) );
150
+
151
+ // Add the notice popup HTML to admin footer.
152
+ add_action( 'admin_footer', array( $this, 'upgrade_to_pro_notice_popup' ) );
153
+ }
154
+ }
155
+ }
156
+
157
+ register_post_type( CARTFLOWS_FLOW_POST_TYPE, $args );
158
+ }
159
+
160
+ /**
161
+ * Show custom add new button.
162
+ */
163
+ public function add_new_notice_button() {
164
+
165
+ $screen = get_current_screen();
166
+
167
+ if ( is_object( $screen ) && CARTFLOWS_FLOW_POST_TYPE === $screen->post_type && 'edit-cartflows_flow' === $screen->id ) {
168
+ ?>
169
+ <script>
170
+ jQuery('.wrap h1.wp-heading-inline').after('<a type="button" class="wcf-custom-add-new-button button">Add New</a>');
171
+ </script>
172
+ <?php
173
+ }
174
+ }
175
+
176
+ /**
177
+ * Upgrade to pro notice popup.
178
+ *
179
+ * @since 1.3.4
180
+ *
181
+ * @return void
182
+ */
183
+ public function upgrade_to_pro_notice_popup() {
184
+
185
+ ?>
186
+ <div id="cartflows-upgrade-notice-overlay" style="display:none;"></div>
187
+ <div id="cartflows-upgrade-notice-popup" style="display:none;">
188
+ <div class="inner">
189
+ <div class="heading">
190
+ <span><?php esc_html_e( 'Upgrade to CartFlows Pro', 'cartflows' ); ?></span>
191
+ <span class="cartflows-close-popup-button tb-close-icon"></span>
192
+ </div>
193
+ <div class="contents">
194
+ <div class="wcf-notice">
195
+ <p>Upgrade to CartFlows Pro for adding more flows and other features. <a href ="https://cartflows.com/" target="_blank"> Click here</a> to upgrade.</p>
196
+ </div>
197
+ </div>
198
+ </div>
199
+ </div>
200
+ <?php
201
+ }
202
+
203
+ /**
204
+ * Change metabox position.
205
+ */
206
+ public function wcf_change_metabox_position() {
207
+
208
+ remove_meta_box( 'slugdiv', CARTFLOWS_FLOW_POST_TYPE, 'normal' );
209
+ add_meta_box( 'slugdiv', __( 'Slug', 'cartflows' ), 'post_slug_meta_box', CARTFLOWS_FLOW_POST_TYPE, 'side', 'high' );
210
+ }
211
+
212
+ /**
213
+ * Add post raw actions
214
+ *
215
+ * @param array $actions actions.
216
+ * @param array $post post data.
217
+ * @return array
218
+ */
219
+ public function post_row_actions( $actions, $post ) {
220
+
221
+ $first_step = $this->get_first_step_url( $post );
222
+
223
+ if ( $first_step && isset( $actions['view'] ) ) {
224
+
225
+ $actions['view'] = '<a href="' . $first_step . '">' . __( 'View', 'cartflows' ) . '</a>';
226
+ }
227
+
228
+ return $actions;
229
+ }
230
+
231
+ /**
232
+ * Returns previous post link
233
+ *
234
+ * @param string $prev_link previous link.
235
+ * @param array $post post data.
236
+ * @return string
237
+ */
238
+ public function preview_post_link( $prev_link, $post ) {
239
+
240
+ if ( $this->is_flow_post_type( $post ) ) {
241
+
242
+ $first_step = $this->get_first_step_url( $post );
243
+
244
+ if ( $first_step ) {
245
+
246
+ return $first_step;
247
+ }
248
+
249
+ return '';
250
+ }
251
+
252
+ return $prev_link;
253
+ }
254
+
255
+ /**
256
+ * Check if post type is flow
257
+ *
258
+ * @param array $post post data.
259
+ * @return bool
260
+ */
261
+ public function is_flow_post_type( $post ) {
262
+
263
+ if ( isset( $post ) && CARTFLOWS_FLOW_POST_TYPE === $post->post_type ) {
264
+
265
+ return true;
266
+ }
267
+
268
+ return false;
269
+ }
270
+
271
+ /**
272
+ * Redirect to first step
273
+ *
274
+ * @return void
275
+ */
276
+ public function redirect_to_step() {
277
+
278
+ global $post;
279
+
280
+ $first_step = $this->get_first_step_url( $post );
281
+
282
+ if ( $first_step ) {
283
+
284
+ wp_safe_redirect( $first_step );
285
+ die;
286
+ }
287
+ }
288
+
289
+ /**
290
+ * Return first step URL
291
+ *
292
+ * @param array $post post data.
293
+ * @return bool
294
+ */
295
+ public function get_first_step_url( $post ) {
296
+
297
+ if ( $this->is_flow_post_type( $post ) ) {
298
+
299
+ $flow_id = $post->ID;
300
+ $title = $post->post_title;
301
+ $steps = get_post_meta( $flow_id, 'wcf-steps', true );
302
+
303
+ if ( is_array( $steps ) && ! empty( $steps ) && isset( $steps[0]['id'] ) ) {
304
+
305
+ return get_permalink( $steps[0]['id'] );
306
+ }
307
+ }
308
+
309
+ return false;
310
+ }
311
+
312
+ /**
313
+ * Register the admin menu for Custom Layouts
314
+ *
315
+ * @since 1.0.0
316
+ * Moved the menu under Appearance -> Custom Layouts
317
+ public function register_admin_menu() {
318
+ add_submenu_page(
319
+ CARTFLOWS_SLUG,
320
+ __( 'Flows', 'wcf' ),
321
+ __( 'Flows', 'wcf' ),
322
+ 'edit_pages',
323
+ 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE
324
+ );
325
+ }
326
+ */
327
+ public function register_as_submenu() {
328
+
329
+ global $submenu;
330
+
331
+ $submenu[ CARTFLOWS_SLUG ][0] = array( //phpcs:ignore
332
+ __( 'Flows', 'cartflows' ),
333
+ 'edit_pages',
334
+ 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE,
335
+ );
336
+ }
337
+
338
+ /**
339
+ * Add Update messages for any custom post type
340
+ *
341
+ * @param array $messages Array of default messages.
342
+ */
343
+ public function custom_post_type_post_update_messages( $messages ) {
344
+
345
+ $custom_post_type = get_post_type( get_the_ID() );
346
+
347
+ if ( CARTFLOWS_FLOW_POST_TYPE == $custom_post_type ) {
348
+
349
+ $obj = get_post_type_object( $custom_post_type );
350
+ $singular_name = $obj->labels->singular_name;
351
+ $messages[ $custom_post_type ] = array(
352
+ 0 => '', // Unused. Messages start at index 1.
353
+ /* translators: %s: singular custom post type name */
354
+ 1 => sprintf( __( '%s updated.', 'cartflows' ), $singular_name ),
355
+ /* translators: %s: singular custom post type name */
356
+ 2 => sprintf( __( 'Custom %s updated.', 'cartflows' ), $singular_name ),
357
+ /* translators: %s: singular custom post type name */
358
+ 3 => sprintf( __( 'Custom %s deleted.', 'cartflows' ), $singular_name ),
359
+ /* translators: %s: singular custom post type name */
360
+ 4 => sprintf( __( '%s updated.', 'cartflows' ), $singular_name ),
361
+ /* translators: %1$s: singular custom post type name ,%2$s: date and time of the revision */
362
+ 5 => isset( $_GET['revision'] ) ? sprintf( __( '%1$s restored to revision from %2$s', 'cartflows' ), $singular_name, wp_post_revision_title( (int) $_GET['revision'], false ) ) : false, //phpcs:ignore
363
+ /* translators: %s: singular custom post type name */
364
+ 6 => sprintf( __( '%s published.', 'cartflows' ), $singular_name ),
365
+ /* translators: %s: singular custom post type name */
366
+ 7 => sprintf( __( '%s saved.', 'cartflows' ), $singular_name ),
367
+ /* translators: %s: singular custom post type name */
368
+ 8 => sprintf( __( '%s submitted.', 'cartflows' ), $singular_name ),
369
+ /* translators: %s: singular custom post type name */
370
+ 9 => sprintf( __( '%s scheduled for.', 'cartflows' ), $singular_name ),
371
+ /* translators: %s: singular custom post type name */
372
+ 10 => sprintf( __( '%s draft updated.', 'cartflows' ), $singular_name ),
373
+ );
374
+ }
375
+
376
+ return $messages;
377
+ }
378
+ }
379
+
380
+ /**
381
+ * Kicking this off by calling 'get_instance()' method
382
+ */
383
+ Cartflows_Flow_Post_Type::get_instance();
modules/flow/classes/class-cartflows-permalink.php CHANGED
@@ -1,159 +1,158 @@
1
- <?php
2
- /**
3
- * Step post type.
4
- *
5
- * @package CartFlows
6
- */
7
-
8
- /**
9
- * Initialization
10
- *
11
- * @since 1.0.0
12
- */
13
- class Cartflows_Permalink {
14
-
15
-
16
- /**
17
- * Member Variable
18
- *
19
- * @var instance
20
- */
21
- private static $instance;
22
-
23
- /**
24
- * Initiator
25
- */
26
- public static function get_instance() {
27
- if ( ! isset( self::$instance ) ) {
28
- self::$instance = new self();
29
- }
30
- return self::$instance;
31
- }
32
-
33
- /**
34
- * Constructor
35
- */
36
- public function __construct() {
37
-
38
- add_filter( 'post_type_link', array( $this, 'post_type_permalinks' ), 10, 3 );
39
- add_action( 'init', array( $this, 'rewrite_step_rule' ) );
40
-
41
- add_action( 'pre_get_posts', array( $this, 'add_cpt_post_names_to_main_query' ), 20 );
42
-
43
- }
44
-
45
- /**
46
- * Modify permalink
47
- *
48
- * @param string $post_link post link.
49
- * @param array $post post data.
50
- * @param string $leavename leave name.
51
- * @return string
52
- */
53
- public function post_type_permalinks( $post_link, $post, $leavename ) {
54
-
55
- if ( isset( $post->post_type ) && CARTFLOWS_STEP_POST_TYPE == $post->post_type ) {
56
-
57
- $flow_id = get_post_meta( $post->ID, 'wcf-flow-id', true );
58
- $flow_name = get_post_field( 'post_name', $flow_id );
59
- $cf_permalink = Cartflows_Helper::get_permalink_settings();
60
-
61
- if ( isset( $cf_permalink['permalink_structure'] ) && ! empty( $cf_permalink['permalink_structure'] ) ) {
62
-
63
- $search = array( 'cartflows_flow', '%flowname%', 'cartflows_step' );
64
- $replace = array( $cf_permalink['permalink_flow_base'], $flow_name, $cf_permalink['permalink'] );
65
- $post_link = str_replace( $search, $replace, $post_link );
66
- } else {
67
-
68
- // If elementor page preview, return post link as it is.
69
- if ( isset( $_REQUEST['elementor-preview'] ) ) { //phpcs:ignore
70
- return $post_link;
71
- }
72
-
73
- $structure = get_option( 'permalink_structure' );
74
-
75
- if ( '/%postname%/' === $structure ) {
76
-
77
- $post_link = str_replace( '/' . $post->post_type . '/', '/', $post_link );
78
-
79
- }
80
- }
81
- }
82
-
83
- return $post_link;
84
- }
85
-
86
- /**
87
- * Reqrite rules for acrtflows step.
88
- */
89
- public function rewrite_step_rule() {
90
-
91
- $cf_permalink = Cartflows_Helper::get_permalink_settings();
92
-
93
- if ( isset( $cf_permalink['permalink_structure'] ) ) {
94
- switch ( $cf_permalink['permalink_structure'] ) {
95
- case '/cartflows_flow/%flowname%/cartflows_step':
96
- add_rewrite_rule( '^' . $cf_permalink['permalink_flow_base'] . '/([^/]*)/' . $cf_permalink['permalink'] . '/([^\/]*)/?', 'index.php?cartflows_step=$matches[2]', 'top' );
97
- break;
98
-
99
- case '/cartflows_flow/%flowname%':
100
- add_rewrite_rule( '^' . $cf_permalink['permalink_flow_base'] . '/([^/]*)/([^/]*)/?', 'index.php?cartflows_step=$matches[2]', 'top' );
101
- break;
102
-
103
- case '/%flowname%/cartflows_step':
104
- add_rewrite_rule( '([^/]*)/' . $cf_permalink['permalink'] . '/([^\/]*)/?', 'index.php?cartflows_step=$matches[2]', 'top' );
105
-
106
- break;
107
-
108
- default:
109
- break;
110
- }
111
- }
112
-
113
- }
114
-
115
- /**
116
- * Have WordPress match postname to any of our public post types.
117
- * All of our public post types can have /post-name/ as the slug, so they need to be unique across all posts.
118
- * By default, WordPress only accounts for posts and pages where the slug is /post-name/.
119
- *
120
- * @param string $query query statement.
121
- */
122
- public function add_cpt_post_names_to_main_query( $query ) {
123
-
124
- // Bail if this is not the main query.
125
- if ( ! $query->is_main_query() ) {
126
- return;
127
- }
128
-
129
- // Bail if this query doesn't match our very specific rewrite rule.
130
- if ( ! isset( $query->query['thrive-variations'] ) && ! isset( $query->query['page'] ) || 2 !== count( $query->query ) ) {
131
- return;
132
- }
133
-
134
- // Bail if we're not querying based on the post name.
135
- if ( empty( $query->query['name'] ) ) {
136
- return;
137
- }
138
-
139
- // Add cartflows step post type to existing post type array.
140
- if ( isset( $query->query_vars['post_type'] ) && is_array( $query->query_vars['post_type'] ) ) {
141
-
142
- $post_types = $query->query_vars['post_type'];
143
-
144
- $post_types[] = CARTFLOWS_STEP_POST_TYPE;
145
-
146
- $query->set( 'post_type', $post_types );
147
-
148
- } else {
149
-
150
- // Add CPT to the list of post types WP will include when it queries based on the post name.
151
- $query->set( 'post_type', array( 'post', 'page', CARTFLOWS_STEP_POST_TYPE ) );
152
- }
153
- }
154
- }
155
-
156
- /**
157
- * Kicking this off by calling 'get_instance()' method
158
- */
159
- Cartflows_Permalink::get_instance();
1
+ <?php
2
+ /**
3
+ * Step post type.
4
+ *
5
+ * @package CartFlows
6
+ */
7
+
8
+ /**
9
+ * Initialization
10
+ *
11
+ * @since 1.0.0
12
+ */
13
+ class Cartflows_Permalink {
14
+
15
+
16
+ /**
17
+ * Member Variable
18
+ *
19
+ * @var instance
20
+ */
21
+ private static $instance;
22
+
23
+ /**
24
+ * Initiator
25
+ */
26
+ public static function get_instance() {
27
+ if ( ! isset( self::$instance ) ) {
28
+ self::$instance = new self();
29
+ }
30
+ return self::$instance;
31
+ }
32
+
33
+ /**
34
+ * Constructor
35
+ */
36
+ public function __construct() {
37
+
38
+ add_filter( 'post_type_link', array( $this, 'post_type_permalinks' ), 10, 3 );
39
+ add_action( 'init', array( $this, 'rewrite_step_rule' ) );
40
+ add_action( 'pre_get_posts', array( $this, 'add_cpt_post_names_to_main_query' ), 20 );
41
+ }
42
+
43
+ /**
44
+ * Modify permalink
45
+ *
46
+ * @param string $post_link post link.
47
+ * @param array $post post data.
48
+ * @param string $leavename leave name.
49
+ * @return string
50
+ */
51
+ public function post_type_permalinks( $post_link, $post, $leavename ) {
52
+
53
+ if ( isset( $post->post_type ) && CARTFLOWS_STEP_POST_TYPE == $post->post_type ) {
54
+
55
+ $flow_id = get_post_meta( $post->ID, 'wcf-flow-id', true );
56
+ $flow_name = get_post_field( 'post_name', $flow_id );
57
+ $cf_permalink = Cartflows_Helper::get_permalink_settings();
58
+
59
+ if ( isset( $cf_permalink['permalink_structure'] ) && ! empty( $cf_permalink['permalink_structure'] ) ) {
60
+
61
+ $sep = '/';
62
+ $search = array( $sep . 'cartflows_flow', $sep . '%flowname%', $sep . 'cartflows_step' );
63
+ $replace = array( $sep . $cf_permalink['permalink_flow_base'], $sep . $flow_name, $sep . $cf_permalink['permalink'] );
64
+ $post_link = str_replace( $search, $replace, $post_link );
65
+ } else {
66
+
67
+ // If elementor page preview, return post link as it is.
68
+ if ( isset( $_REQUEST['elementor-preview'] ) ) { //phpcs:ignore
69
+ return $post_link;
70
+ }
71
+
72
+ $structure = get_option( 'permalink_structure' );
73
+
74
+ if ( '/%postname%/' === $structure ) {
75
+
76
+ $post_link = str_replace( '/' . $post->post_type . '/', '/', $post_link );
77
+
78
+ }
79
+ }
80
+ }
81
+
82
+ return $post_link;
83
+ }
84
+
85
+ /**
86
+ * Reqrite rules for acrtflows step.
87
+ */
88
+ public function rewrite_step_rule() {
89
+
90
+ $cf_permalink = Cartflows_Helper::get_permalink_settings();
91
+
92
+ if ( isset( $cf_permalink['permalink_structure'] ) ) {
93
+ switch ( $cf_permalink['permalink_structure'] ) {
94
+ case '/cartflows_flow/%flowname%/cartflows_step':
95
+ add_rewrite_rule( '^' . $cf_permalink['permalink_flow_base'] . '/([^/]*)/' . $cf_permalink['permalink'] . '/([^\/]*)/?', 'index.php?cartflows_step=$matches[2]', 'top' );
96
+ break;
97
+
98
+ case '/cartflows_flow/%flowname%':
99
+ add_rewrite_rule( '^' . $cf_permalink['permalink_flow_base'] . '/([^/]*)/([^/]*)/?', 'index.php?cartflows_step=$matches[2]', 'top' );
100
+ break;
101
+
102
+ case '/%flowname%/cartflows_step':
103
+ add_rewrite_rule( '([^/]*)/' . $cf_permalink['permalink'] . '/([^\/]*)/?', 'index.php?cartflows_step=$matches[2]', 'top' );
104
+
105
+ break;
106
+
107
+ default:
108
+ break;
109
+ }
110
+ }
111
+
112
+ }
113
+
114
+ /**
115
+ * Have WordPress match postname to any of our public post types.
116
+ * All of our public post types can have /post-name/ as the slug, so they need to be unique across all posts.
117
+ * By default, WordPress only accounts for posts and pages where the slug is /post-name/.
118
+ *
119
+ * @param string $query query statement.
120
+ */
121
+ public function add_cpt_post_names_to_main_query( $query ) {
122
+
123
+ // Bail if this is not the main query.
124
+ if ( ! $query->is_main_query() ) {
125
+ return;
126
+ }
127
+
128
+ // Bail if this query doesn't match our very specific rewrite rule.
129
+ if ( ! isset( $query->query['thrive-variations'] ) && ! isset( $query->query['page'] ) || 2 !== count( $query->query ) ) {
130
+ return;
131
+ }
132
+
133
+ // Bail if we're not querying based on the post name.
134
+ if ( empty( $query->query['name'] ) ) {
135
+ return;
136
+ }
137
+
138
+ // Add cartflows step post type to existing post type array.
139
+ if ( isset( $query->query_vars['post_type'] ) && is_array( $query->query_vars['post_type'] ) ) {
140
+
141
+ $post_types = $query->query_vars['post_type'];
142
+
143
+ $post_types[] = CARTFLOWS_STEP_POST_TYPE;
144
+
145
+ $query->set( 'post_type', $post_types );
146
+
147
+ } else {
148
+
149
+ // Add CPT to the list of post types WP will include when it queries based on the post name.
150
+ $query->set( 'post_type', array( 'post', 'page', CARTFLOWS_STEP_POST_TYPE ) );
151
+ }
152
+ }
153
+ }
154
+
155
+ /**
156
+ * Kicking this off by calling 'get_instance()' method
157
+ */
158
+ Cartflows_Permalink::get_instance();
 
modules/flow/classes/class-cartflows-step-post-type.php CHANGED
@@ -1,496 +1,496 @@
1
- <?php
2
- /**
3
- * Step post type.
4
- *
5
- * @package CartFlows
6
- */
7
-
8
- /**
9
- * Initialization
10
- *
11
- * @since 1.0.0
12
- */
13
- class Cartflows_Step_Post_Type {
14
-
15
-
16
- /**
17
- * Member Variable
18
- *
19
- * @var instance
20
- */
21
- private static $instance;
22
-
23
- /**
24
- * Member Variable
25
- *
26
- * @var body_classes
27
- */
28
- private $body_classes = array();
29
-
30
- /**
31
- * Initiator
32
- */
33
- public static function get_instance() {
34
- if ( ! isset( self::$instance ) ) {
35
- self::$instance = new self();
36
- }
37
- return self::$instance;
38
- }
39
-
40
- /**
41
- * Constructor
42
- */
43
- public function __construct() {
44
-
45
- add_action( 'init', array( $this, 'step_post_type' ) );
46
- add_action( 'init', array( $this, 'add_wp_templates_support' ) );
47
- add_filter( 'post_updated_messages', array( $this, 'post_update_messages' ) );
48
-
49
- add_filter( 'wp_unique_post_slug', array( $this, 'prevent_slug_duplicates' ), 10, 6 );
50
-
51
- add_filter( 'template_include', array( $this, 'load_page_template' ), 90 );
52
- add_filter( 'template_redirect', array( $this, 'query_fix' ), 3 );
53
-
54
- add_action( 'admin_init', array( $this, 'disallowed_admin_all_steps_view' ) );
55
- }
56
-
57
- /**
58
- * Trys to load page.php for a header, footer or part theme layout.
59
- *
60
- * @since 1.0.0
61
- * @param string $template The current template to be loaded.
62
- * @return string
63
- */
64
- public function load_page_template( $template ) {
65
-
66
- global $post;
67
-
68
- if ( 'string' == gettype( $template ) && is_object( $post ) && CARTFLOWS_STEP_POST_TYPE === $post->post_type ) {
69
-
70
- /**
71
- * Remove Next/Prev Navigation
72
- * add_filter('next_post_link', '__return_empty_string');
73
- * add_filter('previous_post_link', '__return_empty_string');
74
- *
75
- * $page = locate_template( array( 'page.php' ) );
76
- *
77
- * if ( ! empty( $page ) ) {
78
- * return $page;
79
- * }
80
- */
81
-
82
- /* Remove Next / Previous Rel Link */
83
- remove_action( 'wp_head', 'adjacent_posts_rel_link_wp_head', 10, 0 );
84
- add_filter( 'next_post_rel_link', '__return_empty_string' );
85
- add_filter( 'previous_post_rel_link', '__return_empty_string' );
86
-
87
- $page_template = get_post_meta( _get_wcf_step_id(), '_wp_page_template', true );
88
-
89
- $page_template = apply_filters( 'cartflows_page_template', $page_template );
90
-
91
- $file = '';
92
-
93
- switch ( $page_template ) {
94
-
95
- case 'cartflows-default':
96
- $file = CARTFLOWS_FLOW_DIR . 'templates/template-default.php';
97
- $this->body_classes[] = $page_template;
98
- break;
99
- case 'cartflows-canvas':
100
- $file = CARTFLOWS_FLOW_DIR . 'templates/template-canvas.php';
101
- $this->body_classes[] = $page_template;
102
- break;
103
- default:
104
- /**
105
- * Remove Next/Prev Navigation
106
- */
107
- add_filter( 'next_post_link', '__return_empty_string' );
108
- add_filter( 'previous_post_link', '__return_empty_string' );
109
-
110
- $page = locate_template( array( 'page.php' ) );
111
-
112
- if ( ! empty( $page ) ) {
113
- $file = $page;
114
- }
115
-
116
- break;
117
-
118
- /**
119
- * Default:
120
- * $file = CARTFLOWS_FLOW_DIR . 'templates/template-default.php';
121
- * $this->body_classes[] = 'cartflows-default';
122
- * break;
123
- */
124
- }
125
-
126
- // Just to be safe, we check if the file exist first.
127
- if ( file_exists( $file ) ) {
128
-
129
- /* Add Body Class */
130
- add_filter( 'body_class', array( $this, 'body_class' ) );
131
-
132
- return $file;
133
- } else {
134
- echo $file;
135
- }
136
- }
137
-
138
- return $template;
139
- }
140
-
141
- /**
142
- * Body classes.
143
- *
144
- * @since 1.0.0
145
- * @param array $classes Body classes.
146
- * @return array
147
- */
148
- public function body_class( $classes = array() ) {
149
-
150
- $classes = array_merge( $classes, $this->body_classes );
151
-
152
- return $classes;
153
- }
154
-
155
- /**
156
- * Create custom post type
157
- */
158
- public function step_post_type() {
159
-
160
- $labels = array(
161
- 'name' => esc_html_x( 'Steps', 'flow step general name', 'cartflows' ),
162
- 'singular_name' => esc_html_x( 'Step', 'flow step singular name', 'cartflows' ),
163
- 'search_items' => esc_html__( 'Search Steps', 'cartflows' ),
164
- 'all_items' => esc_html__( 'All Steps', 'cartflows' ),
165
- 'edit_item' => esc_html__( 'Edit Step', 'cartflows' ),
166
- 'view_item' => esc_html__( 'View Step', 'cartflows' ),
167
- 'add_new' => esc_html__( 'Add New', 'cartflows' ),
168
- 'update_item' => esc_html__( 'Update Step', 'cartflows' ),
169
- 'add_new_item' => esc_html__( 'Add New', 'cartflows' ),
170
- 'new_item_name' => esc_html__( 'New Step Name', 'cartflows' ),
171
- );
172
-
173
- $permalink_settings = Cartflows_Helper::get_permalink_settings();
174
-
175
- $args = array(
176
- 'labels' => $labels,
177
- 'public' => true,
178
- 'query_var' => true,
179
- 'can_export' => true,
180
- 'exclude_from_search' => true,
181
- 'show_ui' => true,
182
- 'show_in_menu' => false,
183
- 'show_in_admin_bar' => true,
184
- 'show_in_rest' => true,
185
- 'supports' => array( 'title', 'editor', 'elementor', 'revisions' ),
186
- 'capability_type' => 'post',
187
- 'capabilities' => array(
188
- 'create_posts' => 'do_not_allow', // Prior to Wordpress 4.5, this was false.
189
- ),
190
- 'map_meta_cap' => true,
191
- );
192
-
193
- if ( isset( $permalink_settings['permalink_structure'] ) && ! empty( $permalink_settings['permalink_structure'] ) ) {
194
- $args['rewrite'] = array(
195
- 'slug' => $permalink_settings['permalink_structure'],
196
- 'with_front' => false,
197
- );
198
-
199
- } elseif ( isset( $permalink_settings['permalink'] ) && ! empty( $permalink_settings['permalink'] ) ) {
200
-
201
- $args['rewrite'] = array(
202
- 'slug' => $permalink_settings['permalink'],
203
- 'with_front' => false,
204
- );
205
- }
206
-
207
- register_post_type( CARTFLOWS_STEP_POST_TYPE, $args );
208
-
209
- // Step Type.
210
- $args = array(
211
- 'label' => __( 'Step Type', 'cartflows' ),
212
- 'public' => false,
213
- 'rewrite' => false,
214
- 'hierarchical' => false,
215
- );
216
-
217
- register_taxonomy( CARTFLOWS_TAXONOMY_STEP_TYPE, CARTFLOWS_STEP_POST_TYPE, $args );
218
-
219
- // Step Flow.
220
- $args = array(
221
- 'label' => __( 'Step Flow', 'cartflows' ),
222
- 'public' => false,
223
- 'rewrite' => false,
224
- 'hierarchical' => false,
225
- );
226
-
227
- register_taxonomy( CARTFLOWS_TAXONOMY_STEP_FLOW, CARTFLOWS_STEP_POST_TYPE, $args );
228
-
229
- if ( is_admin() ) {
230
- /**
231
- * Register 'Elementor' & 'Beaver Builder' site types.
232
- *
233
- * @see self::add_terms();
234
- */
235
- $taxonomy = CARTFLOWS_TAXONOMY_STEP_TYPE;
236
-
237
- $terms = array(
238
- array(
239
- 'name' => __( 'Landing', 'cartflows' ),
240
- 'slug' => 'landing',
241
- 'args' => array(
242
- 'slug' => 'landing',
243
- ),
244
- ),
245
- array(
246
- 'name' => __( 'Optin (Woo)', 'cartflows' ),
247
- 'slug' => 'optin',
248
- 'args' => array(
249
- 'slug' => 'optin',
250
- ),
251
- ),
252
- array(
253
- 'name' => __( 'Checkout (Woo)', 'cartflows' ),
254
- 'slug' => 'checkout',
255
- 'args' => array(
256
- 'slug' => 'checkout',
257
- ),
258
- ),
259
- array(
260
- 'name' => __( 'Thank You (Woo)', 'cartflows' ),
261
- 'slug' => 'thankyou',
262
- 'args' => array(
263
- 'slug' => 'thankyou',
264
- ),
265
- ),
266
- array(
267
- 'name' => __( 'Upsell (Woo)', 'cartflows' ),
268
- 'slug' => 'upsell',
269
- 'args' => array(
270
- 'slug' => 'upsell',
271
- ),
272
- ),
273
- array(
274
- 'name' => __( 'Downsell (Woo)', 'cartflows' ),
275
- 'slug' => 'downsell',
276
- 'args' => array(
277
- 'slug' => 'downsell',
278
- ),
279
- ),
280
- );
281
-
282
- $this->add_terms( $taxonomy, $terms );
283
-
284
- }
285
- }
286
-
287
- /**
288
- * Add WordPress templates.
289
- *
290
- * Adds Cartflows templates to steps
291
- *
292
- * @since 1.0.0
293
- * @access public
294
- */
295
- public function add_wp_templates_support() {
296
- add_filter( 'theme_' . CARTFLOWS_STEP_POST_TYPE . '_templates', array( $this, 'add_page_templates' ), 99, 4 );
297
- }
298
-
299
- /**
300
- * Add page templates.
301
- *
302
- * @since 1.0.0
303
- * @access public
304
- *
305
- * @param array $page_templates Array of page templates.
306
- *
307
- * @param object $wp_theme wp theme.
308
- * @param object $post post.
309
- *
310
- * @return array Page templates.
311
- */
312
- public function add_page_templates( $page_templates, $wp_theme, $post ) {
313
-
314
- $page_templates = array(
315
- 'cartflows-default' => _x( 'CartFlows — Boxed', 'cartflows' ),
316
- 'cartflows-canvas' => _x( 'Template for Page Builders', 'cartflows' ),
317
- );
318
-
319
- return $page_templates;
320
- }
321
-
322
- /**
323
- * Query fixe throwing error on 404 page due our post type changes.
324
- * We are setting post_type as empty array to fix the issue.
325
- * Ther error was throwing due to redirect_canonical function
326
- * This fix is apply for 404 page only
327
- */
328
- public function query_fix() {
329
-
330
- global $wp_query;
331
-
332
- if ( $wp_query->is_404() ) {
333
- $wp_query->set( 'post_type', array() );
334
- }
335
- }
336
-
337
- /**
338
- * Prevent slug duplicated
339
- *
340
- * @param string $slug post slug.
341
- * @param int $post_ID post id.
342
- * @param string $post_status post status.
343
- * @param string $post_type post type.
344
- * @param int $post_parent post parent id.
345
- * @param string $original_slug original slug.
346
- * @return string
347
- */
348
- public function prevent_slug_duplicates( $slug, $post_ID, $post_status, $post_type, $post_parent, $original_slug ) {
349
-
350
- $check_post_types = array(
351
- 'post',
352
- 'page',
353
- CARTFLOWS_STEP_POST_TYPE,
354
- );
355
-
356
- if ( ! in_array( $post_type, $check_post_types, true ) ) {
357
- return $slug;
358
- }
359
-
360
- if ( CARTFLOWS_STEP_POST_TYPE == $post_type ) {
361
- // Saving a post, check for duplicates in POST or PAGE post types.
362
- $post_match = get_page_by_path( $slug, 'OBJECT', 'post' );
363
- $page_match = get_page_by_path( $slug, 'OBJECT', 'page' );
364
-
365
- if ( $post_match || $page_match ) {
366
- $slug .= '-2';
367
- }
368
- } else {
369
-
370
- // Saving a POST or PAGE, check for duplicates in CARTFLOWS_STEP_POST_TYPE post type.
371
- $custom_post_type_match = get_page_by_path( $slug, 'OBJECT', CARTFLOWS_STEP_POST_TYPE );
372
-
373
- if ( $custom_post_type_match ) {
374
- $slug .= '-2';
375
- }
376
- }
377
-
378
- return $slug;
379
- }
380
-
381
- /**
382
- * Add Update messages for any custom post type
383
- *
384
- * @param array $messages Array of default messages.
385
- */
386
- public function post_update_messages( $messages ) {
387
-
388
- $custom_post_type = get_post_type( get_the_ID() );
389
-
390
- if ( CARTFLOWS_STEP_POST_TYPE == $custom_post_type ) {
391
-
392
- $obj = get_post_type_object( $custom_post_type );
393
- $singular_name = $obj->labels->singular_name;
394
- $messages[ $custom_post_type ] = array(
395
- 0 => '', // Unused. Messages start at index 1.
396
- /* translators: %s: singular custom post type name */
397
- 1 => sprintf( __( '%s updated.', 'cartflows' ), $singular_name ),
398
- /* translators: %s: singular custom post type name */
399
- 2 => sprintf( __( 'Custom %s updated.', 'cartflows' ), $singular_name ),
400
- /* translators: %s: singular custom post type name */
401
- 3 => sprintf( __( 'Custom %s deleted.', 'cartflows' ), $singular_name ),
402
- /* translators: %s: singular custom post type name */
403
- 4 => sprintf( __( '%s updated.', 'cartflows' ), $singular_name ),
404
- /* translators: %1$s: singular custom post type name ,%2$s: date and time of the revision */
405
- 5 => isset( $_GET['revision'] ) ? sprintf( __( '%1$s restored to revision from %2$s', 'cartflows' ), $singular_name, wp_post_revision_title( (int) $_GET['revision'], false ) ) : false, //phpcs:ignore
406
- /* translators: %s: singular custom post type name */
407
- 6 => sprintf( __( '%s published.', 'cartflows' ), $singular_name ),
408
- /* translators: %s: singular custom post type name */
409
- 7 => sprintf( __( '%s saved.', 'cartflows' ), $singular_name ),
410
- /* translators: %s: singular custom post type name */
411
- 8 => sprintf( __( '%s submitted.', 'cartflows' ), $singular_name ),
412
- /* translators: %s: singular custom post type name */
413
- 9 => sprintf( __( '%s scheduled for.', 'cartflows' ), $singular_name ),
414
- /* translators: %s: singular custom post type name */
415
- 10 => sprintf( __( '%s draft updated.', 'cartflows' ), $singular_name ),
416
- );
417
- }
418
-
419
- return $messages;
420
- }
421
-
422
- /**
423
- * Add Terms for Taxonomy.
424
- *
425
- * => Example.
426
- *
427
- * $taxonomy = '{taxonomy}';
428
- * $terms = array(
429
- * array(
430
- * 'name' => 'Landing',
431
- * 'slug' => 'landing',
432
- * ),
433
- * array(
434
- * 'name' => 'Checkout',
435
- * 'slug' => 'checkout',
436
- * ),
437
- * );
438
- *
439
- * self::add_terms( $taxonomy, $terms );
440
- *
441
- * @since 1.0.0
442
- * @param string $taxonomy Taxonomy Name.
443
- * @param array $terms Terms list.
444
- * @return void
445
- */
446
- public function add_terms( $taxonomy = '', $terms = array() ) {
447
-
448
- foreach ( $terms as $key => $term ) {
449
-
450
- $term_exist = term_exists( $term['slug'], $taxonomy );
451
-
452
- if ( empty( $term_exist ) ) {
453
-
454
- /**
455
- * Add additional args if passed from request.
456
- *
457
- * @see https://codex.wordpress.org/Function_Reference/wp_insert_term
458
- */
459
- if ( array_key_exists( 'args', $term ) ) {
460
- wp_insert_term( $term['name'], $taxonomy, $term['args'] );
461
- } else {
462
-
463
- $term['args'] = array( $term['slug'] );
464
-
465
- wp_insert_term( $term['name'], $taxonomy, $term['args'] );
466
- }
467
- }
468
- }
469
- }
470
-
471
- /**
472
- * Redirect admin pages.
473
- *
474
- * @return void
475
- */
476
- public function disallowed_admin_all_steps_view() {
477
-
478
- global $pagenow;
479
-
480
- // Check current admin page. If step post type view redirect it to flow.
481
- if ( 'edit.php' === $pagenow && isset( $_GET['post_type'] ) && CARTFLOWS_STEP_POST_TYPE === $_GET['post_type'] ) { //phpcs:ignore
482
-
483
- if ( isset( $_GET['debug'] ) && $_GET['debug'] ) { //phpcs:ignore
484
- return;
485
- }
486
-
487
- wp_safe_redirect( admin_url( 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE ) );
488
- exit;
489
- }
490
- }
491
- }
492
-
493
- /**
494
- * Kicking this off by calling 'get_instance()' method
495
- */
496
- Cartflows_Step_Post_Type::get_instance();
1
+ <?php
2
+ /**
3
+ * Step post type.
4
+ *
5
+ * @package CartFlows
6
+ */
7
+
8
+ /**
9
+ * Initialization
10
+ *
11
+ * @since 1.0.0
12
+ */
13
+ class Cartflows_Step_Post_Type {
14
+
15
+
16
+ /**
17
+ * Member Variable
18
+ *
19
+ * @var instance
20
+ */
21
+ private static $instance;
22
+
23
+ /**
24
+ * Member Variable
25
+ *
26
+ * @var body_classes
27
+ */
28
+ private $body_classes = array();
29
+
30
+ /**
31
+ * Initiator
32
+ */
33
+ public static function get_instance() {
34
+ if ( ! isset( self::$instance ) ) {
35
+ self::$instance = new self();
36
+ }
37
+ return self::$instance;
38
+ }
39
+
40
+ /**
41
+ * Constructor
42
+ */
43
+ public function __construct() {
44
+
45
+ add_action( 'init', array( $this, 'step_post_type' ) );
46
+ add_action( 'init', array( $this, 'add_wp_templates_support' ) );
47
+ add_filter( 'post_updated_messages', array( $this, 'post_update_messages' ) );
48
+
49
+ add_filter( 'wp_unique_post_slug', array( $this, 'prevent_slug_duplicates' ), 10, 6 );
50
+
51
+ add_filter( 'template_include', array( $this, 'load_page_template' ), 90 );
52
+ add_filter( 'template_redirect', array( $this, 'query_fix' ), 3 );
53
+
54
+ add_action( 'admin_init', array( $this, 'disallowed_admin_all_steps_view' ) );
55
+ }
56
+
57
+ /**
58
+ * Trys to load page.php for a header, footer or part theme layout.
59
+ *
60
+ * @since 1.0.0
61
+ * @param string $template The current template to be loaded.
62
+ * @return string
63
+ */
64
+ public function load_page_template( $template ) {
65
+
66
+ global $post;
67
+
68
+ if ( 'string' == gettype( $template ) && is_object( $post ) && CARTFLOWS_STEP_POST_TYPE === $post->post_type ) {
69
+
70
+ /**
71
+ * Remove Next/Prev Navigation
72
+ * add_filter('next_post_link', '__return_empty_string');
73
+ * add_filter('previous_post_link', '__return_empty_string');
74
+ *
75
+ * $page = locate_template( array( 'page.php' ) );
76
+ *
77
+ * if ( ! empty( $page ) ) {
78
+ * return $page;
79
+ * }
80
+ */
81
+
82
+ /* Remove Next / Previous Rel Link */
83
+ remove_action( 'wp_head', 'adjacent_posts_rel_link_wp_head', 10, 0 );
84
+ add_filter( 'next_post_rel_link', '__return_empty_string' );
85
+ add_filter( 'previous_post_rel_link', '__return_empty_string' );
86
+
87
+ $page_template = get_post_meta( _get_wcf_step_id(), '_wp_page_template', true );
88
+
89
+ $page_template = apply_filters( 'cartflows_page_template', $page_template );
90
+
91
+ $file = '';
92
+
93
+ switch ( $page_template ) {
94
+
95
+ case 'cartflows-default':
96
+ $file = CARTFLOWS_FLOW_DIR . 'templates/template-default.php';
97
+ $this->body_classes[] = $page_template;
98
+ break;
99
+ case 'cartflows-canvas':
100
+ $file = CARTFLOWS_FLOW_DIR . 'templates/template-canvas.php';
101
+ $this->body_classes[] = $page_template;
102
+ break;
103
+ default:
104
+ /**
105
+ * Remove Next/Prev Navigation
106
+ */
107
+ add_filter( 'next_post_link', '__return_empty_string' );
108
+ add_filter( 'previous_post_link', '__return_empty_string' );
109
+
110
+ $page = locate_template( array( 'page.php' ) );
111
+
112
+ if ( ! empty( $page ) ) {
113
+ $file = $page;
114
+ }
115
+
116
+ break;
117
+
118
+ /**
119
+ * Default:
120
+ * $file = CARTFLOWS_FLOW_DIR . 'templates/template-default.php';
121
+ * $this->body_classes[] = 'cartflows-default';
122
+ * break;
123
+ */
124
+ }
125
+
126
+ // Just to be safe, we check if the file exist first.
127
+ if ( file_exists( $file ) ) {
128
+
129
+ /* Add Body Class */
130
+ add_filter( 'body_class', array( $this, 'body_class' ) );
131
+
132
+ return $file;
133
+ } else {
134
+ echo $file;
135
+ }
136
+ }
137
+
138
+ return $template;
139
+ }
140
+
141
+ /**
142
+ * Body classes.
143
+ *
144
+ * @since 1.0.0
145
+ * @param array $classes Body classes.
146
+ * @return array
147
+ */
148
+ public function body_class( $classes = array() ) {
149
+
150
+ $classes = array_merge( $classes, $this->body_classes );
151
+
152
+ return $classes;
153
+ }
154
+
155
+ /**
156
+ * Create custom post type
157
+ */
158
+ public function step_post_type() {
159
+
160
+ $labels = array(
161
+ 'name' => esc_html_x( 'Steps', 'flow step general name', 'cartflows' ),
162
+ 'singular_name' => esc_html_x( 'Step', 'flow step singular name', 'cartflows' ),
163
+ 'search_items' => esc_html__( 'Search Steps', 'cartflows' ),
164
+ 'all_items' => esc_html__( 'All Steps', 'cartflows' ),
165
+ 'edit_item' => esc_html__( 'Edit Step', 'cartflows' ),
166
+ 'view_item' => esc_html__( 'View Step', 'cartflows' ),
167
+ 'add_new' => esc_html__( 'Add New', 'cartflows' ),
168
+ 'update_item' => esc_html__( 'Update Step', 'cartflows' ),
169
+ 'add_new_item' => esc_html__( 'Add New', 'cartflows' ),
170
+ 'new_item_name' => esc_html__( 'New Step Name', 'cartflows' ),
171
+ );
172
+
173
+ $permalink_settings = Cartflows_Helper::get_permalink_settings();
174
+
175
+ $args = array(
176
+ 'labels' => $labels,
177
+ 'public' => true,
178
+ 'query_var' => true,
179
+ 'can_export' => true,
180
+ 'exclude_from_search' => true,
181
+ 'show_ui' => true,
182
+ 'show_in_menu' => false,
183
+ 'show_in_admin_bar' => true,
184
+ 'show_in_rest' => true,
185
+ 'supports' => array( 'title', 'editor', 'elementor', 'revisions' ),
186
+ 'capability_type' => 'post',
187
+ 'capabilities' => array(
188
+ 'create_posts' => 'do_not_allow', // Prior to Wordpress 4.5, this was false.
189
+ ),
190
+ 'map_meta_cap' => true,
191
+ );
192
+
193
+ if ( isset( $permalink_settings['permalink_structure'] ) && ! empty( $permalink_settings['permalink_structure'] ) ) {
194
+ $args['rewrite'] = array(
195
+ 'slug' => $permalink_settings['permalink_structure'],
196
+ 'with_front' => false,
197
+ );
198
+
199
+ } elseif ( isset( $permalink_settings['permalink'] ) && ! empty( $permalink_settings['permalink'] ) ) {
200
+
201
+ $args['rewrite'] = array(
202
+ 'slug' => $permalink_settings['permalink'],
203
+ 'with_front' => false,
204
+ );
205
+ }
206
+
207
+ register_post_type( CARTFLOWS_STEP_POST_TYPE, $args );
208
+
209
+ // Step Type.
210
+ $args = array(
211
+ 'label' => __( 'Step Type', 'cartflows' ),
212
+ 'public' => false,
213
+ 'rewrite' => false,
214
+ 'hierarchical' => false,
215
+ );
216
+
217
+ register_taxonomy( CARTFLOWS_TAXONOMY_STEP_TYPE, CARTFLOWS_STEP_POST_TYPE, $args );
218
+
219
+ // Step Flow.
220
+ $args = array(
221
+ 'label' => __( 'Step Flow', 'cartflows' ),
222
+ 'public' => false,
223
+ 'rewrite' => false,
224
+ 'hierarchical' => false,
225
+ );
226
+
227
+ register_taxonomy( CARTFLOWS_TAXONOMY_STEP_FLOW, CARTFLOWS_STEP_POST_TYPE, $args );
228
+
229
+ if ( is_admin() ) {
230
+ /**
231
+ * Register 'Elementor' & 'Beaver Builder' site types.
232
+ *
233
+ * @see self::add_terms();
234
+ */
235
+ $taxonomy = CARTFLOWS_TAXONOMY_STEP_TYPE;
236
+
237
+ $terms = array(
238
+ array(
239
+ 'name' => __( 'Landing', 'cartflows' ),
240
+ 'slug' => 'landing',
241
+ 'args' => array(
242
+ 'slug' => 'landing',
243
+ ),
244
+ ),
245
+ array(
246
+ 'name' => __( 'Optin (Woo)', 'cartflows' ),
247
+ 'slug' => 'optin',
248
+ 'args' => array(
249
+ 'slug' => 'optin',
250
+ ),
251
+ ),
252
+ array(
253
+ 'name' => __( 'Checkout (Woo)', 'cartflows' ),
254
+ 'slug' => 'checkout',
255
+ 'args' => array(
256
+ 'slug' => 'checkout',
257
+ ),
258
+ ),
259
+ array(
260
+ 'name' => __( 'Thank You (Woo)', 'cartflows' ),
261
+ 'slug' => 'thankyou',
262
+ 'args' => array(
263
+ 'slug' => 'thankyou',
264
+ ),
265
+ ),
266
+ array(
267
+ 'name' => __( 'Upsell (Woo)', 'cartflows' ),
268
+ 'slug' => 'upsell',
269
+ 'args' => array(
270
+ 'slug' => 'upsell',
271
+ ),
272
+ ),
273
+ array(
274
+ 'name' => __( 'Downsell (Woo)', 'cartflows' ),
275
+ 'slug' => 'downsell',
276
+ 'args' => array(
277
+ 'slug' => 'downsell',
278
+ ),
279
+ ),
280
+ );
281
+
282
+ $this->add_terms( $taxonomy, $terms );
283
+
284
+ }
285
+ }
286
+
287
+ /**
288
+ * Add WordPress templates.
289
+ *
290
+ * Adds Cartflows templates to steps
291
+ *
292
+ * @since 1.0.0
293
+ * @access public
294
+ */
295
+ public function add_wp_templates_support() {
296
+ add_filter( 'theme_' . CARTFLOWS_STEP_POST_TYPE . '_templates', array( $this, 'add_page_templates' ), 99, 4 );
297
+ }
298
+
299
+ /**
300
+ * Add page templates.
301
+ *
302
+ * @since 1.0.0
303
+ * @access public
304
+ *
305
+ * @param array $page_templates Array of page templates.
306
+ *
307
+ * @param object $wp_theme wp theme.
308
+ * @param object $post post.
309
+ *
310
+ * @return array Page templates.
311
+ */
312
+ public function add_page_templates( $page_templates, $wp_theme, $post ) {
313
+
314
+ $page_templates = array(
315
+ 'cartflows-default' => _x( 'CartFlows — Boxed', 'cartflows' ),
316
+ 'cartflows-canvas' => _x( 'Template for Page Builders', 'cartflows' ),
317
+ );
318
+
319
+ return $page_templates;
320
+ }
321
+
322
+ /**
323
+ * Query fixe throwing error on 404 page due our post type changes.
324
+ * We are setting post_type as empty array to fix the issue.
325
+ * Ther error was throwing due to redirect_canonical function
326
+ * This fix is apply for 404 page only
327
+ */
328
+ public function query_fix() {
329
+
330
+ global $wp_query;
331
+
332
+ if ( $wp_query->is_404() ) {
333
+ $wp_query->set( 'post_type', array() );
334
+ }
335
+ }
336
+
337
+ /**
338
+ * Prevent slug duplicated
339
+ *
340
+ * @param string $slug post slug.
341
+ * @param int $post_ID post id.
342
+ * @param string $post_status post status.
343
+ * @param string $post_type post type.
344
+ * @param int $post_parent post parent id.
345
+ * @param string $original_slug original slug.
346
+ * @return string
347
+ */
348
+ public function prevent_slug_duplicates( $slug, $post_ID, $post_status, $post_type, $post_parent, $original_slug ) {
349
+
350
+ $check_post_types = array(
351
+ 'post',
352
+ 'page',
353
+ CARTFLOWS_STEP_POST_TYPE,
354
+ );
355
+
356
+ if ( ! in_array( $post_type, $check_post_types, true ) ) {
357
+ return $slug;
358
+ }
359
+
360
+ if ( CARTFLOWS_STEP_POST_TYPE == $post_type ) {
361
+ // Saving a post, check for duplicates in POST or PAGE post types.
362
+ $post_match = get_page_by_path( $slug, 'OBJECT', 'post' );
363
+ $page_match = get_page_by_path( $slug, 'OBJECT', 'page' );
364
+
365
+ if ( $post_match || $page_match ) {
366
+ $slug .= '-2';
367
+ }
368
+ } else {
369
+
370
+ // Saving a POST or PAGE, check for duplicates in CARTFLOWS_STEP_POST_TYPE post type.
371
+ $custom_post_type_match = get_page_by_path( $slug, 'OBJECT', CARTFLOWS_STEP_POST_TYPE );
372
+
373
+ if ( $custom_post_type_match ) {
374
+ $slug .= '-2';
375
+ }
376
+ }
377
+
378
+ return $slug;
379
+ }
380
+
381
+ /**
382
+ * Add Update messages for any custom post type
383
+ *
384
+ * @param array $messages Array of default messages.
385
+ */
386
+ public function post_update_messages( $messages ) {
387
+
388
+ $custom_post_type = get_post_type( get_the_ID() );
389
+
390
+ if ( CARTFLOWS_STEP_POST_TYPE == $custom_post_type ) {
391
+
392
+ $obj = get_post_type_object( $custom_post_type );
393
+ $singular_name = $obj->labels->singular_name;
394
+ $messages[ $custom_post_type ] = array(
395
+ 0 => '', // Unused. Messages start at index 1.
396
+ /* translators: %s: singular custom post type name */
397
+ 1 => sprintf( __( '%s updated.', 'cartflows' ), $singular_name ),
398
+ /* translators: %s: singular custom post type name */
399
+ 2 => sprintf( __( 'Custom %s updated.', 'cartflows' ), $singular_name ),
400
+ /* translators: %s: singular custom post type name */
401
+ 3 => sprintf( __( 'Custom %s deleted.', 'cartflows' ), $singular_name ),
402
+ /* translators: %s: singular custom post type name */
403
+ 4 => sprintf( __( '%s updated.', 'cartflows' ), $singular_name ),
404
+ /* translators: %1$s: singular custom post type name ,%2$s: date and time of the revision */
405
+ 5 => isset( $_GET['revision'] ) ? sprintf( __( '%1$s restored to revision from %2$s', 'cartflows' ), $singular_name, wp_post_revision_title( (int) $_GET['revision'], false ) ) : false, //phpcs:ignore
406
+ /* translators: %s: singular custom post type name */
407
+ 6 => sprintf( __( '%s published.', 'cartflows' ), $singular_name ),
408
+ /* translators: %s: singular custom post type name */
409
+ 7 => sprintf( __( '%s saved.', 'cartflows' ), $singular_name ),
410
+ /* translators: %s: singular custom post type name */
411
+ 8 => sprintf( __( '%s submitted.', 'cartflows' ), $singular_name ),
412
+ /* translators: %s: singular custom post type name */
413
+ 9 => sprintf( __( '%s scheduled for.', 'cartflows' ), $singular_name ),
414
+ /* translators: %s: singular custom post type name */
415
+ 10 => sprintf( __( '%s draft updated.', 'cartflows' ), $singular_name ),
416
+ );
417
+ }
418
+
419
+ return $messages;
420
+ }
421
+
422
+ /**
423
+ * Add Terms for Taxonomy.
424
+ *
425
+ * => Example.
426
+ *
427
+ * $taxonomy = '{taxonomy}';
428
+ * $terms = array(
429
+ * array(
430
+ * 'name' => 'Landing',
431
+ * 'slug' => 'landing',
432
+ * ),
433
+ * array(
434
+ * 'name' => 'Checkout',
435
+ * 'slug' => 'checkout',
436
+ * ),
437
+ * );
438
+ *
439
+ * self::add_terms( $taxonomy, $terms );
440
+ *
441
+ * @since 1.0.0
442
+ * @param string $taxonomy Taxonomy Name.
443
+ * @param array $terms Terms list.
444
+ * @return void
445
+ */
446
+ public function add_terms( $taxonomy = '', $terms = array() ) {
447
+
448
+ foreach ( $terms as $key => $term ) {
449
+
450
+ $term_exist = term_exists( $term['slug'], $taxonomy );
451
+
452
+ if ( empty( $term_exist ) ) {
453
+
454
+ /**
455
+ * Add additional args if passed from request.
456
+ *
457
+ * @see https://codex.wordpress.org/Function_Reference/wp_insert_term
458
+ */
459
+ if ( array_key_exists( 'args', $term ) ) {
460
+ wp_insert_term( $term['name'], $taxonomy, $term['args'] );
461
+ } else {
462
+
463
+ $term['args'] = array( $term['slug'] );
464
+
465
+ wp_insert_term( $term['name'], $taxonomy, $term['args'] );
466
+ }
467
+ }
468
+ }
469
+ }
470
+
471
+ /**
472
+ * Redirect admin pages.
473
+ *
474
+ * @return void
475
+ */
476
+ public function disallowed_admin_all_steps_view() {
477
+
478
+ global $pagenow;
479
+
480
+ // Check current admin page. If step post type view redirect it to flow.
481
+ if ( 'edit.php' === $pagenow && isset( $_GET['post_type'] ) && CARTFLOWS_STEP_POST_TYPE === $_GET['post_type'] ) { //phpcs:ignore
482
+
483
+ if ( isset( $_GET['debug'] ) && $_GET['debug'] ) { //phpcs:ignore
484
+ return;
485
+ }
486
+
487
+ wp_safe_redirect( admin_url( 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE ) );
488
+ exit;
489
+ }
490
+ }
491
+ }
492
+
493
+ /**
494
+ * Kicking this off by calling 'get_instance()' method
495
+ */
496
+ Cartflows_Step_Post_Type::get_instance();
readme.txt CHANGED
@@ -3,8 +3,8 @@ Contributors: brainstormforce, wpcrafter
3
  Donate link: https://www.paypal.me/BrainstormForce
4
  Tags: woocommerce, funnel builder, sales funnels, elementor, beaver builder
5
  Requires at least: 4.4
6
- Tested up to: 5.4
7
- Stable tag: 1.5.9
8
  Requires PHP: 5.6
9
  License: GPLv2 or later
10
  License URI: https://www.gnu.org/licenses/gpl-2.0.html
@@ -114,6 +114,8 @@ A good rule of thumb is, if it works with WooCommerce, it will work with CartFlo
114
 
115
  Glad you asked! CartFlows Pro is an optional add-on to CartFlows that adds additional checkout styles, checkout field control, order bumps, one-click upsells / downsells, quantity changer, variable product selector, pro templates, training, and more.
116
 
 
 
117
 
118
  == Screenshots ==
119
 
@@ -125,6 +127,11 @@ Glad you asked! CartFlows Pro is an optional add-on to CartFlows that adds addit
125
 
126
  == Changelog ==
127
 
 
 
 
 
 
128
  = Version 1.5.9 - Thursday, 14th May 2020 =
129
  * New: Added quantity and discount options for the product.
130
  * Fix: Google Analytics JS error.
3
  Donate link: https://www.paypal.me/BrainstormForce
4
  Tags: woocommerce, funnel builder, sales funnels, elementor, beaver builder
5
  Requires at least: 4.4
6
+ Tested up to: 5.4.1
7
+ Stable tag: 1.5.10
8
  Requires PHP: 5.6
9
  License: GPLv2 or later
10
  License URI: https://www.gnu.org/licenses/gpl-2.0.html
114
 
115
  Glad you asked! CartFlows Pro is an optional add-on to CartFlows that adds additional checkout styles, checkout field control, order bumps, one-click upsells / downsells, quantity changer, variable product selector, pro templates, training, and more.
116
 
117
+ = How Many Sales Funnels Can I Make With CartFlows? =
118
+ Glad you asked! Most normal users have less than 3 funnels on a single website, so we felt that it is the perfect number for CartFlows. Power users may need more than 3, so in CartFlows Pro, you can have unlimited funnels. As well as additional checkout styles, checkout field control, order bumps, one-click upsells / downsells, quantity changer, variable product selector, pro templates, training, and more.
119
 
120
  == Screenshots ==
121
 
127
 
128
  == Changelog ==
129
 
130
+ = Version 1.5.10 - Wednesday, 3rd June 2020 =
131
+ * New: Gutenberg templates added.
132
+ * New: Import/Export content support added.
133
+ * Fix: Step slug was not editable in some permalink cases.
134
+
135
  = Version 1.5.9 - Thursday, 14th May 2020 =
136
  * New: Added quantity and discount options for the product.
137
  * Fix: Google Analytics JS error.
theme-support/astra/class-cartflows-astra-compatibility.php CHANGED
@@ -1,113 +1,113 @@
1
- <?php
2
- /**
3
- * Astra theme compatibility
4
- *
5
- * @package CartFlows
6
- */
7
-
8
- if ( ! class_exists( 'Cartflows_Astra_Compatibility' ) ) :
9
-
10
- /**
11
- * Class for Astra theme compatibility
12
- */
13
- class Cartflows_Astra_Compatibility {
14
-
15
- /**
16
- * Member Variable
17
- *
18
- * @var instance
19
- */
20
- private static $instance;
21
-
22
- /**
23
- * Initiator
24
- *
25
- * @since 1.5.7
26
- */
27
- public static function get_instance() {
28
- if ( ! isset( self::$instance ) ) {
29
- self::$instance = new self();
30
- }
31
- return self::$instance;
32
- }
33
-
34
- /**
35
- * Constructor
36
- *
37
- * @since 1.5.7
38
- */
39
- public function __construct() {
40
-
41
- add_action( 'cartflows_checkout_before_shortcode', array( $this, 'cartflows_theme_compatibility_astra' ) );
42
- add_action( 'cartflows_optin_before_shortcode', array( $this, 'cartflows_theme_compatibility_astra' ) );
43
-
44
- add_action( 'wp', array( $this, 'cartflows_load_wp_actions_for_astra' ), 56 );
45
- }
46
-
47
-
48
- /**
49
- * Function to remove the astra hooks.
50
- *
51
- * @since 1.5.7
52
- *
53
- * @return void
54
- */
55
- public function cartflows_theme_compatibility_astra() {
56
- remove_action( 'woocommerce_checkout_before_customer_details', 'astra_two_step_checkout_form_wrapper_div', 1 );
57
- remove_action( 'woocommerce_checkout_before_customer_details', 'astra_two_step_checkout_form_ul_wrapper', 2 );
58
- remove_action( 'woocommerce_checkout_order_review', 'astra_woocommerce_div_wrapper_close', 30 );
59
- remove_action( 'woocommerce_checkout_order_review', 'astra_woocommerce_ul_close', 30 );
60
- remove_action( 'woocommerce_checkout_before_customer_details', 'astra_two_step_checkout_address_li_wrapper', 5 );
61
- remove_action( 'woocommerce_checkout_after_customer_details', 'astra_woocommerce_li_close' );
62
- remove_action( 'woocommerce_checkout_before_order_review', 'astra_two_step_checkout_order_review_wrap', 1 );
63
- remove_action( 'woocommerce_checkout_after_order_review', 'astra_woocommerce_li_close', 40 );
64
-
65
- add_filter( 'astra_theme_woocommerce_dynamic_css', '__return_empty_string' );
66
- }
67
-
68
-
69
- /**
70
- * Function to add/remove the actions/hooks on wp action.
71
- *
72
- * @since 1.5.7
73
- *
74
- * @return void
75
- */
76
- public function cartflows_load_wp_actions_for_astra() {
77
-
78
- // Return if not the CartFlows page.
79
- if ( ! wcf()->utils->is_step_post_type() ) {
80
- return;
81
- }
82
-
83
- $page_template = get_post_meta( _get_wcf_step_id(), '_wp_page_template', true );
84
-
85
- if ( _wcf_supported_template( $page_template ) ) {
86
- return;
87
- }
88
-
89
- add_action( 'wp_enqueue_scripts', array( $this, 'astra_compatibility_external_css' ), 101 );
90
-
91
- // Re-add the WooCommerce's styles & script swhich are form Astra.
92
- $astra_woo = Astra_Woocommerce::get_instance();
93
- add_filter( 'woocommerce_enqueue_styles', array( $astra_woo, 'woo_filter_style' ), 9999 );
94
- }
95
-
96
- /**
97
- * Load the CSS
98
- *
99
- * @since 1.5.7
100
- *
101
- * @return void
102
- */
103
- public function astra_compatibility_external_css() {
104
-
105
- wp_enqueue_style( 'wcf-checkout-astra-compatibility', CARTFLOWS_URL . 'theme-support/astra/css/astra-compatibility.css', '', CARTFLOWS_VER );
106
- }
107
- }
108
- /**
109
- * Kicking this off by calling 'get_instance()' method
110
- */
111
- Cartflows_Astra_Compatibility::get_instance();
112
-
113
- endif;
1
+ <?php
2
+ /**
3
+ * Astra theme compatibility
4
+ *
5
+ * @package CartFlows
6
+ */
7
+
8
+ if ( ! class_exists( 'Cartflows_Astra_Compatibility' ) ) :
9
+
10
+ /**
11
+ * Class for Astra theme compatibility
12
+ */
13
+ class Cartflows_Astra_Compatibility {
14
+
15
+ /**
16
+ * Member Variable
17
+ *
18
+ * @var instance
19
+ */
20
+ private static $instance;
21
+
22
+ /**
23
+ * Initiator
24
+ *
25
+ * @since 1.5.7
26
+ */
27
+ public static function get_instance() {
28
+ if ( ! isset( self::$instance ) ) {
29
+ self::$instance = new self();
30
+ }
31
+ return self::$instance;
32
+ }
33
+
34
+ /**
35
+ * Constructor
36
+ *
37
+ * @since 1.5.7
38
+ */
39
+ public function __construct() {
40
+
41
+ add_action( 'cartflows_checkout_before_shortcode', array( $this, 'cartflows_theme_compatibility_astra' ) );
42
+ add_action( 'cartflows_optin_before_shortcode', array( $this, 'cartflows_theme_compatibility_astra' ) );
43
+
44
+ add_action( 'wp', array( $this, 'cartflows_load_wp_actions_for_astra' ), 56 );
45
+ }
46
+
47
+
48
+ /**
49
+ * Function to remove the astra hooks.
50
+ *
51
+ * @since 1.5.7
52
+ *
53
+ * @return void
54
+ */
55
+ public function cartflows_theme_compatibility_astra() {
56
+ remove_action( 'woocommerce_checkout_before_customer_details', 'astra_two_step_checkout_form_wrapper_div', 1 );
57
+ remove_action( 'woocommerce_checkout_before_customer_details', 'astra_two_step_checkout_form_ul_wrapper', 2 );
58
+ remove_action( 'woocommerce_checkout_order_review', 'astra_woocommerce_div_wrapper_close', 30 );
59
+ remove_action( 'woocommerce_checkout_order_review', 'astra_woocommerce_ul_close', 30 );
60
+ remove_action( 'woocommerce_checkout_before_customer_details', 'astra_two_step_checkout_address_li_wrapper', 5 );
61
+ remove_action( 'woocommerce_checkout_after_customer_details', 'astra_woocommerce_li_close' );
62
+ remove_action( 'woocommerce_checkout_before_order_review', 'astra_two_step_checkout_order_review_wrap', 1 );
63
+ remove_action( 'woocommerce_checkout_after_order_review', 'astra_woocommerce_li_close', 40 );
64
+
65
+ add_filter( 'astra_theme_woocommerce_dynamic_css', '__return_empty_string' );
66
+ }
67
+
68
+
69
+ /**
70
+ * Function to add/remove the actions/hooks on wp action.
71
+ *
72
+ * @since 1.5.7
73
+ *
74
+ * @return void
75
+ */
76
+ public function cartflows_load_wp_actions_for_astra() {
77
+
78
+ // Return if not the CartFlows page.
79
+ if ( ! wcf()->utils->is_step_post_type() ) {
80
+ return;
81
+ }
82
+
83
+ $page_template = get_post_meta( _get_wcf_step_id(), '_wp_page_template', true );
84
+
85
+ if ( _wcf_supported_template( $page_template ) ) {
86
+ return;
87
+ }
88
+
89
+ add_action( 'wp_enqueue_scripts', array( $this, 'astra_compatibility_external_css' ), 101 );
90
+
91
+ // Re-add the WooCommerce's styles & script swhich are form Astra.
92
+ $astra_woo = Astra_Woocommerce::get_instance();
93
+ add_filter( 'woocommerce_enqueue_styles', array( $astra_woo, 'woo_filter_style' ), 9999 );
94
+ }
95
+
96
+ /**
97
+ * Load the CSS
98
+ *
99
+ * @since 1.5.7
100
+ *
101
+ * @return void
102
+ */
103
+ public function astra_compatibility_external_css() {
104
+
105
+ wp_enqueue_style( 'wcf-checkout-astra-compatibility', CARTFLOWS_URL . 'theme-support/astra/css/astra-compatibility.css', '', CARTFLOWS_VER );
106
+ }
107
+ }
108
+ /**
109
+ * Kicking this off by calling 'get_instance()' method
110
+ */
111
+ Cartflows_Astra_Compatibility::get_instance();
112
+
113
+ endif;