diff --git a/.gitignore b/.gitignore index 7a1c28b..55cabbc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ .idea todo.txt assets/css/.sass-cache -/docs/.retype/ +docs/.retype/* diff --git a/assets/js/admin.js b/assets/js/admin.js index 0e26d27..b5007c4 100644 --- a/assets/js/admin.js +++ b/assets/js/admin.js @@ -629,6 +629,7 @@ field.disallow_past_date = input_fdpdisallow_past_date.is(':checked'); break; case 'imageupload': + case 'fileupload': //field.max_file_count = $row.find('input.fu-max-file-count').val(); field.max_file_size = $row.find('input.fu-max-file-size').val(); field.allowed_extensions = $row.find('input.fu-allowed-extensions').val(); @@ -749,10 +750,10 @@ suggest.push(field.name + ":date"); // $("#formula_fields").append('{' + field.name + ':date} '); $("#wck-parameters .defined-fields").append(''); - } else if (field.type === "imageupload") { + } else if (field.type === "imageupload" || field.type === "fileupload") { suggest.push(field.name + ":size"); //$("#formula_fields").append('{' + field.name + ':size} '); - $("#wck-parameters .defined-fields").append(''); + $("#wck-parameters .defined-fields").append(''); } } }; @@ -919,7 +920,7 @@ //$("#" + field_id + " .ft-pattern").val(this.pattern); } else if (this.type === "colorpicker" || this.type === "datepicker" || this.type === "rangedatepicker") { $("#" + field_id + " .fdp-disallow-past-date").prop("checked", this.disallow_past_date); - } else if (this.type === "imageupload") { + } else if (this.type === "imageupload" || this.type === "fileupload") { $("#" + field_id + " .fu-max-file-size").val(this.max_file_size); $("#" + field_id + " .fu-allowed-extensions").val(this.allowed_extensions); var ext = this.allowed_extensions.split("|"); diff --git a/assets/js/admin.min.js b/assets/js/admin.min.js index 375eb96..59e0467 100644 --- a/assets/js/admin.min.js +++ b/assets/js/admin.min.js @@ -1 +1 @@ -!function(e){"use strict";var u={},o={};e(document).ready(function(f){f("body").hasClass("folded")||f("body").addClass("folded");var n=[],t={};f("#f-field-list").sortable({handle:".header",placeholder:"wck-sortable-placeholder",tolerance:"pointer"}),f("#extra-inputs, #addon-inputs").sortable({handle:".action-drag",placeholder:"wck-sortable-placeholder",tolerance:"pointer"}),f('').insertBefore("#wpwrap"),u.colorpicker=f("input.wck-global-color-picker"),u.colorpicker.iris(),u.expressionLastFocusedInput=null,u.wpMediaFrame=null,u.wpMediaTarget=null,u.iconPreloader="data:image/gif;base64,R0lGODlhEAAQAPUVAHt7e729vf///4R7e+/v762trZSUlKWlpZycnPf39+bm5t7e3tbW1s7OzoSEhMXFxc7FzpSMjJyUlP/397WtraWlnM7FxbW1tb21tebe3tbOzqWcnIyEhHNzc3tzc4yMjK2lpbWttcW9vffv76Wtpa2lra2tpb21vcXFzt7e1qWlrdbe1pScnO/v5gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQJBwAVACwAAAAAEAAQAEAGt8CKsGLZfDyez8YyrAAekAdA09R0GoLGE8BgLDQIhwORSSQIDqYxELhcCoXDARHeCBmRSGOh6BMICxIRDBUOAQ0NBiBNIBsTAgscGwgPDxcABYgFHnQSSkMFAAYHcAgRHQVNQgUDmX0NFA6pQxsGC7d9Cn8ECRt2GwddDwMgiCAOC2YYGwCIWlRDGgACAgkADhiVEYtDIAMGAQYcUmxtHwDXc3QdDxV4DhRucHIIAIOqRRxIkkxDQQAh+QQFBwAQACwAAAAAEAAQAAAGr0CIEGLZfDyez8YybBYAh8diYSkMCk1G5PNgrKYKBcMQYQg3hgZjDQ4TEBvIA/BoNCySgQMBIRAUDkVRDQEDIHYgDgx+FxsOFw8PBiBNIAgJCQscAAGRABpNGgCYBACcAQGfoaMJpQ4hqB+UQyAbAgKaGwgXF08FdgUdF7cBG3O8vQ6meypiAw8QRr0FBwcI1wgHDnEQWg4H1NbXBgBlTh4G2dYfHVhNQkUcSBxLTUEAIfkECQcAEAAsAQABAA4ADgAABnBAiFAYYDAeoKEy0GgYF4uG8vN4NJ9QxTBQfQgHQoViMUAEAhiAMqygFM6ftZBAYFzu8jlBcb/kISN0IAUFHHIICQkMBoQHHkoOGYkXHgUkBwdKCgIJBA4QDpgHCAgGFwICE5lfpKQGRQsIch+tBmtBACH5BAUHABQALAEAAQAOAA4AAAaaQAqlAEBcHo3AAVAQMiKO4wPSaDAsnwhj8wkEHuAqg7EwbAAXbyAyGBgaiwVjILlcQgBQFTSALwoHdh8gQkIgEgoKDQWMABqFFBoAiQsHjB6PhZKJChUHBw6EhSAIBAQMBp8IHgVVBQ4UphceBwi2AwAOBwoJBAoOGw62CG8CEwnIGxtPRRIBAtAJCghaQgUdHwYMAgsXDk0UQQAh+QQFBwAQACwBAAEADgAOAAAGcECIECIpBB4XxHBZuASOD5RoyblYn49HYyv0FL4XCECoZTTGhwJoSWYwQIjDwcEWMhYP+cFThywWDAiCfX5/gkp9CgoNH4IGiQoFEHEFDxt0GwsECgtCAxAECQIJpASmiBAeDQKjpQsSbAMYC6QMbEEAIfkEBQcAEAAsAQABAA4ADgAABnZAiNAjOVwCBaFSCDgUCpdjAMNZHpzQU0D0eESEVycHAIgEuo8yAgHxLAGBRkO4Xi7lIoSBbRcyGA0SCB99fn8GD3N9EgsLDxwEAhkOdg2NBQAjAgIKSggMCo0DEAcTCacjBAQKrEsICqeqqwx9DhgMqgwUo0JBACH5BAkHAAAALAEAAQAOAA4AAAVjICACEVIUhzGuyHGc10WtANK+RRwEo92ulx0PIKnRAJfHY2MIGAbHiBLTEDSOogfkkRAIoMdG47EQTDZYcQCTSBwHDwbj4AC0MwgAVLOQi9AEgQqDC4UqIwuChFdHFBqDjCMhACH5BAUHABMALAEAAQAOAA4AAAaTwMmk0PlIDgeEwVMQMiIAA2KKLBwGEcbGkZwiqoULZzNgEC4IBwDAKYQvgIBA8OiAGg0Q4I1YzA8gQkIgHwEBIQmJAxqCExoehgEEioyCGgAPDwELiQiBgiAGmRgXBAQMDgV4BQMiDRAHDgqmEwgDAwYQeBYAGwgECsELCwzFDQYbTxIMwsMMDxFZQqyqww8He0JBACH5BAUHAAMALAEAAQAOAA4AAAZzwIEQYBggEIaPcGlUKBqG4xGw3CQEgkAUcTiYhA7CVcHskgqeSyKRcTA9h0LBwFhvmEJO6FIi+PFLF4IKflR4HgGCDH+AHwEBBQNOGngAGA8BCAMLTgMSSw+hIksKC6YMDA0NoRFMDaepDQGAAyAPqLNMQQAh+QQFBwAYACwBAAEADgAOAAAFZSAmOtciMGKaSlgivAGrIm0yCY2B7KlCJJiDQ7RDHEQEgiplPGKStGXwUFFYAVJMoXBYWLPabcMqW14uh8JigRksKWfJgLHOYQCRgP4ikiwYDA0ND4R6SxaBDRCEfEtYAYIXUSIhACH5BAkHABAALAEAAQAOAA4AAAZyQIhQyEgkFhjHcLggGBMCAcOzbBEII6PAeBhABgsFYbGBOA6iwgEBKSgUjKXQwEJ8Gm/5EMFf+PVCfAgMf4AHhw8LcXpnayAMDA96IAUFQg0MDZIAQheVBVQQDaMPDwEBF6kcQx8ipaaoBUpyGxemlktBACH5BAUHABAALAEAAQAOAA4AAAaRQAikMCg0CATGxVEQMiIGhgJJSCQUiAhjI1F4p1Vr4rAZLBYKBsLh2CgEggSgcG44QI0GyAFJED4PKQsSIEJCewEBUQwMABqGEBodHwgSDYyOkJIInAF5BoWGe5wIB3kBc3kFHgcHWQAPsQEfAAAcBa0HHhsGsokXBcEHbU8fF78XwMNaQgUACAUBFwcGHk0QQQA7",u.fieldsLayout="one-col",u.toggleButton=function(e,i){return i.preventDefault(),e.hasClass("woocommerce-input-toggle--disabled")?(e.removeClass("woocommerce-input-toggle--disabled").addClass("woocommerce-input-toggle--enabled"),!0):(e.removeClass("woocommerce-input-toggle--enabled").addClass("woocommerce-input-toggle--disabled"),!1)},u.fullscreenMode=function(e){e?(f("body").css("overflow","hidden"),f("#postbox-container-2").addClass("fullscreen")):(f("body").css("overflow","auto"),f("#postbox-container-2").removeClass("fullscreen"))},f(".wck-toggle-layout").on("click",function(e){e=u.toggleButton(f(this),e);u.fieldsLayout=e?"two-col":"one-col",u.updateLayout()}),f(".wck-toggle-fullscreen").on("click",function(e){e=u.toggleButton(f(this),e);u.fullscreenMode(e)}),f(".wck-toggle-expand").on("click",function(e){e=u.toggleButton(f(this),e);f(".action-toggle.dashicons-arrow-"+(e?"down":"up")+"-alt2").trigger("click")}),f("body").on("click",".wck-toggle-colspan",function(e){e.preventDefault();e=f(this).parent().parent().parent();f(this).hasClass("woocommerce-input-toggle--disabled")?(f(this).removeClass("woocommerce-input-toggle--disabled").addClass("woocommerce-input-toggle--enabled"),e.addClass("wck-layout-colspan"),e.find(".f-colspan").val(2)):(f(this).removeClass("woocommerce-input-toggle--enabled").addClass("woocommerce-input-toggle--disabled"),e.removeClass("wck-layout-colspan"),e.find(".f-colspan").val(1))}),f(".action-save-post").on("click",function(e){e.preventDefault(),f("#publish").trigger("click"),f("#publish").hasClass("disabled")&&f(this).prop("disabled",!0).addClass("disabled")}),f("body").on("click",".action-duplicate",function(e){e.preventDefault();var e=f(this).parent().parent().parent(),i=e.clone();i.hide(),i.find(".f-title").val(""),i.find(".f-name").val(""),i.insertAfter(e),i.fadeIn(1500,function(){i.find(".dashicons-arrow-down-alt2").trigger("click"),f(this).find(".f-title").fadeOut(150).fadeIn(150).fadeOut(150).fadeIn(150).fadeOut(150).fadeIn(150),f(this).find(".f-name").fadeOut(150).fadeIn(150).fadeOut(150).fadeIn(150).fadeOut(150).fadeIn(150)})}),u.shouldHideExprToolbar=!1,u.stateExprToolbar=!1,f("body").on("focusin","#wck_expression .input-icon input, #wck_inventory .input-icon input, input.expression-editor-enabled",function(e){u.expressionLastFocusedInput=f(this),u.shouldHideExprToolbar=!1;var i=f(this).offset(),t=f(this).outerHeight(),a=f("#wck_expression").offset();f("#wck-expression-toolbar").css({top:i.top-a.top-t-f("#wck-expression-toolbar").outerHeight()-20,left:i.left-a.left}),u.stateExprToolbar||(u.stateExprToolbar=!0,u.saveFields(),f("#wck-parameters .first-selected").prop("selected",!0),f("#wck-expression-toolbar").stop(!0,!1).fadeIn("fast")),f("#wck-parameters .total-price").toggle(f(this).hasClass("show-total-price")),f(this).hasClass("show-total-price")||"{total_price}"!==f("#wck-parameters").val()||f("#wck-parameters").val("")}).on("focusout","#wck_expression input, #wck_inventory input, input.expression-editor-enabled",function(e){u.shouldHideExprToolbar=!(e.relatedTarget&&f("#wck-expression-toolbar").has(e.relatedTarget).length),setTimeout(function(){u.stateExprToolbar&&u.shouldHideExprToolbar&&(f("#wck-expression-toolbar").stop(!0,!1).fadeOut("fast"),u.stateExprToolbar=!1)},200)}).on("click","#wck-expression-toolbar",function(e){e.target!==e.currentTarget&&"OPTION"!==e.target.tagName||u.expressionLastFocusedInput.focus()}).on("click","button.add-field-to-formula, button.add-operator",function(e){e.preventDefault();var i,t,a,e=u.expressionLastFocusedInput;e||(e=f(".input-icon").find("input:visible").first()).focus(),e&&e.length&&(null!==(i=(f(this).hasClass("add-operator")?f(this):f("#wck-parameters")).val())&&(t=e[0].selectionStart,a=e.val(),e.val(a.slice(0,t)+i+(f(this).data("ending")||"")+a.slice(t)),e.focus(),t+=i.length,e[0].setSelectionRange(t,t)))}).on("click",".field .pairs .action-add",function(){f(this).prev(".pair").clone().insertBefore(f(this)).find("input").val("")}).on("click",".field .pairs .action-showimport",function(){f(this).parent().find("div.importer").toggle()}).on("click",".field .pairs .action-import",function(){var t=f(this),e=t.parent().find("textarea").val().trim().split("\n");Array.isArray(e)&&e.forEach(function(e){var e=e.trim().split(";"),i=t.parent().parent().find(".pair").last(),i=i.clone().insertAfter(i);2===e.length?(i.find("input.fs-name").val(e[0]),i.find("input.fs-title").val(e[1])):1===e.length&&i.find("input.fs-title").val(e[0])})}).on("click",".field .pairs .action-removeall",function(){confirm("Are you sure?")&&f(this).parent().find(".pair").slice(1).remove()}).on("click",".field .pair .action-delete",function(){1",{"data-type":e,class:"form-invalid",id:i}).append(u.html[e].replace("{id}",i))),u.buildTooltips("#"+i+" "),0 '+f(this)[0].validationMessage+"").insertBefore(f(this))})),p&&f("label.error").length&&f("html, body").animate({scrollTop:f("label.error").first().offset().top-160},1e3),u.saveJSONdata(),u.saved=!p},u.appendGlobalParameters=function(){f("#wck-parameters .global-parameters").html(""),f.each(wck_global_parameters,function(t,e){var t="global:"+t,a="";n.push(t),e="object"==typeof e?(f.each(e,function(e,i){a=a+'"}),""):" = "+e,f("#wck-parameters .global-parameters").append('"),f("#wck-parameters .global-parameters").append(a)})},u.appendFormulaVars=function(e){(u.fields[e.name]=e).use_expression&&("checkboxgroup"!==e.type?(n.push(e.name),f("#wck-parameters .defined-fields").append('")):(n.push(e.name),f("#wck-parameters .defined-fields").append('"),n.push(e.name+":sum"),f("#wck-parameters .defined-fields").append('"),n.push(e.name+":min"),f("#wck-parameters .defined-fields").append('"),n.push(e.name+":max"),f("#wck-parameters .defined-fields").append('")),"text"!==e.type&&"textarea"!==e.type||(n.push(e.name+":text"),f("#wck-parameters .defined-fields").append('")),"rangedatepicker"===e.type?(n.push(e.name+":date_from"),f("#wck-parameters .defined-fields").append('"),n.push(e.name+":date_to"),f("#wck-parameters .defined-fields").append('"),n.push(e.name+":days"),f("#wck-parameters .defined-fields").append('")):"datepicker"===e.type?(n.push(e.name+":date"),f("#wck-parameters .defined-fields").append('")):"imageupload"===e.type&&(n.push(e.name+":size"),f("#wck-parameters .defined-fields").append('")))},u.saveJSONdata=function(){0
');f(".input-if input",a).val(e),f(".input-equation input",a).val(i),f(!0===t?"div#addon-inputs":"div#extra-inputs").append(a),u.autocomplete()},f("button.add-condition").on("click",function(){u.addCondition()}),f("button.add-addon").on("click",function(){u.addCondition("","",!0)}),u.autocomplete=function(){f(".input-icon input").bind("keydown",function(e){16!==e.keyCode&&219!==e.keyCode||(t[e.keyCode]=!0)}).autocomplete({minLength:0,source:function(e,i){!0===t[16]&&!0===t[219]&&i(n)},focus:function(){return!1},select:function(e,i){return delete t[16],delete t[219],this.value+=i.item.value+"}",!1}})},u.saveExpression=function(){var e,t,i=u.expression.mode;u.expr_saved=!1,"oneline"===i&&(u.expression.expr=f(".expression_oneline input").val(),""!==u.expression.expr&&(u.expr_saved=!0)),"conditional"===i&&(t=[],f(".expression_conditional .input-group").each(function(){var e=f(this).find(".input-if input").val(),i=f(this).find(".input-equation input").val();t.push({type:"condition",if:e,then:i})}),e=f(".expression_conditional .input-else input").val(),t.push({type:"else",if:"true",then:e}),u.expression.expr=t,0Choose field...'),f.each(u.fieldList.find(".field"),function(){var e;"static"===f(this).data("group")||f(this).is(i)||(e=f(this).find(".f-name").val(),t.append('"))}),o.builder.append(o.template.clone()),o.builder.find(".or-condition").remove(),o.context.find(".f-visibility").val());try{a=JSON.parse(a)}catch(e){a=!1}"object"==typeof a?f.each(a,function(e,i){var t=!0;f.each(i,function(e,i){o.add(t?"or":"and",null,i),t=!1})}):o.add("or",null,null),o.window.find("span.self-name").text(i.find(".f-name").val()),o.window.show().css({display:"flex"})},o.close=function(){o.window.hide(),o.builder.empty()},o.add=function(e,i,t){(i=null===i?o.builder.find("."+e+"-group").last():i).append(o.window.find(".template ."+e+"-condition").clone());e=i.find(".and-condition").last();null!==t&&"object"==typeof t?(e.find(".p-field").val(t.field),e.find(".p-comparison").val(t.comp).trigger("change"),e.find(".p-value").val(t.value)):e.find(".p-value").val("")},o.validate=function(){var a=!0,e=o.builder.find(".and-condition");return e.find(".validation-error").removeClass("validation-error"),e.each(function(){var e=f(this).find(".p-field"),i=f(this).find(".p-comparison").val(),t=f(this).find(".p-value");[null,""].includes(e.val())&&(e.addClass("validation-error"),a=!1),t.prop("disabled")||""!==t.val()||(t.addClass("validation-error"),a=!1),["5","6","7","8"].includes(i)&&!t.val().match(/^-?\d*[\.,]?\d+$/)&&(t.addClass("validation-error"),a=!1),"9"===i&&""===t.val()&&(t.addClass("validation-error"),a=!1)}),a},o.window.on("click",".cv-action-and",function(e){e.preventDefault(),o.add("and",f(this).prev(),null)}),o.window.on("click",".cv-action-or",function(e){e.preventDefault(),o.add("or",f(this).prev(),null)}),o.window.on("click",".cv-remove",function(e){e.preventDefault(),(1===f(this).closest(".and-group").children().length?f(this).closest(".or-condition"):f(this).parent()).remove()}),o.window.on("change","select.p-comparison",function(e){var i=["1","2"].includes(f(this).val()),t=f(this).next(".p-value");t.prop("disabled",i),i&&t.val("")}),o.window.on("click",".cv-close",function(e){e.preventDefault(),o.close()}),o.window.on("click",".cv-save",function(e){if(e.preventDefault(),!o.validate())return alert("Please correct the form!"),!1;var a=[],n=[],e=(f.each(o.builder.find(".or-condition"),function(){var i=[],t=[];f.each(f(this).find(".and-condition"),function(){var e={field:f(this).find(".p-field").val(),comp:f(this).find(".p-comparison").val(),comp_text:f(this).find(".p-comparison option:selected").text(),value:f(this).find(".p-value").val()};i.push(e),t.push("{"+e.field+"} "+e.comp_text+" "+e.value)}),a.push(i),n.push(" ( "+t.join(" and ")+" ) ")}),n.join(" or ").replaceAll(" "," "));o.context.find(".f-visibility").val(0===a.length?"":JSON.stringify(a)),o.context.find(".f-visibility-readable").val(e),""!==e?o.context.find(".visibility-readable").val("Rule preview: "+e):o.context.find(".visibility-readable").val(""),o.close()}),f("body").on("click",".action-field-visibility",function(){var e=f(this).closest(".field");o.open(e)}),u.init(),u.loadExpression(),u.autocomplete()})}(jQuery); \ No newline at end of file +!function(e){"use strict";var u={},o={};e(document).ready(function(f){f("body").hasClass("folded")||f("body").addClass("folded");var n=[],t={};f("#f-field-list").sortable({handle:".header",placeholder:"wck-sortable-placeholder",tolerance:"pointer"}),f("#extra-inputs, #addon-inputs").sortable({handle:".action-drag",placeholder:"wck-sortable-placeholder",tolerance:"pointer"}),f('').insertBefore("#wpwrap"),u.colorpicker=f("input.wck-global-color-picker"),u.colorpicker.iris(),u.expressionLastFocusedInput=null,u.wpMediaFrame=null,u.wpMediaTarget=null,u.iconPreloader="data:image/gif;base64,R0lGODlhEAAQAPUVAHt7e729vf///4R7e+/v762trZSUlKWlpZycnPf39+bm5t7e3tbW1s7OzoSEhMXFxc7FzpSMjJyUlP/397WtraWlnM7FxbW1tb21tebe3tbOzqWcnIyEhHNzc3tzc4yMjK2lpbWttcW9vffv76Wtpa2lra2tpb21vcXFzt7e1qWlrdbe1pScnO/v5gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQJBwAVACwAAAAAEAAQAEAGt8CKsGLZfDyez8YyrAAekAdA09R0GoLGE8BgLDQIhwORSSQIDqYxELhcCoXDARHeCBmRSGOh6BMICxIRDBUOAQ0NBiBNIBsTAgscGwgPDxcABYgFHnQSSkMFAAYHcAgRHQVNQgUDmX0NFA6pQxsGC7d9Cn8ECRt2GwddDwMgiCAOC2YYGwCIWlRDGgACAgkADhiVEYtDIAMGAQYcUmxtHwDXc3QdDxV4DhRucHIIAIOqRRxIkkxDQQAh+QQFBwAQACwAAAAAEAAQAAAGr0CIEGLZfDyez8YybBYAh8diYSkMCk1G5PNgrKYKBcMQYQg3hgZjDQ4TEBvIA/BoNCySgQMBIRAUDkVRDQEDIHYgDgx+FxsOFw8PBiBNIAgJCQscAAGRABpNGgCYBACcAQGfoaMJpQ4hqB+UQyAbAgKaGwgXF08FdgUdF7cBG3O8vQ6meypiAw8QRr0FBwcI1wgHDnEQWg4H1NbXBgBlTh4G2dYfHVhNQkUcSBxLTUEAIfkECQcAEAAsAQABAA4ADgAABnBAiFAYYDAeoKEy0GgYF4uG8vN4NJ9QxTBQfQgHQoViMUAEAhiAMqygFM6ftZBAYFzu8jlBcb/kISN0IAUFHHIICQkMBoQHHkoOGYkXHgUkBwdKCgIJBA4QDpgHCAgGFwICE5lfpKQGRQsIch+tBmtBACH5BAUHABQALAEAAQAOAA4AAAaaQAqlAEBcHo3AAVAQMiKO4wPSaDAsnwhj8wkEHuAqg7EwbAAXbyAyGBgaiwVjILlcQgBQFTSALwoHdh8gQkIgEgoKDQWMABqFFBoAiQsHjB6PhZKJChUHBw6EhSAIBAQMBp8IHgVVBQ4UphceBwi2AwAOBwoJBAoOGw62CG8CEwnIGxtPRRIBAtAJCghaQgUdHwYMAgsXDk0UQQAh+QQFBwAQACwBAAEADgAOAAAGcECIECIpBB4XxHBZuASOD5RoyblYn49HYyv0FL4XCECoZTTGhwJoSWYwQIjDwcEWMhYP+cFThywWDAiCfX5/gkp9CgoNH4IGiQoFEHEFDxt0GwsECgtCAxAECQIJpASmiBAeDQKjpQsSbAMYC6QMbEEAIfkEBQcAEAAsAQABAA4ADgAABnZAiNAjOVwCBaFSCDgUCpdjAMNZHpzQU0D0eESEVycHAIgEuo8yAgHxLAGBRkO4Xi7lIoSBbRcyGA0SCB99fn8GD3N9EgsLDxwEAhkOdg2NBQAjAgIKSggMCo0DEAcTCacjBAQKrEsICqeqqwx9DhgMqgwUo0JBACH5BAkHAAAALAEAAQAOAA4AAAVjICACEVIUhzGuyHGc10WtANK+RRwEo92ulx0PIKnRAJfHY2MIGAbHiBLTEDSOogfkkRAIoMdG47EQTDZYcQCTSBwHDwbj4AC0MwgAVLOQi9AEgQqDC4UqIwuChFdHFBqDjCMhACH5BAUHABMALAEAAQAOAA4AAAaTwMmk0PlIDgeEwVMQMiIAA2KKLBwGEcbGkZwiqoULZzNgEC4IBwDAKYQvgIBA8OiAGg0Q4I1YzA8gQkIgHwEBIQmJAxqCExoehgEEioyCGgAPDwELiQiBgiAGmRgXBAQMDgV4BQMiDRAHDgqmEwgDAwYQeBYAGwgECsELCwzFDQYbTxIMwsMMDxFZQqyqww8He0JBACH5BAUHAAMALAEAAQAOAA4AAAZzwIEQYBggEIaPcGlUKBqG4xGw3CQEgkAUcTiYhA7CVcHskgqeSyKRcTA9h0LBwFhvmEJO6FIi+PFLF4IKflR4HgGCDH+AHwEBBQNOGngAGA8BCAMLTgMSSw+hIksKC6YMDA0NoRFMDaepDQGAAyAPqLNMQQAh+QQFBwAYACwBAAEADgAOAAAFZSAmOtciMGKaSlgivAGrIm0yCY2B7KlCJJiDQ7RDHEQEgiplPGKStGXwUFFYAVJMoXBYWLPabcMqW14uh8JigRksKWfJgLHOYQCRgP4ikiwYDA0ND4R6SxaBDRCEfEtYAYIXUSIhACH5BAkHABAALAEAAQAOAA4AAAZyQIhQyEgkFhjHcLggGBMCAcOzbBEII6PAeBhABgsFYbGBOA6iwgEBKSgUjKXQwEJ8Gm/5EMFf+PVCfAgMf4AHhw8LcXpnayAMDA96IAUFQg0MDZIAQheVBVQQDaMPDwEBF6kcQx8ipaaoBUpyGxemlktBACH5BAUHABAALAEAAQAOAA4AAAaRQAikMCg0CATGxVEQMiIGhgJJSCQUiAhjI1F4p1Vr4rAZLBYKBsLh2CgEggSgcG44QI0GyAFJED4PKQsSIEJCewEBUQwMABqGEBodHwgSDYyOkJIInAF5BoWGe5wIB3kBc3kFHgcHWQAPsQEfAAAcBa0HHhsGsokXBcEHbU8fF78XwMNaQgUACAUBFwcGHk0QQQA7",u.fieldsLayout="one-col",u.toggleButton=function(e,i){return i.preventDefault(),e.hasClass("woocommerce-input-toggle--disabled")?(e.removeClass("woocommerce-input-toggle--disabled").addClass("woocommerce-input-toggle--enabled"),!0):(e.removeClass("woocommerce-input-toggle--enabled").addClass("woocommerce-input-toggle--disabled"),!1)},u.fullscreenMode=function(e){e?(f("body").css("overflow","hidden"),f("#postbox-container-2").addClass("fullscreen")):(f("body").css("overflow","auto"),f("#postbox-container-2").removeClass("fullscreen"))},f(".wck-toggle-layout").on("click",function(e){e=u.toggleButton(f(this),e);u.fieldsLayout=e?"two-col":"one-col",u.updateLayout()}),f(".wck-toggle-fullscreen").on("click",function(e){e=u.toggleButton(f(this),e);u.fullscreenMode(e)}),f(".wck-toggle-expand").on("click",function(e){e=u.toggleButton(f(this),e);f(".action-toggle.dashicons-arrow-"+(e?"down":"up")+"-alt2").trigger("click")}),f("body").on("click",".wck-toggle-colspan",function(e){e.preventDefault();e=f(this).parent().parent().parent();f(this).hasClass("woocommerce-input-toggle--disabled")?(f(this).removeClass("woocommerce-input-toggle--disabled").addClass("woocommerce-input-toggle--enabled"),e.addClass("wck-layout-colspan"),e.find(".f-colspan").val(2)):(f(this).removeClass("woocommerce-input-toggle--enabled").addClass("woocommerce-input-toggle--disabled"),e.removeClass("wck-layout-colspan"),e.find(".f-colspan").val(1))}),f(".action-save-post").on("click",function(e){e.preventDefault(),f("#publish").trigger("click"),f("#publish").hasClass("disabled")&&f(this).prop("disabled",!0).addClass("disabled")}),f("body").on("click",".action-duplicate",function(e){e.preventDefault();var e=f(this).parent().parent().parent(),i=e.clone();i.hide(),i.find(".f-title").val(""),i.find(".f-name").val(""),i.insertAfter(e),i.fadeIn(1500,function(){i.find(".dashicons-arrow-down-alt2").trigger("click"),f(this).find(".f-title").fadeOut(150).fadeIn(150).fadeOut(150).fadeIn(150).fadeOut(150).fadeIn(150),f(this).find(".f-name").fadeOut(150).fadeIn(150).fadeOut(150).fadeIn(150).fadeOut(150).fadeIn(150)})}),u.shouldHideExprToolbar=!1,u.stateExprToolbar=!1,f("body").on("focusin","#wck_expression .input-icon input, #wck_inventory .input-icon input, input.expression-editor-enabled",function(e){u.expressionLastFocusedInput=f(this),u.shouldHideExprToolbar=!1;var i=f(this).offset(),t=f(this).outerHeight(),a=f("#wck_expression").offset();f("#wck-expression-toolbar").css({top:i.top-a.top-t-f("#wck-expression-toolbar").outerHeight()-20,left:i.left-a.left}),u.stateExprToolbar||(u.stateExprToolbar=!0,u.saveFields(),f("#wck-parameters .first-selected").prop("selected",!0),f("#wck-expression-toolbar").stop(!0,!1).fadeIn("fast")),f("#wck-parameters .total-price").toggle(f(this).hasClass("show-total-price")),f(this).hasClass("show-total-price")||"{total_price}"!==f("#wck-parameters").val()||f("#wck-parameters").val("")}).on("focusout","#wck_expression input, #wck_inventory input, input.expression-editor-enabled",function(e){u.shouldHideExprToolbar=!(e.relatedTarget&&f("#wck-expression-toolbar").has(e.relatedTarget).length),setTimeout(function(){u.stateExprToolbar&&u.shouldHideExprToolbar&&(f("#wck-expression-toolbar").stop(!0,!1).fadeOut("fast"),u.stateExprToolbar=!1)},200)}).on("click","#wck-expression-toolbar",function(e){e.target!==e.currentTarget&&"OPTION"!==e.target.tagName||u.expressionLastFocusedInput.focus()}).on("click","button.add-field-to-formula, button.add-operator",function(e){e.preventDefault();var i,t,a,e=u.expressionLastFocusedInput;e||(e=f(".input-icon").find("input:visible").first()).focus(),e&&e.length&&(null!==(i=(f(this).hasClass("add-operator")?f(this):f("#wck-parameters")).val())&&(t=e[0].selectionStart,a=e.val(),e.val(a.slice(0,t)+i+(f(this).data("ending")||"")+a.slice(t)),e.focus(),t+=i.length,e[0].setSelectionRange(t,t)))}).on("click",".field .pairs .action-add",function(){f(this).prev(".pair").clone().insertBefore(f(this)).find("input").val("")}).on("click",".field .pairs .action-showimport",function(){f(this).parent().find("div.importer").toggle()}).on("click",".field .pairs .action-import",function(){var t=f(this),e=t.parent().find("textarea").val().trim().split("\n");Array.isArray(e)&&e.forEach(function(e){var e=e.trim().split(";"),i=t.parent().parent().find(".pair").last(),i=i.clone().insertAfter(i);2===e.length?(i.find("input.fs-name").val(e[0]),i.find("input.fs-title").val(e[1])):1===e.length&&i.find("input.fs-title").val(e[0])})}).on("click",".field .pairs .action-removeall",function(){confirm("Are you sure?")&&f(this).parent().find(".pair").slice(1).remove()}).on("click",".field .pair .action-delete",function(){1",{"data-type":e,class:"form-invalid",id:i}).append(u.html[e].replace("{id}",i))),u.buildTooltips("#"+i+" "),0 '+f(this)[0].validationMessage+"").insertBefore(f(this))})),p&&f("label.error").length&&f("html, body").animate({scrollTop:f("label.error").first().offset().top-160},1e3),u.saveJSONdata(),u.saved=!p},u.appendGlobalParameters=function(){f("#wck-parameters .global-parameters").html(""),f.each(wck_global_parameters,function(t,e){var t="global:"+t,a="";n.push(t),e="object"==typeof e?(f.each(e,function(e,i){a=a+'"}),""):" = "+e,f("#wck-parameters .global-parameters").append('"),f("#wck-parameters .global-parameters").append(a)})},u.appendFormulaVars=function(e){(u.fields[e.name]=e).use_expression&&("checkboxgroup"!==e.type?(n.push(e.name),f("#wck-parameters .defined-fields").append('")):(n.push(e.name),f("#wck-parameters .defined-fields").append('"),n.push(e.name+":sum"),f("#wck-parameters .defined-fields").append('"),n.push(e.name+":min"),f("#wck-parameters .defined-fields").append('"),n.push(e.name+":max"),f("#wck-parameters .defined-fields").append('")),"text"!==e.type&&"textarea"!==e.type||(n.push(e.name+":text"),f("#wck-parameters .defined-fields").append('")),"rangedatepicker"===e.type?(n.push(e.name+":date_from"),f("#wck-parameters .defined-fields").append('"),n.push(e.name+":date_to"),f("#wck-parameters .defined-fields").append('"),n.push(e.name+":days"),f("#wck-parameters .defined-fields").append('")):"datepicker"===e.type?(n.push(e.name+":date"),f("#wck-parameters .defined-fields").append('")):"imageupload"!==e.type&&"fileupload"!==e.type||(n.push(e.name+":size"),f("#wck-parameters .defined-fields").append('")))},u.saveJSONdata=function(){0
');f(".input-if input",a).val(e),f(".input-equation input",a).val(i),f(!0===t?"div#addon-inputs":"div#extra-inputs").append(a),u.autocomplete()},f("button.add-condition").on("click",function(){u.addCondition()}),f("button.add-addon").on("click",function(){u.addCondition("","",!0)}),u.autocomplete=function(){f(".input-icon input").bind("keydown",function(e){16!==e.keyCode&&219!==e.keyCode||(t[e.keyCode]=!0)}).autocomplete({minLength:0,source:function(e,i){!0===t[16]&&!0===t[219]&&i(n)},focus:function(){return!1},select:function(e,i){return delete t[16],delete t[219],this.value+=i.item.value+"}",!1}})},u.saveExpression=function(){var e,t,i=u.expression.mode;u.expr_saved=!1,"oneline"===i&&(u.expression.expr=f(".expression_oneline input").val(),""!==u.expression.expr&&(u.expr_saved=!0)),"conditional"===i&&(t=[],f(".expression_conditional .input-group").each(function(){var e=f(this).find(".input-if input").val(),i=f(this).find(".input-equation input").val();t.push({type:"condition",if:e,then:i})}),e=f(".expression_conditional .input-else input").val(),t.push({type:"else",if:"true",then:e}),u.expression.expr=t,0Choose field...'),f.each(u.fieldList.find(".field"),function(){var e;"static"===f(this).data("group")||f(this).is(i)||(e=f(this).find(".f-name").val(),t.append('"))}),o.builder.append(o.template.clone()),o.builder.find(".or-condition").remove(),o.context.find(".f-visibility").val());try{a=JSON.parse(a)}catch(e){a=!1}"object"==typeof a?f.each(a,function(e,i){var t=!0;f.each(i,function(e,i){o.add(t?"or":"and",null,i),t=!1})}):o.add("or",null,null),o.window.find("span.self-name").text(i.find(".f-name").val()),o.window.show().css({display:"flex"})},o.close=function(){o.window.hide(),o.builder.empty()},o.add=function(e,i,t){(i=null===i?o.builder.find("."+e+"-group").last():i).append(o.window.find(".template ."+e+"-condition").clone());e=i.find(".and-condition").last();null!==t&&"object"==typeof t?(e.find(".p-field").val(t.field),e.find(".p-comparison").val(t.comp).trigger("change"),e.find(".p-value").val(t.value)):e.find(".p-value").val("")},o.validate=function(){var a=!0,e=o.builder.find(".and-condition");return e.find(".validation-error").removeClass("validation-error"),e.each(function(){var e=f(this).find(".p-field"),i=f(this).find(".p-comparison").val(),t=f(this).find(".p-value");[null,""].includes(e.val())&&(e.addClass("validation-error"),a=!1),t.prop("disabled")||""!==t.val()||(t.addClass("validation-error"),a=!1),["5","6","7","8"].includes(i)&&!t.val().match(/^-?\d*[\.,]?\d+$/)&&(t.addClass("validation-error"),a=!1),"9"===i&&""===t.val()&&(t.addClass("validation-error"),a=!1)}),a},o.window.on("click",".cv-action-and",function(e){e.preventDefault(),o.add("and",f(this).prev(),null)}),o.window.on("click",".cv-action-or",function(e){e.preventDefault(),o.add("or",f(this).prev(),null)}),o.window.on("click",".cv-remove",function(e){e.preventDefault(),(1===f(this).closest(".and-group").children().length?f(this).closest(".or-condition"):f(this).parent()).remove()}),o.window.on("change","select.p-comparison",function(e){var i=["1","2"].includes(f(this).val()),t=f(this).next(".p-value");t.prop("disabled",i),i&&t.val("")}),o.window.on("click",".cv-close",function(e){e.preventDefault(),o.close()}),o.window.on("click",".cv-save",function(e){if(e.preventDefault(),!o.validate())return alert("Please correct the form!"),!1;var a=[],n=[],e=(f.each(o.builder.find(".or-condition"),function(){var i=[],t=[];f.each(f(this).find(".and-condition"),function(){var e={field:f(this).find(".p-field").val(),comp:f(this).find(".p-comparison").val(),comp_text:f(this).find(".p-comparison option:selected").text(),value:f(this).find(".p-value").val()};i.push(e),t.push("{"+e.field+"} "+e.comp_text+" "+e.value)}),a.push(i),n.push(" ( "+t.join(" and ")+" ) ")}),n.join(" or ").replaceAll(" "," "));o.context.find(".f-visibility").val(0===a.length?"":JSON.stringify(a)),o.context.find(".f-visibility-readable").val(e),""!==e?o.context.find(".visibility-readable").val("Rule preview: "+e):o.context.find(".visibility-readable").val(""),o.close()}),f("body").on("click",".action-field-visibility",function(){var e=f(this).closest(".field");o.open(e)}),u.init(),u.loadExpression(),u.autocomplete()})}(jQuery); \ No newline at end of file diff --git a/assets/js/colorpicker.js b/assets/js/colorpicker.js index a0c74ab..f71d19a 100644 --- a/assets/js/colorpicker.js +++ b/assets/js/colorpicker.js @@ -1,7 +1,17 @@ jQuery(document).ready(function ($) { + "use strict"; + var changeTimeout; + + function triggerChange(event, ui = null) { + clearTimeout(changeTimeout); + changeTimeout = setTimeout(function () { + $(event.target).trigger('change'); + }, 500); + } + $('input.wck-color-picker').wpColorPicker({ - "change": function (event, ui) { - $(this).trigger('change'); - } + "change": triggerChange, + "clear": triggerChange }); + }); \ No newline at end of file diff --git a/assets/js/colorpicker.min.js b/assets/js/colorpicker.min.js index 84bca2d..c458173 100644 --- a/assets/js/colorpicker.min.js +++ b/assets/js/colorpicker.min.js @@ -1 +1 @@ -jQuery(document).ready(function(n){n("input.wck-color-picker").wpColorPicker({change:function(c,e){n(this).trigger("change")}})}); \ No newline at end of file +jQuery(document).ready(function(r){"use strict";var t;function e(e,c=0){clearTimeout(t),t=setTimeout(function(){r(e.target).trigger("change")},500)}r("input.wck-color-picker").wpColorPicker({change:e,clear:e})}); \ No newline at end of file diff --git a/assets/js/wckalkulator.js b/assets/js/wckalkulator.js index 8172da2..7913e6a 100644 --- a/assets/js/wckalkulator.js +++ b/assets/js/wckalkulator.js @@ -1,7 +1,7 @@ (function ($) { "use strict"; $(document).ready(function ($) { - var userTimeout; + var userTimeout, updateTimeout; var _form = wck_ajax_object.form; var shouldCalculatePrice = wck_ajax_object._wck_has_expression === "1"; @@ -9,29 +9,65 @@ if (wck_ajax_object.hasOwnProperty("_wck_visibility_rules") && wck_ajax_object._wck_visibility_rules !== null) { $.each(wck_ajax_object._wck_visibility_rules, function (fieldName, options) { - $("[name*='wck[" + fieldName + "]']").prop("disabled", true).hide().closest('tr').hide(); + findFieldAndToggle(fieldName, false); CV[fieldName] = options; }); } + function findFieldAndToggle(fieldName, show) { + var inputField = $("[name*='wck[" + fieldName + "]']"); + if(inputField.length > 0) { + if(show) { + inputField.prop("disabled", false).show().closest('tr').show(); + } else { + inputField.prop("disabled", true).hide().closest('tr').hide(); + } + } else { + var staticField = $("[data-wck-static-name='" + fieldName + "']"); + if(staticField.length > 0) { + staticField.toggle(show); + } + } + } + function updateUI() { //wck-dynamic support, conditional visibility support var formFields = {}; - jQuery(_form + " [name^=wck").each(function () { - var fieldName = $(this).attr("name").replace("wck[", "").replace("]", "").replace("[]", ""); - formFields["{" + fieldName + "}"] = $(this).val(); - if (CV.hasOwnProperty(fieldName)) { + jQuery(_form + " [data-wck-static-name] , " + _form + " [name^=wck").each(function () { + var fieldName = false; + if($(this)[0].hasAttribute("name")) { + var fieldName = $(this).attr("name").replace("wck[", "").replace("]", "").replace("[]", ""); + formFields["{" + fieldName + "}"] = $(this).val(); + var type = $(this).prop("type"); + switch(type) { + case 'file': + formFields["{" + fieldName + ":size}"] = (($(this)[0].files.length === 1) ? Math.round(($(this)[0].files[0].size / 1000000 + Number.EPSILON) * 100) / 100 : 0 ); + break; + } + } else { + fieldName = $(this).data("wckStaticName"); + } + + if (fieldName && CV.hasOwnProperty(fieldName)) { toggleField(fieldName, CV[fieldName]); } }); + $.each(wck_ajax_object._wck_additional_parameters, function (name, value) { + formFields["{" + name + "}"] = value; + }); + $("span.wck-dynamic").each(function () { var expr = $(this).data('expr'); var vars = expr.match(/{[^}]+}/gm); vars.forEach(function (v, i) { expr = expr.replaceAll(v, formFields[v]); }); - $(this).text(Math.round(Mexp.eval(expr) * 100) / 100); + try { + $(this).text(Math.round((Mexp.eval(expr) + Number.EPSILON) * 100) / 100); + } catch (error) { + console.log("[Mexp]", error); + } }); } @@ -43,6 +79,8 @@ value = value.substring(0, n); } return value; + } else if(field.prop("type") === "file") { + return ((field[0].files.length === 1) ? (Math.round((field[0].files[0].size / 1000000 + Number.EPSILON) * 100) / 100) : 0); } return field.val(); } @@ -64,12 +102,12 @@ return state !== false; }); if (state === true) { - $("[name*='wck[" + fieldName + "]']").prop("disabled", false).show().closest('tr').show(); + findFieldAndToggle(fieldName, true); return false; } }); if (state !== true) { - $("[name*='wck[" + fieldName + "]']").prop("disabled", true).hide().closest('tr').hide(); + findFieldAndToggle(fieldName, false); return false; } } @@ -132,19 +170,21 @@ } }); - $(document).on('change', _form + ' input, ' + _form + ' select, ' + _form + ' textarea', function () { - updateUI(); + $(document).on('change keyup', _form + ' input, ' + _form + ' select, ' + _form + ' textarea', function () { clearTimeout(userTimeout); + clearTimeout(updateTimeout); userTimeout = setTimeout(function () { $("#wckalkulator-price").html('...'); calculatePrice(); - }, 1000); + }, 500); + updateTimeout = setTimeout(function(){ + updateUI(); + }, 300); }); updateUI(); calculatePrice(); - $("span.wck-field-tip").tipTip({ attribute: 'title', defaultPosition: 'left' diff --git a/assets/js/wckalkulator.min.js b/assets/js/wckalkulator.min.js index 4b5cc36..f2552b0 100644 --- a/assets/js/wckalkulator.min.js +++ b/assets/js/wckalkulator.min.js @@ -1 +1 @@ -!function(){"use strict";jQuery(document).ready(function(h){var e,t=wck_ajax_object.form,a="1"===wck_ajax_object._wck_has_expression,i={};function n(){var o={};jQuery(t+" [name^=wck").each(function(){var e=h(this).attr("name").replace("wck[","").replace("]","").replace("[]","");if(o["{"+e+"}"]=h(this).val(),i.hasOwnProperty(e)){var a=e,e=i[e],n=null;if(h.each(e,function(e,t){if(h.each(t,function(e,t){var a=h("[name*='wck["+t.field+"]']");return a.length&&a.each(function(){var e=function(e,t,a){var n,o;["5","6","7","8"].includes(t)&&(n=Math.round(1e3*parseFloat(e))/1e3,o=Math.round(1e3*parseFloat(a))/1e3);try{switch(t){case"1":return""===e;case"2":return""!==e;case"3":return e===a;case"4":return e!==a;case"5":return n1e6*h(this).data("maxfilesize")&&(alert(wck_ajax_object._wck_i18n_maxfilesize+" Max. "+h(this).data("maxfilesize")+"MB"),h(this).val(""))}),h(document).on("change",t+" input, "+t+" select, "+t+" textarea",function(){n(),clearTimeout(e),e=setTimeout(function(){h("#wckalkulator-price").html('...'),o()},1e3)}),n(),o(),h("span.wck-field-tip").tipTip({attribute:"title",defaultPosition:"left"}),h("input[type=checkbox][data-type='checkboxgroup']").change(function(e){var t=h(this).data("group"),a=1===h(this).data("required"),n=h(this).data("limit"),o=h("input[type=checkbox][data-group='"+t+"']:checked").length;0").attr("type","hidden").attr("name",h(this).attr("name")).val("");h(n).append(h(e))})})})}();var wck=function(e){return jQuery("[name*='wck["+e+"]']")};!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.Mexp=t():e.Mexp=t()}(self,function(){return n={28:(e,t,a)=>{a=a(733);a.prototype.formulaEval=function(){"use strict";for(var e,t,a,n=[],o=this.value,h=0;h"+t.value+""+o[h].show+""+e.value+"",type:10}):n.push({value:(1!=t.type?"(":"")+t.value+(1!=t.type?")":"")+""+e.value+"",type:1})):2===o[h].type||9===o[h].type?(e=n.pop(),t=n.pop(),n.push({value:(1!=t.type?"(":"")+t.value+(1!=t.type?")":"")+o[h].show+(1!=e.type?"(":"")+e.value+(1!=e.type?")":""),type:o[h].type})):12===o[h].type&&(e=n.pop(),t=n.pop(),a=n.pop(),n.push({value:o[h].show+"("+a.value+","+t.value+","+e.value+")",type:12}));return n[0].value},e.exports=a},618:(e,t,a)=>{"use strict";var Q=a(178);function B(e,t){for(var a=0;aF.length-2?F.length-1:e.length-i;0{"use strict";function i(e){this.value=e}i.math={isDegree:!0,acos:function(e){return i.math.isDegree?180/Math.PI*Math.acos(e):Math.acos(e)},add:function(e,t){return e+t},asin:function(e){return i.math.isDegree?180/Math.PI*Math.asin(e):Math.asin(e)},atan:function(e){return i.math.isDegree?180/Math.PI*Math.atan(e):Math.atan(e)},acosh:function(e){return Math.log(e+Math.sqrt(e*e-1))},asinh:function(e){return Math.log(e+Math.sqrt(e*e+1))},atanh:function(e){return Math.log((1+e)/(1-e))},C:function(e,t){var a=1,n=e-t,o=t;t{var r=a(618);r.prototype.toPostfix=function(){"use strict";for(var e,t,a,n=[],o=[{value:"(",type:4,pre:0}],h=this.value,i=1;i{var p=a(477);p.prototype.postfixEval=function(e){"use strict";(e=e||{}).PI=Math.PI,e.E=Math.E;for(var t,a,n,o=[],h=this.value,i=void 0!==e.n,A=0;A1e6*i(this).data("maxfilesize")&&(alert(wck_ajax_object._wck_i18n_maxfilesize+" Max. "+i(this).data("maxfilesize")+"MB"),i(this).val(""))}),i(document).on("change keyup",a+" input, "+a+" select, "+a+" textarea",function(){clearTimeout(t),clearTimeout(e),t=setTimeout(function(){i("#wckalkulator-price").html('...'),u()},500),e=setTimeout(function(){o()},300)}),o(),u(),i("span.wck-field-tip").tipTip({attribute:"title",defaultPosition:"left"}),i("input[type=checkbox][data-type='checkboxgroup']").change(function(t){var e=i(this).data("group"),a=1===i(this).data("required"),n=i(this).data("limit"),o=i("input[type=checkbox][data-group='"+e+"']:checked").length;0").attr("type","hidden").attr("name",i(this).attr("name")).val("");i(n).append(i(t))})})})}();var wck=function(t){return jQuery("[name*='wck["+t+"]']")};!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.Mexp=e():t.Mexp=e()}(self,function(){return n={28:(t,e,a)=>{a=a(733);a.prototype.formulaEval=function(){"use strict";for(var t,e,a,n=[],o=this.value,i=0;i"+e.value+""+o[i].show+""+t.value+"",type:10}):n.push({value:(1!=e.type?"(":"")+e.value+(1!=e.type?")":"")+""+t.value+"",type:1})):2===o[i].type||9===o[i].type?(t=n.pop(),e=n.pop(),n.push({value:(1!=e.type?"(":"")+e.value+(1!=e.type?")":"")+o[i].show+(1!=t.type?"(":"")+t.value+(1!=t.type?")":""),type:o[i].type})):12===o[i].type&&(t=n.pop(),e=n.pop(),a=n.pop(),n.push({value:o[i].show+"("+a.value+","+e.value+","+t.value+")",type:12}));return n[0].value},t.exports=a},618:(t,e,a)=>{"use strict";var Q=a(178);function m(t,e){for(var a=0;aF.length-2?F.length-1:t.length-h;0{"use strict";function h(t){this.value=t}h.math={isDegree:!0,acos:function(t){return h.math.isDegree?180/Math.PI*Math.acos(t):Math.acos(t)},add:function(t,e){return t+e},asin:function(t){return h.math.isDegree?180/Math.PI*Math.asin(t):Math.asin(t)},atan:function(t){return h.math.isDegree?180/Math.PI*Math.atan(t):Math.atan(t)},acosh:function(t){return Math.log(t+Math.sqrt(t*t-1))},asinh:function(t){return Math.log(t+Math.sqrt(t*t+1))},atanh:function(t){return Math.log((1+t)/(1-t))},C:function(t,e){var a=1,n=t-e,o=e;e{var r=a(618);r.prototype.toPostfix=function(){"use strict";for(var t,e,a,n=[],o=[{value:"(",type:4,pre:0}],i=this.value,h=1;h{var u=a(477);u.prototype.postfixEval=function(t){"use strict";(t=t||{}).PI=Math.PI,t.E=Math.E;for(var e,a,n,o=[],i=this.value,h=void 0!==t.n,p=0;p - + @@ -27,11 +27,11 @@ - + - + - +
@@ -48,7 +48,7 @@
+
diff --git a/docs/.retype/changelog/index.html b/docs/.retype/changelog/index.html index 935258b..30ccf84 100644 --- a/docs/.retype/changelog/index.html +++ b/docs/.retype/changelog/index.html @@ -3,7 +3,7 @@ - + @@ -11,7 +11,7 @@ CHANGELOG | Product fields and price calculator - + @@ -20,21 +20,21 @@ - + - + - + - + - +
@@ -51,7 +51,7 @@
+
@@ -266,6 +266,35 @@

CHANGELOG

+

2022-09-27 v.1.6.1

+
    +
  • fixed issue with color picker
  • +
+

2022-09-26 v.1.6.0

+
    +
  • image file upload bug fixes
  • +
  • conditional visibility works with static fields (html, paragraph)
  • +
  • added support for in HTML field's content (for example: {=} MB)
  • +
  • display calculated product price in the cart widget (cart popup)
  • +
  • new parameter: product_is_on_sale to use in formula
  • +
  • added parameters to js dynamic formula in HTML field
  • +
  • added placeholder for select and dropdown fields
  • +
  • bug fixed: incorrect value of the image swatch in the cart
  • +
+

v.1.5.5-1.5.7

+
    +
  • bug fixes
  • +
+

2022-08-21 v.1.5.4

+
    +
  • add option to show Price Block before or after "Add to cart" button
  • +
  • bug fixes
  • +
+

2022-08-16 v.1.5.2, v.1.5.3

+
    +
  • image upload bug fix
  • +
  • option to display text before or after field's title
  • +

2022-08-05 v.1.5.0

    diff --git a/docs/.retype/index.html b/docs/.retype/index.html index fdc9b22..d049ea6 100644 --- a/docs/.retype/index.html +++ b/docs/.retype/index.html @@ -3,7 +3,7 @@ - + @@ -30,11 +30,11 @@ - + - + - +
    @@ -51,7 +51,7 @@
    +
    diff --git a/docs/.retype/news/index.html b/docs/.retype/news/index.html index e312b41..6787f51 100644 --- a/docs/.retype/news/index.html +++ b/docs/.retype/news/index.html @@ -3,7 +3,7 @@ - + @@ -30,11 +30,11 @@ - + - + - +
    @@ -51,7 +51,7 @@
    +
    diff --git a/docs/.retype/resources/js/config.js b/docs/.retype/resources/js/config.js index c0478cd..4bd9386 100644 --- a/docs/.retype/resources/js/config.js +++ b/docs/.retype/resources/js/config.js @@ -1 +1 @@ -var __DOCS_CONFIG__ = {"id":"v5kgSSnU2DMVQFD/JIlj3ks8ll545196UrI","key":"KwimltaMyHq+xEMjynzUFrPhynqem7aelmsGeAb44/U.RB9zjyuJ+I8mEKXv5AJELy9genBn6jwi6Tb/iUkxPc9geAUZhC+/L8z1GDtouPLmem6e7WyXwnPqLP4BiG6OeQ.78","base":"/","host":"wckalkulator.com","version":"1.0.0","useRelativePaths":true,"documentName":"index.html","appendDocumentName":false,"trailingSlash":true,"preloadSearch":false,"cacheBustingToken":"2.3.0.713601965991","cacheBustingStrategy":"query","sidebarFilterPlaceholder":"Filter","toolbarFilterPlaceholder":"Filter","showSidebarFilter":true,"filterNotFoundMsg":"No member names found containing the query \"{query}\"","maxHistoryItems":15,"homeIcon":"","access":[{"value":"public","label":"Public"},{"value":"protected","label":"Protected"}],"toolbarLinks":[{"id":"fields","label":"Fields"},{"id":"properties","label":"Properties","shortLabel":"Props"},{"id":"methods","label":"Methods"},{"id":"events","label":"Events"}],"sidebar":[{"n":"/","l":"WC Kalkulator","s":""},{"n":"news","l":"News","s":""},{"n":"usermanual","l":"User Manual","c":false,"o":true,"i":[{"n":"about","l":"About the Plugin","s":""},{"n":"installation","l":"Installation","s":""},{"n":"fields","l":"Field Types","s":""},{"n":"calculation-types","l":"Calculation Modes","s":""},{"n":"expression-syntax","l":"Expression Syntax","s":""},{"n":"example-expressions","l":"Formula Examples","s":""},{"n":"usage","l":"Usage","s":""},{"n":"advanced_usage","l":"Advanced Usage","s":""},{"n":"templates","l":"Templates & Layouts","s":""},{"n":"acf","l":"ACF support","s":""},{"n":"inventory","l":"Stock Management","s":""},{"n":"import_export","l":"Import/Export","s":""},{"n":"uninstall","l":"Uninstallation","s":""},{"n":"videos","l":"Video Tutorials","s":""}],"s":""},{"n":"changelog","l":"CHANGELOG","s":""}],"search":{"mode":0,"minChars":2,"maxResults":20,"placeholder":"Search","hotkeys":["/"],"noResultsFoundMsg":"Sorry, no results found.","recognizeLanguages":true,"languages":[0],"preload":false}}; +var __DOCS_CONFIG__ = {"id":"HDZrj2EOt1n255h/s6RYCMqS9gBb4AcUtDo","key":"4yIegGgDe5CWuZXYGwah1aFR5XY0mvyi59rf0Hx2/Rg.PZrM1V+fBcdAc8+jVYJ6jmwhU1rMVp4lIAKdH+jAvEbvpvvKV9fi5o+M8yzE1+EtLS0t8G76bl1RAx9XJr0UTg.17","base":"/","host":"wckalkulator.com","version":"1.0.0","useRelativePaths":true,"documentName":"index.html","appendDocumentName":false,"trailingSlash":true,"preloadSearch":false,"cacheBustingToken":"2.3.0.717595770947","cacheBustingStrategy":"query","sidebarFilterPlaceholder":"Filter","toolbarFilterPlaceholder":"Filter","showSidebarFilter":true,"filterNotFoundMsg":"No member names found containing the query \"{query}\"","maxHistoryItems":15,"homeIcon":"","access":[{"value":"public","label":"Public"},{"value":"protected","label":"Protected"}],"toolbarLinks":[{"id":"fields","label":"Fields"},{"id":"properties","label":"Properties","shortLabel":"Props"},{"id":"methods","label":"Methods"},{"id":"events","label":"Events"}],"sidebar":[{"n":"/","l":"WC Kalkulator","s":""},{"n":"news","l":"News","s":""},{"n":"usermanual","l":"User Manual","c":false,"o":true,"i":[{"n":"about","l":"About the Plugin","s":""},{"n":"installation","l":"Installation","s":""},{"n":"fields","l":"Field Types","s":""},{"n":"calculation-types","l":"Calculation Modes","s":""},{"n":"expression-syntax","l":"Expression Syntax","s":""},{"n":"example-expressions","l":"Formula Examples","s":""},{"n":"usage","l":"Usage","s":""},{"n":"advanced_usage","l":"Advanced Usage","s":""},{"n":"templates","l":"Templates & Layouts","s":""},{"n":"code_snippets","l":"Code Snippets","s":""},{"n":"acf","l":"ACF support","s":""},{"n":"inventory","l":"Stock Management","s":""},{"n":"import_export","l":"Import/Export","s":""},{"n":"uninstall","l":"Uninstallation","s":""},{"n":"videos","l":"Video Tutorials","s":""}],"s":""},{"n":"changelog","l":"CHANGELOG","s":""}],"search":{"mode":0,"minChars":2,"maxResults":20,"placeholder":"Search","hotkeys":["/"],"noResultsFoundMsg":"Sorry, no results found.","recognizeLanguages":true,"languages":[0],"preload":false}}; diff --git a/docs/.retype/resources/js/config.min.js b/docs/.retype/resources/js/config.min.js index af0f829..4fb04cc 100644 --- a/docs/.retype/resources/js/config.min.js +++ b/docs/.retype/resources/js/config.min.js @@ -1 +1 @@ -var __DOCS_CONFIG__={id:"v5kgSSnU2DMVQFD/JIlj3ks8ll545196UrI",key:"KwimltaMyHq+xEMjynzUFrPhynqem7aelmsGeAb44/U.RB9zjyuJ+I8mEKXv5AJELy9genBn6jwi6Tb/iUkxPc9geAUZhC+/L8z1GDtouPLmem6e7WyXwnPqLP4BiG6OeQ.78",base:"/",host:"wckalkulator.com",version:"1.0.0",useRelativePaths:!0,documentName:"index.html",appendDocumentName:!1,trailingSlash:!0,preloadSearch:!1,cacheBustingToken:"2.3.0.713601965991",cacheBustingStrategy:"query",sidebarFilterPlaceholder:"Filter",toolbarFilterPlaceholder:"Filter",showSidebarFilter:!0,filterNotFoundMsg:'No member names found containing the query "{query}"',maxHistoryItems:15,homeIcon:'',access:[{value:"public",label:"Public"},{value:"protected",label:"Protected"}],toolbarLinks:[{id:"fields",label:"Fields"},{id:"properties",label:"Properties",shortLabel:"Props"},{id:"methods",label:"Methods"},{id:"events",label:"Events"}],sidebar:[{n:"/",l:"WC Kalkulator",s:''},{n:"news",l:"News",s:''},{n:"usermanual",l:"User Manual",c:!1,o:!0,i:[{n:"about",l:"About the Plugin",s:''},{n:"installation",l:"Installation",s:''},{n:"fields",l:"Field Types",s:''},{n:"calculation-types",l:"Calculation Modes",s:''},{n:"expression-syntax",l:"Expression Syntax",s:''},{n:"example-expressions",l:"Formula Examples",s:''},{n:"usage",l:"Usage",s:''},{n:"advanced_usage",l:"Advanced Usage",s:''},{n:"templates",l:"Templates & Layouts",s:''},{n:"acf",l:"ACF support",s:''},{n:"inventory",l:"Stock Management",s:''},{n:"import_export",l:"Import/Export",s:''},{n:"uninstall",l:"Uninstallation",s:''},{n:"videos",l:"Video Tutorials",s:''}],s:''},{n:"changelog",l:"CHANGELOG",s:''}],search:{mode:0,minChars:2,maxResults:20,placeholder:"Search",hotkeys:["/"],noResultsFoundMsg:"Sorry, no results found.",recognizeLanguages:!0,languages:[0],preload:!1}}; \ No newline at end of file +var __DOCS_CONFIG__={id:"HDZrj2EOt1n255h/s6RYCMqS9gBb4AcUtDo",key:"4yIegGgDe5CWuZXYGwah1aFR5XY0mvyi59rf0Hx2/Rg.PZrM1V+fBcdAc8+jVYJ6jmwhU1rMVp4lIAKdH+jAvEbvpvvKV9fi5o+M8yzE1+EtLS0t8G76bl1RAx9XJr0UTg.17",base:"/",host:"wckalkulator.com",version:"1.0.0",useRelativePaths:!0,documentName:"index.html",appendDocumentName:!1,trailingSlash:!0,preloadSearch:!1,cacheBustingToken:"2.3.0.717595770947",cacheBustingStrategy:"query",sidebarFilterPlaceholder:"Filter",toolbarFilterPlaceholder:"Filter",showSidebarFilter:!0,filterNotFoundMsg:'No member names found containing the query "{query}"',maxHistoryItems:15,homeIcon:'',access:[{value:"public",label:"Public"},{value:"protected",label:"Protected"}],toolbarLinks:[{id:"fields",label:"Fields"},{id:"properties",label:"Properties",shortLabel:"Props"},{id:"methods",label:"Methods"},{id:"events",label:"Events"}],sidebar:[{n:"/",l:"WC Kalkulator",s:''},{n:"news",l:"News",s:''},{n:"usermanual",l:"User Manual",c:!1,o:!0,i:[{n:"about",l:"About the Plugin",s:''},{n:"installation",l:"Installation",s:''},{n:"fields",l:"Field Types",s:''},{n:"calculation-types",l:"Calculation Modes",s:''},{n:"expression-syntax",l:"Expression Syntax",s:''},{n:"example-expressions",l:"Formula Examples",s:''},{n:"usage",l:"Usage",s:''},{n:"advanced_usage",l:"Advanced Usage",s:''},{n:"templates",l:"Templates & Layouts",s:''},{n:"code_snippets",l:"Code Snippets",s:''},{n:"acf",l:"ACF support",s:''},{n:"inventory",l:"Stock Management",s:''},{n:"import_export",l:"Import/Export",s:''},{n:"uninstall",l:"Uninstallation",s:''},{n:"videos",l:"Video Tutorials",s:''}],s:''},{n:"changelog",l:"CHANGELOG",s:''}],search:{mode:0,minChars:2,maxResults:20,placeholder:"Search",hotkeys:["/"],noResultsFoundMsg:"Sorry, no results found.",recognizeLanguages:!0,languages:[0],preload:!1}}; \ No newline at end of file diff --git a/docs/.retype/resources/js/search.json b/docs/.retype/resources/js/search.json index 22b20ae..e6a3c2a 100644 --- a/docs/.retype/resources/js/search.json +++ b/docs/.retype/resources/js/search.json @@ -1 +1 @@ -[[{"l":"WC Kalkulator"},{"l":"Custom Fields and Price Calculator for WooCommerce","p":["WC Kalkulator (WCK) is a WordPress plugin which extends the WooCommerce to use custom extra fields with products and orders. Extra product fields can be used to calculate product price and save information in order details.","Absolutely FREE plugin with PRO features","23 field types to get customer input","Price calculation based on formula, conditional expression or price add-ons.","This plugin is absolutely FREE with PRO features. It will always be free, so please donate if you like it!","You can sell products by anything. You are not limited to sell only by length, area, volume, etc. You decide how the prices will be calculated."]},{"i":"what-makes-wc-kalkulator-unique-","l":"What makes WC Kalkulator unique ?","p":["When designing the functionality of the plugin, we wanted to obtain software that would be easy to use and highly configurable and suitable for any type of store.","The plugin allows full freedom to define fields and formulas for calculating the price. Some of fields are not used in formulas, but you can use it to get informations from Customer (for example: text, date, date range, color, dropdown, etc.)","The plugin is designed to work with multisite mode. We encourage you to contact us and request new features.","If you appreciate my work - Buy me a Coffee or Donate via PayPal"]},{"i":"22-field-types-all-free","l":"22 Field Types (ALL FREE)"},{"l":"Definitions","p":["Field- is used to get user's input on the woocommerce product page. Custom Field can be used to calculate the price (is used in formula)","Fieldset- store manager can create the fieldset (set of custom product fields) which consists of different Fields. Fieldset must have at least one Field and the expression (formula) to calculate the product price","Expression/Formula- mathematical and/or logical expression using to calculate the woocommerce custom price. The expression can be single-line (one-line) or conditional. Expression is protected and calculated only server-side.","Validation- each Field has specific requirements to be met. Incorrect values make it impossible to calculate the woocommerce custom price and add the product to the cart.","Global Parameters- are numeric variables which can be used in formulas across all fieldsets."]},{"i":"formulaexpression-builder","l":"Formula/Expression Builder","p":["Use field's values as variables to calculate product price. Drag&drop conditional statements."]},{"l":"Price Add-Ons","p":["Use custom fields to make Product Add-Ons. This feature is experimental and will be continued in the next releases."]},{"l":"Display Fields","p":["Assign fields to products, categories or product tags. Include/exclude options. Mass assignment."]},{"l":"Validation","p":["Each field has built-in validation tests on user input. You can define additional conditions."]},{"l":"Protected Formula","p":["The price is calculated server-side only, so the Client can't see exact expression."]},{"l":"Advanced Customization","p":["Field HTML templates can be overloaded in your theme file. Each field has CSS class to set custom styles."]},{"l":"Functions","p":["You can use basic math functions in the formula. Fields such as Multi-checkbox, Date Picker, Date Range Picker has additional functions to get sum, min, max value or get date, days between dates values as number."]},{"l":"Global Parameters","p":["You can define numeric variable across all fieldsets. You can modify all prices by global parameters."]},{"l":"Cart","p":["The customer can edit product options after adding to cart."]},{"l":"Integration with ACF","p":["You can use acf('field_name') function to get ACF field value in custom price formula."]},{"l":"Compatibility","p":["multisite mode is supported","product shortcodes","translation","virtual and variable products are supported","product regular and sale prices are supported","product tags and attributes","use product attributes in formulas","ACF supported"]},{"l":"More Features","p":["ability to edit product fields after from a cart","additional functions for radio group, checkbox group (sum, max, min), range date picker (days between dated)","attach fieldset to: all products/catgories/tags, selected products/categories/tags","customizable HTML code of every field","define single-line expression to calculate the price","define unlimited conditional expressions to calculate the price","define unlimited fieldsets with unlimited fields","every field has built-in validation tests","expression builder","fields are displayed in product page, cart and order details,","global parameters can be defined and used in formula","HMTL template of every field can be overridden in a theme directory","math functions to use in the expression","product shortcodes are supported","regular and sale price are supported","static fields such as HTML, Heading, Paragraph, Hidden, Link, Attachment","supported multisite","supported price filters","supported variable products","the formula is protected and will not be shown to the user- the price is calculated only server-side","the plugin is translatable","the product will be removed from user's cart when shop manager updates the fieldset settings","This plugin is absolutely FREE with PRO features. It will always be free, so please donate if you like it!"]}],[{"l":"News","p":["This plugin is absolutely FREE with PRO features. It will always be free, so please donate if you like it!"]},{"i":"version-140-has-been-released","l":"Version 1.4.0 has been released","p":["Update: 2022-07-18","[x] new formula builder[x] apply filters on td elements in field's templates[x] new assignment type: product attribute[x] toggle button to publish/unpublish fieldsets quickly[x] support for stock management and stock reduction multiplier[x] layouts feature - you can choose one or two column layout"]},{"i":"version-130-has-been-released","l":"Version 1.3.0 has been released","p":["Update: 2022-07-04","Price Add-ons","Image upload field","Use dynamic formula in a static field's contents","Settings page","Strlen() function to get a text length"]},{"i":"version-120-has-been-released","l":"Version 1.2.0 has been released","p":["Update: 2022-06-13","many new fields","static fields","field's built-in modifiers","global parameters","functions in expressions","customer can edit product in the cart"]},{"i":"what-we-are-working-on","l":"What we are working on?","p":["a new field: file upload,","add a price parameter to all fields and use the value in the formula,","add global fields, so the product could have a one fieldset with calculations and global fields.","add priority for fieldsets","allow editing fields in the user's cart,","apply fieldsets to categories,","Apply for a new feature by clicking the link at the top.","assign to all products/categories, except ...","customizable field's template","mass assignment of fieldsets to products,","some bug fixes reported by users","stock management for numeric fields,","Update: 2022-01-21","Update: 2022-02-18","We are working on new features:","We released new version 1.1.0 which gives more flexibility and performance. We have also added new features, blow:"]}],[{"l":"About the Plugin","p":["The plugin extends the Woocommerce store with the ability to add your own fields to the product page. Almost all fields are used in formulas to calculate a custom price for a product. The plugin allows full freedom to define fields and formulas for calculating the price. Some of fields can be used to get informations from Customer (for example: text, date, date range, color, dropdown, etc.)","The plugin is designed to work with multisite mode. We encourage you to contact us and request new features.","If you appreciate my work - Buy me a Coffee or Donate via PayPal"]},{"l":"Definitions","p":["Field- is used to get user's input on the product page. Field can be used to calculate the price (is used in formula)","Fieldset- store manager can create the fieldset which consists of different Fields. Fieldset must have at least one Field and the expression (formula) to calculate the product price","Expression/Formula- mathematical and/or logical expression using to calculate the product price. The expression can be single-line (one-line) or conditional. Expression is protected and calculated only server-side.","Validation- each Field has specific requirements to be met. Incorrect values make it impossible to calculate the price and add the product to the cart.","Global Parameters- are numeric variables which can be used in formulas across all fieldsets."]},{"l":"Requirements","p":["Minimum tested version, but not recommended","Wordpress v.5.0","Woocommerce v.3.5","Maximum tested version","Wordpress v.6.0","Woocommerce v.6.7","Recommended version","We strongly recommend to use most recent versions of Wordpress and Woocommerce. There is no restriction to PHP version, but please note that PHP below 7.4 is marked as end-of-life. We recommend using PHP7.4 and above. PHP7.4 is supported in Wordpress v5.3 and above.","Supported PHP versions PHP compatibility and Wordpress versions"]},{"l":"Dependencies","p":["Symfony ExpressionLanguage Component","jQuery, jQuery UI (built in Wordpress Core)","Math Expression Evaluator by bugwheels94"]},{"l":"Features","p":["ability to edit product fields after from a cart","additional functions for radio group, checkbox group (sum, max, min), range date picker (days between dated)","attach fieldset to: all products/catgories/tags, selected products/categories/tags","customizable HTML code of every field","define single-line expression to calculate the price","define unlimited conditional expressions to calculate the price","define unlimited fieldsets with unlimited fields","dynamic formula in a static field's contents","every field has built-in validation tests","expression builder","fields are displayed in product page, cart and order details,","global parameters can be defined and used in formula","HTML template of every field can be overridden in a theme directory","image upload field (use file size in formula/expression)","math functions to use in the expression","product shortcodes are supported","regular and sale price are supported","static fields such as HTML, Heading, Paragraph, Hidden, Link, Attachment","supported multisite","supported price filters","supported variable products","the formula is protected and will not be shown to the user- the price is calculated only server-side","the plugin is translatable","the product will be removed from user's cart when shop manager updates the fieldset settings","This plugin is absolutely FREE with PRO features. It will always be free, so please donate if you like it!"]},{"l":"Conflict with other plugins","p":["This plugin has been tested only with Wordpress and Woocommerce without additional plugins. Note that there may be a conflict with plugins that modifies the product price and user's cart, or has similar functionality. This section will be updated and conflicts will be resolved.","We know about issue with displaying prices in a cart page. In some themes there's an issue with cart page. Theme should display cart item price instead of product price. The plugin modifies cart items, but not products itself."]}],[{"l":"Installation","p":["Installation process is the same as for other plugins. The plugin does not require configuration, it is ready to use. The plugin creates new post type - Fieldset.","The plugin adds new menu in Products> WCK Fieldsets.","Plugin supports Wordpress Multisite feature. Fieldsets are separate for each site.","This plugin is absolutely FREE with PRO features. It will always be free, so please donate if you like it!"]}],[{"l":"Field Types","p":["The plugin comes with several built-in fields to be used on the product page. Please contact us if you need to add new field types. We are working on the ability to build custom fields as extensions for the plugin. We would like to meet your expectations as much as possible.","Each field has its own parameters, but some parameters are the same for every field. See the list below:","Parameter","Description","Name","Unique field name used in plugin code. It must consist of A-Z, a-z or underscore. For example: product_width, table_height, etc.","Title","Field name showed to the User. For example: Product width, Table height","Hint for Customer","Help message showed in tooltip. For example: Please choose product color from the list.","CSS Class","CSS class applied to the HTML code of the field. You can define additional styles in custom .css files in theme.","Price","If the field is filled in by the customer, the price will be used in the formula. Otherwise the price is 0. This parameter is not present for the: number field and select field.","See Templates section to know how to modify HTML code of any field."]},{"l":"Number","p":["Number Field is the basic field to use in the plugin. It is standard single-line input field, which takes a numeric value and can be used in a formula/expression.","This field is required by default.","Parameter","Description","Min. value","The minimum value of the field","Max. value","The maximum value of the field","Default value","Initial value of the field. This value is loaded into field when user opens the product page."]},{"l":"Select","p":["Select Field is a standard dropdown field. You must define numeric value of options, because this field is used in the formula/expression.","This field is required by default."]},{"l":"Checkbox","p":["Parameter","Description","Default state","Default state of checkbox. Select this option if you want the field to be checked by default"]},{"l":"Color Picker","p":["Color Picker is a standard input text field with jQuery wpColorPicker and IRIS. JS files are bundled in the Wordpress Core.","Parameter","Description","Required","Select this option to make the field required"]},{"l":"Date Picker","p":["Date Picker is a standard input text field with jQuery UI Datepicker. JS files are bundled in the Wordpress Core.","Parameter","Description","Required","Select this option to make the field required.","Disallow past date","Select this option to prohibit the user from selecting a date earlier than today."]},{"l":"Range Date Picker","p":["Range Date Picker includes two Date Picker fields connected with each other.","Parameter","Description","Required","Select this option to make the field required.","Disallow past date","Select this option to prohibit the user from selecting a date earlier than today."]},{"l":"Dropdown","p":["Dropdown field is almost the same as Select field. This field accepts text values.","Parameter","Description","Required","Select this option to make the field required."]},{"l":"Text","p":["Note that defining Min. length greater than zero makes the field required. Even if you have not checked Required option.","Parameter","Description","Required","Select this option to make the field required.","Min. length","The minimum number of characters that the user can enter.","Max. length","The maximum number of characters that the user can enter.","Placeholder","Support text displayed inside the field. This is not the default value for the field. May be used as a guideline for the user."]},{"l":"Textarea","p":["Note that defining Min. length greater than zero makes the field required. Even if you have not checked Required option.","Parameter","Description","Required","Select this option to make the field required.","Min. length","The minimum number of characters that the user can enter.","Max. length","The maximum number of characters that the user can enter.","Placeholder","Support text displayed inside the field. This is not the default value for the field. May be used as a guideline for the user."]},{"l":"E-mail","p":["E-mail field is used to get e-mail address from the Customer input. This field has an e-mail validation test.","Parameter","Description","Required","Select this option to make the field required.","Min. length","The minimum number of characters that the user can enter.","Max. length","The maximum number of characters that the user can enter.","Placeholder","Support text displayed inside the field. This is not the default value for the field. May be used as a guideline for the user."]},{"l":"Radio","p":["Radio field is used to display a group of radio buttons. It has similar funcationality to the Select field, so u can use option's values in the formula/expression.","This field is required by default."]},{"i":"checkbox-group-multi-checkbox","l":"Checkbox Group (Multi Checkbox)","p":["Checkbox Group is used to display a group of checkboxes. It is possible to define selection limit (i.e. customer can choose max 2 options). Multi Checkbox can be used in the expression, for example: is_selected({multi_cb}; 10) checks if user selected the option with value \"10\". You can also use built-in variables {multi_cb:min}(minimal selected value), {multi_cb:max}(maximal selected value), {multi_cb:sum}(sum of selected values)"]},{"l":"Color Swatches","p":["Color Swatches are shown as square thumbnails, which may be selected by a customer. Each options has a numeric value to use in a formula."]},{"l":"Image Swatches","p":["Image Swatches works like Color Swatches, but you can define images instead of colors."]},{"l":"Image Select","p":["Image Select works similar to Image Swatches, but you can define Caption/Title for each image option."]},{"i":"static-html","l":"Static: HTML","p":["Displays content from a HTML code. It is filtered by wp_kses_post. You can use dynamic expression in the contents, for example: {={field_1}*{field_2}/1000}"]},{"i":"static-attachment","l":"Static: Attachment","p":["You can add file/media attachment, to be downloaded by the Customer on product page."]},{"i":"static-heading","l":"Static: Heading","p":["You can add heading h1-h6 in product page"]},{"i":"static-paragraph","l":"Static: Paragraph","p":["You can add text in paragraph tag in product page. You can use dynamic expression in the contents, for example: {={field_1}*{field_2}/1000}"]},{"i":"static-hidden","l":"Static: Hidden","p":["You can add hidden input fields to store predefined values. This field does not accept user input."]},{"i":"static-link","l":"Static: Link","p":["You can add link to any website, file attachment, URL."]},{"l":"Image upload","p":["You can get image file from the customer. Files are saved in customer directory on checkout. Go to Settings Page to set cron jobs invervals. Files are uploaded to the temp directory and will be deleted after time. Files will be kept longer if the customer places an order. Customer files will be deleted after 360 days (default option), but you can set your own interval.","You can use file size [MB] parameter in formulas."]},{"i":"special-formula-value","l":"Special: Formula Value","p":["This field is not showed on the product page. You can write your own formula and save the value in order item meta data. Value of the field may be displayed on user's cart. Hint: you can use {total_price} in your formula to get total product price calculated by WCK plugin.","This plugin is absolutely FREE with PRO features. It will always be free, so please donate if you like it!"]}],[{"l":"Calculation Modes","p":["The Plugin comes with several calculation modes. You can choose one of mentioned below:","OFF- price calculation is turned off. This mode can be use to get user input without changing the product price","Single-line Formula- it is a simple single-line math expression without any logical conditions","Conditional Expression- if the condition if is met, calculate the price according to the assigned formula in = field. You can use multiple conditions. The else formula is used when none of the conditions are met.","Price Add-ons- if the condition if is met, the product price is increased by add value. You can use multiple conditions with all available functions and operators. Both if and add field accepts math and logical expression with variables.","This plugin is absolutely FREE with PRO features. It will always be free, so please donate if you like it!"]}],[{"l":"Expression Syntax"},{"l":"Field names"},{"l":"Arithmetic operators"},{"l":"Comparision Operators"},{"l":"Logical Operators"},{"l":"Math Functions","p":["Use semicolon ; to separate arguments in functions","This plugin is absolutely FREE with PRO features. It will always be free, so please donate if you like it!"]}],[{"l":"Formula Examples","p":["In this section, we cover examples of how to use mathematical formulas and expressions. Some of the examples are based on questions asked by users."]},{"i":"1-how-to-add-value-to-a-price-so-that-it-is-not-multiplied-by-quantity","l":"1. How to add value to a price so that it is not multiplied by quantity?","p":["By default, the unit price of the product is calculated. If the customer wants to buy, for example, 2 pieces of a product, the calculated price is multiplied by 2. What to do if we want to add a certain value once, regardless of the quantity purchased. The solution is to divide value by {quantity}. Let's see the example. {field_1} will by multiplied by quantity, but {field_2} is added once."]},{"i":"2-how-to-add-price-for-every-character-in-text-field-","l":"2. How to add price for every character in text field ?","p":["Let's say we have a text field that has to be between 1 and 10 characters long. The price of the product is to change depending on the number of characters entered.","Solution #1 - price per character is constans","Solution #2 - price is different for each character","Next we have to build the formula. We have {global:price_per_char} array and we need to get single value by index. The index is strlen({my_field:text}) - 1, so complete formula looks like this:","Solution #3 - use Price Add-on mode and write multiple if and add expressions. For example:"]},{"i":"3-each-product-has-width-and-height-user-gives-only-one-dimension-and-the-price-is-proportional-to-the-calculated-area","l":"3. Each product has width and height. User gives only one dimension and the price is proportional to the calculated area.","p":["User has to input width, but the height will be calculated with proportions from product dimensions.","First of all, set the product width and height in the product options, so we will be using {product_width} and {product_height} variables. Video: How to use product dimensions. Create number field and name it width. The height will be calculated as proportional to the product dimensions. Look at this equations:","If the price per unit equals 99,00 USD, the result formula will be:","The same formula with \"height\" field instead of \"width\""]},{"i":"4-how-to-decrease-product-price-for-logged-user-by--1000-usd-or-by--5-","l":"4. How to decrease product price for logged user by -10,00 USD or by -5 %","p":["We have built-in variable {is_user_logged} which takes values 1 or 0. So the result formula will be:","or","You must be careful when decreasing prices, because it may be 0 or negative. To protect this, use max() function."]},{"i":"5-how-to-use-multicheckbox-and-conditional-number-fields-","l":"5. How to use multicheckbox and conditional number fields ?","p":["In this example we define multicheckbox field named {multi_cb} and three number fields {num_a}, {num_b}, {num_c}.","Multicheckbox {multi_cb} has three options:","value: 1, option title: Option A","value: 2, option title: Option B","value: 3, option title: Option C","Each of number fields {num_a}, {num_b}, {num_c} are visible for one of three {multi_cb} options. So, we need to define visibility rules. For example field {num_a} has rule {multi_cb} == 1, which means that this field will be visible if user checked \"Option A\".","Next, we need to go to \"Price Add-ons\" to set formulas. To check if user has selected certain option we use is_selected() function. This is example how to calculate price based on selected option and number field value:","if is_selected( {multi_cb}; 1 ) add {num_a} * 100","if is_selected( {multi_cb}; 2 ) add {num_b} * 250","if is_selected( {multi_cb}; 3 ) add {num_c} * 500"]}],[{"l":"Usage","p":["Here we explain how to work with the plugin. Please read carefully whole page. Feel free to contact us if something is not clear.","WCK YouTube tutorials","Plugin supports Wordpress Multisite feature. Fieldsets are separate for each site."]},{"l":"Adding new Fieldset","p":["Navigate to Products > WCK Fieldsets in Wordpress dashboard.","Click Add Fieldset to create new one. The empty form looks like below:","Fieldset Title is used only in Wordpress dashboard","Assign to- you can assign this fieldset to products, categories or tags. If product has more than one fieldset, you can set priority.","Higher value have higher priority","Product Fields Settings- here you set options for each field.","Add Field- click on the button to add the field of selected type.","Price Calculation- here you define the formula/expression to calculate the product price. You can choose single-line or conditional mode.","Price Filtering- this option changes product prices in catalog. For example you can set the product price to: from 99,99 USD/m2"]},{"l":"Defining fields","p":["Fields can be added, deleted and reordered (drag&drop). Parameters of each field are described in the Field Types section.","If you appreciate my work - Buy me a Coffee or Donate via PayPal","All settings are validated when saving. Fieldset cannot be saved in case of errors.","Select and Dropdown field has ability to add, delete, import options. You can choose the default option for the field.","The example below shows the Select field with two options with a default option. In this case the first option is default."]},{"l":"Defining expressions","p":["You are responsible for preparing the correct formula, mathematically and logically correct. Be careful and always test expressions. The result (the price) has to be a positive number greater than zero. It is validated during the calculation process.","The Expression can be defined as single-line or conditional. You can use Number and Select fields as variables in the formula. You can also use other fields in the expression and predefined variables {product_price}, {product_regular_price}, {quantity}","Some other fields has a price option. For example the text field {my_text} has price 50,00 USD and is not required. If the customer fill in this field the price of the field will be 50,00. But if the customer leaves this field empty the price will be 0,00. It is important if you take {my_text} in your expression.","The \"=\" (equals sign) is the calculated product price. The plugin checks the conditions one by one. If the condition is true, it returns the value of the assigned formula.","First option - single-line expression:","Second option - conditional expression:","Expression builder has simple autocompletion feature. Please click Update list to add fields to autocompletion. When you type the formula, enter \"{\" sign and you see the list of available fields."]},{"l":"Example of conditional expression","p":["First, we have to define two Number or Select fields named width and height. The price of the product can be 100 USD, 200 USD or (300+area* 0.05) USD.","This plugin is absolutely FREE with PRO features. It will always be free, so please donate if you like it!"]}],[{"l":"Advanced Usage"},{"i":"how-to-get-input-text-length-character-count-","l":"How to get input text length (character count) ?","p":["Add text field with name field_name.","You can get input text using {field_name:text}. There's strlen() function which returns text length, so strlen({field_name:text}) returns input characters count."]},{"i":"how-to-use-multi-checkbox-field-","l":"How to use Multi Checkbox field ?","p":["Let's add multi checkbox field named field_mcb. You can use in expression:","{field_mcb:sum}- sum of selected values","{field_mcb:min}- minimal selected value","{field_mcb:max}- maximal selected value"]},{"i":"how-to-use-range-date-picker-field-","l":"How to use Range Date Picker field ?","p":["Range date picker has two input fields - \"from\" and \"to\" dates. Let's add a new field named rdp","{rdp:date_from}- date \"from\" as unix timestamp","{rdp:date_to}- date \"to\" as unix timestamp","{rdp:days}- number of days between two dates (absolute integer)"]},{"i":"how-deal-with-upload-field-","l":"How deal with Upload field ?","p":["Add Upload/Image Upload field named file","{file}- returns field price defined in the \"Price\" option","{file:size}- returns input file size in MB"]},{"i":"products-variables","l":"Product's variables","p":["Expression builder comes with several built-in variables to use in expressions. The value of that parameters is according to the current product and may be different for each product.","{product_price}- current product price (sale or regular)","{product_regular_price}- current product regular price","{product_weight}- current product weight from Product Data > Shipping","{product_width}- current product width from Product Data > Shipping","{product_height}- current product height from Product Data > Shipping","{product_length}- current product length from Product Data > Shipping","{is_user_logged}- 1 if current visitor is logged in, 0 otherwise","This plugin is absolutely FREE with PRO features. It will always be free, so please donate if you like it!"]}],[{"l":"Templates","p":["WC Kalkulator v1.1.0 brings a new approach to modifying the appearance of fields. Every file in view directory can be overriden. Just copy file from the view directory to the themes/your-theme/wc-kalkulator directory and make your modifications.","For example: view/fields/front/text.php should be copied to the /themes/your-theme/wc-kalkulator/fields/front/text.php"]},{"l":"Structure of the view directory","p":["Files","Description","views/fields/front/*.php","Template files for every field rendered on the produt page","views/woocommerce/catalog_price.php","Template for the price filter - prefix, price, suffix.","views/woocommerce/price_block.php","Template for the \"Total\" in the product page","views/woocommerce/product.php","Container for the fields on the product page"]},{"l":"Filters and Hooks","p":["Example filter to change td class=label tag in field template","Example filter to change td class=value tag in field template"]},{"l":"Layouts","p":["Layouts has beed added in v 1.4.0. You can choose default one column layout or switch to two column layout. In this video I show how to use layouts feature.","This plugin is absolutely FREE with PRO features. It will always be free, so please donate if you like it!"]}],[{"l":"Use ACF in formulas","p":["WC Kalkulator 1.5.0 adds support for ACF plugin. You can use ACF fields values in formulas.","Step 1 - Add field in ACF","Step 2 - Use ACF field value in formula"]},{"l":"Usage","p":["Use acf('field_name') to get custom field value of the Product or Fieldset Post Type. If you need to get field value of differend Post Type, use Post ID as second parameter.","If you want to get ACF field value of different Post, just type in Post ID as a second parameter.","For example: use acf('field_name'; 239) to get ACF field value of Post with ID = 239.","Note that arguments are separated by ;","This function returns float value of the field. The acf(name; post_id) is translated to PHP code floatval( get_field( $name, $post_id ) ); where get_field() is function from the ACF Plugin."]}],[{"i":"stock-management--inventory","l":"Stock Management / Inventory","p":["WC Kalkulator v 1.4.0 brings support for stock management and stock quantity reduction. This feature is available for single and variable products. The idea is to reduce a stock quantity by custom value, which is Quantity x Multiplier.","Multiplier is what you can set in Fieldset's Settings. This value can be a numer or math formula. You can use all available fields, operators and functions.","Product must have stock management enabled in product option"]},{"l":"Video Tutorial","p":["In this video I show how to reduce stock quantity by field's value. Stock quantity is reduced by 90 pieces, because field value is 45 and quantity is 2."]}],[{"i":"importexport-fieldsets","l":"Import/Export fieldsets","p":["WC Kalkulator is built on the new Post Type, which is full compatible with core import/export functionality in Wordpress. Navigate to Tools Export to export Fieldset post type to XML file. Use Tools Import to import that file.","You can also use any importer/exporter plugin in Wordpress.","This plugin is absolutely FREE with PRO features. It will always be free, so please donate if you like it!"]}],[{"l":"Uninstallation","p":["The plugin may be deactivated without losing any of its data.","When the plugin is deactivated, it is possible to uninstall it. During the uninstallation process, all data will be deleted from the Wordpress database.","If you want to save all data for later, please export to the XML file.","This plugin is absolutely FREE with PRO features. It will always be free, so please donate if you like it!"]}],[{"l":"Video Tutorials","p":["This plugin is absolutely FREE with PRO features. It will always be free, so please donate if you like it!"]},{"l":"1. Basic Usage"},{"i":"2-how-to-work-with-fieldsets-priority-","l":"2. How to work with fieldset's priority ?"},{"i":"3-how-to-use-date-pickers-","l":"3. How to use Date Pickers ?"},{"i":"4-what-is-global-parameter-and-how-to-use-it-","l":"4. What is Global Parameter and how to use it ?"},{"i":"5-how-to-use-text-input-and-count-text-length-","l":"5. How to use text input and count text length ?"},{"i":"6-how-to-set-custom-field-template-template-overriding-","l":"6. How to set custom field template (template overriding) ?"},{"i":"7-how-to-use-product-dimensions-and-weight-in-formula-","l":"7. How to use product dimensions and weight in formula ?"},{"i":"8-how-to-set-different-price-for-loggedunlogged-users-","l":"8. How to set different price for logged/unlogged users ?"},{"i":"9-how-to-use-arrays-and-json-objects-in-global-parameters-","l":"9. How to use arrays and json objects in Global Parameters ?"},{"i":"10-stock-management-reduction-multiplier","l":"10. Stock Management (Reduction Multiplier)"},{"i":"11-layouts-two-column-layout","l":"11. Layouts, two-column layout"}],[{"l":"CHANGELOG","p":["2022-01-20 v.1.0.0","2022-02-18 v.1.1.0","2022-04-20 v.1.1.1","2022-05-08 v.1.1.2","2022-06-13 v.1.2.0","2022-06-13 v.1.2.1","2022-06-14 v.1.2.2","2022-06-15 v.1.2.3","2022-07-04 v.1.3.0","2022-07-06 v.1.3.1","2022-07-07 v.1.3.2","2022-07-11 v 1.3.3","2022-07-21 v.1.4.0","2022-07-22 v.1.4.1, 1.4.2","2022-07-22 v.1.4.3","2022-07-23 v.1.4.4","2022-07-23 v.1.4.5","2022-07-23 v.1.4.6","2022-08-05 v.1.5.0","add notices","added a price option to all fields","added is_selected() function","Added new fields: email, radio","added support for array and json objects in global parameters","added the priority option to fieldsets","Additional functions for radio group, checkbox group (sum, max, min), range date picker (days between dated)","apply filters on td elements in field's templates","Assign fieldset to product's tags","assign the fieldset to products/categories on the fieldset's edit page","Bug fix","Bug fixed: missing numberposts argument on get_posts()","Bug fixed: str_replace on array","bug fixes","bug fixes in multi checkbox","conditional visibility (set rules to show/hide fields)","conditional visibility support for multi checkbox","cron jobs to keep uploaded files clean","Customer can edit cart item","field's template can be overrided in your theme folder","fieldset post type","fieldset's options (toggle default price blocks)","fixed field builder (js script issue)","fixed issue with price calculation","fixed typo in HTML code for dropdown and select fields","Global parameters can be defined and used in formula","Image upload field added – you can use file size parameter in expressions","Initial release","layouts feature - you can choose one or two column layout","Math functions to use in the expression","more columns on fieldset table","new assignment type: product attribute","new calculation mode - Price Add-ons","new edit page","new field: formula value","New fields: image select, image swatches, color swatches, checkbox group (multicheckbox), HTML, Heading, Paragraph, Hidden, Link, Attachment","new formula builder","new variable to determine if current visitor is logged in","new variables to get product's weight, width, height, length","performance fixes","Settings page added – you can define custom product form selector, you can toggle error messages for admin/manager","strlen() function added to expressions – it returns text length","support for stock management and stock reduction multiplier","text field has new option: pattern (regexp)","toggle button to publish/unpublish fieldsets quickly","upload path settings","you can use formulas in HTML/Paragraph field, for example: {=*/100}"]}]] \ No newline at end of file +[[{"l":"WC Kalkulator"},{"l":"Custom Fields and Price Calculator for WooCommerce","p":["WC Kalkulator (WCK) is a WordPress plugin which extends the WooCommerce to use custom extra fields with products and orders. Extra product fields can be used to calculate product price and save information in order details.","Absolutely FREE plugin with PRO features","23 field types to get customer input","Price calculation based on formula, conditional expression or price add-ons.","This plugin is absolutely FREE with PRO features. It will always be free, so please donate if you like it!","You can sell products by anything. You are not limited to sell only by length, area, volume, etc. You decide how the prices will be calculated."]},{"i":"what-makes-wc-kalkulator-unique-","l":"What makes WC Kalkulator unique ?","p":["When designing the functionality of the plugin, we wanted to obtain software that would be easy to use and highly configurable and suitable for any type of store.","The plugin allows full freedom to define fields and formulas for calculating the price. Some of fields are not used in formulas, but you can use it to get informations from Customer (for example: text, date, date range, color, dropdown, etc.)","The plugin is designed to work with multisite mode. We encourage you to contact us and request new features.","If you appreciate my work - Buy me a Coffee or Donate via PayPal"]},{"i":"22-field-types-all-free","l":"22 Field Types (ALL FREE)"},{"l":"Definitions","p":["Field- is used to get user's input on the woocommerce product page. Custom Field can be used to calculate the price (is used in formula)","Fieldset- store manager can create the fieldset (set of custom product fields) which consists of different Fields. Fieldset must have at least one Field and the expression (formula) to calculate the product price","Expression/Formula- mathematical and/or logical expression using to calculate the woocommerce custom price. The expression can be single-line (one-line) or conditional. Expression is protected and calculated only server-side.","Validation- each Field has specific requirements to be met. Incorrect values make it impossible to calculate the woocommerce custom price and add the product to the cart.","Global Parameters- are numeric variables which can be used in formulas across all fieldsets."]},{"i":"formulaexpression-builder","l":"Formula/Expression Builder","p":["Use field's values as variables to calculate product price. Drag&drop conditional statements."]},{"l":"Price Add-Ons","p":["Use custom fields to make Product Add-Ons. This feature is experimental and will be continued in the next releases."]},{"l":"Display Fields","p":["Assign fields to products, categories or product tags. Include/exclude options. Mass assignment."]},{"l":"Validation","p":["Each field has built-in validation tests on user input. You can define additional conditions."]},{"l":"Protected Formula","p":["The price is calculated server-side only, so the Client can't see exact expression."]},{"l":"Advanced Customization","p":["Field HTML templates can be overloaded in your theme file. Each field has CSS class to set custom styles."]},{"l":"Functions","p":["You can use basic math functions in the formula. Fields such as Multi-checkbox, Date Picker, Date Range Picker has additional functions to get sum, min, max value or get date, days between dates values as number."]},{"l":"Global Parameters","p":["You can define numeric variable across all fieldsets. You can modify all prices by global parameters."]},{"l":"Cart","p":["The customer can edit product options after adding to cart."]},{"l":"Integration with ACF","p":["You can use acf('field_name') function to get ACF field value in custom price formula."]},{"l":"Compatibility","p":["multisite mode is supported","product shortcodes","translation","virtual and variable products are supported","product regular and sale prices are supported","product tags and attributes","use product attributes in formulas","ACF supported"]},{"l":"More Features","p":["ability to edit product fields after from a cart","additional functions for radio group, checkbox group (sum, max, min), range date picker (days between dated)","attach fieldset to: all products/catgories/tags, selected products/categories/tags","customizable HTML code of every field","define single-line expression to calculate the price","define unlimited conditional expressions to calculate the price","define unlimited fieldsets with unlimited fields","every field has built-in validation tests","expression builder","fields are displayed in product page, cart and order details,","global parameters can be defined and used in formula","HMTL template of every field can be overridden in a theme directory","math functions to use in the expression","product shortcodes are supported","regular and sale price are supported","static fields such as HTML, Heading, Paragraph, Hidden, Link, Attachment","supported multisite","supported price filters","supported variable products","the formula is protected and will not be shown to the user- the price is calculated only server-side","the plugin is translatable","the product will be removed from user's cart when shop manager updates the fieldset settings","This plugin is absolutely FREE with PRO features. It will always be free, so please donate if you like it!"]}],[{"l":"News","p":["This plugin is absolutely FREE with PRO features. It will always be free, so please donate if you like it!"]},{"i":"version-140-has-been-released","l":"Version 1.4.0 has been released","p":["Update: 2022-07-18","[x] new formula builder[x] apply filters on td elements in field's templates[x] new assignment type: product attribute[x] toggle button to publish/unpublish fieldsets quickly[x] support for stock management and stock reduction multiplier[x] layouts feature - you can choose one or two column layout"]},{"i":"version-130-has-been-released","l":"Version 1.3.0 has been released","p":["Update: 2022-07-04","Price Add-ons","Image upload field","Use dynamic formula in a static field's contents","Settings page","Strlen() function to get a text length"]},{"i":"version-120-has-been-released","l":"Version 1.2.0 has been released","p":["Update: 2022-06-13","many new fields","static fields","field's built-in modifiers","global parameters","functions in expressions","customer can edit product in the cart"]},{"i":"what-we-are-working-on","l":"What we are working on?","p":["a new field: file upload,","add a price parameter to all fields and use the value in the formula,","add global fields, so the product could have a one fieldset with calculations and global fields.","add priority for fieldsets","allow editing fields in the user's cart,","apply fieldsets to categories,","Apply for a new feature by clicking the link at the top.","assign to all products/categories, except ...","customizable field's template","mass assignment of fieldsets to products,","some bug fixes reported by users","stock management for numeric fields,","Update: 2022-01-21","Update: 2022-02-18","We are working on new features:","We released new version 1.1.0 which gives more flexibility and performance. We have also added new features, blow:"]}],[{"l":"About the Plugin","p":["The plugin extends the Woocommerce store with the ability to add your own fields to the product page. Almost all fields are used in formulas to calculate a custom price for a product. The plugin allows full freedom to define fields and formulas for calculating the price. Some of fields can be used to get informations from Customer (for example: text, date, date range, color, dropdown, etc.)","The plugin is designed to work with multisite mode. We encourage you to contact us and request new features.","If you appreciate my work - Buy me a Coffee or Donate via PayPal"]},{"l":"Definitions","p":["Field- is used to get user's input on the product page. Field can be used to calculate the price (is used in formula)","Fieldset- store manager can create the fieldset which consists of different Fields. Fieldset must have at least one Field and the expression (formula) to calculate the product price","Expression/Formula- mathematical and/or logical expression using to calculate the product price. The expression can be single-line (one-line) or conditional. Expression is protected and calculated only server-side.","Validation- each Field has specific requirements to be met. Incorrect values make it impossible to calculate the price and add the product to the cart.","Global Parameters- are numeric variables which can be used in formulas across all fieldsets."]},{"l":"Requirements","p":["Minimum tested version, but not recommended","Wordpress v.5.0","Woocommerce v.3.5","Maximum tested version","Wordpress v.6.0","Woocommerce v.6.7","Recommended version","We strongly recommend to use most recent versions of Wordpress and Woocommerce. There is no restriction to PHP version, but please note that PHP below 7.4 is marked as end-of-life. We recommend using PHP7.4 and above. PHP7.4 is supported in Wordpress v5.3 and above.","Supported PHP versions PHP compatibility and Wordpress versions"]},{"l":"Dependencies","p":["Symfony ExpressionLanguage Component","jQuery, jQuery UI (built in Wordpress Core)","Math Expression Evaluator by bugwheels94"]},{"l":"Features","p":["ability to edit product fields after from a cart","additional functions for radio group, checkbox group (sum, max, min), range date picker (days between dated)","attach fieldset to: all products/catgories/tags, selected products/categories/tags","customizable HTML code of every field","define single-line expression to calculate the price","define unlimited conditional expressions to calculate the price","define unlimited fieldsets with unlimited fields","dynamic formula in a static field's contents","every field has built-in validation tests","expression builder","fields are displayed in product page, cart and order details,","global parameters can be defined and used in formula","HTML template of every field can be overridden in a theme directory","image upload field (use file size in formula/expression)","math functions to use in the expression","product shortcodes are supported","regular and sale price are supported","static fields such as HTML, Heading, Paragraph, Hidden, Link, Attachment","supported multisite","supported price filters","supported variable products","the formula is protected and will not be shown to the user- the price is calculated only server-side","the plugin is translatable","the product will be removed from user's cart when shop manager updates the fieldset settings","This plugin is absolutely FREE with PRO features. It will always be free, so please donate if you like it!"]},{"l":"Conflict with other plugins","p":["This plugin has been tested only with Wordpress and Woocommerce without additional plugins. Note that there may be a conflict with plugins that modifies the product price and user's cart, or has similar functionality. This section will be updated and conflicts will be resolved.","We know about issue with displaying prices in a cart page. In some themes there's an issue with cart page. Theme should display cart item price instead of product price. The plugin modifies cart items, but not products itself."]}],[{"l":"Installation","p":["Installation process is the same as for other plugins. The plugin does not require configuration, it is ready to use. The plugin creates new post type - Fieldset.","The plugin adds new menu in Products> WCK Fieldsets.","Plugin supports Wordpress Multisite feature. Fieldsets are separate for each site.","This plugin is absolutely FREE with PRO features. It will always be free, so please donate if you like it!"]}],[{"l":"Field Types","p":["The plugin comes with several built-in fields to be used on the product page. Please contact us if you need to add new field types. We are working on the ability to build custom fields as extensions for the plugin. We would like to meet your expectations as much as possible.","Each field has its own parameters, but some parameters are the same for every field. See the list below:","Parameter","Description","Name","Unique field name used in plugin code. It must consist of A-Z, a-z or underscore. For example: product_width, table_height, etc.","Title","Field name showed to the User. For example: Product width, Table height","Hint for Customer","Help message showed in tooltip. For example: Please choose product color from the list.","CSS Class","CSS class applied to the HTML code of the field. You can define additional styles in custom .css files in theme.","Price","If the field is filled in by the customer, the price will be used in the formula. Otherwise the price is 0. This parameter is not present for the: number field and select field.","See Templates section to know how to modify HTML code of any field."]},{"l":"Number","p":["Number Field is the basic field to use in the plugin. It is standard single-line input field, which takes a numeric value and can be used in a formula/expression.","This field is required by default.","Parameter","Description","Min. value","The minimum value of the field","Max. value","The maximum value of the field","Default value","Initial value of the field. This value is loaded into field when user opens the product page."]},{"l":"Select","p":["Select Field is a standard dropdown field. You must define numeric value of options, because this field is used in the formula/expression.","This field is required by default."]},{"l":"Checkbox","p":["Parameter","Description","Default state","Default state of checkbox. Select this option if you want the field to be checked by default"]},{"l":"Color Picker","p":["Color Picker is a standard input text field with jQuery wpColorPicker and IRIS. JS files are bundled in the Wordpress Core.","Parameter","Description","Required","Select this option to make the field required"]},{"l":"Date Picker","p":["Date Picker is a standard input text field with jQuery UI Datepicker. JS files are bundled in the Wordpress Core.","Parameter","Description","Required","Select this option to make the field required.","Disallow past date","Select this option to prohibit the user from selecting a date earlier than today."]},{"l":"Range Date Picker","p":["Range Date Picker includes two Date Picker fields connected with each other.","Parameter","Description","Required","Select this option to make the field required.","Disallow past date","Select this option to prohibit the user from selecting a date earlier than today."]},{"l":"Dropdown","p":["Dropdown field is almost the same as Select field. This field accepts text values.","Parameter","Description","Required","Select this option to make the field required."]},{"l":"Text","p":["Note that defining Min. length greater than zero makes the field required. Even if you have not checked Required option.","Parameter","Description","Required","Select this option to make the field required.","Min. length","The minimum number of characters that the user can enter.","Max. length","The maximum number of characters that the user can enter.","Placeholder","Support text displayed inside the field. This is not the default value for the field. May be used as a guideline for the user."]},{"l":"Textarea","p":["Note that defining Min. length greater than zero makes the field required. Even if you have not checked Required option.","Parameter","Description","Required","Select this option to make the field required.","Min. length","The minimum number of characters that the user can enter.","Max. length","The maximum number of characters that the user can enter.","Placeholder","Support text displayed inside the field. This is not the default value for the field. May be used as a guideline for the user."]},{"l":"E-mail","p":["E-mail field is used to get e-mail address from the Customer input. This field has an e-mail validation test.","Parameter","Description","Required","Select this option to make the field required.","Min. length","The minimum number of characters that the user can enter.","Max. length","The maximum number of characters that the user can enter.","Placeholder","Support text displayed inside the field. This is not the default value for the field. May be used as a guideline for the user."]},{"l":"Radio","p":["Radio field is used to display a group of radio buttons. It has similar funcationality to the Select field, so u can use option's values in the formula/expression.","This field is required by default."]},{"i":"checkbox-group-multi-checkbox","l":"Checkbox Group (Multi Checkbox)","p":["Checkbox Group is used to display a group of checkboxes. It is possible to define selection limit (i.e. customer can choose max 2 options). Multi Checkbox can be used in the expression, for example: is_selected({multi_cb}; 10) checks if user selected the option with value \"10\". You can also use built-in variables {multi_cb:min}(minimal selected value), {multi_cb:max}(maximal selected value), {multi_cb:sum}(sum of selected values)"]},{"l":"Color Swatches","p":["Color Swatches are shown as square thumbnails, which may be selected by a customer. Each options has a numeric value to use in a formula."]},{"l":"Image Swatches","p":["Image Swatches works like Color Swatches, but you can define images instead of colors."]},{"l":"Image Select","p":["Image Select works similar to Image Swatches, but you can define Caption/Title for each image option."]},{"i":"static-html","l":"Static: HTML","p":["Displays content from a HTML code. It is filtered by wp_kses_post. You can use dynamic expression in the contents, for example: {={field_1}*{field_2}/1000}"]},{"i":"static-attachment","l":"Static: Attachment","p":["You can add file/media attachment, to be downloaded by the Customer on product page."]},{"i":"static-heading","l":"Static: Heading","p":["You can add heading h1-h6 in product page"]},{"i":"static-paragraph","l":"Static: Paragraph","p":["You can add text in paragraph tag in product page. You can use dynamic expression in the contents, for example: {={field_1}*{field_2}/1000}"]},{"i":"static-hidden","l":"Static: Hidden","p":["You can add hidden input fields to store predefined values. This field does not accept user input."]},{"i":"static-link","l":"Static: Link","p":["You can add link to any website, file attachment, URL."]},{"l":"Image upload","p":["You can get image file from the customer. Files are saved in customer directory on checkout. Go to Settings Page to set cron jobs invervals. Files are uploaded to the temp directory and will be deleted after time. Files will be kept longer if the customer places an order. Customer files will be deleted after 360 days (default option), but you can set your own interval.","You can use {field_name:size} variable in formulas to get uploaded image file size in [MiB]"]},{"i":"special-formula-value","l":"Special: Formula Value","p":["This field is not showed on the product page. You can write your own formula and save the value in order item meta data. Value of the field may be displayed on user's cart. Hint: you can use {total_price} in your formula to get total product price calculated by WCK plugin.","This plugin is absolutely FREE with PRO features. It will always be free, so please donate if you like it!"]}],[{"l":"Calculation Modes","p":["The Plugin comes with several calculation modes. You can choose one of mentioned below:","OFF- price calculation is turned off. This mode can be use to get user input without changing the product price","Single-line Formula- it is a simple single-line math expression without any logical conditions","Conditional Expression- if the condition if is met, calculate the price according to the assigned formula in = field. You can use multiple conditions. The else formula is used when none of the conditions are met.","Price Add-ons- if the condition if is met, the product price is increased by add value. You can use multiple conditions with all available functions and operators. Both if and add field accepts math and logical expression with variables.","This plugin is absolutely FREE with PRO features. It will always be free, so please donate if you like it!"]}],[{"l":"Expression Syntax"},{"l":"Field names"},{"l":"Arithmetic operators"},{"l":"Comparision Operators"},{"l":"Logical Operators"},{"l":"Math Functions","p":["Use semicolon ; to separate arguments in functions","This plugin is absolutely FREE with PRO features. It will always be free, so please donate if you like it!"]}],[{"l":"Formula Examples","p":["In this section, we cover examples of how to use mathematical formulas and expressions. Some of the examples are based on questions asked by users."]},{"i":"1-how-to-add-value-to-a-price-so-that-it-is-not-multiplied-by-quantity","l":"1. How to add value to a price so that it is not multiplied by quantity?","p":["By default, the unit price of the product is calculated. If the customer wants to buy, for example, 2 pieces of a product, the calculated price is multiplied by 2. What to do if we want to add a certain value once, regardless of the quantity purchased. The solution is to divide value by {quantity}. Let's see the example. {field_1} will by multiplied by quantity, but {field_2} is added once."]},{"i":"2-how-to-add-price-for-every-character-in-text-field-","l":"2. How to add price for every character in text field ?","p":["Let's say we have a text field that has to be between 1 and 10 characters long. The price of the product is to change depending on the number of characters entered.","Solution #1 - price per character is constans","Solution #2 - price is different for each character","Next we have to build the formula. We have {global:price_per_char} array and we need to get single value by index. The index is strlen({my_field:text}) - 1, so complete formula looks like this:","Solution #3 - use Price Add-on mode and write multiple if and add expressions. For example:"]},{"i":"3-each-product-has-width-and-height-user-gives-only-one-dimension-and-the-price-is-proportional-to-the-calculated-area","l":"3. Each product has width and height. User gives only one dimension and the price is proportional to the calculated area.","p":["User has to input width, but the height will be calculated with proportions from product dimensions.","First of all, set the product width and height in the product options, so we will be using {product_width} and {product_height} variables. Video: How to use product dimensions. Create number field and name it width. The height will be calculated as proportional to the product dimensions. Look at this equations:","If the price per unit equals 99,00 USD, the result formula will be:","The same formula with \"height\" field instead of \"width\""]},{"i":"4-how-to-decrease-product-price-for-logged-user-by--1000-usd-or-by--5-","l":"4. How to decrease product price for logged user by -10,00 USD or by -5 %","p":["We have built-in variable {is_user_logged} which takes values 1 or 0. So the result formula will be:","or","You must be careful when decreasing prices, because it may be 0 or negative. To protect this, use max() function."]},{"i":"5-how-to-use-multicheckbox-and-conditional-number-fields-","l":"5. How to use multicheckbox and conditional number fields ?","p":["In this example we define multicheckbox field named {multi_cb} and three number fields {num_a}, {num_b}, {num_c}.","Multicheckbox {multi_cb} has three options:","value: 1, option title: Option A","value: 2, option title: Option B","value: 3, option title: Option C","Each of number fields {num_a}, {num_b}, {num_c} are visible for one of three {multi_cb} options. So, we need to define visibility rules. For example field {num_a} has rule {multi_cb} == 1, which means that this field will be visible if user checked \"Option A\".","Next, we need to go to \"Price Add-ons\" to set formulas. To check if user has selected certain option we use is_selected() function. This is example how to calculate price based on selected option and number field value:","if is_selected( {multi_cb}; 1 ) add {num_a} * 100","if is_selected( {multi_cb}; 2 ) add {num_b} * 250","if is_selected( {multi_cb}; 3 ) add {num_c} * 500"]}],[{"l":"Usage","p":["Here we explain how to work with the plugin. Please read carefully whole page. Feel free to contact us if something is not clear.","WCK YouTube tutorials","Plugin supports Wordpress Multisite feature. Fieldsets are separate for each site."]},{"l":"Adding new Fieldset","p":["Navigate to Products > WCK Fieldsets in Wordpress dashboard.","Click Add Fieldset to create new one. The empty form looks like below:","Fieldset Title is used only in Wordpress dashboard","Assign to- you can assign this fieldset to products, categories or tags. If product has more than one fieldset, you can set priority.","Higher value have higher priority","Product Fields Settings- here you set options for each field.","Add Field- click on the button to add the field of selected type.","Price Calculation- here you define the formula/expression to calculate the product price. You can choose single-line or conditional mode.","Price Filtering- this option changes product prices in catalog. For example you can set the product price to: from 99,99 USD/m2"]},{"l":"Defining fields","p":["Fields can be added, deleted and reordered (drag&drop). Parameters of each field are described in the Field Types section.","If you appreciate my work - Buy me a Coffee or Donate via PayPal","All settings are validated when saving. Fieldset cannot be saved in case of errors.","Select and Dropdown field has ability to add, delete, import options. You can choose the default option for the field.","The example below shows the Select field with two options with a default option. In this case the first option is default."]},{"l":"Defining expressions","p":["You are responsible for preparing the correct formula, mathematically and logically correct. Be careful and always test expressions. The result (the price) has to be a positive number greater than zero. It is validated during the calculation process.","The Expression can be defined as single-line or conditional. You can use Number and Select fields as variables in the formula. You can also use other fields in the expression and predefined variables {product_price}, {product_regular_price}, {quantity}","Some other fields has a price option. For example the text field {my_text} has price 50,00 USD and is not required. If the customer fill in this field the price of the field will be 50,00. But if the customer leaves this field empty the price will be 0,00. It is important if you take {my_text} in your expression.","The \"=\" (equals sign) is the calculated product price. The plugin checks the conditions one by one. If the condition is true, it returns the value of the assigned formula.","First option - single-line expression:","Second option - conditional expression:","Expression builder has simple autocompletion feature. Please click Update list to add fields to autocompletion. When you type the formula, enter \"{\" sign and you see the list of available fields."]},{"l":"Example of conditional expression","p":["First, we have to define two Number or Select fields named width and height. The price of the product can be 100 USD, 200 USD or (300+area* 0.05) USD.","This plugin is absolutely FREE with PRO features. It will always be free, so please donate if you like it!"]}],[{"l":"Advanced Usage"},{"i":"how-to-get-input-text-length-character-count-","l":"How to get input text length (character count) ?","p":["Add text field with name field_name.","You can get input text using {field_name:text}. There's strlen() function which returns text length, so strlen({field_name:text}) returns input characters count."]},{"i":"how-to-use-multi-checkbox-field-","l":"How to use Multi Checkbox field ?","p":["Let's add multi checkbox field named field_mcb. You can use in expression:","{field_mcb:sum}- sum of selected values","{field_mcb:min}- minimal selected value","{field_mcb:max}- maximal selected value"]},{"i":"how-to-use-range-date-picker-field-","l":"How to use Range Date Picker field ?","p":["Range date picker has two input fields - \"from\" and \"to\" dates. Let's add a new field named rdp","{rdp:date_from}- date \"from\" as unix timestamp","{rdp:date_to}- date \"to\" as unix timestamp","{rdp:days}- number of days between two dates (absolute integer)"]},{"i":"how-deal-with-upload-field-","l":"How deal with Upload field ?","p":["Add Upload/Image Upload field named file","{file}- returns field price defined in the \"Price\" option","{file:size}- returns input file size in MB"]},{"i":"products-variables","l":"Product's variables","p":["Expression builder comes with several built-in variables to use in expressions. The value of that parameters is according to the current product and may be different for each product.","{product_price}- current product price (sale or regular)","{product_regular_price}- current product regular price","{product_weight}- current product weight from Product Data > Shipping","{product_width}- current product width from Product Data > Shipping","{product_height}- current product height from Product Data > Shipping","{product_length}- current product length from Product Data > Shipping","{is_user_logged}- 1 if current visitor is logged in, 0 otherwise","This plugin is absolutely FREE with PRO features. It will always be free, so please donate if you like it!"]}],[{"l":"Templates","p":["WC Kalkulator v1.1.0 brings a new approach to modifying the appearance of fields. Every file in view directory can be overriden. Just copy file from the view directory to the themes/your-theme/wc-kalkulator directory and make your modifications.","For example: view/fields/front/text.php should be copied to the /themes/your-theme/wc-kalkulator/fields/front/text.php"]},{"l":"Structure of the view directory","p":["Files","Description","views/fields/front/*.php","Template files for every field rendered on the produt page","views/woocommerce/catalog_price.php","Template for the price filter - prefix, price, suffix.","views/woocommerce/price_block.php","Template for the \"Total\" in the product page","views/woocommerce/product.php","Container for the fields on the product page"]},{"l":"Filters and Hooks","p":["Example filter to change td class=label tag in field template","Example filter to change td class=value tag in field template"]},{"l":"Layouts","p":["Layouts has beed added in v 1.4.0. You can choose default one column layout or switch to two column layout. In this video I show how to use layouts feature.","This plugin is absolutely FREE with PRO features. It will always be free, so please donate if you like it!"]}],[{"l":"Useful Code Snippets","p":["WC Kalculator is an advanced plugin to deal with additional product fields and calculate custom prices. Some functionalities are very specific and require an individual approach. In this section, we will post some useful code snippets for use in your own projects. You can get even more out of this plugin!"]},{"i":"1-product-quick-view-lightbox","l":"1. Product Quick View (lightbox)","p":["Some themes use Quick View to show a lightbox with product details and \"Add to Cart\" button. WCK Plugin can't work in a lightbox, so in this code snippet we will show how to replace ATC button with \"Customize Product\", which will redirect to the product page."]},{"i":"2-move-price-block-to-the-different-position---for-example-above-the-fields","l":"2. Move Price block to the different position - for example above the fields"}],[{"l":"Use ACF in formulas","p":["WC Kalkulator 1.5.0 adds support for ACF plugin. You can use ACF fields values in formulas.","Step 1 - Add field in ACF","Step 2 - Use ACF field value in formula"]},{"l":"Usage","p":["Use acf('field_name') to get custom field value of the Product or Fieldset Post Type. If you need to get field value of differend Post Type, use Post ID as second parameter.","If you want to get ACF field value of different Post, just type in Post ID as a second parameter.","For example: use acf('field_name'; 239) to get ACF field value of Post with ID = 239.","Note that arguments are separated by ;","This function returns float value of the field. The acf(name; post_id) is translated to PHP code floatval( get_field( $name, $post_id ) ); where get_field() is function from the ACF Plugin."]}],[{"i":"stock-management--inventory","l":"Stock Management / Inventory","p":["WC Kalkulator v 1.4.0 brings support for stock management and stock quantity reduction. This feature is available for single and variable products. The idea is to reduce a stock quantity by custom value, which is Quantity x Multiplier.","Multiplier is what you can set in Fieldset's Settings. This value can be a numer or math formula. You can use all available fields, operators and functions.","Product must have stock management enabled in product option"]},{"l":"Video Tutorial","p":["In this video I show how to reduce stock quantity by field's value. Stock quantity is reduced by 90 pieces, because field value is 45 and quantity is 2."]}],[{"i":"importexport-fieldsets","l":"Import/Export fieldsets","p":["WC Kalkulator is built on the new Post Type, which is full compatible with core import/export functionality in Wordpress. Navigate to Tools Export to export Fieldset post type to XML file. Use Tools Import to import that file.","You can also use any importer/exporter plugin in Wordpress.","This plugin is absolutely FREE with PRO features. It will always be free, so please donate if you like it!"]}],[{"l":"Uninstallation","p":["The plugin may be deactivated without losing any of its data.","When the plugin is deactivated, it is possible to uninstall it. During the uninstallation process, all data will be deleted from the Wordpress database.","If you want to save all data for later, please export to the XML file.","This plugin is absolutely FREE with PRO features. It will always be free, so please donate if you like it!"]}],[{"l":"Video Tutorials","p":["This plugin is absolutely FREE with PRO features. It will always be free, so please donate if you like it!"]},{"l":"1. Basic Usage"},{"i":"2-how-to-work-with-fieldsets-priority-","l":"2. How to work with fieldset's priority ?"},{"i":"3-how-to-use-date-pickers-","l":"3. How to use Date Pickers ?"},{"i":"4-what-is-global-parameter-and-how-to-use-it-","l":"4. What is Global Parameter and how to use it ?"},{"i":"5-how-to-use-text-input-and-count-text-length-","l":"5. How to use text input and count text length ?"},{"i":"6-how-to-set-custom-field-template-template-overriding-","l":"6. How to set custom field template (template overriding) ?"},{"i":"7-how-to-use-product-dimensions-and-weight-in-formula-","l":"7. How to use product dimensions and weight in formula ?"},{"i":"8-how-to-set-different-price-for-loggedunlogged-users-","l":"8. How to set different price for logged/unlogged users ?"},{"i":"9-how-to-use-arrays-and-json-objects-in-global-parameters-","l":"9. How to use arrays and json objects in Global Parameters ?"},{"i":"10-stock-management-reduction-multiplier","l":"10. Stock Management (Reduction Multiplier)"},{"i":"11-layouts-two-column-layout","l":"11. Layouts, two-column layout"}],[{"l":"CHANGELOG","p":["2022-01-20 v.1.0.0","2022-02-18 v.1.1.0","2022-04-20 v.1.1.1","2022-05-08 v.1.1.2","2022-06-13 v.1.2.0","2022-06-13 v.1.2.1","2022-06-14 v.1.2.2","2022-06-15 v.1.2.3","2022-07-04 v.1.3.0","2022-07-06 v.1.3.1","2022-07-07 v.1.3.2","2022-07-11 v 1.3.3","2022-07-21 v.1.4.0","2022-07-22 v.1.4.1, 1.4.2","2022-07-22 v.1.4.3","2022-07-23 v.1.4.4","2022-07-23 v.1.4.5","2022-07-23 v.1.4.6","2022-08-05 v.1.5.0","2022-08-16 v.1.5.2, v.1.5.3","2022-08-21 v.1.5.4","2022-09-26 v.1.6.0","2022-09-27 v.1.6.1","add notices","add option to show Price Block before or after \"Add to cart\" button","added a price option to all fields","added is_selected() function","Added new fields: email, radio","added parameters to js dynamic formula in HTML field","added placeholder for select and dropdown fields","added support for array and json objects in global parameters","added support for in HTML field's content (for example: {=} MB)","added the priority option to fieldsets","Additional functions for radio group, checkbox group (sum, max, min), range date picker (days between dated)","apply filters on td elements in field's templates","Assign fieldset to product's tags","assign the fieldset to products/categories on the fieldset's edit page","Bug fix","bug fixed: incorrect value of the image swatch in the cart","Bug fixed: missing numberposts argument on get_posts()","Bug fixed: str_replace on array","bug fixes","bug fixes in multi checkbox","conditional visibility (set rules to show/hide fields)","conditional visibility support for multi checkbox","conditional visibility works with static fields (html, paragraph)","cron jobs to keep uploaded files clean","Customer can edit cart item","display calculated product price in the cart widget (cart popup)","field's template can be overrided in your theme folder","fieldset post type","fieldset's options (toggle default price blocks)","fixed field builder (js script issue)","fixed issue with color picker","fixed issue with price calculation","fixed typo in HTML code for dropdown and select fields","Global parameters can be defined and used in formula","image file upload bug fixes","image upload bug fix","Image upload field added – you can use file size parameter in expressions","Initial release","layouts feature - you can choose one or two column layout","Math functions to use in the expression","more columns on fieldset table","new assignment type: product attribute","new calculation mode - Price Add-ons","new edit page","new field: formula value","New fields: image select, image swatches, color swatches, checkbox group (multicheckbox), HTML, Heading, Paragraph, Hidden, Link, Attachment","new formula builder","new parameter: product_is_on_sale to use in formula","new variable to determine if current visitor is logged in","new variables to get product's weight, width, height, length","option to display text before or after field's title","performance fixes","Settings page added – you can define custom product form selector, you can toggle error messages for admin/manager","strlen() function added to expressions – it returns text length","support for stock management and stock reduction multiplier","text field has new option: pattern (regexp)","toggle button to publish/unpublish fieldsets quickly","upload path settings","v.1.5.5-1.5.7","you can use formulas in HTML/Paragraph field, for example: {=*/100}"]}]] \ No newline at end of file diff --git a/docs/.retype/sitemap.xml.gz b/docs/.retype/sitemap.xml.gz index 08dbefd..7cf90ff 100644 Binary files a/docs/.retype/sitemap.xml.gz and b/docs/.retype/sitemap.xml.gz differ diff --git a/docs/.retype/usermanual/about/index.html b/docs/.retype/usermanual/about/index.html index 6982110..8e6b230 100644 --- a/docs/.retype/usermanual/about/index.html +++ b/docs/.retype/usermanual/about/index.html @@ -3,7 +3,7 @@ - + @@ -30,11 +30,11 @@ - + - + - +
    @@ -51,7 +51,7 @@
    +
    diff --git a/docs/.retype/usermanual/advanced_usage/index.html b/docs/.retype/usermanual/advanced_usage/index.html index e96da90..9783261 100644 --- a/docs/.retype/usermanual/advanced_usage/index.html +++ b/docs/.retype/usermanual/advanced_usage/index.html @@ -3,7 +3,7 @@ - + @@ -30,11 +30,11 @@ - + - + - +
    @@ -51,7 +51,7 @@
    +
    diff --git a/docs/.retype/usermanual/calculation-types/index.html b/docs/.retype/usermanual/calculation-types/index.html index ec0d2c3..a5a3fe1 100644 --- a/docs/.retype/usermanual/calculation-types/index.html +++ b/docs/.retype/usermanual/calculation-types/index.html @@ -3,7 +3,7 @@ - + @@ -30,11 +30,11 @@ - + - + - +
    @@ -51,7 +51,7 @@
    +
    diff --git a/docs/.retype/usermanual/example-expressions/index.html b/docs/.retype/usermanual/example-expressions/index.html index 1938658..da03c08 100644 --- a/docs/.retype/usermanual/example-expressions/index.html +++ b/docs/.retype/usermanual/example-expressions/index.html @@ -3,7 +3,7 @@ - + @@ -30,11 +30,11 @@ - + - + - +
    @@ -51,7 +51,7 @@
    +
    diff --git a/docs/.retype/usermanual/expression-syntax/index.html b/docs/.retype/usermanual/expression-syntax/index.html index b69ed29..2bd3fae 100644 --- a/docs/.retype/usermanual/expression-syntax/index.html +++ b/docs/.retype/usermanual/expression-syntax/index.html @@ -3,7 +3,7 @@ - + @@ -30,11 +30,11 @@ - + - + - +
    @@ -51,7 +51,7 @@
    +
    diff --git a/docs/.retype/usermanual/fields/index.html b/docs/.retype/usermanual/fields/index.html index 7e9e288..01f30ff 100644 --- a/docs/.retype/usermanual/fields/index.html +++ b/docs/.retype/usermanual/fields/index.html @@ -3,7 +3,7 @@ - + @@ -30,12 +30,12 @@ - + - + - - + +
    @@ -52,7 +52,7 @@
    +
    @@ -809,7 +809,7 @@

    -

    You can use file size [MB] parameter in formulas.

    +

    You can use {field_name:size} variable in formulas to get uploaded image file size in [MiB]

    diff --git a/docs/.retype/usermanual/import_export/index.html b/docs/.retype/usermanual/import_export/index.html index 52d7067..66b1386 100644 --- a/docs/.retype/usermanual/import_export/index.html +++ b/docs/.retype/usermanual/import_export/index.html @@ -3,7 +3,7 @@ - + @@ -30,11 +30,11 @@ - + - + - +
    @@ -51,7 +51,7 @@
    +
    diff --git a/docs/.retype/usermanual/installation/index.html b/docs/.retype/usermanual/installation/index.html index 37fd647..dc12bfa 100644 --- a/docs/.retype/usermanual/installation/index.html +++ b/docs/.retype/usermanual/installation/index.html @@ -3,7 +3,7 @@ - + @@ -32,11 +32,11 @@ - + - + - +
    @@ -53,7 +53,7 @@
    +
    diff --git a/docs/.retype/usermanual/templates/index.html b/docs/.retype/usermanual/templates/index.html index 04d00bc..d46fb5c 100644 --- a/docs/.retype/usermanual/templates/index.html +++ b/docs/.retype/usermanual/templates/index.html @@ -3,7 +3,7 @@ - + @@ -30,12 +30,12 @@ - + - + - - + +
    @@ -52,7 +52,7 @@
    +
    @@ -390,10 +390,10 @@
    - + Next - ACF support + Code Snippets diff --git a/docs/.retype/usermanual/uninstall/index.html b/docs/.retype/usermanual/uninstall/index.html index f3eda67..ec7e023 100644 --- a/docs/.retype/usermanual/uninstall/index.html +++ b/docs/.retype/usermanual/uninstall/index.html @@ -3,7 +3,7 @@ - + @@ -30,11 +30,11 @@ - + - + - +
    @@ -51,7 +51,7 @@
    +
    diff --git a/docs/.retype/usermanual/usage/index.html b/docs/.retype/usermanual/usage/index.html index cc0a4c3..bad7e43 100644 --- a/docs/.retype/usermanual/usage/index.html +++ b/docs/.retype/usermanual/usage/index.html @@ -3,7 +3,7 @@ - + @@ -32,11 +32,11 @@ - + - + - +
    @@ -53,7 +53,7 @@
    +
    diff --git a/docs/.retype/usermanual/videos/index.html b/docs/.retype/usermanual/videos/index.html index b1984a8..e6d1972 100644 --- a/docs/.retype/usermanual/videos/index.html +++ b/docs/.retype/usermanual/videos/index.html @@ -3,7 +3,7 @@ - + @@ -30,11 +30,11 @@ - + - + - +
    @@ -51,7 +51,7 @@
    +
    diff --git a/docs/changelog.md b/docs/changelog.md index bea74f5..8568bf9 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -5,6 +5,30 @@ icon: git-branch --- # CHANGELOG +2022-09-27 v.1.6.1 +- fixed issue with color picker + +2022-09-26 v.1.6.0 +- image file upload bug fixes +- conditional visibility works with static fields (html, paragraph) +- added support for {image:size} in HTML field's content (for example: {={image:size}} MB) +- display calculated product price in the cart widget (cart popup) +- new parameter: product_is_on_sale to use in formula +- added parameters to js dynamic formula in HTML field +- added placeholder for select and dropdown fields +- bug fixed: incorrect value of the image swatch in the cart + +v.1.5.5-1.5.7 +- bug fixes + +2022-08-21 v.1.5.4 +- add option to show Price Block before or after "Add to cart" button +- bug fixes + +2022-08-16 v.1.5.2, v.1.5.3 +- image upload bug fix +- option to display text before or after field's title + 2022-08-05 v.1.5.0 - fieldset's options (toggle default price blocks) diff --git a/docs/retype.yml b/docs/retype.yml index 4ebcb99..b6b2e46 100644 --- a/docs/retype.yml +++ b/docs/retype.yml @@ -5,7 +5,7 @@ meta: title: " | Product fields and price calculator" branding: title: WC Kalkulator - label: PRO 1.5 + label: 1.6 links: - text: Buy me a Coffee link: https://www.buymeacoffee.com/piatkowski diff --git a/docs/usermanual/code_snippets.md b/docs/usermanual/code_snippets.md new file mode 100644 index 0000000..e2b7ee5 --- /dev/null +++ b/docs/usermanual/code_snippets.md @@ -0,0 +1,94 @@ +--- +order: -610 +label: "Code Snippets" +icon: file-code +--- + +# Useful Code Snippets + +WC Kalculator is an advanced plugin to deal with additional product fields and calculate custom prices. Some functionalities are very specific and require an individual approach. In this section, we will post some useful code snippets for use in your own projects. You can get even more out of this plugin! + +## 1. Product Quick View (lightbox) + +Some themes use Quick View to show a lightbox with product details and "Add to Cart" button. +WCK Plugin can't work in a lightbox, so in this code snippet we will show how to replace ATC button with "Customize Product", which will redirect to the product page. + +``` # Replace ATC Button with Customize Product Button + + /* + * Code goes to the functions.php in your theme + * In most cases QV's content is returned by some AJAX action + * You can use browser dev tools to get action name and change 'REPLACE_WITH_QUICKVIEW_ACTION' + */ + + if(!function_exists('wck_before_atc')) { + function wck_before_atc() { + if( + wp_doing_ajax() && + isset($_POST['action']) && + $_POST['action'] === 'REPLACE_WITH_QUICKVIEW_ACTION' + ) { + echo ''; // end HTML content + ?> + + Customize Product + + +

    + +

    + 10 and the hook must be wp_enqueue_scripts +add_action( 'wp_enqueue_scripts', 'wck_remove_default_price_block', 20); + +// woocommerce_before_add_to_cart_form - is an example +add_action('woocommerce_before_add_to_cart_form', 'wck_add_custom_price_block'); +``` \ No newline at end of file diff --git a/readme.md b/readme.md index f042da3..db77411 100644 --- a/readme.md +++ b/readme.md @@ -2,7 +2,7 @@ Tags: woocommerce custom fields, woocommerce product price, woocommerce product fields, woocommerce custom price field, woocommerce personalized product, woocommerce custom product fields, product fields, custom product price, price calculation, price formula Requires at least: 5.0 Tested up to: 6.0.1 -Stable tag: 1.5.7 +Stable tag: 1.6.1 Requires PHP: 5.6 License: GNU GPLv2 Donate link: https://www.paypal.com/donate/?hosted_button_id=5DNZK72H5YCBY @@ -149,6 +149,22 @@ You can use `acf('field_name')` function to get ACF field value in custom price Full documentation at: [www.wckalkulator.com](https://wckalkulator.com) == Changelog == +2022-09-27 v.1.6.1 +- fixed issue with color picker + +2022-09-26 v.1.6.0 +- image file upload bug fixes +- conditional visibility works with static fields (html, paragraph) +- added support for {image:size} in HTML field's content (for example: {={image:size}} MB) +- display calculated product price in the cart widget (cart popup) +- new parameter: product_is_on_sale to use in formula +- added parameters to js dynamic formula in HTML field +- added placeholder for select and dropdown fields +- bug fixed: incorrect value of the image swatch in the cart + +v.1.5.5-1.5.7 +- bug fixes + 2022-08-21 v.1.5.4 - add option to show Price Block before or after "Add to cart" button - bug fixes diff --git a/src/Ajax.php b/src/Ajax.php index b9e8e72..e613ecf 100644 --- a/src/Ajax.php +++ b/src/Ajax.php @@ -58,6 +58,8 @@ public static function enqueue_scripts() { $fieldset = FieldsetProduct::getInstance(); if ($fieldset->has_fieldset('current')/* && $fieldset->has_expression('current')*/) { + $fieldset->init(); + $formula_parameters = $fieldset->set_additional_input_variables(true); wp_enqueue_script( 'wck-ajax-script', @@ -76,7 +78,8 @@ public static function enqueue_scripts() '_wck_i18n_required' => __('You should check at least one option.', 'wc-kalkulator'), '_wck_i18n_maxfilesize' => __('This file is too big!', 'wc-kalkulator'), 'form' => Settings::get('form_css_selector'), - '_wck_visibility_rules' => $fieldset->visibility_rules() + '_wck_visibility_rules' => $fieldset->visibility_rules(), + '_wck_additional_parameters' => ($formula_parameters) ) ) . ';' ); diff --git a/src/Cron.php b/src/Cron.php index ccd63e4..3615c85 100644 --- a/src/Cron.php +++ b/src/Cron.php @@ -115,6 +115,10 @@ public static function delete_customer_uploads() //$upload_path = wp_upload_dir()['basedir'] . $customer_dir; $upload_path = Settings::get('upload_customer_data_dir'); + if(!file_exists($upload_path)) { + return; + } + $ext = array('jpg', 'jpeg', 'png', 'gif'); $dir = new \RecursiveDirectoryIterator($upload_path); $files = new \RecursiveIteratorIterator($dir); diff --git a/src/Fields/AbstractField.php b/src/Fields/AbstractField.php index 591043d..8df5951 100644 --- a/src/Fields/AbstractField.php +++ b/src/Fields/AbstractField.php @@ -9,256 +9,242 @@ * * @package WCKalkulator */ -abstract class AbstractField -{ - protected $groups; - - public final function __construct() - { - $required = array("parameters", "data", "default_data", "type", "admin_title", "use_expression", "group"); - - foreach ($required as $property) { - if (!property_exists($this, $property)) - throw new \LogicException(get_class($this) . ' must have a "' . $property . '" property.'); - } - - $this->groups = array( - 'input' => __('Input Fields', 'wc-kalkulator'), - 'select' => __('Select Fields', 'wc-kalkulator'), - 'picker' => __('Picker Fields', 'wc-kalkulator'), - 'upload' => __('Upload Fields', 'wc-kalkulator'), - 'static' => __('Static Fields', 'wc-kalkulator'), - 'special' => __('Special Fields', 'wc-kalkulator'), - 'other' => __('Other Fields', 'wc-kalkulator') - ); - - if (!array_key_exists($this->group, $this->groups)) { - throw new \LogicException(get_class($this) . ' has unknown group property.'); - } - - } - - /** - * @param $data - */ - public function fromArray($data) - { - $this->data = $data; - $this->default_data(); - } - - protected function default_data() - { - $data_keys = array_keys($this->data); - foreach ($this->default_data as $param => $default_value) { - if (!in_array($param, $data_keys)) { - $this->data[$param] = $default_value; - } - } - } - - /** - * @return array - */ - public function prepared_data() - { - return array( - 'type' => $this->type(), - 'title' => $this->data("title"), - 'before_title' => $this->data("before_title"), - 'after_title' => $this->data("after_title"), - 'hint' => $this->html_hint(), - 'name' => "wck[" . $this->data("name") . "]", - 'id' => 'wck_' . $this->data("name"), - 'css_class' => $this->data("css_class"), - 'required' => ($this->is_required() || $this->is_required_when_visible() ? ' required' : ''), // add "required" attribute - 'is_required' => $this->is_required() ? '1' : '0', // is always required - 'show_required_asterisk' => $this->is_required() || $this->is_required_when_visible() - ); - } - - /** - * @return string - */ - public function type() - { - return $this->type; - } - - /** - * @param string $key - * @return array|string|null - */ - public function data($key = '') - { - if ($key === '') { - return $this->data; - } - - if (!empty($this->data[$key])) { - return $this->data[$key]; - } - - return; - } - - /** - * @return string - */ - public function html_hint() - { - if ($this->data("hint") != '') - return ''; - return ''; - } - - /** - * Returns true if the field is always required - * - * @return mixed - */ - public function is_required() - { - return !($this->group() === 'static' || $this->type() === 'formula') && $this->data["required"] === '1'; - } - - /** - * Returns true if the field is required when visible - * - * @return mixed - * @since 1.5.0 - */ - public function is_required_when_visible() - { - return $this->data["required"] === '2'; - } - - /** - * @param $json - */ - public function fromJSON($json) - { - $this->data = json_decode($json, true); - $this->default_data(); - } - - /** - * @return false|string - */ - public function toJSON() - { - return wp_json_encode($this->data); - } - - /** - * @param $type - * @return bool - */ - public function is_type($type) - { - return is_array($type) ? in_array($this->type, $type) : $this->type === $type; - } - - /** - * @param string $param - * @return string - */ - public function render_for_admin($param = '') - { - return View::render('fields/admin', array( - 'admin_fields' => $this->admin_fields(), - 'title' => $this->admin_title(), - 'type' => $this->type(), - 'use_expression' => $this->use_expression() ? 'true' : 'false', - 'group' => $this->group(), - 'show_title' => $this->show_title() - )); - } - - abstract public function admin_fields($param = ''); - - abstract public function order_item_value($value); - - /** - * Checks if we need to hide "Title" field on admin page - * - * @return bool - */ - public function show_title() - { - /** - * If property exists return its value - */ - if (property_exists($this, 'show_title')) { - return $this->show_title; - } - - /** - * If field's group is not static, return true (Title field should be visible) - */ - if ($this->group() !== 'static') { - return true; - } - - /** - * In other case (static group) return false (Title field should be hidden) - */ - return false; - } - - /** - * @return string - */ - public function admin_title() - { - return $this->admin_title; - } - - /** - * @return mixed - */ - public function use_expression() - { - return $this->use_expression; - } - - abstract public function render_for_product($param = ''); - - abstract public function render_for_cart($param = ''); - - abstract public function validate($value); - - /** - * @return mixed - */ - public function group() - { - return $this->group; - } - - public function group_title() - { - return $this->groups[$this->group]; - } - - /** - * @return mixed - */ - public function icon() - { - return $this->icon; - } - - public function enqueue_scripts() - { - } - - /** - * @return array - */ - public function localize_script() - { - return array(); - } +abstract class AbstractField { + protected $groups; + + public final function __construct() { + $required = array( "parameters", "data", "default_data", "type", "admin_title", "use_expression", "group" ); + + foreach ( $required as $property ) { + if ( ! property_exists( $this, $property ) ) { + throw new \LogicException( get_class( $this ) . ' must have a "' . $property . '" property.' ); + } + } + + $this->groups = array( + 'input' => __( 'Input Fields', 'wc-kalkulator' ), + 'select' => __( 'Select Fields', 'wc-kalkulator' ), + 'picker' => __( 'Picker Fields', 'wc-kalkulator' ), + 'upload' => __( 'Upload Fields', 'wc-kalkulator' ), + 'static' => __( 'Static Fields', 'wc-kalkulator' ), + 'special' => __( 'Special Fields', 'wc-kalkulator' ), + 'other' => __( 'Other Fields', 'wc-kalkulator' ) + ); + + if ( ! array_key_exists( $this->group, $this->groups ) ) { + throw new \LogicException( get_class( $this ) . ' has unknown group property.' ); + } + + } + + /** + * @param $data + */ + public function fromArray( $data ) { + $this->data = $data; + $this->default_data(); + } + + protected function default_data() { + $data_keys = array_keys( $this->data ); + foreach ( $this->default_data as $param => $default_value ) { + if ( ! in_array( $param, $data_keys ) ) { + $this->data[ $param ] = $default_value; + } + } + } + + /** + * @return array + */ + public function prepared_data() { + return array( + 'type' => $this->type(), + 'title' => $this->data( "title" ), + 'before_title' => $this->data( "before_title" ), + 'after_title' => $this->data( "after_title" ), + 'hint' => $this->html_hint(), + 'name' => "wck[" . $this->data( "name" ) . "]", + 'id' => 'wck_' . $this->data( "name" ), + 'css_class' => $this->data( "css_class" ), + 'required' => ( $this->is_required() || $this->is_required_when_visible() ? ' required' : '' ), + // add "required" attribute + 'is_required' => $this->is_required() ? '1' : '0', + // is always required + 'show_required_asterisk' => $this->is_required() || $this->is_required_when_visible() + ); + } + + /** + * @return string + */ + public function type() { + return $this->type; + } + + /** + * @param string $key + * + * @return array|string|null + */ + public function data( $key = '' ) { + if ( $key === '' ) { + return $this->data; + } + + if ( ! empty( $this->data[ $key ] ) ) { + return $this->data[ $key ]; + } + + return; + } + + /** + * @return string + */ + public function html_hint() { + if ( $this->data( "hint" ) != '' ) { + return ''; + } + + return ''; + } + + /** + * Returns true if the field is always required + * + * @return mixed + */ + public function is_required() { + return ! ( $this->group() === 'static' || $this->type() === 'formula' ) && $this->data["required"] === '1'; + } + + /** + * Returns true if the field is required when visible + * + * @return mixed + * @since 1.5.0 + */ + public function is_required_when_visible() { + return $this->data["required"] === '2'; + } + + /** + * @param $json + */ + public function fromJSON( $json ) { + $this->data = json_decode( $json, true ); + $this->default_data(); + } + + /** + * @return false|string + */ + public function toJSON() { + return wp_json_encode( $this->data ); + } + + /** + * @param $type + * + * @return bool + */ + public function is_type( $type ) { + return is_array( $type ) ? in_array( $this->type, $type ) : $this->type === $type; + } + + /** + * @param string $param + * + * @return string + */ + public function render_for_admin( $param = '' ) { + return View::render( 'fields/admin', array( + 'admin_fields' => $this->admin_fields(), + 'title' => $this->admin_title(), + 'type' => $this->type(), + 'use_expression' => $this->use_expression() ? 'true' : 'false', + 'group' => $this->group(), + 'show_title' => $this->show_title() + ) ); + } + + abstract public function admin_fields( $param = '' ); + + abstract public function order_item_value( $value ); + + /** + * Checks if we need to hide "Title" field on admin page + * + * @return bool + */ + public function show_title() { + /** + * If property exists return its value + */ + if ( property_exists( $this, 'show_title' ) ) { + return $this->show_title; + } + + /** + * If field's group is not static, return true (Title field should be visible) + */ + if ( $this->group() !== 'static' ) { + return true; + } + + /** + * In other case (static group) return false (Title field should be hidden) + */ + return false; + } + + /** + * @return string + */ + public function admin_title() { + return $this->admin_title; + } + + /** + * @return mixed + */ + public function use_expression() { + return $this->use_expression; + } + + abstract public function render_for_product( $param = '' ); + + abstract public function render_for_cart( $param = '' ); + + abstract public function validate( $value ); + + /** + * @return mixed + */ + public function group() { + return $this->group; + } + + public function group_title() { + return $this->groups[ $this->group ]; + } + + /** + * @return mixed + */ + public function icon() { + return $this->icon; + } + + public function enqueue_scripts() { + } + + /** + * @return array + */ + public function localize_script() { + return array(); + } } \ No newline at end of file diff --git a/src/Fields/AttachmentField.php b/src/Fields/AttachmentField.php index 83aceef..b6e75d0 100644 --- a/src/Fields/AttachmentField.php +++ b/src/Fields/AttachmentField.php @@ -8,59 +8,64 @@ * Class LinkField * @package WCKalkulator */ -class AttachmentField extends HtmlField -{ - protected $parameters = array("type", "name", "content", "title", "target"); - protected $default_data = array("required" => false, "content" => "", "target" => "_blank"); - protected $data; - protected $type = "attachment"; - protected $admin_title; - protected $use_expression = false; - protected $group = "static"; - protected $show_title = true; - - /** - * Output HTML for fields at backend. - * @param $value - * @return string - */ - public function admin_fields($value = '') - { - $this->admin_title = __("File Attachment", "wc-kalkulator"); - return View::render('fields/admin/' . $this->type); - } - - /** - * Output HTML for product page - * @param $value - * @return string - */ - public function render_for_product($value = "") - { - $args = $this->prepared_data(); - $args['content'] = $this->data('content'); - return View::render('fields/front/' . $this->type, $args); - } - - /** - * No need to show hidden field in the user's cart - * @param $value - * @return string - */ - public function render_for_cart($value = '') - { - return; - } - - /** - * No need to validate hidden static field - * @param $value - * @return bool - */ - public function validate($value) - { - return true; - - } - +class AttachmentField extends HtmlField { + protected $parameters = array( "type", "name", "content", "title", "target" ); + protected $default_data = array( "required" => false, "content" => "", "target" => "_blank" ); + protected $data; + protected $type = "attachment"; + protected $admin_title; + protected $use_expression = false; + protected $group = "static"; + protected $show_title = true; + + /** + * Output HTML for fields at backend. + * + * @param $value + * + * @return string + */ + public function admin_fields( $value = '' ) { + $this->admin_title = __( "File Attachment", "wc-kalkulator" ); + + return View::render( 'fields/admin/' . $this->type ); + } + + /** + * Output HTML for product page + * + * @param $value + * + * @return string + */ + public function render_for_product( $value = "" ) { + $args = $this->prepared_data(); + $args['content'] = $this->data( 'content' ); + + return View::render( 'fields/front/' . $this->type, $args ); + } + + /** + * No need to show hidden field in the user's cart + * + * @param $value + * + * @return string + */ + public function render_for_cart( $value = '' ) { + return; + } + + /** + * No need to validate hidden static field + * + * @param $value + * + * @return bool + */ + public function validate( $value ) { + return true; + + } + } \ No newline at end of file diff --git a/src/Fields/CheckboxField.php b/src/Fields/CheckboxField.php index 3bae831..e71a9da 100644 --- a/src/Fields/CheckboxField.php +++ b/src/Fields/CheckboxField.php @@ -8,76 +8,82 @@ * Class CheckboxField * @package WCKalkulator */ -class CheckboxField extends AbstractField -{ - protected $parameters = array("type", "name", "title", "hint", "css_class", "required", "default_state", "price"); - protected $default_data = array("css_class" => "", "required" => false, "default_state" => "", "hint" => ""); - protected $data; - protected $type = "checkbox"; - protected $admin_title; - protected $use_expression = false; - protected $group = "select"; - - /** - * Output HTML for fields at backend. - * @param $value - * @return string - */ - public function admin_fields($value = '') - { - $this->admin_title = __("Checkbox", "wc-kalkulator"); - return View::render('fields/admin/checkbox'); - } - - /** - * Output HTML for product page - * @param $value - * @return string - */ - public function render_for_product($value = 0) - { - $value = (int)$value; - $args = $this->prepared_data(); - $args['value'] = $value === 1; - $args['default_state'] = $this->data["default_state"]; - $args['checked'] = ($value === 1) || ($value === 0 && (int)$this->data["default_state"] === 1); - return View::render('fields/front/checkbox', $args); - } - - /** - * Output HTML for User's cart nad order meta - * @param $value - * @return string - */ - public function render_for_cart($value = 0) - { - $checked = (int)$value === 1; - return View::render('fields/cart', array( - 'title' => $this->data['title'], - 'value' => ($checked ? __('yes', 'wc-kalkulator') : __('no', 'wc-kalkulator')) - )); - } - - /** - * Run all validation tests - * @param $value - * @return bool - */ - public function validate($value) - { - return empty($value) || (int)$value === 1; - } - - /** - * Display value of the field in order line item at backend - * - * @param $value - * @return string - * @since 1.2.0 - */ - public function order_item_value($value) - { - return (int)$value === 1 ? __('yes', 'wc-kalkulator') : __('no', 'wc-kalkulator'); - } - +class CheckboxField extends AbstractField { + protected $parameters = array( "type", "name", "title", "hint", "css_class", "required", "default_state", "price" ); + protected $default_data = array( "css_class" => "", "required" => false, "default_state" => "", "hint" => "" ); + protected $data; + protected $type = "checkbox"; + protected $admin_title; + protected $use_expression = false; + protected $group = "select"; + + /** + * Output HTML for fields at backend. + * + * @param $value + * + * @return string + */ + public function admin_fields( $value = '' ) { + $this->admin_title = __( "Checkbox", "wc-kalkulator" ); + + return View::render( 'fields/admin/checkbox' ); + } + + /** + * Output HTML for product page + * + * @param $value + * + * @return string + */ + public function render_for_product( $value = 0 ) { + $value = (int) $value; + $args = $this->prepared_data(); + $args['value'] = $value === 1; + $args['default_state'] = $this->data["default_state"]; + $args['checked'] = ( $value === 1 ) || ( $value === 0 && (int) $this->data["default_state"] === 1 ); + + return View::render( 'fields/front/checkbox', $args ); + } + + /** + * Output HTML for User's cart nad order meta + * + * @param $value + * + * @return string + */ + public function render_for_cart( $value = 0 ) { + $checked = (int) $value === 1; + + return View::render( 'fields/cart', array( + 'title' => $this->data['title'], + 'value' => ( $checked ? __( 'yes', 'wc-kalkulator' ) : __( 'no', 'wc-kalkulator' ) ) + ) ); + } + + /** + * Run all validation tests + * + * @param $value + * + * @return bool + */ + public function validate( $value ) { + return empty( $value ) || (int) $value === 1; + } + + /** + * Display value of the field in order line item at backend + * + * @param $value + * + * @return string + * @since 1.2.0 + */ + public function order_item_value( $value ) { + return (int) $value === 1 ? __( 'yes', 'wc-kalkulator' ) : __( 'no', 'wc-kalkulator' ); + } + } \ No newline at end of file diff --git a/src/Fields/CheckboxgroupField.php b/src/Fields/CheckboxgroupField.php index 96b8c8e..9d41a74 100644 --- a/src/Fields/CheckboxgroupField.php +++ b/src/Fields/CheckboxgroupField.php @@ -8,108 +8,119 @@ * Class CheckboxgroupField * @package WCKalkulator */ -class CheckboxgroupField extends SelectField -{ - protected $type = "checkboxgroup"; - protected $default_data = array("css_class" => "", "required" => false, "default_value" => "", "hint" => "", "select_limit" => 0); - - /** - * Output HTML for fields at backend. - * @param $value - * @return string - */ - public function admin_fields($value = '') - { - $this->admin_title = __("Multi Checkbox", "wc-kalkulator"); - return View::render('fields/admin/' . $this->type); - } - - /** - * Output HTML for User's cart nad order meta - * @param $value - * @return string - */ - public function render_for_cart($value = '') - { - return View::render('fields/cart', array( - 'title' => $this->data['title'], - 'value' => $this->order_item_value($value) - )); - } - - /** - * Output HTML for product page - * @param $selected_name - * @return string - */ - public function render_for_product($selected_name = "") - { - if ($selected_name === "") { - $selected_name = $this->data["default_value"]; - } - $args = $this->prepared_data(); - $args['value'] = $selected_name; - $args['options_name'] = $this->data['options_name']; - $args['options_title'] = $this->data['options_title']; - $args['select_limit'] = absint($this->data('select_limit')); - - return View::render('fields/front/' . $this->type, $args); - } - - /** - * Run validation tests - * @param $value - * @return bool - */ - public function validate($value) - { - if (!$this->is_required() && empty($value)) { - return true; - } - - if (is_array($value)) { - - if (((int)$this->data('select_limit') > 0 && count($value) > $this->data('select_limit')) || ($this->is_required() && count($value) === 0)) { - return false; - } - - foreach ($value as $val) { - if (!in_array($val, $this->data["options_name"])) { - return false; - } - return true; - } - } - - /** - * if $value is not an array - */ - - if ($this->is_required() && empty($value)) { - return false; - } - - return in_array($value, $this->data["options_name"]); - } - - - /** - * Display value of the field in order line item at backend - * - * @param $value - * @return string - * @since 1.2.0 - */ - public function order_item_value($value) - { - if (is_array($value)) { - foreach ($value as $key => $val) { - $value[$key] = $this->get_option_title($val); - } - $value = join(", ", $value); - } else { - $value = $this->get_option_title($value); - } - return $value; - } +class CheckboxgroupField extends SelectField { + protected $type = "checkboxgroup"; + protected $default_data = array( "css_class" => "", + "required" => false, + "default_value" => "", + "hint" => "", + "select_limit" => 0 + ); + + /** + * Output HTML for fields at backend. + * + * @param $value + * + * @return string + */ + public function admin_fields( $value = '' ) { + $this->admin_title = __( "Multi Checkbox", "wc-kalkulator" ); + + return View::render( 'fields/admin/' . $this->type ); + } + + /** + * Output HTML for User's cart nad order meta + * + * @param $value + * + * @return string + */ + public function render_for_cart( $value = '' ) { + return View::render( 'fields/cart', array( + 'title' => $this->data['title'], + 'value' => $this->order_item_value( $value ) + ) ); + } + + /** + * Output HTML for product page + * + * @param $selected_name + * + * @return string + */ + public function render_for_product( $selected_name = "" ) { + if ( $selected_name === "" ) { + $selected_name = $this->data["default_value"]; + } + $args = $this->prepared_data(); + $args['value'] = $selected_name; + $args['options_name'] = $this->data['options_name']; + $args['options_title'] = $this->data['options_title']; + $args['select_limit'] = absint( $this->data( 'select_limit' ) ); + + return View::render( 'fields/front/' . $this->type, $args ); + } + + /** + * Run validation tests + * + * @param $value + * + * @return bool + */ + public function validate( $value ) { + if ( ! $this->is_required() && empty( $value ) ) { + return true; + } + + if ( is_array( $value ) ) { + + if ( ( (int) $this->data( 'select_limit' ) > 0 && count( $value ) > $this->data( 'select_limit' ) ) || ( $this->is_required() && count( $value ) === 0 ) ) { + return false; + } + + foreach ( $value as $val ) { + if ( ! in_array( $val, $this->data["options_name"] ) ) { + return false; + } + + return true; + } + } + + /** + * if $value is not an array + */ + + if ( $this->is_required() && empty( $value ) ) { + return false; + } + + return in_array( $value, $this->data["options_name"] ); + } + + + /** + * Display value of the field in order line item at backend + * + * @param $value + * + * @return string + * @since 1.2.0 + */ + public function order_item_value( $value ) { + if ( is_array( $value ) ) { + foreach ( $value as $key => $val ) { + $value[ $key ] = $this->get_option_title( $val ); + } + $value = join( ", ", $value ); + } else { + $value = $this->get_option_title( $value ); + } + + return $value; + } } \ No newline at end of file diff --git a/src/Fields/ColorpickerField.php b/src/Fields/ColorpickerField.php index e63c2f9..b3e54dd 100644 --- a/src/Fields/ColorpickerField.php +++ b/src/Fields/ColorpickerField.php @@ -9,80 +9,86 @@ * Class ColorpickerField * @package WCKalkulator */ -class ColorpickerField extends TextField -{ - protected $type = "colorpicker"; - protected $group = "picker"; - - /** - * Called in enqueue_scripts action - */ - public function enqueue_scripts() - { - wp_enqueue_style('wp-color-picker'); - wp_enqueue_script( - 'iris', - admin_url('js/iris.min.js'), - array('jquery-ui-draggable', 'jquery-ui-slider', 'jquery-touch-punch'), - false, - 1 - ); - wp_enqueue_script( - 'wp-color-picker', - admin_url('js/color-picker.min.js'), - array('iris', 'wp-i18n'), - false, - 1 - ); - wp_enqueue_script( - 'wck-color-picker', - Plugin::url() . '/assets/js/colorpicker.min.js', - array('wp-color-picker'), - Plugin::VERSION, - 1 - ); - } - - /** - * Output HTML for fields at backend. - * @param $value - * @return string - */ - public function admin_fields($value = '') - { - $this->admin_title = __("Color Picker", "wc-kalkulator"); - return View::render('fields/admin/colorpicker'); - } - - /** - * Output HTML for product page - * @param $value - * @return string - */ - public function render_for_product($value = "") - { - $args = $args = $this->prepared_data(); - $args['value'] = $value; - return View::render('fields/front/colorpicker', $args); - } - - /** - * Run validation tests - * @param $value - * @return bool - */ - public function validate($value) - { - if(!$this->is_required() && empty($value)) { - return true; - } - if (strlen($value) === 7) { - if ($value[0] === '#') { - $hex = substr($value, 1); - return ctype_xdigit($hex); - } - } - return false; - } - + +class ColorpickerField extends TextField { + protected $type = "colorpicker"; + protected $group = "picker"; + + /** + * Called in enqueue_scripts action + */ + public function enqueue_scripts() { + wp_enqueue_style( 'wp-color-picker' ); + wp_enqueue_script( + 'iris', + admin_url( 'js/iris.min.js' ), + array( 'jquery-ui-draggable', 'jquery-ui-slider', 'jquery-touch-punch' ), + false, + 1 + ); + wp_enqueue_script( + 'wp-color-picker', + admin_url( 'js/color-picker.min.js' ), + array( 'iris', 'wp-i18n' ), + false, + 1 + ); + wp_enqueue_script( + 'wck-color-picker', + Plugin::url() . '/assets/js/colorpicker.min.js', + array( 'wp-color-picker' ), + Plugin::VERSION, + 1 + ); + } + + /** + * Output HTML for fields at backend. + * + * @param $value + * + * @return string + */ + public function admin_fields( $value = '' ) { + $this->admin_title = __( "Color Picker", "wc-kalkulator" ); + + return View::render( 'fields/admin/colorpicker' ); + } + + /** + * Output HTML for product page + * + * @param $value + * + * @return string + */ + public function render_for_product( $value = "" ) { + $args = $args = $this->prepared_data(); + $args['value'] = $value; + + return View::render( 'fields/front/colorpicker', $args ); + } + + /** + * Run validation tests + * + * @param $value + * + * @return bool + */ + public function validate( $value ) { + if ( ! $this->is_required() && empty( $value ) ) { + return true; + } + if ( strlen( $value ) === 7 ) { + if ( $value[0] === '#' ) { + $hex = substr( $value, 1 ); + + return ctype_xdigit( $hex ); + } + } + + return false; + } + } \ No newline at end of file diff --git a/src/Fields/ColorswatchesField.php b/src/Fields/ColorswatchesField.php index 6044bd1..408a8a7 100644 --- a/src/Fields/ColorswatchesField.php +++ b/src/Fields/ColorswatchesField.php @@ -8,68 +8,89 @@ * Class ColorswatchesField * @package WCKalkulator */ -class ColorswatchesField extends SelectField -{ - protected $parameters = array("type", "name", "title", "hint", "options_name", "options_title", "options_image", "css_class", "required", "default_value"); - protected $default_data = array("css_class" => "", "required" => false, "default_value" => "", "hint" => "", "image_size" => 40); - protected $type = "colorswatches"; - - /** - * Output HTML for fields at backend. - * @param $value - * @return string - */ - public function admin_fields($value = '') - { - $this->admin_title = __("Color Swatches", "wc-kalkulator"); - return View::render('fields/admin/' . $this->type); - } - - /** - * Output HTML for product page - * @param $selected_name - * @return string - */ - public function render_for_product($selected_name = "") - { - if ($selected_name === "") { - $selected_name = $this->data["default_value"]; - } - $args = $this->prepared_data(); - $args['value'] = $selected_name; - $args['options_name'] = $this->data['options_name']; - $args['options_title'] = $this->data['options_title']; - $args['size'] = $this->data('image_size'); - - return View::render('fields/front/' . $this->type, $args); - } - - /** - * Output HTML for User's cart nad order meta - * @param $value - * @return string - */ - public function render_for_cart($value = '') - { - $value = $this->get_option_title($value); - - return View::render('fields/cart', array( - 'title' => $this->data['title'], - 'colorswatch' => $value - )); - } - - /** - * Display value of the field in order line item at backend - * - * @param $value - * @return string - * @since 1.2.0 - */ - public function order_item_value($value) - { - $color = $this->get_option_title($value); - return '' . $color . ''; - } +class ColorswatchesField extends SelectField { + protected $parameters = array( + "type", + "name", + "title", + "hint", + "options_name", + "options_title", + "options_image", + "css_class", + "required", + "default_value" + ); + protected $default_data = array( + "css_class" => "", + "required" => false, + "default_value" => "", + "hint" => "", + "image_size" => 40 + ); + protected $type = "colorswatches"; + + /** + * Output HTML for fields at backend. + * + * @param $value + * + * @return string + */ + public function admin_fields( $value = '' ) { + $this->admin_title = __( "Color Swatches", "wc-kalkulator" ); + + return View::render( 'fields/admin/' . $this->type ); + } + + /** + * Output HTML for product page + * + * @param $selected_name + * + * @return string + */ + public function render_for_product( $selected_name = "" ) { + if ( $selected_name === "" ) { + $selected_name = $this->data["default_value"]; + } + $args = $this->prepared_data(); + $args['value'] = $selected_name; + $args['options_name'] = $this->data['options_name']; + $args['options_title'] = $this->data['options_title']; + $args['size'] = $this->data( 'image_size' ); + + return View::render( 'fields/front/' . $this->type, $args ); + } + + /** + * Output HTML for User's cart nad order meta + * + * @param $value + * + * @return string + */ + public function render_for_cart( $value = '' ) { + $value = $this->get_option_title( $value ); + + return View::render( 'fields/cart', array( + 'title' => $this->data['title'], + 'colorswatch' => $value + ) ); + } + + /** + * Display value of the field in order line item at backend + * + * @param $value + * + * @return string + * @since 1.2.0 + */ + public function order_item_value( $value ) { + $color = $this->get_option_title( $value ); + + return '' . $color . ''; + } } \ No newline at end of file diff --git a/src/Fields/DatepickerField.php b/src/Fields/DatepickerField.php index 848476b..ea0f9d0 100644 --- a/src/Fields/DatepickerField.php +++ b/src/Fields/DatepickerField.php @@ -9,123 +9,141 @@ * Class DatepickerField * @package WCKalkulator */ -class DatepickerField extends TextField -{ - protected $parameters = array("type", "name", "title", "hint", "css_class", "required", "disallow_past_date", "price"); - protected $default_data = array("css_class" => "", "required" => false, "disallow_past_date" => false, "hint" => ""); - protected $type = "datepicker"; - protected $group = "picker"; - /** - * Called in enqueue_scripts action - */ - public function enqueue_scripts() - { - wp_enqueue_style( - 'wck-jquery-ui-css', - Plugin::url() . '/assets/css/jquery-ui.min.css' - ); - wp_enqueue_script('jquery-ui-datepicker'); - wp_enqueue_script( - 'wck-date-picker', - Plugin::url() . '/assets/js/datepicker.min.js', - array('jquery-ui-datepicker'), - Plugin::VERSION, - 1 - ); - } - - /** - * @return array - */ - public function localize_script() - { - $options = array( - 'dateFormat' => 'yy-mm-dd', - 'minDate' => $this->data('disallow_past_date') ? '0' : null - ); - - return array( - 'script' => 'wck-date-picker', - 'field_name' => $this->data("name"), - 'options' => $options - ); - } - - /** - * Output HTML for fields at backend. - * @param $value - * @return string - */ - public function admin_fields($value = '') - { - $this->admin_title = __("Date Picker", "wc-kalkulator"); - return View::render('fields/admin/datepicker'); - } - - /** - * Output HTML for product page - * @param $value - * @return string - */ - public function render_for_product($value = "") - { - $args = $this->prepared_data(); - $args['value'] = $value; - $args['disallow_past_date'] = $this->data["disallow_past_date"]; - - return View::render('fields/front/datepicker', $args); - } - - /** - * Run validation tests - * @param $value - * @return bool - */ - public function validate($value) - { - if (!$this->is_required() && empty($value)) { - return true; - } - //yyyy-mm-dd - $is_valid = false; - $date_arr = explode('-', $value); - if (count($date_arr) === 3) { - $year = $date_arr[0]; - $month = $date_arr[1]; - $day = $date_arr[2]; - $is_valid = checkdate($month, $day, $year); - } - if (!$is_valid) { - error_log($this->data("name") . " - date is incorrect " . $value); - } - - if ($is_valid && $this->data("disallow_past_date")) { - try { - $date = new \DateTime($value); - $date->setTime(0, 0, 0); - $now = new \DateTime(); - $now->setTime(0, 0, 0); - } catch(\Exception $e) { - error_log($this->data("name") . " - DateTime exception"); - return false; - } - $is_valid = $date >= $now; - if (!$is_valid) { - error_log($this->data("name") . " - past date is not allowed"); - } - } - return $is_valid; - } - - /** - * Display value of the field in order line item at backend - * - * @param $value - * @return string - * @since 1.2.0 - */ - public function order_item_value($value) - { - return $this->get_option_title($value); - } +class DatepickerField extends TextField { + protected $parameters = array( + "type", + "name", + "title", + "hint", + "css_class", + "required", + "disallow_past_date", + "price" + ); + protected $default_data = array( + "css_class" => "", + "required" => false, + "disallow_past_date" => false, + "hint" => "" + ); + protected $type = "datepicker"; + protected $group = "picker"; + + /** + * Called in enqueue_scripts action + */ + public function enqueue_scripts() { + wp_enqueue_style( + 'wck-jquery-ui-css', + Plugin::url() . '/assets/css/jquery-ui.min.css' + ); + wp_enqueue_script( 'jquery-ui-datepicker' ); + wp_enqueue_script( + 'wck-date-picker', + Plugin::url() . '/assets/js/datepicker.min.js', + array( 'jquery-ui-datepicker' ), + Plugin::VERSION, + 1 + ); + } + + /** + * @return array + */ + public function localize_script() { + $options = array( + 'dateFormat' => 'yy-mm-dd', + 'minDate' => $this->data( 'disallow_past_date' ) ? '0' : null + ); + + return array( + 'script' => 'wck-date-picker', + 'field_name' => $this->data( "name" ), + 'options' => $options + ); + } + + /** + * Output HTML for fields at backend. + * + * @param $value + * + * @return string + */ + public function admin_fields( $value = '' ) { + $this->admin_title = __( "Date Picker", "wc-kalkulator" ); + + return View::render( 'fields/admin/datepicker' ); + } + + /** + * Output HTML for product page + * + * @param $value + * + * @return string + */ + public function render_for_product( $value = "" ) { + $args = $this->prepared_data(); + $args['value'] = $value; + $args['disallow_past_date'] = $this->data["disallow_past_date"]; + + return View::render( 'fields/front/datepicker', $args ); + } + + /** + * Run validation tests + * + * @param $value + * + * @return bool + */ + public function validate( $value ) { + if ( ! $this->is_required() && empty( $value ) ) { + return true; + } + //yyyy-mm-dd + $is_valid = false; + $date_arr = explode( '-', $value ); + if ( count( $date_arr ) === 3 ) { + $year = $date_arr[0]; + $month = $date_arr[1]; + $day = $date_arr[2]; + $is_valid = checkdate( $month, $day, $year ); + } + if ( ! $is_valid ) { + error_log( $this->data( "name" ) . " - date is incorrect " . $value ); + } + + if ( $is_valid && $this->data( "disallow_past_date" ) ) { + try { + $date = new \DateTime( $value ); + $date->setTime( 0, 0, 0 ); + $now = new \DateTime(); + $now->setTime( 0, 0, 0 ); + } catch ( \Exception $e ) { + error_log( $this->data( "name" ) . " - DateTime exception" ); + + return false; + } + $is_valid = $date >= $now; + if ( ! $is_valid ) { + error_log( $this->data( "name" ) . " - past date is not allowed" ); + } + } + + return $is_valid; + } + + /** + * Display value of the field in order line item at backend + * + * @param $value + * + * @return string + * @since 1.2.0 + */ + public function order_item_value( $value ) { + return $this->get_option_title( $value ); + } } \ No newline at end of file diff --git a/src/Fields/DropdownField.php b/src/Fields/DropdownField.php index 1fcee3b..234b9d9 100644 --- a/src/Fields/DropdownField.php +++ b/src/Fields/DropdownField.php @@ -8,81 +8,96 @@ * Class DropdownField * @package WCKalkulator */ -class DropdownField extends AbstractField -{ - protected $parameters = array("type", "name", "title", "hint", "options_title", "css_class", "required", "default_value", "price"); - protected $default_data = array("css_class" => "", "required" => false, "default_value" => "", "hint" => ""); - protected $data; - protected $type = "dropdown"; - protected $admin_title; - protected $use_expression = false; - protected $group = "select"; - - /** - * Output HTML for fields at backend. - * @param $value - * @return string - */ - public function admin_fields($value = '') - { - $this->admin_title = __("Dropdown", "wc-kalkulator"); - return View::render('fields/admin/dropdown'); - } - - /** - * Output HTML for product page - * @param $selected_name - * @return string - */ - public function render_for_product($selected_name = "") - { - if ($selected_name === "") { - $selected_name = $this->data["default_value"]; - } - $args = $this->prepared_data(); - $args['value'] = $selected_name; - $args['options_title'] = $this->data['options_title']; - - return View::render('fields/front/dropdown', $args); - - } - - /** - * Output HTML for User's cart nad order meta - * @param $value - * @return string - */ - public function render_for_cart($value = '') - { - return View::render('fields/cart', array( - 'title' => $this->data['title'], - 'value' => $value - )); - } - - /** - * Run validation tests - * @param $value - * @return bool - */ - public function validate($value) - { - if (!$this->is_required() && empty($value)) { - return true; - } - return in_array($value, $this->data["options_title"]); - } - - /** - * Display value of the field in order line item at backend - * - * @param $value - * @return string - * @since 1.2.0 - */ - public function order_item_value($value) - { - return $value; - } - +class DropdownField extends AbstractField { + protected $parameters = array( + "type", + "name", + "title", + "hint", + "options_title", + "css_class", + "required", + "default_value", + "price" + ); + protected $default_data = array( "css_class" => "", "required" => false, "default_value" => "", "hint" => "" ); + protected $data; + protected $type = "dropdown"; + protected $admin_title; + protected $use_expression = false; + protected $group = "select"; + + /** + * Output HTML for fields at backend. + * + * @param $value + * + * @return string + */ + public function admin_fields( $value = '' ) { + $this->admin_title = __( "Dropdown", "wc-kalkulator" ); + + return View::render( 'fields/admin/dropdown' ); + } + + /** + * Output HTML for product page + * + * @param $selected_name + * + * @return string + */ + public function render_for_product( $selected_name = "" ) { + if ( $selected_name === "" ) { + $selected_name = $this->data["default_value"]; + } + $args = $this->prepared_data(); + $args['value'] = $selected_name; + $args['options_title'] = $this->data['options_title']; + + return View::render( 'fields/front/dropdown', $args ); + + } + + /** + * Output HTML for User's cart nad order meta + * + * @param $value + * + * @return string + */ + public function render_for_cart( $value = '' ) { + return View::render( 'fields/cart', array( + 'title' => $this->data['title'], + 'value' => $value + ) ); + } + + /** + * Run validation tests + * + * @param $value + * + * @return bool + */ + public function validate( $value ) { + if ( ! $this->is_required() && empty( $value ) ) { + return true; + } + + return in_array( $value, $this->data["options_title"] ); + } + + /** + * Display value of the field in order line item at backend + * + * @param $value + * + * @return string + * @since 1.2.0 + */ + public function order_item_value( $value ) { + return $value; + } + } \ No newline at end of file diff --git a/src/Fields/EmailField.php b/src/Fields/EmailField.php index 6820553..1ff2582 100644 --- a/src/Fields/EmailField.php +++ b/src/Fields/EmailField.php @@ -8,48 +8,50 @@ * Class EmailField * @package WCKalkulator */ -class EmailField extends TextField -{ - protected $type = "email"; - protected $group = "input"; - - /** - * @param string $value - * @return string - */ - public function admin_fields($value = '') - { - $html = parent::admin_fields($value); - $this->admin_title = __("E-mail Field", "wc-kalkulator"); - return $html; - } - - /** - * Output HTML for product page - * @param $value - * @return string - */ - public function render_for_product($value = "") - { - $args = $this->prepared_data(); - $args['placeholder'] = esc_html($this->data["default_value"]); - $args['min_length'] = $this->data["min"]; - $args['max_length'] = $this->data["max"]; - $args['value'] = $value; - - return View::render('fields/front/email', $args); - } - - /** - * Run all validation tests - * @param $value - * @return bool - */ - public function validate($value) - { - $is_email_valid = empty($value) ? true : sanitize_email($value); - - return parent::validate($value) && $is_email_valid; - } - +class EmailField extends TextField { + protected $type = "email"; + protected $group = "input"; + + /** + * @param string $value + * + * @return string + */ + public function admin_fields( $value = '' ) { + $html = parent::admin_fields( $value ); + $this->admin_title = __( "E-mail Field", "wc-kalkulator" ); + + return $html; + } + + /** + * Output HTML for product page + * + * @param $value + * + * @return string + */ + public function render_for_product( $value = "" ) { + $args = $this->prepared_data(); + $args['placeholder'] = esc_html( $this->data["default_value"] ); + $args['min_length'] = $this->data["min"]; + $args['max_length'] = $this->data["max"]; + $args['value'] = $value; + + return View::render( 'fields/front/email', $args ); + } + + /** + * Run all validation tests + * + * @param $value + * + * @return bool + */ + public function validate( $value ) { + $is_email_valid = empty( $value ) ? true : sanitize_email( $value ); + + return parent::validate( $value ) && $is_email_valid; + } + } \ No newline at end of file diff --git a/src/Fields/EmptyField.php b/src/Fields/EmptyField.php index 9a6ff7e..3a2d48c 100644 --- a/src/Fields/EmptyField.php +++ b/src/Fields/EmptyField.php @@ -8,69 +8,68 @@ * Class EmptyField * @package WCKalkulator */ -class EmptyField extends AbstractField -{ - protected $parameters = array("type", "name", "content"); - protected $default_data = array("required" => false); - protected $data; - protected $type = "empty"; - protected $admin_title; - protected $use_expression = false; - protected $group = "static"; +class EmptyField extends AbstractField { + protected $parameters = array( "type", "name", "content" ); + protected $default_data = array( "required" => false ); + protected $data; + protected $type = "empty"; + protected $admin_title; + protected $use_expression = false; + protected $group = "static"; - /** - * Output HTML for fields at backend. - * - * @param $value - * @return string - */ - public function admin_fields($value = '') - { - $this->admin_title = __("Empty", "wc-kalkulator"); - return View::render('fields/admin/' . $this->type); - } + /** + * Output HTML for fields at backend. + * + * @param $value + * + * @return string + */ + public function admin_fields( $value = '' ) { + $this->admin_title = __( "Empty", "wc-kalkulator" ); - /** - * Output HTML for product page - * - * @param $value - * @return string - */ - public function render_for_product($value = "") - { - return ''; - } + return View::render( 'fields/admin/' . $this->type ); + } - /** - * No need to show static field in the user's cart - * - * @param $value - * @return string - */ - public function render_for_cart($value = '') - { - return ''; - } + /** + * Output HTML for product page + * + * @param $value + * + * @return string + */ + public function render_for_product( $value = "" ) { + return ''; + } - /** - * No need to validate static field - * - * @param $value - * @return bool - */ - public function validate($value) - { - return true; - } + /** + * No need to show static field in the user's cart + * + * @param $value + * + * @return string + */ + public function render_for_cart( $value = '' ) { + return ''; + } - /** - * No need to display the field in order line item - * - * @param $value - */ - public function order_item_value($value) - { - return; - } + /** + * No need to validate static field + * + * @param $value + * + * @return bool + */ + public function validate( $value ) { + return true; + } + + /** + * No need to display the field in order line item + * + * @param $value + */ + public function order_item_value( $value ) { + return; + } } \ No newline at end of file diff --git a/src/Fields/FileuploadField.php b/src/Fields/FileuploadField.php index f9f99d5..27816bc 100644 --- a/src/Fields/FileuploadField.php +++ b/src/Fields/FileuploadField.php @@ -5,97 +5,185 @@ use WCKalkulator\View; /** - * - * - * - * !!!!! This class is not finished yet !!!! - * - * - * - * - * - * Class FileuploadFiled + * Class FileuploadField * @package WCKalkulator */ -class FileuploadField extends AbstractField -{ - protected $parameters = array("type", "name", "title", "hint", "css_class", "required", "max_file_count", "max_file_size", "allowed_extensions"); - protected $default_data = array("css_class" => "", "required" => false, "default_value" => "", "hint" => ""); - protected $data; - protected $type = "fileupload"; - protected $admin_title; - protected $use_expression = false; - protected $group = "upload"; - - /** - * Output HTML for fields at backend. - * @param $value - * @return string - */ - public function admin_fields($value = '') - { - $this->admin_title = __("File Upload", "wc-kalkulator"); - return View::render('fields/admin/fileupload'); - } - - /** - * Output HTML for product page - * @param $value - * @return string - */ - public function render_for_product($value = "") - { - $args = $this->prepared_data(); - $args['max_file_count'] = $this->data('max_file_count'); - $args['max_file_size'] = $this->data('max_file_size'); - $args['allowed_extensions'] = $this->data('allowed_extensions'); - return View::render('fields/front/fileupload', $args); - } - - /** - * Output HTML for User's cart nad order meta - * @param $value - * @return string - */ - public function render_for_cart($value = '') - { - return View::render('fields/cart', array( - 'title' => $this->data['title'], - 'value' => $value - )); - } - - /** - * Run all validation tests - * @param $value - * @return bool - */ - public function validate($value) - { - if(!$this->is_required() && empty($value)) { - return true; - } - - $is_required_and_nonempty = true; - if ($this->data['required']) { - if (empty($value) || $value === "") { - $is_required_and_nonempty = false; - } - } - - return $is_required_and_nonempty; - } - - /** - * Display value of the field in order line item at backend - * - * @param $value - * @return string - * @since 1.2.0 - */ - public function order_item_value($value) - { - return $value; - } - +class FileuploadField extends AbstractField { + protected $parameters = array( + "type", + "name", + "title", + "hint", + "css_class", + "required", + "max_file_size", + "allowed_extensions" + ); + protected $default_data = array( "css_class" => "", "required" => false, "default_value" => "", "hint" => "" ); + protected $data; + protected $type = "fileupload"; + protected $admin_title; + protected $use_expression = true; + protected $group = "upload"; + protected $mimes = array( + "pdf" => "application/pdf", + "jpg" => "image/jpeg", + "jpeg" => "image/jpeg", + "png" => "image/png", + "gif" => "image/gif" + ); + protected $ext = array( "pdf", "jpg", "jpeg", "png", "gif" ); + + /** + * Output HTML for fields at backend. + * + * @param $value + * + * @return string + */ + public function admin_fields( $value = '' ) { + $this->admin_title = __( "File Upload", "wc-kalkulator" ); + + return View::render( 'fields/admin/' . $this->type ); + } + + /** + * Output HTML for product page + * + * @param $value + * + * @return string + */ + public function render_for_product( $value = "" ) { + $args = $this->prepared_data(); + $args['max_file_size'] = $this->data( 'max_file_size' ); + if ( ! empty( $this->data( 'allowed_extensions' ) ) ) { + $args['allowed_extensions'] = $this->data( 'allowed_extensions' ); + $args['accept'] = '.' . str_replace( '|', ', .', $this->data( 'allowed_extensions' ) ); + } else { + $args['allowed_extensions'] = 'pdf|jpg|jpeg|png|gif'; + $args['accept'] = '.pdf, .jpg, .jpeg, .png, .gif'; + } + + return View::render( 'fields/front/' . $this->type, $args ); + } + + /** + * Output HTML for User's cart nad order meta + * + * @param $file + * + * @return string + */ + public function render_for_cart( $file = '' ) { + if ( is_array( $file ) ) { + return View::render( 'fields/cart', array( + 'title' => $this->data['title'], + 'value' => esc_html( $file['original_name'] ) . ' (' . round( $file['size'] / 1000000, 2 ) . ' MB)' + ) ); + } + } + + /** + * Run all validation tests + * + * @param $value + * + * @return bool + */ + public function validate( $value ) { + if ( ! $this->is_required() && empty( $value ) ) { + return true; + } + + if ( $this->data['required'] && empty( $value ) ) { + return false; + } + + if ( is_array( $value ) ) { + if ( is_uploaded_file( $value['tmp_name'] ) ) { + $allowed_size = $this->data( 'max_file_size' ) * 1000000; //Bytes + $allowed_ext = array(); + + foreach ( $this->ext as $ext ) { + if ( strpos( $this->data( 'allowed_extensions' ), $ext ) !== false ) { + $allowed_ext[] = $ext; + } + } + + if ( empty( $allowed_ext ) ) { + $allowed_ext = $this->ext; + } + + $mimes = array(); + + foreach ( $allowed_ext as $ext ) { + $mimes[ $ext ] = $this->mimes[ $ext ]; + } + + if ( $value['size'] > 0 && $value['size'] <= $allowed_size && filesize( $value['tmp_name'] ) <= $allowed_size ) { + $fileinfo = wp_check_filetype_and_ext( $value['tmp_name'], $value['original_name'], $mimes ); + if ( $fileinfo['type'] !== false && in_array( $fileinfo['type'], + $mimes ) && in_array( $fileinfo['ext'], $allowed_ext ) ) { + return true; + } + } + } + } + + return false; + } + + /** + * Display value of the field in order line item at backend + * + * @param $value + * + * @return string + * @since 1.2.0 + */ + public function order_item_value( $value ) { + return $value; + } + + /** + * Handles file upload. Copy file from temp location to the customer directory + * + * @param $data + * + * @return bool + * @since 1.3.0 + */ + public function upload( $data ) { + if ( ! file_exists( $data['upload_tmp'] ) ) { + return false; + } + + $dir = dirname( $data['upload_path'] ); + if ( ! file_exists( $dir ) ) { + mkdir( $dir, 0755, true ); + file_put_contents( $dir . '/index.html', '' ); + } + + return rename( $data['upload_tmp'], $data['upload_path'] ); + } + + /** + * Handles file upload from POST to the temp directory + * + * @param $data + * + * @return bool + * @since 1.3.0 + */ + public function upload_temp( $data ) { + if ( move_uploaded_file( $data['tmp_name'], $data['upload_tmp'] ) ) { + chmod( $data['upload_tmp'], 0644 ); + + return true; + } + + return false; + } + } \ No newline at end of file diff --git a/src/Fields/FormulaField.php b/src/Fields/FormulaField.php index cd1dc94..0915992 100644 --- a/src/Fields/FormulaField.php +++ b/src/Fields/FormulaField.php @@ -8,62 +8,67 @@ * Class FormulaField * @package WCKalkulator */ -class FormulaField extends HtmlField -{ - protected $parameters = array("type", "name", "content", "title"); - protected $default_data = array("required" => false, "content" => ""); - protected $data; - protected $type = "formula"; - protected $admin_title; - protected $use_expression = false; - protected $group = "special"; - protected $show_title = true; +class FormulaField extends HtmlField { + protected $parameters = array( "type", "name", "content", "title" ); + protected $default_data = array( "required" => false, "content" => "" ); + protected $data; + protected $type = "formula"; + protected $admin_title; + protected $use_expression = false; + protected $group = "special"; + protected $show_title = true; - /** - * Output HTML for fields at backend. - * @param $value - * @return string - */ - public function admin_fields($value = '') - { - $this->admin_title = __("Value of Formula", "wc-kalkulator"); - return View::render('fields/admin/' . $this->type); - } + /** + * Output HTML for fields at backend. + * + * @param $value + * + * @return string + */ + public function admin_fields( $value = '' ) { + $this->admin_title = __( "Value of Formula", "wc-kalkulator" ); - /** - * Output HTML for product page - * @param $value - * @return string - */ - public function render_for_product($value = "") - { - return ""; - } + return View::render( 'fields/admin/' . $this->type ); + } - /** - * No need to show hidden field in the user's cart - * @param $value - * @return string - */ - public function render_for_cart($value = '') - { - if($this->data('display_on_user_cart') === '1') { - return View::render('fields/cart', array( - 'title' => $this->data['title'], - 'value' => $value - )); - } - return ""; - } + /** + * Output HTML for product page + * + * @param $value + * + * @return string + */ + public function render_for_product( $value = "" ) { + return ""; + } - /** - * No need to validate - * @param $value - * @return bool - */ - public function validate($value) - { - return true; - } + /** + * No need to show hidden field in the user's cart + * + * @param $value + * + * @return string + */ + public function render_for_cart( $value = '' ) { + if ( $this->data( 'display_on_user_cart' ) === '1' ) { + return View::render( 'fields/cart', array( + 'title' => $this->data['title'], + 'value' => $value + ) ); + } + + return ""; + } + + /** + * No need to validate + * + * @param $value + * + * @return bool + */ + public function validate( $value ) { + return true; + } } \ No newline at end of file diff --git a/src/Fields/HeadingField.php b/src/Fields/HeadingField.php index cbfa5a8..f5f29a1 100644 --- a/src/Fields/HeadingField.php +++ b/src/Fields/HeadingField.php @@ -8,37 +8,40 @@ * Class StaticHtmlField * @package WCKalkulator */ -class HeadingField extends HtmlField -{ - protected $parameters = array("type", "name", "content", "level"); - protected $default_data = array("required" => false, "content" => "", "level" => "1"); - protected $data; - protected $type = "heading"; - protected $admin_title; - protected $use_expression = false; - protected $group = "static"; - - /** - * Output HTML for fields at backend. - * @param $value - * @return string - */ - public function admin_fields($value = '') - { - $this->admin_title = __("Heading", "wc-kalkulator"); - return View::render('fields/admin/' . $this->type); - } - - /** - * Output HTML for product page - * @param $value - * @return string - */ - public function render_for_product($value = "") - { - return View::render('fields/front/' . $this->type, array( - 'content' => $this->data('content'), - 'level' => $this->data('level') - )); - } +class HeadingField extends HtmlField { + protected $parameters = array( "type", "name", "content", "level" ); + protected $default_data = array( "required" => false, "content" => "", "level" => "1" ); + protected $data; + protected $type = "heading"; + protected $admin_title; + protected $use_expression = false; + protected $group = "static"; + + /** + * Output HTML for fields at backend. + * + * @param $value + * + * @return string + */ + public function admin_fields( $value = '' ) { + $this->admin_title = __( "Heading", "wc-kalkulator" ); + + return View::render( 'fields/admin/' . $this->type ); + } + + /** + * Output HTML for product page + * + * @param $value + * + * @return string + */ + public function render_for_product( $value = "" ) { + return View::render( 'fields/front/' . $this->type, array( + 'name' => $this->data( 'name' ), + 'content' => $this->data( 'content' ), + 'level' => $this->data( 'level' ) + ) ); + } } \ No newline at end of file diff --git a/src/Fields/HiddenField.php b/src/Fields/HiddenField.php index 08468e9..92438a7 100644 --- a/src/Fields/HiddenField.php +++ b/src/Fields/HiddenField.php @@ -8,59 +8,64 @@ * Class HiddenField * @package WCKalkulator */ -class HiddenField extends HtmlField -{ - protected $parameters = array("type", "name", "content", "title"); - protected $default_data = array("required" => false, "content" => ""); - protected $data; - protected $type = "hidden"; - protected $admin_title; - protected $use_expression = false; - protected $group = "static"; - protected $show_title = true; - - /** - * Output HTML for fields at backend. - * @param $value - * @return string - */ - public function admin_fields($value = '') - { - $this->admin_title = __("Hidden", "wc-kalkulator"); - return View::render('fields/admin/' . $this->type); - } - - /** - * Output HTML for product page - * @param $value - * @return string - */ - public function render_for_product($value = "") - { - $args = $this->prepared_data(); - $args['content'] = $this->data('content'); - return View::render('fields/front/' . $this->type, $args); - } - - /** - * No need to show hidden field in the user's cart - * @param $value - * @return string - */ - public function render_for_cart($value = '') - { - return; - } - - /** - * No need to validate hidden static field - * @param $value - * @return bool - */ - public function validate($value) - { - return stripslashes($value) === ($this->data('title') . ': '. $this->data('content')); +class HiddenField extends HtmlField { + protected $parameters = array( "type", "name", "content", "title" ); + protected $default_data = array( "required" => false, "content" => "" ); + protected $data; + protected $type = "hidden"; + protected $admin_title; + protected $use_expression = false; + protected $group = "static"; + protected $show_title = true; + + /** + * Output HTML for fields at backend. + * + * @param $value + * + * @return string + */ + public function admin_fields( $value = '' ) { + $this->admin_title = __( "Hidden", "wc-kalkulator" ); + + return View::render( 'fields/admin/' . $this->type ); + } + + /** + * Output HTML for product page + * + * @param $value + * + * @return string + */ + public function render_for_product( $value = "" ) { + $args = $this->prepared_data(); + $args['content'] = $this->data( 'content' ); + + return View::render( 'fields/front/' . $this->type, $args ); + } + + /** + * No need to show hidden field in the user's cart + * + * @param $value + * + * @return string + */ + public function render_for_cart( $value = '' ) { + return; + } + + /** + * No need to validate hidden static field + * + * @param $value + * + * @return bool + */ + public function validate( $value ) { + return stripslashes( $value ) === ( $this->data( 'title' ) . ': ' . $this->data( 'content' ) ); + + } - } - } \ No newline at end of file diff --git a/src/Fields/HtmlField.php b/src/Fields/HtmlField.php index 092558d..7a8ab56 100644 --- a/src/Fields/HtmlField.php +++ b/src/Fields/HtmlField.php @@ -8,76 +8,78 @@ * Class HtmlField * @package WCKalkulator */ -class HtmlField extends AbstractField -{ - protected $parameters = array("type", "name", "content"); - protected $default_data = array("required" => false, "content"); - protected $data; - protected $type = "html"; - protected $admin_title; - protected $use_expression = false; - protected $group = "static"; +class HtmlField extends AbstractField { + protected $parameters = array( "type", "name", "content" ); + protected $default_data = array( "required" => false, "content" ); + protected $data; + protected $type = "html"; + protected $admin_title; + protected $use_expression = false; + protected $group = "static"; - /** - * Output HTML for fields at backend. - * - * @param $value - * @return string - */ - public function admin_fields($value = '') - { - $this->admin_title = __("HTML", "wc-kalkulator"); - return View::render('fields/admin/' . $this->type); - } + /** + * Output HTML for fields at backend. + * + * @param $value + * + * @return string + */ + public function admin_fields( $value = '' ) { + $this->admin_title = __( "HTML", "wc-kalkulator" ); - /** - * Output HTML for product page - * - * @param $value - * @return string - */ - public function render_for_product($value = "") - { - $content = $this->data('content'); - preg_match('/{=(.+)}/m', $content, $matches); - if(!empty($matches)) { - $content = str_replace($matches[0], '', $content); - } - return View::render('fields/front/' . $this->type, array( - 'content' => $content - )); - } + return View::render( 'fields/admin/' . $this->type ); + } - /** - * No need to show static field in the user's cart - * - * @param $value - * @return string - */ - public function render_for_cart($value = '') - { - return; - } + /** + * Output HTML for product page + * + * @param $value + * + * @return string + */ + public function render_for_product( $value = "" ) { + $content = $this->data( 'content' ); + preg_match( '/{=(.+)}/m', $content, $matches ); + if ( ! empty( $matches ) ) { + $content = str_replace( $matches[0], '', + $content ); + } + + return View::render( 'fields/front/' . $this->type, array( + 'name' => $this->data( 'name' ), + 'content' => $content + ) ); + } + + /** + * No need to show static field in the user's cart + * + * @param $value + * + * @return string + */ + public function render_for_cart( $value = '' ) { + return; + } + + /** + * No need to validate static field + * + * @param $value + * + * @return bool + */ + public function validate( $value ) { + return true; + } + + /** + * No need to display the field in order line item + * + * @param $value + */ + public function order_item_value( $value ) { + return; + } - /** - * No need to validate static field - * - * @param $value - * @return bool - */ - public function validate($value) - { - return true; - } - - /** - * No need to display the field in order line item - * - * @param $value - */ - public function order_item_value($value) - { - return; - } - } \ No newline at end of file diff --git a/src/Fields/ImageselectField.php b/src/Fields/ImageselectField.php index ca8e27e..447ea9c 100644 --- a/src/Fields/ImageselectField.php +++ b/src/Fields/ImageselectField.php @@ -8,82 +8,102 @@ * Class ImageselectField * @package WCKalkulator */ -class ImageselectField extends SelectField -{ - protected $parameters = array("type", "name", "title", "hint", "options_name", "options_title", "options_image", "css_class", "required", "default_value"); - protected $default_data = array("css_class" => "", "required" => false, "default_value" => "", "hint" => "", "image_size" => 60); - protected $type = "imageselect"; - - /** - * Output HTML for fields at backend. - * @param $value - * @return string - */ - public function admin_fields($value = '') - { - $this->admin_title = __("Select Image", "wc-kalkulator"); - return View::render('fields/admin/' . $this->type); - } - - /** - * Output HTML for User's cart nad order meta - * @param $value - * @return string - */ - public function render_for_cart($value = '') - { - $value = $this->get_option_image($value); - - return View::render('fields/cart', array( - 'title' => $this->data['title'], - 'value' => $this->get_option_title($value), - 'image' => $value, - - )); - } - - /** - * Return option title based on option value from select field - * @param $value - * @return string - */ - public function get_option_image($value) - { - $id = array_search($value, $this->data['options_name']); - return wp_get_attachment_image_url( $this->data['options_image'][ $id ] ); - } - - /** - * Output HTML for product page - * @param $selected_name - * @return string - */ - public function render_for_product($selected_name = "") - { - if ($selected_name === "") { - $selected_name = $this->data["default_value"]; - } - $args = $this->prepared_data(); - $args['value'] = $selected_name; - $args['options_name'] = $this->data['options_name']; - $args['options_title'] = $this->data['options_title']; - $args['options_image'] = $this->data['options_image']; - $args['size'] = $this->data("image_size"); - - return View::render('fields/front/' . $this->type, $args); - } - - /** - * Display value of the field in order line item at backend - * - * @param $value - * @return string - * @since 1.2.0 - */ - public function order_item_value($value) - { - $img = $this->get_option_image($value); - $title = $this->get_option_title($value); - return $title . ' '; - } +class ImageselectField extends SelectField { + protected $parameters = array( + "type", + "name", + "title", + "hint", + "options_name", + "options_title", + "options_image", + "css_class", + "required", + "default_value" + ); + protected $default_data = array( + "css_class" => "", + "required" => false, + "default_value" => "", + "hint" => "", + "image_size" => 60 + ); + protected $type = "imageselect"; + + /** + * Output HTML for fields at backend. + * + * @param $value + * + * @return string + */ + public function admin_fields( $value = '' ) { + $this->admin_title = __( "Select Image", "wc-kalkulator" ); + + return View::render( 'fields/admin/' . $this->type ); + } + + /** + * Output HTML for User's cart nad order meta + * + * @param $value + * + * @return string + */ + public function render_for_cart( $value = '' ) { + return View::render( 'fields/cart', array( + 'title' => $this->data['title'], + 'value' => $this->get_option_title( $value ), + 'image' => $this->get_option_image( $value ), + ) ); + } + + /** + * Return option title based on option value from select field + * + * @param $value + * + * @return string + */ + public function get_option_image( $value ) { + $id = array_search( $value, $this->data['options_name'] ); + + return wp_get_attachment_image_url( $this->data['options_image'][ $id ] ); + } + + /** + * Output HTML for product page + * + * @param $selected_name + * + * @return string + */ + public function render_for_product( $selected_name = "" ) { + if ( $selected_name === "" ) { + $selected_name = $this->data["default_value"]; + } + $args = $this->prepared_data(); + $args['value'] = $selected_name; + $args['options_name'] = $this->data['options_name']; + $args['options_title'] = $this->data['options_title']; + $args['options_image'] = $this->data['options_image']; + $args['size'] = $this->data( "image_size" ); + + return View::render( 'fields/front/' . $this->type, $args ); + } + + /** + * Display value of the field in order line item at backend + * + * @param $value + * + * @return string + * @since 1.2.0 + */ + public function order_item_value( $value ) { + $img = $this->get_option_image( $value ); + $title = $this->get_option_title( $value ); + + return $title . ' '; + } } \ No newline at end of file diff --git a/src/Fields/ImageswatchesField.php b/src/Fields/ImageswatchesField.php index 20f8763..33c6859 100644 --- a/src/Fields/ImageswatchesField.php +++ b/src/Fields/ImageswatchesField.php @@ -8,19 +8,20 @@ * Class ImageswatchesField * @package WCKalkulator */ -class ImageswatchesField extends ImageselectField -{ - protected $type = "imageswatches"; - - /** - * Output HTML for fields at backend. - * @param $value - * @return string - */ - public function admin_fields($value = '') - { - $this->admin_title = __("Image Swatches", "wc-kalkulator"); - return View::render('fields/admin/imageselect'); - } - +class ImageswatchesField extends ImageselectField { + protected $type = "imageswatches"; + + /** + * Output HTML for fields at backend. + * + * @param $value + * + * @return string + */ + public function admin_fields( $value = '' ) { + $this->admin_title = __( "Image Swatches", "wc-kalkulator" ); + + return View::render( 'fields/admin/imageselect' ); + } + } \ No newline at end of file diff --git a/src/Fields/ImageuploadField.php b/src/Fields/ImageuploadField.php index 62c71f2..fad7231 100644 --- a/src/Fields/ImageuploadField.php +++ b/src/Fields/ImageuploadField.php @@ -8,155 +8,180 @@ * Class ImageuploadField * @package WCKalkulator */ -class ImageuploadField extends AbstractField -{ - protected $parameters = array("type", "name", "title", "hint", "css_class", "required", "max_file_size", "allowed_extensions"); - protected $default_data = array("css_class" => "", "required" => false, "default_value" => "", "hint" => ""); - protected $data; - protected $type = "imageupload"; - protected $admin_title; - protected $use_expression = true; - protected $group = "upload"; - protected $mimes = array("jpg" => "image/jpeg", "jpeg" => "image/jpeg", "png" => "image/png", "gif" => "image/gif"); - protected $ext = array("jpg", "jpeg", "png", "gif"); - - /** - * Output HTML for fields at backend. - * @param $value - * @return string - */ - public function admin_fields($value = '') - { - $this->admin_title = __("Image Upload", "wc-kalkulator"); - return View::render('fields/admin/' . $this->type); - } - - /** - * Output HTML for product page - * @param $value - * @return string - */ - public function render_for_product($value = "") - { - $args = $this->prepared_data(); - $args['max_file_size'] = $this->data('max_file_size'); - if (!empty($this->data('allowed_extensions'))) { - $args['allowed_extensions'] = $this->data('allowed_extensions'); - $args['accept'] = '.' . str_replace('|', ', .', $this->data('allowed_extensions')); - } else { - $args['allowed_extensions'] = 'jpg|jpeg|png|gif'; - $args['accept'] = '.jpg, .jpeg, .png, .gif'; - } - return View::render('fields/front/' . $this->type, $args); - } - - /** - * Output HTML for User's cart nad order meta - * @param $file - * @return string - */ - public function render_for_cart($file = '') - { - if (is_array($file)) { - return View::render('fields/cart', array( - 'title' => $this->data['title'], - 'value' => esc_html($file['original_name']) . ' (' . round($file['size'] / 1000000, 2) . ' MB)' - )); - } - } - - /** - * Run all validation tests - * @param $value - * @return bool - */ - public function validate($value) - { - if (!$this->is_required() && empty($value)) - return true; - - if ($this->data['required'] && empty($value)) - return false; - - if (is_array($value)) { - if (is_uploaded_file($value['tmp_name'])) { - $allowed_size = $this->data('max_file_size') * 1000000; //Bytes - $allowed_ext = array(); - - foreach ($this->ext as $ext) { - if (strpos($this->data('allowed_extensions'), $ext) !== false) { - $allowed_ext[] = $ext; - } - } - - if (empty($allowed_ext)) - $allowed_ext = $this->ext; - - $mimes = array(); - - foreach ($allowed_ext as $ext) - $mimes[$ext] = $this->mimes[$ext]; - - if ($value['size'] > 0 && $value['size'] <= $allowed_size && filesize($value['tmp_name']) <= $allowed_size) { - $image_mime = wp_get_image_mime($value['tmp_name']); - if ($image_mime !== false && in_array($image_mime, $mimes)) { - return true; - } - } - } - } - - return false; - } - - /** - * Display value of the field in order line item at backend - * - * @param $value - * @return string - * @since 1.2.0 - */ - public function order_item_value($value) - { - return $value; - } - - /** - * Handles file upload. Copy file from temp location to the customer directory - * - * @param $data - * @return bool - * @since 1.3.0 - */ - public function upload($data) - { - if (!file_exists($data['upload_tmp'])) { - return false; - } - - $dir = dirname($data['upload_path']); - if (!file_exists($dir)) { - mkdir($dir, 0755, true); - file_put_contents($dir . '/index.html', ''); - } - - return rename($data['upload_tmp'], $data['upload_path']); - } - - /** - * Handles file upload from POST to the temp directory - * - * @param $data - * @return bool - * @since 1.3.0 - */ - public function upload_temp($data) - { - if (move_uploaded_file($data['tmp_name'], $data['upload_tmp'])) { - chmod($data['upload_tmp'], 0644); - return true; - } - return false; - } +class ImageuploadField extends AbstractField { + protected $parameters = array( + "type", + "name", + "title", + "hint", + "css_class", + "required", + "max_file_size", + "allowed_extensions" + ); + protected $default_data = array( "css_class" => "", "required" => false, "default_value" => "", "hint" => "" ); + protected $data; + protected $type = "imageupload"; + protected $admin_title; + protected $use_expression = true; + protected $group = "upload"; + protected $mimes = array( + "jpg" => "image/jpeg", + "jpeg" => "image/jpeg", + "png" => "image/png", + "gif" => "image/gif" + ); + protected $ext = array( "jpg", "jpeg", "png", "gif" ); + + /** + * Output HTML for fields at backend. + * + * @param $value + * + * @return string + */ + public function admin_fields( $value = '' ) { + $this->admin_title = __( "Image Upload", "wc-kalkulator" ); + + return View::render( 'fields/admin/' . $this->type ); + } + + /** + * Output HTML for product page + * + * @param $value + * + * @return string + */ + public function render_for_product( $value = "" ) { + $args = $this->prepared_data(); + $args['max_file_size'] = $this->data( 'max_file_size' ); + if ( ! empty( $this->data( 'allowed_extensions' ) ) ) { + $args['allowed_extensions'] = $this->data( 'allowed_extensions' ); + $args['accept'] = '.' . str_replace( '|', ', .', $this->data( 'allowed_extensions' ) ); + } else { + $args['allowed_extensions'] = 'jpg|jpeg|png|gif'; + $args['accept'] = '.jpg, .jpeg, .png, .gif'; + } + + return View::render( 'fields/front/' . $this->type, $args ); + } + + /** + * Output HTML for User's cart nad order meta + * + * @param $file + * + * @return string + */ + public function render_for_cart( $file = '' ) { + if ( is_array( $file ) ) { + return View::render( 'fields/cart', array( + 'title' => $this->data['title'], + 'value' => esc_html( $file['original_name'] ) . ' (' . round( $file['size'] / 1000000, 2 ) . ' MB)' + ) ); + } + } + + /** + * Run all validation tests + * + * @param $value + * + * @return bool + */ + public function validate( $value ) { + if ( ! $this->is_required() && empty( $value ) ) { + return true; + } + + if ( $this->data['required'] && empty( $value ) ) { + return false; + } + + if ( is_array( $value ) ) { + if ( is_uploaded_file( $value['tmp_name'] ) ) { + $allowed_size = $this->data( 'max_file_size' ) * 1000000; //Bytes + $allowed_ext = array(); + + foreach ( $this->ext as $ext ) { + if ( strpos( $this->data( 'allowed_extensions' ), $ext ) !== false ) { + $allowed_ext[] = $ext; + } + } + + if ( empty( $allowed_ext ) ) { + $allowed_ext = $this->ext; + } + + $mimes = array(); + + foreach ( $allowed_ext as $ext ) { + $mimes[ $ext ] = $this->mimes[ $ext ]; + } + + if ( $value['size'] > 0 && $value['size'] <= $allowed_size && filesize( $value['tmp_name'] ) <= $allowed_size ) { + $image_mime = wp_get_image_mime( $value['tmp_name'] ); + if ( $image_mime !== false && in_array( $image_mime, $mimes ) ) { + return true; + } + } + } + } + + return false; + } + + /** + * Display value of the field in order line item at backend + * + * @param $value + * + * @return string + * @since 1.2.0 + */ + public function order_item_value( $value ) { + return $value; + } + + /** + * Handles file upload. Copy file from temp location to the customer directory + * + * @param $data + * + * @return bool + * @since 1.3.0 + */ + public function upload( $data ) { + if ( ! file_exists( $data['upload_tmp'] ) ) { + return false; + } + + $dir = dirname( $data['upload_path'] ); + if ( ! file_exists( $dir ) ) { + mkdir( $dir, 0755, true ); + file_put_contents( $dir . '/index.html', '' ); + } + + return rename( $data['upload_tmp'], $data['upload_path'] ); + } + + /** + * Handles file upload from POST to the temp directory + * + * @param $data + * + * @return bool + * @since 1.3.0 + */ + public function upload_temp( $data ) { + if ( move_uploaded_file( $data['tmp_name'], $data['upload_tmp'] ) ) { + chmod( $data['upload_tmp'], 0644 ); + + return true; + } + + return false; + } } \ No newline at end of file diff --git a/src/Fields/LinkField.php b/src/Fields/LinkField.php index f749a44..1e14d07 100644 --- a/src/Fields/LinkField.php +++ b/src/Fields/LinkField.php @@ -8,60 +8,65 @@ * Class LinkField * @package WCKalkulator */ -class LinkField extends HtmlField -{ - protected $parameters = array("type", "name", "content", "title", "target"); - protected $default_data = array("required" => false, "content" => "", "target" => "_blank"); - protected $data; - protected $type = "link"; - protected $admin_title; - protected $use_expression = false; - protected $group = "static"; - protected $show_title = true; - - /** - * Output HTML for fields at backend. - * @param $value - * @return string - */ - public function admin_fields($value = '') - { - $this->admin_title = __("Link / URL", "wc-kalkulator"); - return View::render('fields/admin/' . $this->type); - } - - /** - * Output HTML for product page - * @param $value - * @return string - */ - public function render_for_product($value = "") - { - $args = $this->prepared_data(); - $args['content'] = $this->data('content'); - $args['target'] = $this->data('target'); - return View::render('fields/front/' . $this->type, $args); - } - - /** - * No need to show hidden field in the user's cart - * @param $value - * @return string - */ - public function render_for_cart($value = '') - { - return; - } - - /** - * No need to validate hidden static field - * @param $value - * @return bool - */ - public function validate($value) - { - return true; - - } - +class LinkField extends HtmlField { + protected $parameters = array( "type", "name", "content", "title", "target" ); + protected $default_data = array( "required" => false, "content" => "", "target" => "_blank" ); + protected $data; + protected $type = "link"; + protected $admin_title; + protected $use_expression = false; + protected $group = "static"; + protected $show_title = true; + + /** + * Output HTML for fields at backend. + * + * @param $value + * + * @return string + */ + public function admin_fields( $value = '' ) { + $this->admin_title = __( "Link / URL", "wc-kalkulator" ); + + return View::render( 'fields/admin/' . $this->type ); + } + + /** + * Output HTML for product page + * + * @param $value + * + * @return string + */ + public function render_for_product( $value = "" ) { + $args = $this->prepared_data(); + $args['content'] = $this->data( 'content' ); + $args['target'] = $this->data( 'target' ); + + return View::render( 'fields/front/' . $this->type, $args ); + } + + /** + * No need to show hidden field in the user's cart + * + * @param $value + * + * @return string + */ + public function render_for_cart( $value = '' ) { + return; + } + + /** + * No need to validate hidden static field + * + * @param $value + * + * @return bool + */ + public function validate( $value ) { + return true; + + } + } \ No newline at end of file diff --git a/src/Fields/NumberField.php b/src/Fields/NumberField.php index 90c9133..9365b66 100644 --- a/src/Fields/NumberField.php +++ b/src/Fields/NumberField.php @@ -8,88 +8,103 @@ * Class NumberField * @package WCKalkulator */ -class NumberField extends AbstractField -{ - protected $parameters = array("type", "name", "title", "hint", "min", "max", "css_class", "required", "default_value"); - protected $default_data = array("css_class" => "", "required" => true, "default_value" => "", "hint" => ""); - protected $data; - protected $type = "number"; - protected $admin_title; - protected $use_expression = true; - protected $group = "input"; - - /** - * Output HTML for fields at backend. - * @param $value - * @return string - */ - public function admin_fields($value = "") - { - $this->admin_title = __("Number Field", "wc-kalkulator"); - return View::render('fields/admin/number'); - } - - /** - * Output HTML for product page - * @param $value - * @return string - */ - public function render_for_product($value = "") - { - if ($value === "") { - $value = $this->data["default_value"]; - if ($value === "") { - $value = $this->data["min"]; - } - } - - $args = $this->prepared_data(); - $args['min'] = $this->data["min"]; - $args['max'] = $this->data["max"]; - $args['value'] = $value; - - return View::render('fields/front/number', $args); - } - - /** - * Output HTML for User's cart nad order meta - * @param $value - * @return string - */ - public function render_for_cart($value = '') - { - return View::render('fields/cart', array( - 'title' => $this->data['title'], - 'value' => $value - )); - } - - /** - * Run all validation tests - * @param $value - * @return bool - */ - public function validate($value) - { - if (!$this->is_required() && empty($value)) { - return true; - } - $is_greater_than_min = $value >= $this->data["min"]; - $is_less_than_max = $value <= $this->data["max"]; - $is_numeric = is_numeric($value); - return $is_greater_than_min && $is_less_than_max && $is_numeric; - } - - /** - * Display value of the field in order line item at backend - * - * @param $value - * @return string - * @since 1.2.0 - */ - public function order_item_value($value) - { - return $value; - } - +class NumberField extends AbstractField { + protected $parameters = array( + "type", + "name", + "title", + "hint", + "min", + "max", + "css_class", + "required", + "default_value" + ); + protected $default_data = array( "css_class" => "", "required" => true, "default_value" => "", "hint" => "" ); + protected $data; + protected $type = "number"; + protected $admin_title; + protected $use_expression = true; + protected $group = "input"; + + /** + * Output HTML for fields at backend. + * + * @param $value + * + * @return string + */ + public function admin_fields( $value = "" ) { + $this->admin_title = __( "Number Field", "wc-kalkulator" ); + + return View::render( 'fields/admin/number' ); + } + + /** + * Output HTML for product page + * + * @param $value + * + * @return string + */ + public function render_for_product( $value = "" ) { + if ( $value === "" ) { + $value = $this->data["default_value"]; + if ( $value === "" ) { + $value = $this->data["min"]; + } + } + + $args = $this->prepared_data(); + $args['min'] = $this->data["min"]; + $args['max'] = $this->data["max"]; + $args['value'] = $value; + + return View::render( 'fields/front/number', $args ); + } + + /** + * Output HTML for User's cart nad order meta + * + * @param $value + * + * @return string + */ + public function render_for_cart( $value = '' ) { + return View::render( 'fields/cart', array( + 'title' => $this->data['title'], + 'value' => $value + ) ); + } + + /** + * Run all validation tests + * + * @param $value + * + * @return bool + */ + public function validate( $value ) { + if ( ! $this->is_required() && empty( $value ) ) { + return true; + } + $is_greater_than_min = $value >= $this->data["min"]; + $is_less_than_max = $value <= $this->data["max"]; + $is_numeric = is_numeric( $value ); + + return $is_greater_than_min && $is_less_than_max && $is_numeric; + } + + /** + * Display value of the field in order line item at backend + * + * @param $value + * + * @return string + * @since 1.2.0 + */ + public function order_item_value( $value ) { + return $value; + } + } \ No newline at end of file diff --git a/src/Fields/ParagraphField.php b/src/Fields/ParagraphField.php index 1ccaf5e..d0002c2 100644 --- a/src/Fields/ParagraphField.php +++ b/src/Fields/ParagraphField.php @@ -8,25 +8,26 @@ * Class ParagraphField * @package WCKalkulator */ -class ParagraphField extends HtmlField -{ - protected $parameters = array("type", "name", "content"); - protected $default_data = array("required" => false, "content"); - protected $data; - protected $type = "paragraph"; - protected $admin_title; - protected $use_expression = false; - protected $group = "static"; - - /** - * Output HTML for fields at backend. - * @param $value - * @return string - */ - public function admin_fields($value = '') - { - $this->admin_title = __("Paragraph", "wc-kalkulator"); - return View::render('fields/admin/' . $this->type); - } - +class ParagraphField extends HtmlField { + protected $parameters = array( "type", "name", "content" ); + protected $default_data = array( "required" => false, "content" ); + protected $data; + protected $type = "paragraph"; + protected $admin_title; + protected $use_expression = false; + protected $group = "static"; + + /** + * Output HTML for fields at backend. + * + * @param $value + * + * @return string + */ + public function admin_fields( $value = '' ) { + $this->admin_title = __( "Paragraph", "wc-kalkulator" ); + + return View::render( 'fields/admin/' . $this->type ); + } + } \ No newline at end of file diff --git a/src/Fields/RadioField.php b/src/Fields/RadioField.php index a17c577..2127202 100644 --- a/src/Fields/RadioField.php +++ b/src/Fields/RadioField.php @@ -8,38 +8,40 @@ * Class RadioField * @package WCKalkulator */ -class RadioField extends SelectField -{ - protected $type = "radio"; - protected $group = "select"; - - /** - * Output HTML for fields at backend. - * @param $value - * @return string - */ - public function admin_fields($value = '') - { - $this->admin_title = __("Radio", "wc-kalkulator"); - return View::render('fields/admin/select'); - } - - /** - * Output HTML for product page - * @param $selected_name - * @return string - */ - public function render_for_product($selected_name = "") - { - if ($selected_name === "") { - $selected_name = $this->data["default_value"]; - } - $args = $this->prepared_data(); - $args['value'] = $selected_name; - $args['options_name'] = $this->data['options_name']; - $args['options_title'] = $this->data['options_title']; - - return View::render('fields/front/radio', $args); - } - +class RadioField extends SelectField { + protected $type = "radio"; + protected $group = "select"; + + /** + * Output HTML for fields at backend. + * + * @param $value + * + * @return string + */ + public function admin_fields( $value = '' ) { + $this->admin_title = __( "Radio", "wc-kalkulator" ); + + return View::render( 'fields/admin/select' ); + } + + /** + * Output HTML for product page + * + * @param $selected_name + * + * @return string + */ + public function render_for_product( $selected_name = "" ) { + if ( $selected_name === "" ) { + $selected_name = $this->data["default_value"]; + } + $args = $this->prepared_data(); + $args['value'] = $selected_name; + $args['options_name'] = $this->data['options_name']; + $args['options_title'] = $this->data['options_title']; + + return View::render( 'fields/front/radio', $args ); + } + } \ No newline at end of file diff --git a/src/Fields/RangedatepickerField.php b/src/Fields/RangedatepickerField.php index c217c4b..f194759 100644 --- a/src/Fields/RangedatepickerField.php +++ b/src/Fields/RangedatepickerField.php @@ -9,173 +9,181 @@ * Class DatepickerField * @package WCKalkulator */ -class RangedatepickerField extends DatepickerField -{ - protected $type = "rangedatepicker"; - protected $group = "picker"; - - /** - * Called in enqueue_scripts action - */ - public function enqueue_scripts() - { - wp_enqueue_style( - 'wck-jquery-ui-css', - Plugin::url() . '/assets/css/jquery-ui.min.css' - ); - wp_enqueue_script('jquery-ui-datepicker'); - wp_enqueue_script( - 'wck-range-date-picker', - Plugin::url() . '/assets/js/rangedatepicker.min.js', - array('jquery-ui-datepicker'), - Plugin::VERSION, - 1 - ); - } - - /** - * @return array - */ - public function localize_script() - { - $options = array( - 'dateFormat' => 'yy-mm-dd', - 'minDate' => $this->data('disallow_past_date') ? '0' : null - ); - - return array( - 'script' => 'wck-range-date-picker', - 'field_name' => $this->data("name"), - 'options' => $options - ); - } - - /** - * Output HTML for fields at backend. - * @param $value - * @return string - */ - public function admin_fields($value = '') - { - $html = parent::admin_fields(); - $this->admin_title = __("Range Date Picker", "wc-kalkulator"); - return $html; - } - - /** - * Output HTML for product page - * @param $value - * @return string - */ - public function render_for_product($value = array()) - { - $args = $this->prepared_data(); - $args['value_from'] = isset($value['from']) ? $value['from'] : ''; - $args['value_to'] = isset($value['to']) ? $value['to'] : ''; - $args['disallow_past_date'] = $this->data["disallow_past_date"]; - - return View::render('fields/front/rangedatepicker', $args); - } - - /** - * Output HTML for User's cart nad order meta - * @param $value - * @return string - */ - public function render_for_cart($value = array()) - { - return View::render('fields/cart', array( - 'title' => $this->data['title'], - 'value' => $value["from"] . ' - ' . $value["to"] - )); - } - - /** - * @param $value - * @return bool - * @throws \Exception - */ - public function validate($value) - { - if (!isset($value["from"]) || !isset($value["to"]) || count($value) != 2) { - error_log($this->data("name") . " does not exists or is not an array of 2 items"); - return false; - } - - if ($this->is_required()) { - if (empty($value["from"]) || empty($value["to"])) { - error_log($this->data("name") . " is required and has empty values"); - return false; - } - } else { - if (empty($value["from"]) xor empty($value["to"])) { - error_log($this->data("name") . " is not required, but has incorrect value"); - return false; - } - if (empty($value["from"]) && empty($value["to"])) { - return true; - } - } - - //1. Check correct date - $count_valid = 0; - foreach ($value as $date) { - $date_arr = explode('-', $date); - if (count($date_arr) === 3) { - $year = $date_arr[0]; - $month = $date_arr[1]; - $day = $date_arr[2]; - $count_valid += checkdate($month, $day, $year) ? 1 : 0; - } - } - $is_valid = $count_valid === 2; - if (!$is_valid) { - error_log($this->data("name") . " - date is incorrect " . print_r($value, true) . " = " . $count_valid); - } - //2. Check past date option - if ($is_valid) { - foreach ($value as $date) { - if ($this->data("disallow_past_date")) { - try { - $datetime = new \DateTime($date); - $datetime->setTime(0, 0, 0); - $now = new \DateTime(); - $now->setTime(0, 0, 0); - } catch (\Exception $e) { - error_log($this->data("name") . " - DateTime exception"); - return false; - } - if ($datetime < $now) { - error_log($this->data("name") . " - past date is not allowed"); - return false; - } - } - } - //3. Check date "from" is earlier than date "to" - $date_from = new \DateTime($value["from"]); - $date_from->setTime(0, 0, 0); - $date_to = new \DateTime($value["to"]); - $date_to->setTime(0, 0, 0); - - if ($date_from > $date_to) { - error_log($this->data("name") . " date A is greater than date B"); - return false; - } - - } - - return $is_valid; - } - - /** - * Display value of the field in order line item at backend - * - * @param $value - * @return string - * @since 1.2.0 - */ - public function order_item_value($value) - { - return $value["from"] . ' - ' . $value["to"]; - } +class RangedatepickerField extends DatepickerField { + protected $type = "rangedatepicker"; + protected $group = "picker"; + + /** + * Called in enqueue_scripts action + */ + public function enqueue_scripts() { + wp_enqueue_style( + 'wck-jquery-ui-css', + Plugin::url() . '/assets/css/jquery-ui.min.css' + ); + wp_enqueue_script( 'jquery-ui-datepicker' ); + wp_enqueue_script( + 'wck-range-date-picker', + Plugin::url() . '/assets/js/rangedatepicker.min.js', + array( 'jquery-ui-datepicker' ), + Plugin::VERSION, + 1 + ); + } + + /** + * @return array + */ + public function localize_script() { + $options = array( + 'dateFormat' => 'yy-mm-dd', + 'minDate' => $this->data( 'disallow_past_date' ) ? '0' : null + ); + + return array( + 'script' => 'wck-range-date-picker', + 'field_name' => $this->data( "name" ), + 'options' => $options + ); + } + + /** + * Output HTML for fields at backend. + * + * @param $value + * + * @return string + */ + public function admin_fields( $value = '' ) { + $html = parent::admin_fields(); + $this->admin_title = __( "Range Date Picker", "wc-kalkulator" ); + + return $html; + } + + /** + * Output HTML for product page + * + * @param $value + * + * @return string + */ + public function render_for_product( $value = array() ) { + $args = $this->prepared_data(); + $args['value_from'] = isset( $value['from'] ) ? $value['from'] : ''; + $args['value_to'] = isset( $value['to'] ) ? $value['to'] : ''; + $args['disallow_past_date'] = $this->data["disallow_past_date"]; + + return View::render( 'fields/front/rangedatepicker', $args ); + } + + /** + * Output HTML for User's cart nad order meta + * + * @param $value + * + * @return string + */ + public function render_for_cart( $value = array() ) { + return View::render( 'fields/cart', array( + 'title' => $this->data['title'], + 'value' => $value["from"] . ' - ' . $value["to"] + ) ); + } + + /** + * @param $value + * + * @return bool + * @throws \Exception + */ + public function validate( $value ) { + if ( ! isset( $value["from"] ) || ! isset( $value["to"] ) || count( $value ) != 2 ) { + error_log( $this->data( "name" ) . " does not exists or is not an array of 2 items" ); + + return false; + } + + if ( $this->is_required() ) { + if ( empty( $value["from"] ) || empty( $value["to"] ) ) { + error_log( $this->data( "name" ) . " is required and has empty values" ); + + return false; + } + } else { + if ( empty( $value["from"] ) xor empty( $value["to"] ) ) { + error_log( $this->data( "name" ) . " is not required, but has incorrect value" ); + + return false; + } + if ( empty( $value["from"] ) && empty( $value["to"] ) ) { + return true; + } + } + + //1. Check correct date + $count_valid = 0; + foreach ( $value as $date ) { + $date_arr = explode( '-', $date ); + if ( count( $date_arr ) === 3 ) { + $year = $date_arr[0]; + $month = $date_arr[1]; + $day = $date_arr[2]; + $count_valid += checkdate( $month, $day, $year ) ? 1 : 0; + } + } + $is_valid = $count_valid === 2; + if ( ! $is_valid ) { + error_log( $this->data( "name" ) . " - date is incorrect " . print_r( $value, + true ) . " = " . $count_valid ); + } + //2. Check past date option + if ( $is_valid ) { + foreach ( $value as $date ) { + if ( $this->data( "disallow_past_date" ) ) { + try { + $datetime = new \DateTime( $date ); + $datetime->setTime( 0, 0, 0 ); + $now = new \DateTime(); + $now->setTime( 0, 0, 0 ); + } catch ( \Exception $e ) { + error_log( $this->data( "name" ) . " - DateTime exception" ); + + return false; + } + if ( $datetime < $now ) { + error_log( $this->data( "name" ) . " - past date is not allowed" ); + + return false; + } + } + } + //3. Check date "from" is earlier than date "to" + $date_from = new \DateTime( $value["from"] ); + $date_from->setTime( 0, 0, 0 ); + $date_to = new \DateTime( $value["to"] ); + $date_to->setTime( 0, 0, 0 ); + + if ( $date_from > $date_to ) { + error_log( $this->data( "name" ) . " date A is greater than date B" ); + + return false; + } + + } + + return $is_valid; + } + + /** + * Display value of the field in order line item at backend + * + * @param $value + * + * @return string + * @since 1.2.0 + */ + public function order_item_value( $value ) { + return $value["from"] . ' - ' . $value["to"]; + } } \ No newline at end of file diff --git a/src/Fields/SelectField.php b/src/Fields/SelectField.php index 08401e0..90bc650 100644 --- a/src/Fields/SelectField.php +++ b/src/Fields/SelectField.php @@ -15,7 +15,7 @@ class SelectField extends AbstractField protected $data; protected $type = "select"; protected $admin_title; - protected $use_expression = true; + protected $use_expression = true; protected $group = "select"; /** diff --git a/src/Fields/TextField.php b/src/Fields/TextField.php index 12bb249..11d9940 100644 --- a/src/Fields/TextField.php +++ b/src/Fields/TextField.php @@ -8,101 +8,125 @@ * Class TextField * @package WCKalkulator */ -class TextField extends AbstractField -{ - protected $parameters = array("type", "name", "title", "hint", "css_class", "required", "default_value", "min", "max", "price", "pattern"); - protected $default_data = array("css_class" => "", "required" => false, "default_value" => "", "hint" => "", "pattern" => ""); - protected $data; - protected $type = "text"; - protected $admin_title; - protected $use_expression = true; - protected $group = "input"; - - /** - * Output HTML for fields at backend. - * @param $value - * @return string - */ - public function admin_fields($value = '') - { - $this->admin_title = __("Text", "wc-kalkulator"); - return View::render('fields/admin/text'); - } - - /** - * Output HTML for product page - * @param $value - * @return string - */ - public function render_for_product($value = "") - { - $args = $this->prepared_data(); - $args['placeholder'] = esc_html($this->data["default_value"]); - $args['min_length'] = $this->data["min"]; - $args['max_length'] = $this->data["max"]; - $args['value'] = $value; - $args['pattern'] = $this->data('pattern'); - - return View::render('fields/front/text', $args); - } - - /** - * Output HTML for User's cart nad order meta - * @param $value - * @return string - */ - public function render_for_cart($value = '') - { - return View::render('fields/cart', array( - 'title' => $this->data['title'], - 'value' => $value - )); - } - - /** - * Run all validation tests - * @param $value - * @return bool - */ - public function validate($value) - { - if(!$this->is_required() && empty($value)) { - return true; - } - - $length = strlen(esc_html($value)); - - if (intval($this->data["min"]) > 0) - $is_longer_than_min = $length >= $this->data["min"]; - else - $is_longer_than_min = true; - - if (intval($this->data["max"]) > 0) - $is_shorter_than_max = $length <= $this->data["max"]; - else - $is_shorter_than_max = true; - - - $is_required_and_nonempty = true; - if ($this->data['required']) { - if (empty($value) || $value === "") { - $is_required_and_nonempty = false; - } - } - - return $is_longer_than_min && $is_shorter_than_max && $is_required_and_nonempty; - } - - /** - * Display value of the field in order line item at backend - * - * @param $value - * @return string - * @since 1.2.0 - */ - public function order_item_value($value) - { - return $value; - } - +class TextField extends AbstractField { + protected $parameters = array( + "type", + "name", + "title", + "hint", + "css_class", + "required", + "default_value", + "min", + "max", + "price", + "pattern" + ); + protected $default_data = array( + "css_class" => "", + "required" => false, + "default_value" => "", + "hint" => "", + "pattern" => "" + ); + protected $data; + protected $type = "text"; + protected $admin_title; + protected $use_expression = true; + protected $group = "input"; + + /** + * Output HTML for fields at backend. + * + * @param $value + * + * @return string + */ + public function admin_fields( $value = '' ) { + $this->admin_title = __( "Text", "wc-kalkulator" ); + + return View::render( 'fields/admin/text' ); + } + + /** + * Output HTML for product page + * + * @param $value + * + * @return string + */ + public function render_for_product( $value = "" ) { + $args = $this->prepared_data(); + $args['placeholder'] = esc_html( $this->data["default_value"] ); + $args['min_length'] = $this->data["min"]; + $args['max_length'] = $this->data["max"]; + $args['value'] = $value; + $args['pattern'] = $this->data( 'pattern' ); + + return View::render( 'fields/front/text', $args ); + } + + /** + * Output HTML for User's cart nad order meta + * + * @param $value + * + * @return string + */ + public function render_for_cart( $value = '' ) { + return View::render( 'fields/cart', array( + 'title' => $this->data['title'], + 'value' => $value + ) ); + } + + /** + * Run all validation tests + * + * @param $value + * + * @return bool + */ + public function validate( $value ) { + if ( ! $this->is_required() && empty( $value ) ) { + return true; + } + + $length = strlen( esc_html( $value ) ); + + if ( intval( $this->data["min"] ) > 0 ) { + $is_longer_than_min = $length >= $this->data["min"]; + } else { + $is_longer_than_min = true; + } + + if ( intval( $this->data["max"] ) > 0 ) { + $is_shorter_than_max = $length <= $this->data["max"]; + } else { + $is_shorter_than_max = true; + } + + + $is_required_and_nonempty = true; + if ( $this->data['required'] ) { + if ( empty( $value ) || $value === "" ) { + $is_required_and_nonempty = false; + } + } + + return $is_longer_than_min && $is_shorter_than_max && $is_required_and_nonempty; + } + + /** + * Display value of the field in order line item at backend + * + * @param $value + * + * @return string + * @since 1.2.0 + */ + public function order_item_value( $value ) { + return $value; + } + } \ No newline at end of file diff --git a/src/Fields/TextareaField.php b/src/Fields/TextareaField.php index 775652a..f24c623 100644 --- a/src/Fields/TextareaField.php +++ b/src/Fields/TextareaField.php @@ -8,35 +8,36 @@ * Class TextField * @package WCKalkulator */ -class TextareaField extends TextField -{ - protected $type = "textarea"; - protected $group = "input"; - - /** - * @param string $value - * @return string - */ - public function admin_fields($value = '') - { - $html = parent::admin_fields($value); - $this->admin_title = __("Textarea", "wc-kalkulator"); - return $html; - } - - /** - * Output HTML for product page - * @param $value - * @return string - */ - public function render_for_product($value = "") - { - $args = $this->prepared_data(); - $args['placeholder'] = esc_html($this->data["default_value"]); - $args['min_length'] = $this->data["min"]; - $args['max_length'] = $this->data["max"]; - $args['value'] = $value; - - return View::render('fields/front/textarea', $args); - } +class TextareaField extends TextField { + protected $type = "textarea"; + protected $group = "input"; + + /** + * @param string $value + * + * @return string + */ + public function admin_fields( $value = '' ) { + $html = parent::admin_fields( $value ); + $this->admin_title = __( "Textarea", "wc-kalkulator" ); + + return $html; + } + + /** + * Output HTML for product page + * + * @param $value + * + * @return string + */ + public function render_for_product( $value = "" ) { + $args = $this->prepared_data(); + $args['placeholder'] = esc_html( $this->data["default_value"] ); + $args['min_length'] = $this->data["min"]; + $args['max_length'] = $this->data["max"]; + $args['value'] = $value; + + return View::render( 'fields/front/textarea', $args ); + } } \ No newline at end of file diff --git a/src/FieldsetProduct.php b/src/FieldsetProduct.php index 2434cc2..6cc3c7c 100644 --- a/src/FieldsetProduct.php +++ b/src/FieldsetProduct.php @@ -360,6 +360,22 @@ public function field($name) return false; } + public function set_default_input() + { + $data = array(); + foreach ($this->fields() as $name => $field) { + $field = (object) $field->data(); + if ((int)$field->use_expression === 1) { + if($field->type === 'checkboxgroup') { + $data[$name] = array($field->default_value); + } else { + $data[$name] = $field->default_value; + } + } + } + $this->user_input = $data; + } + /** * Gets user input from $_POST. Sanitize input * @@ -368,7 +384,6 @@ public function field($name) */ public function get_user_input() { - $user_input = array(); $allowed_names = $this->fields_names(); //if (isset($_POST['wck']) && is_array($_POST['wck'])) { @@ -387,17 +402,6 @@ public function get_user_input() $user_input = Sanitizer::sanitize($filtered_post, 'array'); //} - foreach ($allowed_names as $name) { - if (isset($_POST['wck'][$name])) { - $filtered_post[$name] = $_POST['wck'][$name]; - } else { - /* Set Default values if the field is not in POST data */ - if ($this->field($name)['type'] === 'checkboxgroup') { - $filtered_post[$name] = array(); - } - } - } - $user_input['_files'] = array(); /* Since v.1.3.1 upload path is defined in WCK Settings @@ -613,36 +617,37 @@ public function validate_values() /** * Add field's static price to $user_input * - * @param $input - * @return void + * @param $return + * @return void|array * @since 1.2.0 */ - public function set_additional_input_variables() + public function set_additional_input_variables($return = false) { - if (!is_array($this->user_input)) { + if (!$return && !is_array($this->user_input)) { return; } - $field_names = array_keys($this->user_input); + if(!$return) { + $field_names = array_keys($this->user_input); + foreach ($this->fields() as $field) { + $name = $field->data("name"); - foreach ($this->fields() as $field) { - $name = $field->data("name"); + // Check if field has price paramter and its name is in user input + if ($field->data("price") !== null && in_array($name, $field_names)) { + $static_price = Sanitizer::sanitize($field->data("price"), "price"); - // Check if field has price paramter and its name is in user input - if ($field->data("price") !== null && in_array($name, $field_names)) { - $static_price = Sanitizer::sanitize($field->data("price"), "price"); + if ($field->type() === "checkbox") { + $static_price = intval((int)$this->user_input[$name] === 1) * $static_price; + } - if ($field->type() === "checkbox") { - $static_price = intval((int)$this->user_input[$name] === 1) * $static_price; + if (empty($this->user_input[$field->data("name")])) { + $static_price = 0; + } + $this->user_input[$name] = $static_price; } - if (empty($this->user_input[$field->data("name")])) { - $static_price = 0; + if ($field->group() !== 'static' && isset($this->user_input[$name])) { + $this->set_additional_field_parameters($field, $this->user_input[$name]); } - $this->user_input[$name] = $static_price; - } - - if ($field->group() !== 'static' && isset($this->user_input[$name])) { - $this->set_additional_field_parameters($field, $this->user_input[$name]); } } @@ -659,6 +664,7 @@ public function set_additional_input_variables() $this->user_input["product_height"] = $product_helper->get_height(); $this->user_input["product_length"] = $product_helper->get_length(); $this->user_input["product_regular_price"] = $product_helper->regular_price(); + $this->user_input["product_is_on_sale"] = (bool)$product_helper->is_on_sale(); } } @@ -690,6 +696,10 @@ public function set_additional_input_variables() "variation_id" => $this->variation_id //lowest priority )); + if($return) { + return $this->user_input; + } + } /** @@ -724,7 +734,13 @@ public function set_additional_field_parameters($field, $input) $this->user_input[$name . ':text'] = sanitize_text_field($input); break; case 'imageupload': - $this->user_input[$name . ':size'] = round(absint($input) / 1000000, 2); + case 'fileupload': + if (is_array($input)) { + $size = $input['size']; + } else { + $size = $input; + } + $this->user_input[$name . ':size'] = round(absint($size) / 1000000, 2); break; } } @@ -772,7 +788,7 @@ public function calculate() if (isset($result['value']) && $result['is_error'] === false) { $this->user_input['total_price'] = $result['value'] * $this->user_input["quantity"]; } - return $parser->execute(); + return $result; } else { return Ajax::response('error', $parser->error); } @@ -781,6 +797,21 @@ public function calculate() } } + /** + * Calculate minimum price amount to display in price block + * + * @return void + * @since 1.6.0 + */ + public function calculate_minimum() + { + $parser = new ExpressionParser($this->expression(), $this->user_input); + if ($parser->is_ready()) { + return $parser->execute(); + } + return -1; + } + /** * Calculates the value of formula fields * diff --git a/src/Woocommerce/Cart.php b/src/Woocommerce/Cart.php index b9a5232..5a159d5 100644 --- a/src/Woocommerce/Cart.php +++ b/src/Woocommerce/Cart.php @@ -18,17 +18,18 @@ class Cart * @var Cart */ protected static $instance; - + /** * @var array */ protected $fieldsets; - + private function __construct() { add_action('woocommerce_cart_loaded_from_session', array($this, 'check_cart')); + add_filter('woocommerce_widget_cart_item_quantity', array($this, 'widget_cart_item_quantity'), 10, 3); } - + /** * Get instance of a singleton * @@ -40,10 +41,10 @@ public static function getInstance(): Cart if (self::$instance === null) { self::$instance = new static(); } - + return self::$instance; } - + /** * Check cart items for outdated fieldsets. Removes products with outdated fieldsets */ @@ -54,7 +55,7 @@ public function check_cart() foreach ($cart_items as $cart_item_key => $cart_item) { $fieldset_version_hash = isset($cart_item['wckalkulator_fieldset_version_hash']) ? $cart_item['wckalkulator_fieldset_version_hash'] : ''; $fieldset_id = isset($cart_item['wckalkulator_fieldset_id']) ? $cart_item['wckalkulator_fieldset_id'] : 0; - + if ($this->is_fieldset_outdated($fieldset_id, $fieldset_version_hash)) { wc_add_notice( sprintf(__('The product "%s" has been changed by shop manager and removed from the cart. ', 'woocommerce_kalkulator'), @@ -65,7 +66,25 @@ public function check_cart() } } } - + + /** + * Show the calculated product price in cart widget (cart popup) + * + * @param $html + * @param $cart_item + * @param $cart_item_key + * @return mixed|string + * @since 1.6.0 + */ + public function widget_cart_item_quantity($html, $cart_item, $cart_item_key) + { + if (isset($cart_item['wckalkulator_price'])) { + return '' . sprintf('%s × %s', $cart_item['quantity'], strip_tags(wc_price($cart_item['wckalkulator_price']))) . ''; + } else { + return $html; + } + } + /** * Check if fieldset has been updated by admin/manager. * @@ -84,10 +103,10 @@ private function is_fieldset_outdated($id, $hash) if (!isset($this->fielsets[$id])) { $this->fieldsets[$id] = FieldsetProduct::getInstance()->get_data($id); } - + return $hash !== $this->fieldsets[$id]->version_hash; } - + private function __clone() { } diff --git a/src/Woocommerce/Product.php b/src/Woocommerce/Product.php index a55d0fe..79d5b7f 100644 --- a/src/Woocommerce/Product.php +++ b/src/Woocommerce/Product.php @@ -19,6 +19,8 @@ */ class Product { + private static $default_price = 0; + /** * Add hooks and filters * @@ -43,8 +45,29 @@ public static function init() PriceFilter::getInstance(); Cart::getInstance(); + + //remove_action('woocommerce_single_product_summary', 'woocommerce_template_single_price', 10); + //add_filter('woocommerce_structured_data_product_offer', array(__CLASS__, 'override_structured_data'), 10, 2); } + /** + * Change product price in structured data + * + * @param $markup_offer + * @param $product + * @return array + * @since 1.6.0 + */ + /*public static function override_structured_data($markup_offer, $product) + { + if(self::$default_price > 0) { + $formated_price = wc_format_decimal(self::$default_price, wc_get_price_decimals()); + $markup_offer['price'] = $formated_price; + $markup_offer['priceSpecification']['price'] = $formated_price; + } + return $markup_offer; + }*/ + /** * Add styles and scripts to the product page * @@ -64,6 +87,20 @@ public static function enqueue_scripts() $fieldset->add_action_price_block(); } + /*$default_price = 0; + $fieldset = FieldsetProduct::getInstance(); + $fieldset->init(); + $fieldset->set_default_input(); + if ($fieldset->validate(true)) { + try { + $default_price = $fieldset->calculate_minimum(); + $default_price = $default_price['value']; + } catch (\Exception $e) { + $default_price = 0; + } + } + self::$default_price = $default_price;*/ + /* * "Price.min.css" forces price block to be hidden. * Price blocks should be visible if the product is type of "variable" and user has selected 'variation_prices_visible' option. @@ -227,7 +264,9 @@ public static function validate_fields_on_product_page($validation, $product_id, */ public static function price_block() { - echo View::render('woocommerce/price_block'); + echo View::render('woocommerce/price_block', array( + 'default_price' => self::$default_price + )); } /** diff --git a/views/admin/expression.php b/views/admin/expression.php index 6b90393..6608e67 100644 --- a/views/admin/expression.php +++ b/views/admin/expression.php @@ -128,6 +128,7 @@ class="first-selected"> + diff --git a/views/fields/admin/fileupload.php b/views/fields/admin/fileupload.php index 9266a99..9fce47b 100644 --- a/views/fields/admin/fileupload.php +++ b/views/fields/admin/fileupload.php @@ -2,7 +2,9 @@ if (!defined('ABSPATH')) { exit; } + use WCKalkulator\Helper; + ?> + - - \ No newline at end of file + + + + + + + \ No newline at end of file diff --git a/views/fields/front/dropdown.php b/views/fields/front/dropdown.php index bd5b26c..cc7b66e 100644 --- a/views/fields/front/dropdown.php +++ b/views/fields/front/dropdown.php @@ -14,6 +14,7 @@ ', $view->field_type)); ?> - + class="wck_imageupload id); ?>" + name="name); ?>" + accept="accept); ?>" + data-maxfilesize="max_file_size); ?>"required); ?>> \ No newline at end of file diff --git a/views/fields/front/html.php b/views/fields/front/html.php index 861d0c6..7296e28 100644 --- a/views/fields/front/html.php +++ b/views/fields/front/html.php @@ -3,7 +3,7 @@ exit; } ?> - +"> ', $view->field_type)); ?> content); ?> diff --git a/views/fields/front/select.php b/views/fields/front/select.php index d87932c..7b0ad81 100644 --- a/views/fields/front/select.php +++ b/views/fields/front/select.php @@ -13,6 +13,7 @@ ', $view->field_type)); ?>