diff --git a/Gruntfile.js b/Gruntfile.js index cf9b2285a..6236889cc 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -28,7 +28,8 @@ module.exports = function( grunt) { // one to one front: { files: { - '<%= dirs.css %>/frontend-forms.css': '<%= dirs.less %>/frontend-forms.less' + '<%= dirs.css %>/frontend-forms.css': '<%= dirs.less %>/frontend-forms.less', + '<%= dirs.css %>/elementor-frontend-forms.css': '<%= dirs.less %>/elementor-frontend-forms.less' } }, diff --git a/assets/css/elementor-frontend-forms.css b/assets/css/elementor-frontend-forms.css new file mode 100644 index 000000000..c46f8e910 --- /dev/null +++ b/assets/css/elementor-frontend-forms.css @@ -0,0 +1,197 @@ +/** + * DESCRIPTION: Elementor-specific WPUF frontend form styles + * + * This file contains form styles scoped to the Elementor widget wrapper + * to avoid conflicts with the theme and provide better Elementor integration. + * + * @package WPUF\Elementor + */ +.wpuf-elementor-widget-wrapper { + --wpuf-border-color: #dadbdd; + --wpuf-border-radius: 7px; + --wpuf-text-color: #606266; + --wpuf-primary-color: #1a7efb; + --wpuf-danger-color: #F56C6C; +} +.wpuf-elementor-widget-wrapper .wpuf-fields input[type="text"], +.wpuf-elementor-widget-wrapper .wpuf-fields input[type="email"], +.wpuf-elementor-widget-wrapper .wpuf-fields input[type="url"], +.wpuf-elementor-widget-wrapper .wpuf-fields input[type="password"], +.wpuf-elementor-widget-wrapper .wpuf-fields input[type="number"], +.wpuf-elementor-widget-wrapper .wpuf-fields input[type="tel"], +.wpuf-elementor-widget-wrapper .wpuf-fields textarea, +.wpuf-elementor-widget-wrapper .wpuf-fields select { + padding: 12px 15px; + color: var(--wpuf-text-color); + border: 1px solid var(--wpuf-border-color); + border-radius: var(--wpuf-border-radius); + transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; + margin-bottom: 0; + width: 100%; +} +.wpuf-elementor-widget-wrapper .wpuf-fields input[type="text"]:focus, +.wpuf-elementor-widget-wrapper .wpuf-fields input[type="email"]:focus, +.wpuf-elementor-widget-wrapper .wpuf-fields input[type="url"]:focus, +.wpuf-elementor-widget-wrapper .wpuf-fields input[type="password"]:focus, +.wpuf-elementor-widget-wrapper .wpuf-fields input[type="number"]:focus, +.wpuf-elementor-widget-wrapper .wpuf-fields input[type="tel"]:focus, +.wpuf-elementor-widget-wrapper .wpuf-fields textarea:focus, +.wpuf-elementor-widget-wrapper .wpuf-fields select:focus { + color: var(--wpuf-text-color); + background-color: #fff; + border-color: var(--wpuf-primary-color); + outline: none; + box-shadow: 0 0 0 2px rgba(26, 126, 251, 0.1); +} +.wpuf-elementor-widget-wrapper .wpuf-fields .wpuf-radio-block, +.wpuf-elementor-widget-wrapper .wpuf-fields .wpuf-checkbox-block { + display: flex; + align-items: center; + margin-bottom: 6px; +} +.wpuf-elementor-widget-wrapper ul.wpuf-form { + list-style: none; +} +.wpuf-elementor-widget-wrapper ul.wpuf-form li:not(:first-child) { + margin-top: 2rem; +} +.wpuf-elementor-widget-wrapper ul.wpuf-form li.wpuf-el .wpuf-label { + margin-bottom: 1rem; +} +.wpuf-elementor-widget-wrapper[data-align="left"] { + margin: 0 auto 0 0; +} +.wpuf-elementor-widget-wrapper[data-align="center"] { + margin: 0 auto; +} +.wpuf-elementor-widget-wrapper[data-align="right"] { + margin: 0 0 0 auto; +} +.wpuf-elementor-widget-wrapper.wpuf-elementor-submit-full .wpuf-submit .wpuf-submit-button { + width: 100%; + display: block; +} +.wpuf-elementor-widget-wrapper.wpuf-elementor-upload-full .wpuf-attachment-upload-filelist .file-selector { + width: 100%; + display: block; +} +.wpuf-elementor-widget-wrapper.wpuf-elementor-hide-labels .wpuf-label { + display: none !important; +} +.wpuf-elementor-widget-wrapper.wpuf-elementor-hide-errors .wpuf-error, +.wpuf-elementor-widget-wrapper.wpuf-elementor-hide-errors .error { + display: none; +} +.wpuf-elementor-widget-wrapper.wpuf-elementor-hide-placeholder input::-webkit-input-placeholder, +.wpuf-elementor-widget-wrapper.wpuf-elementor-hide-placeholder textarea::-webkit-input-placeholder { + opacity: 0; + visibility: hidden; +} +.wpuf-elementor-widget-wrapper.wpuf-elementor-hide-placeholder input::-moz-placeholder, +.wpuf-elementor-widget-wrapper.wpuf-elementor-hide-placeholder textarea::-moz-placeholder { + opacity: 0; + visibility: hidden; +} +.wpuf-elementor-widget-wrapper.wpuf-elementor-hide-placeholder input:-moz-placeholder, +.wpuf-elementor-widget-wrapper.wpuf-elementor-hide-placeholder textarea:-moz-placeholder { + opacity: 0; + visibility: hidden; +} +.wpuf-elementor-widget-wrapper.wpuf-elementor-hide-placeholder input:-ms-input-placeholder, +.wpuf-elementor-widget-wrapper.wpuf-elementor-hide-placeholder textarea:-ms-input-placeholder { + opacity: 0; + visibility: hidden; +} +.wpuf-elementor-widget-wrapper.wpuf-elementor-hide-placeholder input::-ms-input-placeholder, +.wpuf-elementor-widget-wrapper.wpuf-elementor-hide-placeholder textarea::-ms-input-placeholder { + opacity: 0; + visibility: hidden; +} +.wpuf-elementor-widget-wrapper.wpuf-elementor-custom-radio-checkbox input[type="checkbox"], +.wpuf-elementor-widget-wrapper.wpuf-elementor-custom-radio-checkbox input[type="radio"] { + outline: none; + min-width: 1px; + width: 15px; + height: 15px; + background: #ddd; + padding: 3px; +} +.wpuf-elementor-widget-wrapper.wpuf-elementor-custom-radio-checkbox input[type="radio"] { + border-radius: 50%; +} +.wpuf-elementor-widget-wrapper.wpuf-elementor-submit-center .wpuf-submit { + text-align: center; +} +.wpuf-elementor-widget-wrapper.wpuf-elementor-submit-center .wpuf-submit .wpuf-submit-button { + margin: 0 auto; + display: inline-flex; + align-items: center; + justify-content: center; +} +.wpuf-elementor-widget-wrapper.wpuf-elementor-submit-right .wpuf-submit { + text-align: right; +} +.wpuf-elementor-widget-wrapper.wpuf-elementor-submit-left .wpuf-submit { + text-align: left; +} +.wpuf-elementor-widget-wrapper .wpuf-math-captcha .captcha { + display: flex; + align-items: center; + gap: 10px; + flex-wrap: wrap; +} +.wpuf-elementor-widget-wrapper .wpuf-math-captcha .captcha .refresh { + cursor: pointer; + transition: opacity 0.2s ease; +} +.wpuf-elementor-widget-wrapper .wpuf-math-captcha .captcha .refresh:hover { + opacity: 0.7; +} +.wpuf-elementor-widget-wrapper .wpuf-math-captcha .captcha .refresh svg { + display: block; +} +.wpuf-elementor-widget-wrapper .wpuf-math-captcha .captcha .captcha-number-area .captcha-number { + display: flex; + align-items: center; + gap: 5px; + margin: 0; + font-size: 16px; + font-weight: 500; + color: var(--wpuf-text-color); +} +.wpuf-elementor-widget-wrapper .wpuf-math-captcha .captcha .captcha-equal { + font-size: 18px; + font-weight: 600; + color: var(--wpuf-text-color); +} +.wpuf-elementor-widget-wrapper .wpuf-math-captcha .captcha .wpuf-captcha-input-wrapper { + flex: 1; + min-width: 80px; + position: relative; +} +.wpuf-elementor-widget-wrapper .wpuf-math-captcha .captcha .wpuf-captcha-input-wrapper .wpuf-captcha-input { + padding: 11px 15px; + color: var(--wpuf-text-color); + border: 1px solid var(--wpuf-border-color); + border-radius: var(--wpuf-border-radius); + transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; + margin-bottom: 0; + width: 100%; + font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; +} +.wpuf-elementor-widget-wrapper .wpuf-math-captcha .captcha .wpuf-captcha-input-wrapper .wpuf-captcha-input:focus { + color: var(--wpuf-text-color); + background-color: #fff; + border-color: var(--wpuf-primary-color); + outline: none; + box-shadow: 0 0 0 2px rgba(26, 126, 251, 0.1); +} +.wpuf-elementor-widget-wrapper .wpuf-math-captcha .captcha .wpuf-captcha-input-wrapper .wpuf-captcha-error { + display: block; + margin-top: 5px; + font-size: 13px; + color: var(--wpuf-danger-color); +} +.lity { + z-index: 9999 !important; +} diff --git a/assets/css/elementor-subscription-plans.css b/assets/css/elementor-subscription-plans.css new file mode 100644 index 000000000..53d3c8301 --- /dev/null +++ b/assets/css/elementor-subscription-plans.css @@ -0,0 +1,195 @@ +/** + * DESCRIPTION: Elementor-specific WPUF subscription plans styles + * + * This file contains subscription plans display styles scoped to the + * Elementor widget wrapper to avoid conflicts with the theme. + * Design values (colors, fonts, spacing) are controlled by Elementor widget settings. + * + * @package WPUF\Elementor + */ + +/* Widget Container */ +.wpuf-subscription-plans-wrapper { + width: 100%; + margin: 0 auto; +} + +/* Grid Layout */ +.wpuf-subscription-plans-grid { + display: grid; +} + +/* Responsive: Mobile - 1 column */ +@media (max-width: 767px) { + .wpuf-subscription-plans-grid { + grid-template-columns: 1fr; + } +} + +/* Plans Per Row: 1 column */ +.wpuf-subscription-plans-wrapper.wpuf-sub-plans-1 .wpuf-subscription-plans-grid { + grid-template-columns: 1fr; +} + +/* Plans Per Row: 2 columns */ +@media (min-width: 768px) { + .wpuf-subscription-plans-wrapper.wpuf-sub-plans-2 .wpuf-subscription-plans-grid { + grid-template-columns: repeat(2, 1fr); + } +} + +/* Plans Per Row: 3 columns */ +@media (min-width: 768px) { + .wpuf-subscription-plans-wrapper.wpuf-sub-plans-3 .wpuf-subscription-plans-grid { + grid-template-columns: repeat(3, 1fr); + } +} + +/* Plans Per Row: 4 columns */ +@media (min-width: 768px) { + .wpuf-subscription-plans-wrapper.wpuf-sub-plans-4 .wpuf-subscription-plans-grid { + grid-template-columns: repeat(4, 1fr); + } +} + +/* Plan Card */ +.wpuf-sub-card { + transition: box-shadow 0.3s ease, transform 0.3s ease; +} + +.wpuf-sub-card:hover { + box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.1); +} + +/* Plan Name */ +.wpuf-sub-plan-name { + margin: 0 0 0 0; + line-height: 1.3; +} + +/* Description */ +.wpuf-sub-description { + margin-bottom: 20px; + line-height: 1.6; +} + +.wpuf-sub-description p { + margin: 0 0 12px 0; +} + +.wpuf-sub-description p:last-child { + margin-bottom: 0; +} + +/* Price Wrapper */ +.wpuf-sub-price-wrapper { + margin-bottom: 20px; +} + +/* Price */ +.wpuf-sub-price { + display: flex; + align-items: baseline; + flex-wrap: wrap; + gap: 4px; + line-height: 1.2; +} + +/* Trial Description */ +.wpuf-sub-trial-description { + margin-bottom: 20px; + line-height: 1.5; +} + +/* Button Wrapper */ +.wpuf-sub-button-wrapper { + margin-bottom: 20px; +} + +/* Subscribe Button */ +.wpuf-sub-button { + display: inline-block; + text-align: center; + text-decoration: none; + transition: all 0.2s ease; + cursor: pointer; +} + +.wpuf-sub-button:hover { + opacity: 0.9; +} + +.wpuf-sub-button-disabled { + opacity: 0.6; + cursor: not-allowed; + pointer-events: none; +} + +/* Features List */ +.wpuf-sub-features-list { + list-style: none; + margin: 0; + padding: 0; +} + +.wpuf-sub-feature-item { + display: flex; + align-items: flex-start; + gap: 12px; + line-height: 1.5; +} + +.wpuf-sub-feature-item:last-child { + margin-bottom: 0; +} + +.wpuf-sub-feature-icon { + flex-shrink: 0; + margin-top: 2px; +} + +.wpuf-sub-feature-hidden { + display: none; +} + +/* Features Toggle Button */ +.wpuf-sub-features-toggle-wrapper { + margin-top: 16px; +} + +.wpuf-sub-features-toggle { + background: none; + border: none; + padding: 0; + cursor: pointer; + text-decoration: none; + transition: opacity 0.2s ease; +} + +.wpuf-sub-features-toggle:hover { + opacity: 0.8; +} + +/* Empty State (Editor) */ +.wpuf-subscription-empty-state { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding: 60px 20px; + text-align: center; + border: 2px dashed #d1d5db; + border-radius: 12px; +} + +.wpuf-subscription-empty-icon { + margin-bottom: 16px; +} + +.wpuf-subscription-empty-text { + margin: 0 0 8px 0; +} + +.wpuf-subscription-empty-hint { + margin: 0; +} diff --git a/assets/js/elementor-subscription-plans.js b/assets/js/elementor-subscription-plans.js new file mode 100644 index 000000000..32042b79c --- /dev/null +++ b/assets/js/elementor-subscription-plans.js @@ -0,0 +1,44 @@ +/** + * DESCRIPTION: Elementor subscription plans widget JavaScript + * + * Handles the expandable features list functionality for the + * subscription plans widget. + * + * @package WPUF\Elementor + */ + +(function() { + 'use strict'; + + // Handle feature toggle buttons + document.addEventListener('click', function(e) { + if (e.target.classList.contains('wpuf-sub-features-toggle')) { + e.preventDefault(); + var button = e.target; + var packId = button.getAttribute('data-pack-id'); + var isExpanded = button.getAttribute('data-expanded') === 'true'; + var featuresList = document.getElementById('wpuf-sub-features-list-' + packId); + var seeMoreBtn = featuresList.parentElement.querySelector('.wpuf-sub-features-see-more'); + var seeLessBtn = featuresList.parentElement.querySelector('.wpuf-sub-features-see-less'); + var hiddenItems = featuresList.querySelectorAll('.wpuf-sub-feature-hidden'); + + if (isExpanded) { + // Collapse + hiddenItems.forEach(function(item) { + item.style.display = 'none'; + }); + seeMoreBtn.style.display = ''; + seeLessBtn.style.display = 'none'; + button.setAttribute('data-expanded', 'false'); + } else { + // Expand + hiddenItems.forEach(function(item) { + item.style.display = 'flex'; + }); + seeMoreBtn.style.display = 'none'; + seeLessBtn.style.display = ''; + seeLessBtn.setAttribute('data-expanded', 'true'); + } + } + }); +})(); diff --git a/assets/less/elementor-frontend-forms.less b/assets/less/elementor-frontend-forms.less new file mode 100644 index 000000000..553e0973c --- /dev/null +++ b/assets/less/elementor-frontend-forms.less @@ -0,0 +1,254 @@ +/** + * DESCRIPTION: Elementor-specific WPUF frontend form styles + * + * This file contains form styles scoped to the Elementor widget wrapper + * to avoid conflicts with the theme and provide better Elementor integration. + * + * @package WPUF\Elementor + */ + +// ============================================ +// CSS Custom Properties (Variables) +// ============================================ + +.wpuf-elementor-widget-wrapper { + --wpuf-border-color: #dadbdd; + --wpuf-border-radius: 7px; + --wpuf-text-color: #606266; + --wpuf-primary-color: #1a7efb; + --wpuf-danger-color: #F56C6C; + + // ============================================ + // Base Input Styles + // ============================================ + + .wpuf-fields input[type="text"], + .wpuf-fields input[type="email"], + .wpuf-fields input[type="url"], + .wpuf-fields input[type="password"], + .wpuf-fields input[type="number"], + .wpuf-fields input[type="tel"], + .wpuf-fields textarea, + .wpuf-fields select { + padding: 12px 15px; + color: var(--wpuf-text-color); + border: 1px solid var(--wpuf-border-color); + border-radius: var(--wpuf-border-radius); + transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; + margin-bottom: 0; + width: 100%; + + &:focus { + color: var(--wpuf-text-color); + background-color: #fff; + border-color: var(--wpuf-primary-color); + outline: none; + box-shadow: 0 0 0 2px rgba(26, 126, 251, 0.1); + } + } + + .wpuf-fields .wpuf-radio-block, + .wpuf-fields .wpuf-checkbox-block { + display: flex; + align-items: center; + margin-bottom: 6px; + } + + ul.wpuf-form { + list-style: none; + + li:not(:first-child) { + margin-top: 2rem; + } + + li.wpuf-el { + .wpuf-label { + margin-bottom: 1rem; + } + + } + } + + // Container alignment based on data-align attribute + &[data-align="left"] { + margin: 0 auto 0 0; + } + + &[data-align="center"] { + margin: 0 auto; + } + + &[data-align="right"] { + margin: 0 0 0 auto; + } + + // Full width submit button + &.wpuf-elementor-submit-full .wpuf-submit .wpuf-submit-button { + width: 100%; + display: block; + } + + // Full width upload button + &.wpuf-elementor-upload-full .wpuf-attachment-upload-filelist .file-selector { + width: 100%; + display: block; + } + + // Hide labels option + &.wpuf-elementor-hide-labels .wpuf-label { + display: none !important; + } + + // Hide error messages option + &.wpuf-elementor-hide-errors .wpuf-error, + &.wpuf-elementor-hide-errors .error { + display: none; + } + + // Hide placeholder option + &.wpuf-elementor-hide-placeholder input::-webkit-input-placeholder, + &.wpuf-elementor-hide-placeholder textarea::-webkit-input-placeholder { + opacity: 0; + visibility: hidden; + } + + &.wpuf-elementor-hide-placeholder input::-moz-placeholder, + &.wpuf-elementor-hide-placeholder textarea::-moz-placeholder { + opacity: 0; + visibility: hidden; + } + + &.wpuf-elementor-hide-placeholder input:-moz-placeholder, + &.wpuf-elementor-hide-placeholder textarea:-moz-placeholder { + opacity: 0; + visibility: hidden; + } + + &.wpuf-elementor-hide-placeholder input:-ms-input-placeholder, + &.wpuf-elementor-hide-placeholder textarea:-ms-input-placeholder { + opacity: 0; + visibility: hidden; + } + + &.wpuf-elementor-hide-placeholder input::-ms-input-placeholder, + &.wpuf-elementor-hide-placeholder textarea::-ms-input-placeholder { + opacity: 0; + visibility: hidden; + } + + // Custom radio/checkbox styling + &.wpuf-elementor-custom-radio-checkbox input[type="checkbox"], + &.wpuf-elementor-custom-radio-checkbox input[type="radio"] { + outline: none; + min-width: 1px; + width: 15px; + height: 15px; + background: #ddd; + padding: 3px; + } + + &.wpuf-elementor-custom-radio-checkbox input[type="radio"] { + border-radius: 50%; + } + + // Submit button alignment + &.wpuf-elementor-submit-center .wpuf-submit { + text-align: center; + + .wpuf-submit-button { + margin: 0 auto; + display: inline-flex; + align-items: center; + justify-content: center; + } + } + + &.wpuf-elementor-submit-right .wpuf-submit { + text-align: right; + } + + &.wpuf-elementor-submit-left .wpuf-submit { + text-align: left; + } + + // ============================================ + // Math Captcha Styles + // ============================================ + + .wpuf-math-captcha { + .captcha { + display: flex; + align-items: center; + gap: 10px; + flex-wrap: wrap; + + .refresh { + cursor: pointer; + transition: opacity 0.2s ease; + + &:hover { + opacity: 0.7; + } + + svg { + display: block; + } + } + + .captcha-number-area { + .captcha-number { + display: flex; + align-items: center; + gap: 5px; + margin: 0; + font-size: 16px; + font-weight: 500; + color: var(--wpuf-text-color); + } + } + + .captcha-equal { + font-size: 18px; + font-weight: 600; + color: var(--wpuf-text-color); + } + + .wpuf-captcha-input-wrapper { + flex: 1; + min-width: 80px; + position: relative; + + .wpuf-captcha-input { + padding: 11px 15px; + color: var(--wpuf-text-color); + border: 1px solid var(--wpuf-border-color); + border-radius: var(--wpuf-border-radius); + transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; + margin-bottom: 0; + width: 100%; + font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; + + &:focus { + color: var(--wpuf-text-color); + background-color: #fff; + border-color: var(--wpuf-primary-color); + outline: none; + box-shadow: 0 0 0 2px rgba(26, 126, 251, 0.1); + } + } + + .wpuf-captcha-error { + display: block; + margin-top: 5px; + font-size: 13px; + color: var(--wpuf-danger-color); + } + } + } + } +} + +// Ensure lity popup appears above Elementor popup +.lity { + z-index: 9999 !important; +} \ No newline at end of file diff --git a/includes/Admin/template-parts/modal-v4.2.php b/includes/Admin/template-parts/modal-v4.2.php index 94e668198..dab721df6 100644 --- a/includes/Admin/template-parts/modal-v4.2.php +++ b/includes/Admin/template-parts/modal-v4.2.php @@ -454,8 +454,6 @@ class="wpuf-btn-secondary wpuf-w-max wpuf-absolute wpuf-top-[50%] wpuf-left-[50% $( '.wpuf-ai-forms-template a' ).on( 'click', $.proxy( this.handleAIFormsClick, this ) ); $( '#ai-config-cancel' ).on( 'click', $.proxy( this.closeAIConfigModal, this ) ); $( '#ai-config-settings' ).on( 'click', $.proxy( this.goToSettings, this ) ); - } else { - console.log('NOT attaching AI click handler - AI is configured or template not found'); } }, diff --git a/includes/Assets.php b/includes/Assets.php index aa9a20372..f28e1005b 100644 --- a/includes/Assets.php +++ b/includes/Assets.php @@ -109,6 +109,12 @@ public function get_styles() { 'frontend-forms' => [ 'src' => WPUF_ASSET_URI . '/css/frontend-forms.css', ], + 'elementor-frontend-forms' => [ + 'src' => WPUF_ASSET_URI . '/css/elementor-frontend-forms.css', + ], + 'elementor-subscription-plans' => [ + 'src' => WPUF_ASSET_URI . '/css/elementor-subscription-plans.css', + ], 'frontend-subscriptions' => [ 'src' => WPUF_ASSET_URI . '/css/frontend-subscriptions.min.css', ], @@ -415,6 +421,10 @@ public function get_scripts() { 'src' => WPUF_ASSET_URI . '/js/frontend-subscriptions.min.js', 'in_footer' => true, ], + 'elementor-subscription-plans' => [ + 'src' => WPUF_ASSET_URI . '/js/elementor-subscription-plans.js', + 'in_footer' => true, + ], ]; if ( ! empty( $api_key ) ) { diff --git a/includes/Fields/Field_Contract.php b/includes/Fields/Field_Contract.php index cd714f454..7535fb11c 100755 --- a/includes/Fields/Field_Contract.php +++ b/includes/Fields/Field_Contract.php @@ -763,6 +763,33 @@ public function get_default_textarea_option_settings() { ]; } + /** + * Check if we should render admin-style markup + * + * Returns true for admin dashboard, but false for Elementor editor + * since Elementor editor needs frontend-style markup for proper preview. + * + * @since WPUF_SINCE + * + * @return bool + */ + protected function use_admin_markup() { + if ( ! is_admin() ) { + return false; + } + + // Check if we're in Elementor editor mode + // Elementor editor needs frontend markup for proper preview + if ( class_exists( '\Elementor\Plugin' ) ) { + $elementor = \Elementor\Plugin::$instance; + if ( $elementor && $elementor->editor && $elementor->editor->is_edit_mode() ) { + return false; + } + } + + return true; + } + /** * Prints form input label for admin * @@ -770,7 +797,7 @@ public function get_default_textarea_option_settings() { * @param int $form_id */ public function field_print_label( $field, $form_id = 0 ) { - if ( is_admin() ) { ?> + if ( $this->use_admin_markup() ) { ?> print_list_attributes( $field ); ?>> required_mark( $field ) ); ?> @@ -782,7 +809,7 @@ public function field_print_label( $field, $form_id = 0 ) { } public function after_field_print_label() { - if ( is_admin() ) { + if ( $this->use_admin_markup() ) { ?> diff --git a/includes/Fields/Form_Field_Post_Excerpt.php b/includes/Fields/Form_Field_Post_Excerpt.php index b3d8c9aae..636853bc9 100755 --- a/includes/Fields/Form_Field_Post_Excerpt.php +++ b/includes/Fields/Form_Field_Post_Excerpt.php @@ -56,6 +56,7 @@ public function render( $field_settings, $form_id, $type = 'post', $post_id = nu ]; $editor_settings = apply_filters( 'wpuf_textarea_editor_args', $editor_settings ); + wp_editor( $value, $textarea_id, $editor_settings ); } elseif ( ! empty( $field_settings['rich'] ) && $field_settings['rich'] == 'teeny' ) { $editor_settings = [ @@ -68,6 +69,7 @@ public function render( $field_settings, $form_id, $type = 'post', $post_id = nu ]; $editor_settings = apply_filters( 'wpuf_textarea_editor_args', $editor_settings ); + wp_editor( $value, $textarea_id, $editor_settings ); } else { ?> diff --git a/includes/Frontend.php b/includes/Frontend.php index 908332727..9785e13bf 100644 --- a/includes/Frontend.php +++ b/includes/Frontend.php @@ -68,8 +68,11 @@ public function enqueue_scripts() { // Load appropriate subscription script based on shortcode if ( wpuf_has_shortcode( 'wpuf_sub_pack' ) ) { - // Load new frontend-subscriptions script for subscription pack shortcode (pricing page) - wp_enqueue_style( 'wpuf-frontend-subscriptions' ); + // Skip loading frontend-subscriptions CSS on Elementor pages (Elementor widget has its own CSS) + $is_elementor_page = did_action( 'elementor/loaded' ) && isset( $post->ID ) && \Elementor\Plugin::$instance->db->is_built_with_elementor( $post->ID ); + if ( ! $is_elementor_page ) { + wp_enqueue_style( 'wpuf-frontend-subscriptions' ); + } wp_enqueue_script( 'wpuf-frontend-subscriptions' ); } else { // Load old subscriptions script for all other pages (dashboard, account, etc.) diff --git a/includes/Integrations.php b/includes/Integrations.php index 99bb8ea77..eca318303 100644 --- a/includes/Integrations.php +++ b/includes/Integrations.php @@ -45,6 +45,10 @@ public function __construct() { } } } + + add_action('elementor/init', function() { + $this->container['elementor'] = new Integrations\Elementor\Elementor(); + }); } /** diff --git a/includes/Integrations/Elementor/Elementor.php b/includes/Integrations/Elementor/Elementor.php new file mode 100644 index 000000000..40e5e87af --- /dev/null +++ b/includes/Integrations/Elementor/Elementor.php @@ -0,0 +1,261 @@ +enqueue_wpuf_form_assets(); + + // Ensure editor scripts are loaded for TinyMCE in Elementor preview + if ( function_exists( 'wp_enqueue_editor' ) ) { + wp_enqueue_editor(); + + // Also explicitly enqueue TinyMCE scripts if available + if ( function_exists( 'wp_enqueue_script' ) ) { + // Check if these scripts exist and enqueue them + global $wp_scripts; + if ( isset( $wp_scripts->registered['tinymce'] ) ) { + wp_enqueue_script( 'tinymce' ); + } + if ( isset( $wp_scripts->registered['wp-tinymce'] ) ) { + wp_enqueue_script( 'wp-tinymce' ); + } + } + } + + /** + * Fires after WPUF has enqueued its scripts in Elementor context. + * + * @since WPUF_SINCE + */ + do_action( 'wpuf_elementor_after_enqueue_scripts' ); + } + + /** + * Enqueue all required WPUF form assets for Elementor + * + * Ensures all necessary styles and scripts are loaded for WPUF forms + * to render properly in Elementor preview and frontend. + * + * @since WPUF_SINCE + * + * @return void + */ + private function enqueue_wpuf_form_assets() { + // Core styles (already handled by enqueue_styles, but ensure they're available) + wp_enqueue_style( 'wpuf-sweetalert2' ); + wp_enqueue_style( 'wpuf-jquery-ui' ); + + // Core scripts required for all WPUF forms + wp_enqueue_script( 'suggest' ); + wp_enqueue_script( 'wpuf-billing-address' ); + wp_enqueue_script( 'wpuf-upload' ); + wp_enqueue_script( 'wpuf-frontend-form' ); + wp_enqueue_script( 'wpuf-sweetalert2' ); + wp_enqueue_script( 'wpuf-subscriptions' ); + + // Localize wpuf-upload script + wp_localize_script( + 'wpuf-upload', + 'wpuf_upload', + [ + 'confirmMsg' => __( 'Are you sure?', 'wp-user-frontend' ), + 'delete_it' => __( 'Yes, delete it', 'wp-user-frontend' ), + 'cancel_it' => __( 'No, cancel it', 'wp-user-frontend' ), + 'ajaxurl' => admin_url( 'admin-ajax.php' ), + 'nonce' => wp_create_nonce( 'wpuf_nonce' ), + 'plupload' => [ + 'url' => admin_url( 'admin-ajax.php' ) . '?nonce=' . wp_create_nonce( 'wpuf-upload-nonce' ), + 'flash_swf_url' => includes_url( 'js/plupload/plupload.flash.swf' ), + 'filters' => [ + [ + 'title' => __( 'Allowed Files', 'wp-user-frontend' ), + 'extensions' => '*', + ], + ], + 'multipart' => true, + 'urlstream_upload' => true, + 'warning' => __( 'Maximum number of files reached!', 'wp-user-frontend' ), + 'size_error' => __( 'The file you have uploaded exceeds the file size limit. Please try again.', 'wp-user-frontend' ), + 'type_error' => __( 'You have uploaded an incorrect file type. Please try again.', 'wp-user-frontend' ), + ], + ] + ); + + // Localize wpuf-frontend-form script + wp_localize_script( + 'wpuf-frontend-form', + 'wpuf_frontend', + apply_filters( + 'wpuf_frontend_object', + [ + 'asset_url' => WPUF_ASSET_URI, + 'ajaxurl' => admin_url( 'admin-ajax.php' ), + 'error_message' => __( 'Please fix the errors to proceed', 'wp-user-frontend' ), + 'nonce' => wp_create_nonce( 'wpuf_nonce' ), + 'word_limit' => __( 'Word limit reached', 'wp-user-frontend' ), + 'cancelSubMsg' => __( 'Are you sure you want to cancel your current subscription ?', 'wp-user-frontend' ), + 'delete_it' => __( 'Yes', 'wp-user-frontend' ), + 'cancel_it' => __( 'No', 'wp-user-frontend' ), + 'word_max_title' => __( 'Maximum word limit reached. Please shorten your texts.', 'wp-user-frontend' ), + 'word_max_details' => __( 'This field supports a maximum of %number% words, and the limit is reached. Remove a few words to reach the acceptable limit of the field.', 'wp-user-frontend' ), + 'word_min_title' => __( 'Minimum word required.', 'wp-user-frontend' ), + 'word_min_details' => __( 'This field requires minimum %number% words. Please add some more text.', 'wp-user-frontend' ), + 'char_max_title' => __( 'Maximum character limit reached. Please shorten your texts.', 'wp-user-frontend' ), + 'char_max_details' => __( 'This field supports a maximum of %number% characters, and the limit is reached. Remove a few characters to reach the acceptable limit of the field.', 'wp-user-frontend' ), + 'char_min_title' => __( 'Minimum character required.', 'wp-user-frontend' ), + 'char_min_details' => __( 'This field requires minimum %number% characters. Please add some more character.', 'wp-user-frontend' ), + 'protected_shortcodes' => wpuf_get_protected_shortcodes(), + 'protected_shortcodes_message' => __( 'Using %shortcode% is restricted', 'wp-user-frontend' ), + 'password_warning_weak' => __( 'Your password should be at least weak in strength', 'wp-user-frontend' ), + 'password_warning_medium' => __( 'Your password needs to be medium strength for better protection', 'wp-user-frontend' ), + 'password_warning_strong' => __( 'Create a strong password for maximum security', 'wp-user-frontend' ), + ] + ) + ); + + wp_localize_script( + 'wpuf-frontend-form', + 'error_str_obj', + [ + 'required' => __( 'is required', 'wp-user-frontend' ), + 'mismatch' => __( 'does not match', 'wp-user-frontend' ), + 'validation' => __( 'is not valid', 'wp-user-frontend' ), + ] + ); + + // Localize subscription script + wp_localize_script( + 'wpuf-subscriptions', + 'wpuf_subscription', + apply_filters( + 'wpuf_subscription_js_data', + [ + 'pack_notice' => __( 'Please Cancel Your Currently Active Pack first!', 'wp-user-frontend' ), + ] + ) + ); + + // Localize billing address script + wp_localize_script( + 'wpuf-billing-address', + 'ajax_object', + [ + 'ajaxurl' => admin_url( 'admin-ajax.php' ), + 'fill_notice' => __( 'Some Required Fields are not filled!', 'wp-user-frontend' ), + ] + ); + + // Conditionally enqueue Google Maps if API key is configured + $api_key = wpuf_get_option( 'gmap_api_key', 'wpuf_general' ); + if ( ! empty( $api_key ) ) { + $scheme = is_ssl() ? 'https' : 'http'; + wp_enqueue_script( 'wpuf-google-maps', $scheme . '://maps.google.com/maps/api/js?libraries=places&key=' . $api_key, [], null, true ); + } + } + + /** + * Register Elementor Widget Category + * + * @param \Elementor\Elements_Manager $elements_manager + * + * @return void + */ + public function register_category( $elements_manager ) { + $elements_manager->add_category( + 'user-frontend', + [ + 'title' => __( 'User Frontend', 'wp-user-frontend' ), + 'icon' => 'eicon-form-horizontal', + ] + ); + } + + /** + * Register Elementor Widgets + * + * @param \Elementor\Widgets_Manager $widgets_manager + * + * @return void + */ + public function register_widgets( $widgets_manager ) { + require_once __DIR__ . '/Widget.php'; + require_once __DIR__ . '/Subscription_Plans_Widget.php'; + + $widgets_manager->register( new Widget() ); + $widgets_manager->register( new Subscription_Plans_Widget() ); + } +} diff --git a/includes/Integrations/Elementor/Subscription_Plans_Widget.php b/includes/Integrations/Elementor/Subscription_Plans_Widget.php new file mode 100644 index 000000000..1e5848bba --- /dev/null +++ b/includes/Integrations/Elementor/Subscription_Plans_Widget.php @@ -0,0 +1,1506 @@ +register_content_controls(); + + // Style Controls + $this->register_container_style_controls(); + $this->register_plan_name_style_controls(); + $this->register_price_style_controls(); + $this->register_trial_description_style_controls(); + $this->register_features_list_style_controls(); + $this->register_button_style_controls(); + } + + /** + * Register content controls + * + * @since WPUF_SINCE + * + * @return void + */ + protected function register_content_controls() { + $this->start_controls_section( + 'section_content', + [ + 'label' => __( 'Content', 'wp-user-frontend' ), + ] + ); + + $this->add_control( + 'plans_per_row', + [ + 'label' => __( 'Plans Per Row', 'wp-user-frontend' ), + 'type' => Controls_Manager::SELECT, + 'default' => '3', + 'options' => [ + '1' => __( '1', 'wp-user-frontend' ), + '2' => __( '2', 'wp-user-frontend' ), + '3' => __( '3', 'wp-user-frontend' ), + '4' => __( '4', 'wp-user-frontend' ), + ], + ] + ); + + $this->add_control( + 'order_by', + [ + 'label' => __( 'Order By', 'wp-user-frontend' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'custom', + 'description' => __( 'Choose how to sort the subscription plans. Custom Order uses the sort order set in each plan\'s settings.', 'wp-user-frontend' ), + 'options' => [ + 'custom' => __( 'Custom Order', 'wp-user-frontend' ), + 'id' => __( 'Plan ID', 'wp-user-frontend' ), + 'price_asc' => __( 'Price (Low to High)', 'wp-user-frontend' ), + 'price_desc' => __( 'Price (High to Low)', 'wp-user-frontend' ), + ], + ] + ); + + $this->end_controls_section(); + } + + /** + * Register container style controls + * + * @since WPUF_SINCE + * + * @return void + */ + protected function register_container_style_controls() { + $this->start_controls_section( + 'section_container_style', + [ + 'label' => __( 'Container', 'wp-user-frontend' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_responsive_control( + 'container_width', + [ + 'label' => __( 'Container Width', 'wp-user-frontend' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', '%' ], + 'range' => [ + 'px' => [ 'min' => 100, 'max' => 1500 ], + '%' => [ 'min' => 10, 'max' => 100 ], + ], + 'selectors' => [ + '{{WRAPPER}} .wpuf-subscription-plans-wrapper' => 'max-width: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'container_bg_color', + [ + 'label' => __( 'Background Color', 'wp-user-frontend' ), + 'type' => Controls_Manager::COLOR, + 'default' => '#ffffff', + 'selectors' => [ + '{{WRAPPER}} .wpuf-sub-card' => 'background-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Border::get_type(), + [ + 'name' => 'card_border', + 'selector' => '{{WRAPPER}} .wpuf-sub-card', + 'fields_options' => [ + 'border' => [ + 'default' => 'solid', + ], + 'width' => [ + 'default' => [ + 'top' => '1', + 'right' => '1', + 'bottom' => '1', + 'left' => '1', + 'isLinked' => true, + ], + ], + 'color' => [ + 'default' => '#e5e7eb', + ], + ], + ] + ); + + $this->add_control( + 'card_border_radius', + [ + 'label' => __( 'Border Radius', 'wp-user-frontend' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%' ], + 'default' => [ + 'top' => '12', + 'right' => '12', + 'bottom' => '12', + 'left' => '12', + 'isLinked' => true, + ], + 'selectors' => [ + '{{WRAPPER}} .wpuf-sub-card' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'card_box_shadow', + 'selector' => '{{WRAPPER}} .wpuf-sub-card', + ] + ); + + $this->add_responsive_control( + 'card_padding', + [ + 'label' => __( 'Card Padding', 'wp-user-frontend' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', 'em', '%' ], + 'default' => [ + 'top' => '24', + 'right' => '24', + 'bottom' => '24', + 'left' => '24', + 'isLinked' => true, + ], + 'selectors' => [ + '{{WRAPPER}} .wpuf-sub-card' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'card_margin', + [ + 'label' => __( 'Card Margin', 'wp-user-frontend' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', 'em', '%' ], + 'selectors' => [ + '{{WRAPPER}} .wpuf-sub-card' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'cards_gap', + [ + 'label' => __( 'Gap Between Cards', 'wp-user-frontend' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px' ], + 'range' => [ 'px' => [ 'min' => 0, 'max' => 100 ] ], + 'default' => [ + 'size' => '20', + 'unit' => 'px', + ], + 'selectors' => [ + '{{WRAPPER}} .wpuf-subscription-plans-grid' => 'gap: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->end_controls_section(); + } + + /** + * Register plan name style controls + * + * @since WPUF_SINCE + * + * @return void + */ + protected function register_plan_name_style_controls() { + $this->start_controls_section( + 'section_plan_name_style', + [ + 'label' => __( 'Plan Name', 'wp-user-frontend' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'plan_name_color', + [ + 'label' => __( 'Text Color', 'wp-user-frontend' ), + 'type' => Controls_Manager::COLOR, + 'default' => '#111827', + 'selectors' => [ + '{{WRAPPER}} .wpuf-sub-plan-name' => 'color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'plan_name_typography', + 'selector' => '{{WRAPPER}} .wpuf-sub-plan-name', + 'fields_options' => [ + 'font_size' => [ + 'default' => [ + 'size' => '24', + 'unit' => 'px', + ], + ], + 'font_weight' => [ + 'default' => '700', + ], + ], + ] + ); + + $this->add_responsive_control( + 'plan_name_align', + [ + 'label' => __( 'Text Alignment', 'wp-user-frontend' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'left' => [ 'title' => __( 'Left', 'wp-user-frontend' ), 'icon' => 'eicon-text-align-left' ], + 'center' => [ 'title' => __( 'Center', 'wp-user-frontend' ), 'icon' => 'eicon-text-align-center' ], + 'right' => [ 'title' => __( 'Right', 'wp-user-frontend' ), 'icon' => 'eicon-text-align-right' ], + ], + 'default' => 'left', + 'selectors' => [ + '{{WRAPPER}} .wpuf-sub-plan-name' => 'text-align: {{VALUE}};', + ], + ] + ); + + $this->add_responsive_control( + 'plan_name_margin_bottom', + [ + 'label' => __( 'Margin Bottom', 'wp-user-frontend' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px' ], + 'range' => [ 'px' => [ 'min' => 0, 'max' => 50 ] ], + 'default' => [ + 'size' => '16', + 'unit' => 'px', + ], + 'selectors' => [ + '{{WRAPPER}} .wpuf-sub-plan-name' => 'margin-bottom: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->end_controls_section(); + } + + /** + * Register price style controls + * + * @since WPUF_SINCE + * + * @return void + */ + protected function register_price_style_controls() { + $this->start_controls_section( + 'section_price_style', + [ + 'label' => __( 'Price', 'wp-user-frontend' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'price_color', + [ + 'label' => __( 'Text Color', 'wp-user-frontend' ), + 'type' => Controls_Manager::COLOR, + 'default' => '#111827', + 'selectors' => [ + '{{WRAPPER}} .wpuf-sub-price' => 'color: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'currency_color', + [ + 'label' => __( 'Currency Symbol Color', 'wp-user-frontend' ), + 'type' => Controls_Manager::COLOR, + 'default' => '#6b7280', + 'selectors' => [ + '{{WRAPPER}} .wpuf-sub-currency' => 'color: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'billing_cycle_color', + [ + 'label' => __( 'Billing Cycle Text Color', 'wp-user-frontend' ), + 'type' => Controls_Manager::COLOR, + 'default' => '#6b7280', + 'selectors' => [ + '{{WRAPPER}} .wpuf-sub-billing-cycle' => 'color: {{VALUE}};', + ], + ] + ); + + $this->add_responsive_control( + 'billing_cycle_font_size', + [ + 'label' => __( 'Billing Cycle Text Size', 'wp-user-frontend' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em' ], + 'range' => [ 'px' => [ 'min' => 8, 'max' => 50 ] ], + 'selectors' => [ + '{{WRAPPER}} .wpuf-sub-billing-cycle' => 'font-size: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'price_typography', + 'selector' => '{{WRAPPER}} .wpuf-sub-price', + 'fields_options' => [ + 'font_size' => [ + 'default' => [ + 'size' => '36', + 'unit' => 'px', + ], + ], + 'font_weight' => [ + 'default' => '700', + ], + ], + ] + ); + + $this->add_responsive_control( + 'price_align', + [ + 'label' => __( 'Text Alignment', 'wp-user-frontend' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'left' => [ 'title' => __( 'Left', 'wp-user-frontend' ), 'icon' => 'eicon-text-align-left' ], + 'center' => [ 'title' => __( 'Center', 'wp-user-frontend' ), 'icon' => 'eicon-text-align-center' ], + 'right' => [ 'title' => __( 'Right', 'wp-user-frontend' ), 'icon' => 'eicon-text-align-right' ], + ], + 'default' => 'left', + 'selectors' => [ + '{{WRAPPER}} .wpuf-sub-price-wrapper' => 'text-align: {{VALUE}};', + '{{WRAPPER}} .wpuf-sub-price' => 'justify-content: {{VALUE}};', + ], + ] + ); + + $this->add_responsive_control( + 'price_margin_bottom', + [ + 'label' => __( 'Margin Bottom', 'wp-user-frontend' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px' ], + 'range' => [ 'px' => [ 'min' => 0, 'max' => 50 ] ], + 'default' => [ + 'size' => '20', + 'unit' => 'px', + ], + 'selectors' => [ + '{{WRAPPER}} .wpuf-sub-price-wrapper' => 'margin-bottom: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->end_controls_section(); + } + + /** + * Register trial description style controls + * + * @since WPUF_SINCE + * + * @return void + */ + protected function register_trial_description_style_controls() { + $this->start_controls_section( + 'section_trial_style', + [ + 'label' => __( 'Trial Description', 'wp-user-frontend' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'trial_color', + [ + 'label' => __( 'Text Color', 'wp-user-frontend' ), + 'type' => Controls_Manager::COLOR, + 'default' => '#059669', + 'selectors' => [ + '{{WRAPPER}} .wpuf-sub-trial-description' => 'color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'trial_typography', + 'selector' => '{{WRAPPER}} .wpuf-sub-trial-description', + 'fields_options' => [ + 'font_size' => [ + 'default' => [ + 'size' => '14', + 'unit' => 'px', + ], + ], + ], + ] + ); + + $this->add_responsive_control( + 'trial_font_size', + [ + 'label' => __( 'Text Size', 'wp-user-frontend' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em' ], + 'range' => [ 'px' => [ 'min' => 8, 'max' => 50 ] ], + 'selectors' => [ + '{{WRAPPER}} .wpuf-sub-trial-description' => 'font-size: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'trial_align', + [ + 'label' => __( 'Text Alignment', 'wp-user-frontend' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'left' => [ 'title' => __( 'Left', 'wp-user-frontend' ), 'icon' => 'eicon-text-align-left' ], + 'center' => [ 'title' => __( 'Center', 'wp-user-frontend' ), 'icon' => 'eicon-text-align-center' ], + 'right' => [ 'title' => __( 'Right', 'wp-user-frontend' ), 'icon' => 'eicon-text-align-right' ], + ], + 'default' => 'left', + 'selectors' => [ + '{{WRAPPER}} .wpuf-sub-trial-description' => 'text-align: {{VALUE}};', + ], + ] + ); + + $this->end_controls_section(); + } + + /** + * Register features list style controls + * + * @since WPUF_SINCE + * + * @return void + */ + protected function register_features_list_style_controls() { + $this->start_controls_section( + 'section_features_style', + [ + 'label' => __( 'Features List', 'wp-user-frontend' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'features_color', + [ + 'label' => __( 'Text Color', 'wp-user-frontend' ), + 'type' => Controls_Manager::COLOR, + 'default' => '#4b5563', + 'selectors' => [ + '{{WRAPPER}} .wpuf-sub-features-list' => 'color: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'icon_color', + [ + 'label' => __( 'Icon Color', 'wp-user-frontend' ), + 'type' => Controls_Manager::COLOR, + 'default' => '#10b981', + 'selectors' => [ + '{{WRAPPER}} .wpuf-sub-feature-icon' => 'fill: {{VALUE}};', + ], + ] + ); + + $this->add_responsive_control( + 'icon_size', + [ + 'label' => __( 'Icon Size', 'wp-user-frontend' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px' ], + 'range' => [ 'px' => [ 'min' => 10, 'max' => 50 ] ], + 'default' => [ + 'size' => '20', + 'unit' => 'px', + ], + 'selectors' => [ + '{{WRAPPER}} .wpuf-sub-feature-icon' => 'width: {{SIZE}}{{UNIT}}; height: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'features_typography', + 'selector' => '{{WRAPPER}} .wpuf-sub-features-list', + 'fields_options' => [ + 'font_size' => [ + 'default' => [ + 'size' => '14', + 'unit' => 'px', + ], + ], + ], + ] + ); + + $this->add_responsive_control( + 'features_line_spacing', + [ + 'label' => __( 'Line Spacing', 'wp-user-frontend' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px' ], + 'range' => [ 'px' => [ 'min' => 0, 'max' => 50 ] ], + 'default' => [ + 'size' => '12', + 'unit' => 'px', + ], + 'selectors' => [ + '{{WRAPPER}} .wpuf-sub-feature-item' => 'margin-bottom: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'features_margin_bottom', + [ + 'label' => __( 'Margin Bottom', 'wp-user-frontend' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px' ], + 'range' => [ 'px' => [ 'min' => 0, 'max' => 50 ] ], + 'selectors' => [ + '{{WRAPPER}} .wpuf-sub-features-list' => 'margin-bottom: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->end_controls_section(); + } + + /** + * Register button style controls + * + * @since WPUF_SINCE + * + * @return void + */ + protected function register_button_style_controls() { + $this->start_controls_section( + 'section_button_style', + [ + 'label' => __( 'Subscribe Button', 'wp-user-frontend' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'button_typography', + 'selector' => '{{WRAPPER}} .wpuf-sub-button', + 'fields_options' => [ + 'font_size' => [ + 'default' => [ + 'size' => '16', + 'unit' => 'px', + ], + ], + 'font_weight' => [ + 'default' => '600', + ], + ], + ] + ); + + $this->add_responsive_control( + 'button_font_size', + [ + 'label' => __( 'Text Size', 'wp-user-frontend' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem' ], + 'range' => [ + 'px' => [ 'min' => 8, 'max' => 50 ], + 'em' => [ 'min' => 0.5, 'max' => 5 ], + 'rem' => [ 'min' => 0.5, 'max' => 5 ], + ], + 'default' => [ + 'size' => '1', + 'unit' => 'rem', + ], + 'selectors' => [ + '{{WRAPPER}} .wpuf-sub-button' => 'font-size: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'button_align', + [ + 'label' => __( 'Alignment', 'wp-user-frontend' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'left' => [ 'title' => __( 'Left', 'wp-user-frontend' ), 'icon' => 'eicon-h-align-left' ], + 'center' => [ 'title' => __( 'Center', 'wp-user-frontend' ), 'icon' => 'eicon-h-align-center' ], + 'right' => [ 'title' => __( 'Right', 'wp-user-frontend' ), 'icon' => 'eicon-h-align-right' ], + ], + 'default' => 'center', + 'selectors' => [ + '{{WRAPPER}} .wpuf-sub-button-wrapper' => 'text-align: {{VALUE}};', + ], + ] + ); + + $this->start_controls_tabs( 'tabs_button_style' ); + + $this->start_controls_tab( 'tab_button_normal', [ 'label' => __( 'Normal', 'wp-user-frontend' ) ] ); + + $this->add_control( + 'button_text_color', + [ + 'label' => __( 'Text Color', 'wp-user-frontend' ), + 'type' => Controls_Manager::COLOR, + 'default' => '#ffffff', + 'selectors' => [ + '{{WRAPPER}} .wpuf-sub-button' => 'color: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'button_bg_color', + [ + 'label' => __( 'Background Color', 'wp-user-frontend' ), + 'type' => Controls_Manager::COLOR, + 'default' => '#64748b', + 'selectors' => [ + '{{WRAPPER}} .wpuf-sub-button' => 'background-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Border::get_type(), + [ + 'name' => 'button_border', + 'selector' => '{{WRAPPER}} .wpuf-sub-button', + 'fields_options' => [ + 'border' => [ + 'default' => 'solid', + ], + 'width' => [ + 'default' => [ + 'top' => '1', + 'right' => '1', + 'bottom' => '1', + 'left' => '1', + 'isLinked' => true, + ], + ], + 'color' => [ + 'default' => 'transparent', + ], + ], + ] + ); + + $this->add_control( + 'button_border_radius', + [ + 'label' => __( 'Border Radius', 'wp-user-frontend' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%' ], + 'default' => [ + 'top' => '5', + 'right' => '5', + 'bottom' => '5', + 'left' => '5', + 'isLinked' => true, + ], + 'selectors' => [ + '{{WRAPPER}} .wpuf-sub-button' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'button_padding', + [ + 'label' => __( 'Padding', 'wp-user-frontend' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', 'em', '%' ], + 'default' => [ + 'top' => '5', + 'right' => '20', + 'bottom' => '5', + 'left' => '20', + 'isLinked' => false, + ], + 'selectors' => [ + '{{WRAPPER}} .wpuf-sub-button' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( 'tab_button_hover', [ 'label' => __( 'Hover', 'wp-user-frontend' ) ] ); + + $this->add_control( + 'button_hover_text_color', + [ + 'label' => __( 'Text Color', 'wp-user-frontend' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .wpuf-sub-button:hover' => 'color: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'button_hover_bg_color', + [ + 'label' => __( 'Background Color', 'wp-user-frontend' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .wpuf-sub-button:hover' => 'background-color: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'button_hover_border_color', + [ + 'label' => __( 'Border Color', 'wp-user-frontend' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .wpuf-sub-button:hover' => 'border-color: {{VALUE}};', + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->end_controls_section(); + } + + /** + * Retrieve subscription plans based on widget settings + * + * @since WPUF_SINCE + * + * @param array $settings Widget settings. + * @return array Array of subscription packs + */ + protected function get_subscription_plans( $settings ) { + $args = [ + 'post_type' => 'wpuf_subscription', + 'posts_per_page' => -1, + 'post_status' => 'publish', + ]; + + $order_by = isset( $settings['order_by'] ) ? $settings['order_by'] : 'custom'; + + switch ( $order_by ) { + case 'id': + $args['orderby'] = 'ID'; + $args['order'] = 'ASC'; + break; + case 'price_asc': + $args['orderby'] = 'meta_value_num'; + $args['meta_key'] = '_billing_amount'; + $args['order'] = 'ASC'; + break; + case 'price_desc': + $args['orderby'] = 'meta_value_num'; + $args['meta_key'] = '_billing_amount'; + $args['order'] = 'DESC'; + break; + case 'custom': + default: + $args['meta_key'] = '_sort_order'; + $args['orderby'] = [ 'meta_value_num' => 'ASC', 'title' => 'ASC' ]; + break; + } + + $packs = get_posts( $args ); + + if ( ! empty( $packs ) ) { + foreach ( $packs as $key => $post ) { + $packs[ $key ]->meta_value = wpuf()->subscription->get_subscription_meta( $post->ID, $post ); + } + } + + return $packs; + } + + /** + * Get the CSS class for plans per row + * + * @since WPUF_SINCE + * + * @param string $plans_per_row Number of plans per row. + * @return string CSS class + */ + protected function get_plans_per_row_class( $plans_per_row ) { + return 'wpuf-sub-plans-' . $plans_per_row; + } + + /** + * Render the widget output on the frontend + * + * @since WPUF_SINCE + * + * @return void + */ + protected function render() { + $settings = $this->get_settings_for_display(); + + $packs = $this->get_subscription_plans( $settings ); + + $is_elementor_editor = $this->is_editor_render(); + + // Show empty state in editor if no plans + if ( $is_elementor_editor && empty( $packs ) ) { + $this->render_empty_state(); + return; + } + + // Show nothing in frontend if no plans + if ( ! $is_elementor_editor && empty( $packs ) ) { + return; + } + + $plans_per_row = isset( $settings['plans_per_row'] ) ? $settings['plans_per_row'] : '3'; + $grid_class = $this->get_plans_per_row_class( $plans_per_row ); + + $this->add_render_attribute( + 'wrapper', + [ + 'class' => [ 'wpuf-subscription-plans-wrapper', $grid_class ], + ] + ); + + $user_id = get_current_user_id(); + $current_pack = wpuf()->subscription->get_user_pack( $user_id ); + $current_pack_id = isset( $current_pack['pack_id'] ) ? $current_pack['pack_id'] : ''; + $current_pack_status = isset( $current_pack['status'] ) ? $current_pack['status'] : ''; + + echo '
get_render_attribute_string( 'wrapper' ) . '>'; + echo '
'; + + foreach ( $packs as $pack ) : + $this->render_plan_card( $pack, $current_pack_id, $current_pack_status ); + endforeach; + + echo '
'; + echo '
'; + + if ( $is_elementor_editor ) { + $this->render_toggle_script(); + } + } + + /** + * Render empty state for Elementor editor + * + * @since WPUF_SINCE + * + * @return void + */ + protected function render_empty_state() { + echo '
'; + echo '
'; + echo '
'; + echo ''; + echo ''; + echo ''; + echo '
'; + echo '

' . esc_html__( 'No subscription plans available.', 'wp-user-frontend' ) . '

'; + echo '

' . esc_html__( 'Create a subscription plan in WPUF settings.', 'wp-user-frontend' ) . '

'; + echo '
'; + echo '
'; + } + + /** + * Render a single plan card + * + * @since WPUF_SINCE + * + * @param \WP_Post $pack The subscription plan post object. + * @param string $current_pack_id Current active pack ID. + * @param string $current_pack_status Current pack status. + * @return void + */ + protected function render_plan_card( $pack, $current_pack_id, $current_pack_status ) { + $settings = $this->get_settings_for_display(); + $billing_amount = isset( $pack->meta_value['billing_amount'] ) ? floatval( $pack->meta_value['billing_amount'] ) : 0; + $recurring_pay = wpuf_is_checkbox_or_toggle_on( $pack->meta_value['recurring_pay'] ?? '' ); + $trial_status = wpuf_is_checkbox_or_toggle_on( $pack->meta_value['trial_status'] ?? '' ); + $billing_cycle_number = isset( $pack->meta_value['billing_cycle_number'] ) ? $pack->meta_value['billing_cycle_number'] : 1; + $cycle_period = isset( $pack->meta_value['cycle_period'] ) ? $pack->meta_value['cycle_period'] : 'month'; + $trial_duration = isset( $pack->meta_value['trial_duration'] ) ? $pack->meta_value['trial_duration'] : 0; + $trial_duration_type = isset( $pack->meta_value['trial_duration_type'] ) ? $pack->meta_value['trial_duration_type'] : 'day'; + + $this->add_render_attribute( + 'card-' . $pack->ID, + [ + 'class' => [ 'wpuf-sub-card', 'wpuf-sub-card-' . $pack->ID ], + ] + ); + + echo '
get_render_attribute_string( 'card-' . $pack->ID ) . '>'; + + // Plan Name + echo '

' . esc_html( $pack->post_title ) . '

'; + + // Description + if ( ! empty( $pack->post_content ) ) { + echo '
' . wp_kses_post( wpautop( $pack->post_content ) ) . '
'; + } + + // Price Section + echo '
'; + if ( $billing_amount > 0 ) { + $currency_symbol = wpuf_get_currency( 'symbol' ); + $amount_formatted = number_format( $billing_amount, 2, '.', '' ); + + echo '
'; + echo '' . esc_html( $currency_symbol ) . ''; + echo '' . esc_html( $amount_formatted ) . ''; + + if ( $recurring_pay ) { + $cycle_label = wpuf()->subscription->get_cycle_label( $cycle_period, $billing_cycle_number ); + $billing_text = sprintf( __( 'Every %s %s', 'wp-user-frontend' ), $billing_cycle_number, $cycle_label ); + echo '' . esc_html( $billing_text ) . ''; + } else { + echo '' . esc_html__( 'One time payment', 'wp-user-frontend' ) . ''; + } + echo '
'; + } else { + echo '
' . esc_html__( 'Free', 'wp-user-frontend' ) . '
'; + } + echo '
'; + + // Trial Description + if ( $billing_amount > 0 && $recurring_pay && $trial_status && $trial_duration > 0 ) { + $duration = _n( $trial_duration_type, $trial_duration_type . 's', $trial_duration, 'wp-user-frontend' ); + $trial_text = sprintf( __( 'Trial available for first %1$s %2$s', 'wp-user-frontend' ), $trial_duration, $duration ); + echo '
' . esc_html( $trial_text ) . '
'; + } + + // Button + $this->render_button( $pack, $current_pack_id, $current_pack_status, $billing_amount ); + + // Features List + $this->render_features_list( $pack ); + + echo '
'; + } + + /** + * Render the subscribe button + * + * @since WPUF_SINCE + * + * @param \WP_Post $pack The subscription plan post object. + * @param string $current_pack_id Current active pack ID. + * @param string $current_pack_status Current pack status. + * @param float $billing_amount The billing amount. + * @return void + */ + protected function render_button( $pack, $current_pack_id, $current_pack_status, $billing_amount ) { + $user_id = get_current_user_id(); + + $is_completed = ( $current_pack_id == $pack->ID && 'completed' === $current_pack_status ); + + // Get button labels from WPUF settings + if ( ! is_user_logged_in() ) { + $button_text = wpuf_get_option( 'logged_out_label', 'wpuf_subscription_settings', '' ); + $button_text = $button_text ? $button_text : __( 'Sign Up', 'wp-user-frontend' ); + } elseif ( $billing_amount === 0.0 || $billing_amount === '0.00' ) { + $button_text = wpuf_get_option( 'free_label', 'wpuf_subscription_settings', '' ); + $button_text = $button_text ? $button_text : __( 'Free', 'wp-user-frontend' ); + } else { + $button_text = wpuf_get_option( 'logged_in_label', 'wpuf_subscription_settings', '' ); + $button_text = $button_text ? $button_text : __( 'Buy Now', 'wp-user-frontend' ); + } + + // Build button URL + if ( ! is_user_logged_in() ) { + $query_args = [ + 'action' => 'register', + 'type' => 'wpuf_sub', + 'pack_id' => $pack->ID, + ]; + $button_url = wp_registration_url(); + } else { + $query_args = [ + 'action' => 'wpuf_pay', + 'type' => 'pack', + 'pack_id' => $pack->ID, + ]; + $button_url = get_permalink( wpuf_get_option( 'payment_page', 'wpuf_payment' ) ); + } + + $button_url = add_query_arg( $query_args, $button_url ); + + $this->add_render_attribute( + 'button-' . $pack->ID, + [ + 'class' => [ 'wpuf-sub-button', 'wpuf-sub-button-' . $pack->ID ], + 'href' => esc_url( $button_url ), + ] + ); + + if ( $is_completed ) { + $this->add_render_attribute( 'button-' . $pack->ID, 'href', 'javascript:void(0)' ); + $this->add_render_attribute( 'button-' . $pack->ID, 'class', 'wpuf-sub-button-disabled' ); + } + + echo '
'; + echo 'get_render_attribute_string( 'button-' . $pack->ID ) . '>' . esc_html( $button_text ) . ''; + echo '
'; + } + + /** + * Render the features list for a plan + * + * @since WPUF_SINCE + * + * @param \WP_Post $pack The subscription plan post object. + * @return void + */ + protected function render_features_list( $pack ) { + $features_list = []; + + // Check if custom features are set + if ( isset( $pack->meta_value['features'] ) && is_array( $pack->meta_value['features'] ) && ! empty( $pack->meta_value['features'] ) ) { + foreach ( $pack->meta_value['features'] as $feature ) { + $features_list[] = esc_html( $feature ); + } + } else { + // Build features from subscription settings + $post_type_limits = isset( $pack->meta_value['_post_type_name'] ) ? maybe_unserialize( $pack->meta_value['_post_type_name'] ) : []; + $additional_cpt = isset( $pack->meta_value['additional_cpt_options'] ) ? maybe_unserialize( $pack->meta_value['additional_cpt_options'] ) : []; + $all_limits = array_merge( (array) $post_type_limits, (array) $additional_cpt ); + + // Posts limit + if ( isset( $all_limits['post'] ) && '0' !== $all_limits['post'] ) { + if ( '-1' === $all_limits['post'] ) { + $features_list[] = __( 'Unlimited posts', 'wp-user-frontend' ); + } else { + $features_list[] = sprintf( __( '%d posts allowed', 'wp-user-frontend' ), intval( $all_limits['post'] ) ); + } + } + + // Pages limit + if ( isset( $all_limits['page'] ) && '0' !== $all_limits['page'] ) { + if ( '-1' === $all_limits['page'] ) { + $features_list[] = __( 'Unlimited pages', 'wp-user-frontend' ); + } else { + $features_list[] = sprintf( __( '%d pages allowed', 'wp-user-frontend' ), intval( $all_limits['page'] ) ); + } + } + + // User Requests limit + if ( isset( $all_limits['user_request'] ) && '0' !== $all_limits['user_request'] ) { + if ( '-1' === $all_limits['user_request'] ) { + $features_list[] = __( 'Unlimited user requests', 'wp-user-frontend' ); + } else { + $features_list[] = sprintf( __( '%d user requests allowed', 'wp-user-frontend' ), intval( $all_limits['user_request'] ) ); + } + } + + // WooCommerce Products limit + if ( isset( $all_limits['product'] ) && '0' !== $all_limits['product'] ) { + if ( '-1' === $all_limits['product'] ) { + $features_list[] = __( 'Unlimited products', 'wp-user-frontend' ); + } else { + $features_list[] = sprintf( __( '%d products allowed', 'wp-user-frontend' ), intval( $all_limits['product'] ) ); + } + } + + // Reusable Blocks limit + if ( isset( $all_limits['wp_block'] ) && '0' !== $all_limits['wp_block'] ) { + if ( '-1' === $all_limits['wp_block'] ) { + $features_list[] = __( 'Unlimited reusable blocks', 'wp-user-frontend' ); + } else { + $features_list[] = sprintf( __( '%d reusable blocks allowed', 'wp-user-frontend' ), intval( $all_limits['wp_block'] ) ); + } + } + + // Templates limit + if ( isset( $all_limits['wp_template'] ) && '0' !== $all_limits['wp_template'] ) { + if ( '-1' === $all_limits['wp_template'] ) { + $features_list[] = __( 'Unlimited templates', 'wp-user-frontend' ); + } else { + $features_list[] = sprintf( __( '%d templates allowed', 'wp-user-frontend' ), intval( $all_limits['wp_template'] ) ); + } + } + + // Template Parts limit + if ( isset( $all_limits['wp_template_part'] ) && '0' !== $all_limits['wp_template_part'] ) { + if ( '-1' === $all_limits['wp_template_part'] ) { + $features_list[] = __( 'Unlimited template parts', 'wp-user-frontend' ); + } else { + $features_list[] = sprintf( __( '%d template parts allowed', 'wp-user-frontend' ), intval( $all_limits['wp_template_part'] ) ); + } + } + + // Navigation Menus limit + if ( isset( $all_limits['wp_navigation'] ) && '0' !== $all_limits['wp_navigation'] ) { + if ( '-1' === $all_limits['wp_navigation'] ) { + $features_list[] = __( 'Unlimited navigation menus', 'wp-user-frontend' ); + } else { + $features_list[] = sprintf( __( '%d navigation menus allowed', 'wp-user-frontend' ), intval( $all_limits['wp_navigation'] ) ); + } + } + + // Global Styles limit + if ( isset( $all_limits['wp_global_styles'] ) && '0' !== $all_limits['wp_global_styles'] ) { + if ( '-1' === $all_limits['wp_global_styles'] ) { + $features_list[] = __( 'Unlimited global styles', 'wp-user-frontend' ); + } else { + $features_list[] = sprintf( __( '%d global styles allowed', 'wp-user-frontend' ), intval( $all_limits['wp_global_styles'] ) ); + } + } + + // Font Families limit + if ( isset( $all_limits['wp_font_family'] ) && '0' !== $all_limits['wp_font_family'] ) { + if ( '-1' === $all_limits['wp_font_family'] ) { + $features_list[] = __( 'Unlimited font families', 'wp-user-frontend' ); + } else { + $features_list[] = sprintf( __( '%d font families allowed', 'wp-user-frontend' ), intval( $all_limits['wp_font_family'] ) ); + } + } + + // Font Faces limit + if ( isset( $all_limits['wp_font_face'] ) && '0' !== $all_limits['wp_font_face'] ) { + if ( '-1' === $all_limits['wp_font_face'] ) { + $features_list[] = __( 'Unlimited font faces', 'wp-user-frontend' ); + } else { + $features_list[] = sprintf( __( '%d font faces allowed', 'wp-user-frontend' ), intval( $all_limits['wp_font_face'] ) ); + } + } + + // Product Variations limit + if ( isset( $all_limits['product_variation'] ) && '0' !== $all_limits['product_variation'] ) { + if ( '-1' === $all_limits['product_variation'] ) { + $features_list[] = __( 'Unlimited product variations', 'wp-user-frontend' ); + } else { + $features_list[] = sprintf( __( '%d product variations allowed', 'wp-user-frontend' ), intval( $all_limits['product_variation'] ) ); + } + } + + // Shop Orders limit + if ( isset( $all_limits['shop_order'] ) && '0' !== $all_limits['shop_order'] ) { + if ( '-1' === $all_limits['shop_order'] ) { + $features_list[] = __( 'Unlimited shop orders', 'wp-user-frontend' ); + } else { + $features_list[] = sprintf( __( '%d shop orders allowed', 'wp-user-frontend' ), intval( $all_limits['shop_order'] ) ); + } + } + + // Shop Refunds limit + if ( isset( $all_limits['shop_order_refund'] ) && '0' !== $all_limits['shop_order_refund'] ) { + if ( '-1' === $all_limits['shop_order_refund'] ) { + $features_list[] = __( 'Unlimited shop refunds', 'wp-user-frontend' ); + } else { + $features_list[] = sprintf( __( '%d shop refunds allowed', 'wp-user-frontend' ), intval( $all_limits['shop_order_refund'] ) ); + } + } + + // Shop Coupons limit + if ( isset( $all_limits['shop_coupon'] ) && '0' !== $all_limits['shop_coupon'] ) { + if ( '-1' === $all_limits['shop_coupon'] ) { + $features_list[] = __( 'Unlimited shop coupons', 'wp-user-frontend' ); + } else { + $features_list[] = sprintf( __( '%d shop coupons allowed', 'wp-user-frontend' ), intval( $all_limits['shop_coupon'] ) ); + } + } + + // Featured items limit + if ( isset( $pack->meta_value['_total_feature_item'] ) && '0' !== $pack->meta_value['_total_feature_item'] ) { + if ( '-1' === $pack->meta_value['_total_feature_item'] ) { + $features_list[] = __( 'Unlimited featured items', 'wp-user-frontend' ); + } else { + $features_list[] = sprintf( __( '%d featured items', 'wp-user-frontend' ), intval( $pack->meta_value['_total_feature_item'] ) ); + } + } + + // Post expiration + if ( isset( $pack->meta_value['_enable_post_expiration'] ) && 'yes' === $pack->meta_value['_enable_post_expiration'] ) { + $expiry_period = isset( $pack->meta_value['_post_expiration_number'] ) ? intval( $pack->meta_value['_post_expiration_number'] ) : 0; + $expiry_type = isset( $pack->meta_value['_post_expiration_period'] ) ? $pack->meta_value['_post_expiration_period'] : 'day'; + + if ( $expiry_period > 0 ) { + $features_list[] = sprintf( __( 'Posts expire after %d %s', 'wp-user-frontend' ), $expiry_period, $expiry_type . ( $expiry_period > 1 ? 's' : '' ) ); + } else { + $features_list[] = __( 'Post expiration enabled', 'wp-user-frontend' ); + } + } + + // Recurring payment + if ( wpuf_is_checkbox_or_toggle_on( $pack->meta_value['recurring_pay'] ?? '' ) ) { + $features_list[] = __( 'Recurring subscription', 'wp-user-frontend' ); + } + + // Trial period + if ( wpuf_is_checkbox_or_toggle_on( $pack->meta_value['trial_status'] ?? '' ) ) { + $trial_duration = isset( $pack->meta_value['trial_duration'] ) ? intval( $pack->meta_value['trial_duration'] ) : 0; + $trial_type = isset( $pack->meta_value['trial_duration_type'] ) ? $pack->meta_value['trial_duration_type'] : 'day'; + + if ( $trial_duration > 0 ) { + $features_list[] = sprintf( __( '%d %s free trial', 'wp-user-frontend' ), $trial_duration, $trial_type . ( $trial_duration > 1 ? 's' : '' ) ); + } else { + $features_list[] = __( 'Free trial available', 'wp-user-frontend' ); + } + } + + // Mail notification on expiry + if ( isset( $pack->meta_value['_enable_mail_after_expired'] ) && 'yes' === $pack->meta_value['_enable_mail_after_expired'] ) { + $features_list[] = __( 'Email notifications on post expiry', 'wp-user-frontend' ); + } + + // If no features found, show a basic feature + if ( empty( $features_list ) ) { + $features_list[] = __( 'Full website access', 'wp-user-frontend' ); + } + } + + // Render features list + if ( ! empty( $features_list ) ) { + $features_count = count( $features_list ); + $initial_display_count = 5; + $pack_id = $pack->ID; + + echo ''; + + // Show See More/Less button if features exceed initial display count + if ( $features_count > $initial_display_count ) { + $hidden_count = $features_count - $initial_display_count; + + echo '
'; + echo ''; + echo ''; + echo '
'; + } + } + } + + /** + * Render toggle script for expandable features + * + * @since WPUF_SINCE + * + * @return void + */ + protected function render_toggle_script() { + ?> + + editor ) && \Elementor\Plugin::$instance->editor->is_edit_mode() ) + || ( isset( \Elementor\Plugin::$instance->preview ) && \Elementor\Plugin::$instance->preview->is_preview_mode() ) + ); + } + + /** + * Render the widget output in the editor + * + * When empty, Elementor will fall back to using the render() method for + * both frontend and editor preview. + * + * @since WPUF_SINCE + * + * @access protected + */ + protected function content_template() {} +} diff --git a/includes/Integrations/Elementor/Widget.php b/includes/Integrations/Elementor/Widget.php new file mode 100644 index 000000000..b034f4c19 --- /dev/null +++ b/includes/Integrations/Elementor/Widget.php @@ -0,0 +1,1280 @@ +start_controls_section( + 'section_content', + [ + 'label' => __( 'Content', 'wp-user-frontend' ), + ] + ); + + $this->add_control( + 'form_id', + [ + 'label' => __( 'Select Form', 'wp-user-frontend' ), + 'type' => Controls_Manager::SELECT, + 'default' => '', + 'options' => $this->get_wpuf_forms(), + ] + ); + + $this->end_controls_section(); + + // Style Tab + $this->register_container_style_controls(); + $this->register_label_style_controls(); + $this->register_input_style_controls(); + $this->register_placeholder_style_controls(); + $this->register_radio_checkbox_style_controls(); + $this->register_upload_button_style_controls(); + $this->register_submit_button_style_controls(); + + /** + * Fires after the widget has registered its style controls. + * + * Use this to add additional style sections (e.g. for Pro features like multistep). + * + * @since WPUF_SINCE + * + * @param \Elementor\Widget_Base $this The widget instance. + */ + do_action( 'wpuf_elementor_widget_register_style_controls', $this ); + } + + /** + * Retrieve all published WPUF forms + * + * @since WPUF_SINCE + * + * @return array Array of forms formatted as select options + */ + protected function get_wpuf_forms() { + $forms = get_posts( [ + 'post_type' => 'wpuf_forms', + 'posts_per_page' => -1, + 'post_status' => 'publish', + ] ); + + $options = [ '' => __( 'Select a Form', 'wp-user-frontend' ) ]; + + if ( ! empty( $forms ) ) { + foreach ( $forms as $form ) { + $options[ $form->ID ] = $form->post_title; + } + } + + /** + * Filters the form options shown in the widget's form dropdown. + * + * @since WPUF_SINCE + * + * @param array $options Associative array of form_id => form_title. + * @param \Elementor\Widget_Base $this The widget instance. + */ + return apply_filters( 'wpuf_elementor_form_options', $options, $this ); + } + + /** + * Register container style controls + * + * @since WPUF_SINCE + * + * @return void + */ + protected function register_container_style_controls() { + $this->start_controls_section( + 'section_container_style', + [ + 'label' => __( 'Form Container', 'wp-user-frontend' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => 'container_background', + 'label' => __( 'Background', 'wp-user-frontend' ), + 'types' => [ 'classic', 'gradient' ], + 'selector' => '{{WRAPPER}} .wpuf-elementor-widget-wrapper', + ] + ); + + $this->add_responsive_control( + 'container_max_width', + [ + 'label' => __( 'Max Width', 'wp-user-frontend' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', '%' ], + 'range' => [ + 'px' => [ 'min' => 10, 'max' => 1500 ], + 'em' => [ 'min' => 1, 'max' => 80 ], + ], + 'selectors' => [ + '{{WRAPPER}} .wpuf-elementor-widget-wrapper' => 'width: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'container_alignment', + [ + 'label' => __( 'Alignment', 'wp-user-frontend' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'default' => [ + 'title' => __( 'Default', 'wp-user-frontend' ), + 'icon' => 'eicon-ban', + ], + 'left' => [ + 'title' => __( 'Left', 'wp-user-frontend' ), + 'icon' => 'eicon-h-align-left', + ], + 'center' => [ + 'title' => __( 'Center', 'wp-user-frontend' ), + 'icon' => 'eicon-h-align-center', + ], + 'right' => [ + 'title' => __( 'Right', 'wp-user-frontend' ), + 'icon' => 'eicon-h-align-right', + ], + ], + 'default' => 'default', + ] + ); + + $this->add_responsive_control( + 'container_padding', + [ + 'label' => __( 'Padding', 'wp-user-frontend' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', 'em', '%' ], + 'selectors' => [ + '{{WRAPPER}} .wpuf-elementor-widget-wrapper' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'container_margin', + [ + 'label' => __( 'Margin', 'wp-user-frontend' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', 'em', '%' ], + 'selectors' => [ + '{{WRAPPER}} .wpuf-elementor-widget-wrapper' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Border::get_type(), + [ + 'name' => 'container_border', + 'selector' => '{{WRAPPER}} .wpuf-elementor-widget-wrapper', + ] + ); + + $this->add_control( + 'container_border_radius', + [ + 'label' => __( 'Border Radius', 'wp-user-frontend' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%' ], + 'selectors' => [ + '{{WRAPPER}} .wpuf-elementor-widget-wrapper' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'container_box_shadow', + 'selector' => '{{WRAPPER}} .wpuf-elementor-widget-wrapper', + ] + ); + + $this->end_controls_section(); + } + + /** + * Register label style controls + * + * @since WPUF_SINCE + * + * @return void + */ + protected function register_label_style_controls() { + $this->start_controls_section( + 'section_label_style', + [ + 'label' => __( 'Labels', 'wp-user-frontend' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'label_color', + [ + 'label' => __( 'Text Color', 'wp-user-frontend' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .wpuf-form .wpuf-label' => 'color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'label_typography', + 'selector' => '{{WRAPPER}} .wpuf-form .wpuf-label', + ] + ); + + $this->add_control( + 'label_asterisk_color', + [ + 'label' => __( 'Asterisk Color', 'wp-user-frontend' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .wpuf-form .wpuf-label .required' => 'color: {{VALUE}};', + ], + 'separator' => 'before', + ] + ); + + $this->add_control( + 'label_asterisk_size', + [ + 'label' => __( 'Asterisk Size', 'wp-user-frontend' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', '%' ], + 'range' => [ + 'px' => [ 'min' => 0, 'max' => 30, 'step' => 1 ], + '%' => [ 'min' => 0, 'max' => 30, 'step' => 1 ], + ], + 'selectors' => [ + '{{WRAPPER}} .wpuf-form .wpuf-label .required' => 'font-size: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->end_controls_section(); + } + + /** + * Register input field style controls + * + * @since WPUF_SINCE + * + * @return void + */ + protected function register_input_style_controls() { + $input_selector = '{{WRAPPER}} .wpuf-form input[type="text"], {{WRAPPER}} .wpuf-form input[type="email"], {{WRAPPER}} .wpuf-form input[type="url"], {{WRAPPER}} .wpuf-form input[type="password"], {{WRAPPER}} .wpuf-form input[type="number"], {{WRAPPER}} .wpuf-form textarea, {{WRAPPER}} .wpuf-form select'; + + $this->start_controls_section( + 'section_input_style', + [ + 'label' => __( 'Input & Textarea', 'wp-user-frontend' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_responsive_control( + 'input_alignment', + [ + 'label' => __( 'Alignment', 'wp-user-frontend' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'left' => [ 'title' => __( 'Left', 'wp-user-frontend' ), 'icon' => 'eicon-text-align-left' ], + 'center' => [ 'title' => __( 'Center', 'wp-user-frontend' ), 'icon' => 'eicon-text-align-center' ], + 'right' => [ 'title' => __( 'Right', 'wp-user-frontend' ), 'icon' => 'eicon-text-align-right' ], + ], + 'selectors' => [ $input_selector => 'text-align: {{VALUE}};' ], + ] + ); + + $this->start_controls_tabs( 'tabs_input_style' ); + + $this->start_controls_tab( 'tab_input_normal', [ 'label' => __( 'Normal', 'wp-user-frontend' ) ] ); + + $this->add_control( + 'input_bg_color', + [ + 'label' => __( 'Background Color', 'wp-user-frontend' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ $input_selector => 'background-color: {{VALUE}};' ], + ] + ); + + $this->add_control( + 'input_text_color', + [ + 'label' => __( 'Text Color', 'wp-user-frontend' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ $input_selector => 'color: {{VALUE}};' ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ 'name' => 'input_typography', 'selector' => $input_selector ] + ); + + $this->add_group_control( + Group_Control_Border::get_type(), + [ 'name' => 'input_border', 'selector' => $input_selector ] + ); + + $this->add_control( + 'input_border_radius', + [ + 'label' => __( 'Border Radius', 'wp-user-frontend' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%' ], + 'selectors' => [ $input_selector => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};' ], + ] + ); + + $this->add_responsive_control( + 'input_padding', + [ + 'label' => __( 'Padding', 'wp-user-frontend' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', 'em', '%' ], + 'selectors' => [ $input_selector => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};' ], + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'input_box_shadow', + 'selector' => $input_selector, + 'separator' => 'before', + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( 'tab_input_focus', [ 'label' => __( 'Focus', 'wp-user-frontend' ) ] ); + + $this->add_control( + 'input_focus_bg_color', + [ + 'label' => __( 'Background Color', 'wp-user-frontend' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .wpuf-form input[type="text"]:focus, {{WRAPPER}} .wpuf-form input[type="email"]:focus, {{WRAPPER}} .wpuf-form input[type="url"]:focus, {{WRAPPER}} .wpuf-form input[type="password"]:focus, {{WRAPPER}} .wpuf-form input[type="number"]:focus, {{WRAPPER}} .wpuf-form textarea:focus, {{WRAPPER}} .wpuf-form select:focus' => 'background-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Border::get_type(), + [ + 'name' => 'input_focus_border', + 'selector' => '{{WRAPPER}} .wpuf-form input[type="text"]:focus, {{WRAPPER}} .wpuf-form input[type="email"]:focus, {{WRAPPER}} .wpuf-form input[type="url"]:focus, {{WRAPPER}} .wpuf-form input[type="password"]:focus, {{WRAPPER}} .wpuf-form input[type="number"]:focus, {{WRAPPER}} .wpuf-form textarea:focus, {{WRAPPER}} .wpuf-form select:focus', + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'input_focus_box_shadow', + 'selector' => '{{WRAPPER}} .wpuf-form input[type="text"]:focus, {{WRAPPER}} .wpuf-form input[type="email"]:focus, {{WRAPPER}} .wpuf-form input[type="url"]:focus, {{WRAPPER}} .wpuf-form input[type="password"]:focus, {{WRAPPER}} .wpuf-form input[type="number"]:focus, {{WRAPPER}} .wpuf-form textarea:focus, {{WRAPPER}} .wpuf-form select:focus', + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->end_controls_section(); + } + + /** + * Register placeholder style controls. + * + * @since WPUF_SINCE + * + * @return void + */ + protected function register_placeholder_style_controls() { + $this->start_controls_section( + 'section_placeholder_style', + [ + 'label' => __( 'Placeholder', 'wp-user-frontend' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $placeholder_selector = '{{WRAPPER}} .wpuf-form input::placeholder, {{WRAPPER}} .wpuf-form textarea::placeholder, {{WRAPPER}} .wpuf-form input::-webkit-input-placeholder, {{WRAPPER}} .wpuf-form textarea::-webkit-input-placeholder, {{WRAPPER}} .wpuf-form input::-moz-placeholder, {{WRAPPER}} .wpuf-form textarea::-moz-placeholder, {{WRAPPER}} .wpuf-form input:-ms-input-placeholder, {{WRAPPER}} .wpuf-form textarea:-ms-input-placeholder'; + + $this->add_control( + 'placeholder_color', + [ + 'label' => __( 'Text Color', 'wp-user-frontend' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ $placeholder_selector => 'color: {{VALUE}};' ], + ] + ); + + $this->end_controls_section(); + } + + /** + * Register radio and checkbox style controls. + * + * @since WPUF_SINCE + * + * @return void + */ + protected function register_radio_checkbox_style_controls() { + $this->start_controls_section( + 'section_radio_checkbox_style', + [ + 'label' => __( 'Radio & Checkbox', 'wp-user-frontend' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_responsive_control( + 'radio_checkbox_size', + [ + 'label' => __( 'Size', 'wp-user-frontend' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px' ], + 'range' => [ 'px' => [ 'min' => 0, 'max' => 80, 'step' => 1 ] ], + 'default' => [ 'size' => 18, 'unit' => 'px' ], + 'selectors' => [ + '{{WRAPPER}} .wpuf-form input[type="radio"], {{WRAPPER}} .wpuf-form input[type="checkbox"]' => 'width: {{SIZE}}{{UNIT}}; height: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'radio_checkbox_spacing', + [ + 'label' => __( 'Spacing', 'wp-user-frontend' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em' ], + 'range' => [ 'px' => [ 'min' => 0, 'max' => 30, 'step' => 1 ] ], + 'selectors' => [ + '{{WRAPPER}} .wpuf-form input[type="radio"], {{WRAPPER}} .wpuf-form input[type="checkbox"]' => 'margin-right: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'radio_checkbox_selector_color', + [ + 'label' => __( 'Selector Color', 'wp-user-frontend' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .wpuf-form input[type="radio"], {{WRAPPER}} .wpuf-form input[type="checkbox"]' => 'accent-color: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'radio_checkbox_options_text_color', + [ + 'label' => __( 'Options Text Color', 'wp-user-frontend' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .wpuf-form .wpuf-radio-block, {{WRAPPER}} .wpuf-form .wpuf-checkbox-block, {{WRAPPER}} .wpuf-form .wpuf-radio-inline, {{WRAPPER}} .wpuf-form .wpuf-checkbox-inline' => 'color: {{VALUE}};', + ], + ] + ); + + $this->end_controls_section(); + } + + /** + * Register upload button style controls + * + * Styles the file/image upload buttons (e.g. "Select File", "Select Image") within WPUF forms. + * + * @since WPUF_SINCE + * + * @return void + */ + protected function register_upload_button_style_controls() { + $btn_selector = '{{WRAPPER}} .wpuf-form .file-selector'; + $align_selector = '{{WRAPPER}} .wpuf-form .wpuf-attachment-upload-filelist'; + + $this->start_controls_section( + 'section_upload_button_style', + [ + 'label' => __( 'Upload Button', 'wp-user-frontend' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'upload_button_width_type', + [ + 'label' => __( 'Width', 'wp-user-frontend' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'custom', + 'options' => [ + 'full-width' => __( 'Full Width', 'wp-user-frontend' ), + 'custom' => __( 'Custom', 'wp-user-frontend' ), + ], + ] + ); + + $this->add_responsive_control( + 'upload_button_align', + [ + 'label' => __( 'Alignment', 'wp-user-frontend' ), + 'type' => Controls_Manager::CHOOSE, + 'default' => 'left', + 'options' => [ + 'left' => [ 'title' => __( 'Left', 'wp-user-frontend' ), 'icon' => 'eicon-h-align-left' ], + 'center' => [ 'title' => __( 'Center', 'wp-user-frontend' ), 'icon' => 'eicon-h-align-center' ], + 'right' => [ 'title' => __( 'Right', 'wp-user-frontend' ), 'icon' => 'eicon-h-align-right' ], + ], + 'selectors' => [ $align_selector => 'text-align: {{VALUE}};' ], + 'condition' => [ 'upload_button_width_type' => 'custom' ], + ] + ); + + $this->add_responsive_control( + 'upload_button_width', + [ + 'label' => __( 'Width', 'wp-user-frontend' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%' ], + 'range' => [ 'px' => [ 'min' => 0, 'max' => 1200, 'step' => 1 ] ], + 'selectors' => [ $btn_selector => 'width: {{SIZE}}{{UNIT}};' ], + 'condition' => [ 'upload_button_width_type' => 'custom' ], + ] + ); + + $this->start_controls_tabs( 'tabs_upload_button_style' ); + + $this->start_controls_tab( 'tab_upload_button_normal', [ 'label' => __( 'Normal', 'wp-user-frontend' ) ] ); + + $this->add_control( + 'upload_button_bg_color', + [ + 'label' => __( 'Background Color', 'wp-user-frontend' ), + 'type' => Controls_Manager::COLOR, + 'default' => '#6b7280', + 'selectors' => [ $btn_selector => 'background-color: {{VALUE}};' ], + ] + ); + + $this->add_control( + 'upload_button_text_color', + [ + 'label' => __( 'Text Color', 'wp-user-frontend' ), + 'type' => Controls_Manager::COLOR, + 'default' => '#ffffff', + 'selectors' => [ $btn_selector => 'color: {{VALUE}};' ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'upload_button_typography', + 'selector' => $btn_selector, + 'fields_options' => [ + 'font_weight' => [ + 'default' => '500', + ], + 'font_size' => [ + 'default' => [ + 'unit' => 'px', + 'size' => '16', + ], + ], + ], + ] + ); + + $this->add_group_control( + Group_Control_Border::get_type(), + [ + 'name' => 'upload_button_border', + 'selector' => $btn_selector, + 'fields_options' => [ + 'border' => [ + 'default' => 'solid', + ], + 'width' => [ + 'default' => [ + 'top' => '0', + 'right' => '0', + 'bottom' => '0', + 'left' => '0', + ], + ], + 'color' => [ + 'default' => 'transparent', + ], + ], + ] + ); + + $this->add_control( + 'upload_button_border_radius', + [ + 'label' => __( 'Border Radius', 'wp-user-frontend' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%' ], + 'default' => [ + 'top' => '6', + 'right' => '6', + 'bottom' => '6', + 'left' => '6', + 'unit' => 'px', + ], + 'selectors' => [ $btn_selector => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};' ], + ] + ); + + $this->add_responsive_control( + 'upload_button_padding', + [ + 'label' => __( 'Padding', 'wp-user-frontend' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', 'em', '%' ], + 'default' => [ + 'top' => '12', + 'right' => '24', + 'bottom' => '12', + 'left' => '24', + 'unit' => 'px', + ], + 'selectors' => [ $btn_selector => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};' ], + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'upload_button_box_shadow', + 'selector' => $btn_selector, + 'separator' => 'before', + 'fields_options' => [ + 'box_shadow_type' => [ + 'default' => 'yes', + ], + 'box_shadow' => [ + 'default' => [ + 'horizontal' => 0, + 'vertical' => 1, + 'blur' => 3, + 'spread' => 0, + 'color' => 'rgba(0, 0, 0, 0.1)', + ], + ], + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( 'tab_upload_button_hover', [ 'label' => __( 'Hover', 'wp-user-frontend' ) ] ); + + $this->add_control( + 'upload_button_hover_bg_color', + [ + 'label' => __( 'Background Color', 'wp-user-frontend' ), + 'type' => Controls_Manager::COLOR, + 'default' => '#4b5563', + 'selectors' => [ $btn_selector . ':hover' => 'background-color: {{VALUE}};' ], + ] + ); + + $this->add_control( + 'upload_button_hover_text_color', + [ + 'label' => __( 'Text Color', 'wp-user-frontend' ), + 'type' => Controls_Manager::COLOR, + 'default' => '#ffffff', + 'selectors' => [ $btn_selector . ':hover' => 'color: {{VALUE}};' ], + ] + ); + + $this->add_control( + 'upload_button_hover_border_color', + [ + 'label' => __( 'Border Color', 'wp-user-frontend' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ $btn_selector . ':hover' => 'border-color: {{VALUE}};' ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->end_controls_section(); + } + + /** + * Register submit button style controls + * + * @since WPUF_SINCE + * + * @return void + */ + protected function register_submit_button_style_controls() { + $btn_selector = '{{WRAPPER}} .wpuf-form .wpuf-submit-button'; + + $this->start_controls_section( + 'section_submit_button_style', + [ + 'label' => __( 'Submit Button', 'wp-user-frontend' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'submit_button_width_type', + [ + 'label' => __( 'Width', 'wp-user-frontend' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'custom', + 'options' => [ + 'full-width' => __( 'Full Width', 'wp-user-frontend' ), + 'custom' => __( 'Custom', 'wp-user-frontend' ), + ], + ] + ); + + $this->add_responsive_control( + 'submit_button_align', + [ + 'label' => __( 'Alignment', 'wp-user-frontend' ), + 'type' => Controls_Manager::CHOOSE, + 'default' => 'left', + 'options' => [ + 'left' => [ 'title' => __( 'Left', 'wp-user-frontend' ), 'icon' => 'eicon-h-align-left' ], + 'center' => [ 'title' => __( 'Center', 'wp-user-frontend' ), 'icon' => 'eicon-h-align-center' ], + 'right' => [ 'title' => __( 'Right', 'wp-user-frontend' ), 'icon' => 'eicon-h-align-right' ], + ], + 'selectors' => [ '{{WRAPPER}} .wpuf-form .wpuf-submit' => 'text-align: {{VALUE}};' ], + 'condition' => [ 'submit_button_width_type' => 'custom' ], + ] + ); + + $this->add_responsive_control( + 'submit_button_width', + [ + 'label' => __( 'Width', 'wp-user-frontend' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%' ], + 'range' => [ 'px' => [ 'min' => 0, 'max' => 1200, 'step' => 1 ] ], + 'selectors' => [ $btn_selector => 'width: {{SIZE}}{{UNIT}};' ], + 'condition' => [ 'submit_button_width_type' => 'custom' ], + ] + ); + + $this->start_controls_tabs( 'tabs_submit_button_style' ); + + $this->start_controls_tab( 'tab_submit_button_normal', [ 'label' => __( 'Normal', 'wp-user-frontend' ) ] ); + + $this->add_control( + 'submit_button_bg_color', + [ + 'label' => __( 'Background Color', 'wp-user-frontend' ), + 'type' => Controls_Manager::COLOR, + 'default' => '#6b7280', + 'selectors' => [ $btn_selector => 'background-color: {{VALUE}};' ], + ] + ); + + $this->add_control( + 'submit_button_text_color', + [ + 'label' => __( 'Text Color', 'wp-user-frontend' ), + 'type' => Controls_Manager::COLOR, + 'default' => '#ffffff', + 'selectors' => [ $btn_selector => 'color: {{VALUE}};' ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'submit_button_typography', + 'selector' => $btn_selector, + 'fields_options' => [ + 'font_weight' => [ + 'default' => '500', + ], + 'font_size' => [ + 'default' => [ + 'unit' => 'px', + 'size' => '16', + ], + ], + ], + ] + ); + + $this->add_group_control( + Group_Control_Border::get_type(), + [ + 'name' => 'submit_button_border', + 'selector' => $btn_selector, + 'fields_options' => [ + 'border' => [ + 'default' => 'solid', + ], + 'width' => [ + 'default' => [ + 'top' => '0', + 'right' => '0', + 'bottom' => '0', + 'left' => '0', + ], + ], + 'color' => [ + 'default' => 'transparent', + ], + ], + ] + ); + + $this->add_control( + 'submit_button_border_radius', + [ + 'label' => __( 'Border Radius', 'wp-user-frontend' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%' ], + 'default' => [ + 'top' => '6', + 'right' => '6', + 'bottom' => '6', + 'left' => '6', + 'unit' => 'px', + ], + 'selectors' => [ $btn_selector => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};' ], + ] + ); + + $this->add_responsive_control( + 'submit_button_padding', + [ + 'label' => __( 'Padding', 'wp-user-frontend' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', 'em', '%' ], + 'default' => [ + 'top' => '12', + 'right' => '24', + 'bottom' => '12', + 'left' => '24', + 'unit' => 'px', + ], + 'selectors' => [ $btn_selector => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};' ], + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'submit_button_box_shadow', + 'selector' => $btn_selector, + 'separator' => 'before', + 'fields_options' => [ + 'box_shadow_type' => [ + 'default' => 'yes', + ], + 'box_shadow' => [ + 'default' => [ + 'horizontal' => 0, + 'vertical' => 1, + 'blur' => 3, + 'spread' => 0, + 'color' => 'rgba(0, 0, 0, 0.1)', + ], + ], + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( 'tab_submit_button_hover', [ 'label' => __( 'Hover', 'wp-user-frontend' ) ] ); + + $this->add_control( + 'submit_button_hover_bg_color', + [ + 'label' => __( 'Background Color', 'wp-user-frontend' ), + 'type' => Controls_Manager::COLOR, + 'default' => '#4b5563', + 'selectors' => [ $btn_selector . ':hover' => 'background-color: {{VALUE}};' ], + ] + ); + + $this->add_control( + 'submit_button_hover_text_color', + [ + 'label' => __( 'Text Color', 'wp-user-frontend' ), + 'type' => Controls_Manager::COLOR, + 'default' => '#ffffff', + 'selectors' => [ $btn_selector . ':hover' => 'color: {{VALUE}};' ], + ] + ); + + $this->add_control( + 'submit_button_hover_border_color', + [ + 'label' => __( 'Border Color', 'wp-user-frontend' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ $btn_selector . ':hover' => 'border-color: {{VALUE}};' ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->end_controls_section(); + } + + /** + * Render the widget output on the frontend + * + * @since WPUF_SINCE + * + * @return void + */ + protected function render() { + $settings = $this->get_settings_for_display(); + $form_id = isset( $settings['form_id'] ) ? $settings['form_id'] : null; + + if ( empty( $form_id ) ) { + return; + } + + $wrapper_classes = [ 'wpuf-elementor-widget-wrapper' ]; + + if ( ! empty( $settings['submit_button_width_type'] ) && 'full-width' === $settings['submit_button_width_type'] ) { + $wrapper_classes[] = 'wpuf-elementor-submit-full'; + } + + if ( ! empty( $settings['upload_button_width_type'] ) && 'full-width' === $settings['upload_button_width_type'] ) { + $wrapper_classes[] = 'wpuf-elementor-upload-full'; + } + + /** + * Filters the CSS classes applied to the widget wrapper. + * + * @since WPUF_SINCE + * + * @param string[] $wrapper_classes Array of class names. + * @param array $settings Widget settings. + * @param int|null $form_id Selected form ID. + */ + $wrapper_classes = apply_filters( 'wpuf_elementor_widget_wrapper_classes', $wrapper_classes, $settings, $form_id ); + + $this->add_render_attribute( 'wrapper', 'class', $wrapper_classes ); + + // Set alignment attribute if not default + if ( ! empty( $settings['container_alignment'] ) && 'default' !== $settings['container_alignment'] ) { + $this->add_render_attribute( 'wrapper', 'data-align', $settings['container_alignment'] ); + } + + $wrapper_attributes = apply_filters( 'wpuf_elementor_widget_wrapper_attributes', [], $settings, $form_id ); + foreach ( $wrapper_attributes as $attr_key => $attr_value ) { + if ( is_string( $attr_key ) && is_string( $attr_value ) ) { + $this->add_render_attribute( 'wrapper', $attr_key, $attr_value ); + } + } + + $shortcode_str = '[wpuf_form id="' . $form_id . '"]'; + $output = do_shortcode( $shortcode_str ); + + $is_elementor = class_exists( '\Elementor\Plugin' ) && ( + ( isset( \Elementor\Plugin::$instance->editor ) && \Elementor\Plugin::$instance->editor->is_edit_mode() ) + || ( isset( \Elementor\Plugin::$instance->preview ) && \Elementor\Plugin::$instance->preview->is_preview_mode() ) + ); + + echo '
get_render_attribute_string( 'wrapper' ) ) . '>'; + echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- shortcode output + + // Initialize TinyMCE in Elementor preview + if ( $is_elementor ) { + ?> + + '; + + /** + * Fires after the widget has rendered its output. + * + * @since WPUF_SINCE + * + * @param \Elementor\Widget_Base $this The widget instance. + */ + do_action( 'wpuf_elementor_widget_after_render', $this ); + } + + /** + * Render the widget output in the editor. + * + * When empty, Elementor will fall back to using the render() method for + * both frontend and editor preview. + * + * @since WPUF_SINCE + * + * @access protected + */ + protected function content_template() {} +} diff --git a/languages/wp-user-frontend.pot b/languages/wp-user-frontend.pot index 5d72a6b4b..77270aba1 100644 --- a/languages/wp-user-frontend.pot +++ b/languages/wp-user-frontend.pot @@ -4,7 +4,7 @@ msgid "" msgstr "" "Project-Id-Version: WP User Frontend 4.2.8\n" "Report-Msgid-Bugs-To: https://wedevs.com/contact/\n" -"POT-Creation-Date: 2026-01-28 06:28:38+00:00\n" +"POT-Creation-Date: 2026-02-17 06:00:07+00:00\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -219,6 +219,7 @@ msgid "WP User Frontend" msgstr "" #: admin/class-admin-settings.php:89 includes/Admin/Menu.php:24 +#: includes/Integrations/Elementor/Elementor.php:240 msgid "User Frontend" msgstr "" @@ -600,26 +601,26 @@ msgstr "" msgid "Learn More" msgstr "" -#: admin/html/form-settings-display.php:11 wpuf-functions.php:5603 +#: admin/html/form-settings-display.php:11 wpuf-functions.php:5608 msgid "Label Position" msgstr "" -#: admin/html/form-settings-display.php:16 wpuf-functions.php:5606 +#: admin/html/form-settings-display.php:16 wpuf-functions.php:5611 msgid "Above Element" msgstr "" -#: admin/html/form-settings-display.php:17 wpuf-functions.php:5607 +#: admin/html/form-settings-display.php:17 wpuf-functions.php:5612 msgid "Left of Element" msgstr "" -#: admin/html/form-settings-display.php:18 wpuf-functions.php:5608 +#: admin/html/form-settings-display.php:18 wpuf-functions.php:5613 msgid "Right of Element" msgstr "" #: admin/html/form-settings-display.php:19 #: includes/Admin/Customizer_Options.php:119 #: includes/Fields/Field_Contract.php:400 -#: includes/Fields/Form_Field_Column.php:112 wpuf-functions.php:5609 +#: includes/Fields/Form_Field_Column.php:112 wpuf-functions.php:5614 msgid "Hidden" msgstr "" @@ -627,7 +628,7 @@ msgstr "" msgid "Where the labels of the form should display" msgstr "" -#: admin/html/form-settings-display.php:35 wpuf-functions.php:5596 +#: admin/html/form-settings-display.php:35 wpuf-functions.php:5601 msgid "Use Theme CSS" msgstr "" @@ -642,7 +643,8 @@ msgstr "" #: includes/Fields/Field_Contract.php:519 #: includes/Fields/Form_Field_Checkbox.php:86 #: includes/Fields/Form_Field_Radio.php:86 includes/Free/Form_Element.php:525 -#: includes/Frontend.php:122 includes/functions/settings-options.php:128 +#: includes/Frontend.php:122 includes/Integrations/Elementor/Elementor.php:171 +#: includes/functions/settings-options.php:128 #: includes/functions/settings-options.php:147 #: includes/functions/settings-options.php:268 #: includes/functions/settings-options.php:279 @@ -660,7 +662,8 @@ msgstr "" #: includes/Fields/Field_Contract.php:518 #: includes/Fields/Form_Field_Checkbox.php:85 #: includes/Fields/Form_Field_Radio.php:85 includes/Free/Form_Element.php:524 -#: includes/Frontend.php:121 includes/functions/settings-options.php:127 +#: includes/Frontend.php:121 includes/Integrations/Elementor/Elementor.php:170 +#: includes/functions/settings-options.php:127 #: includes/functions/settings-options.php:146 #: includes/functions/settings-options.php:267 #: includes/functions/settings-options.php:278 @@ -680,7 +683,7 @@ msgid "Payment Options" msgstr "" #: admin/html/form-settings-payment.php:26 includes/Setup_Wizard.php:339 -#: includes/functions/settings-options.php:564 wpuf-functions.php:5477 +#: includes/functions/settings-options.php:564 wpuf-functions.php:5482 msgid "Enable Payments" msgstr "" @@ -745,7 +748,7 @@ msgid "Amount to be charged per post" msgstr "" #: admin/html/form-settings-payment.php:88 -#: includes/functions/settings-options.php:650 wpuf-functions.php:5512 +#: includes/functions/settings-options.php:650 wpuf-functions.php:5517 msgid "Payment Success Page" msgstr "" @@ -767,7 +770,7 @@ msgstr "" msgid "Set Post Status to" msgstr "" -#: admin/html/form-settings-post-edit.php:24 wpuf-functions.php:5335 +#: admin/html/form-settings-post-edit.php:24 wpuf-functions.php:5340 msgid "No Change" msgstr "" @@ -777,7 +780,7 @@ msgid "Redirect To" msgstr "" #: admin/html/form-settings-post-edit.php:36 -#: admin/html/form-settings-post.php:138 wpuf-functions.php:5263 +#: admin/html/form-settings-post.php:138 wpuf-functions.php:5268 msgid "Newly created post" msgstr "" @@ -788,13 +791,13 @@ msgstr "" #: admin/html/form-settings-post-edit.php:38 #: admin/html/form-settings-post.php:140 includes/Free/Form_Element.php:422 -#: wpuf-functions.php:5265 wpuf-functions.php:5350 +#: wpuf-functions.php:5270 wpuf-functions.php:5355 msgid "To a page" msgstr "" #: admin/html/form-settings-post-edit.php:39 #: admin/html/form-settings-post.php:141 includes/Free/Form_Element.php:423 -#: wpuf-functions.php:5266 wpuf-functions.php:5351 +#: wpuf-functions.php:5271 wpuf-functions.php:5356 msgid "To a custom URL" msgstr "" @@ -802,19 +805,19 @@ msgstr "" msgid "After successfull submit, where the page will redirect to" msgstr "" -#: admin/html/form-settings-post-edit.php:54 wpuf-functions.php:5355 +#: admin/html/form-settings-post-edit.php:54 wpuf-functions.php:5360 msgid "Post Update Message" msgstr "" #: admin/html/form-settings-post-edit.php:61 #: admin/html/form-settings-post.php:163 includes/Free/Form_Element.php:452 -#: wpuf-functions.php:5275 wpuf-functions.php:5369 +#: wpuf-functions.php:5280 wpuf-functions.php:5374 msgid "Page" msgstr "" #: admin/html/form-settings-post-edit.php:76 #: admin/html/form-settings-post.php:178 includes/Free/Form_Element.php:475 -#: wpuf-functions.php:5281 wpuf-functions.php:5375 +#: wpuf-functions.php:5286 wpuf-functions.php:5380 msgid "Custom URL" msgstr "" @@ -844,7 +847,7 @@ msgstr "" msgid "This page is restricted. Please {login} / {register} to view this page." msgstr "" -#: admin/html/form-settings-post.php:15 wpuf-functions.php:5272 +#: admin/html/form-settings-post.php:15 wpuf-functions.php:5277 msgid "Post saved" msgstr "" @@ -859,7 +862,7 @@ msgstr "" msgid "Save Draft" msgstr "" -#: admin/html/form-settings-post.php:29 wpuf-functions.php:5236 +#: admin/html/form-settings-post.php:29 wpuf-functions.php:5241 msgid "Post Type" msgstr "" @@ -901,7 +904,7 @@ msgstr "" msgid "After successful submit, where the page will redirect to" msgstr "" -#: admin/html/form-settings-post.php:156 wpuf-functions.php:5270 +#: admin/html/form-settings-post.php:156 wpuf-functions.php:5275 msgid "Message to show" msgstr "" @@ -909,11 +912,11 @@ msgstr "" msgid "Comment Status" msgstr "" -#: admin/html/form-settings-post.php:188 wpuf-functions.php:5627 +#: admin/html/form-settings-post.php:188 wpuf-functions.php:5632 msgid "Open" msgstr "" -#: admin/html/form-settings-post.php:189 wpuf-functions.php:5628 +#: admin/html/form-settings-post.php:189 wpuf-functions.php:5633 msgid "Closed" msgstr "" @@ -947,7 +950,7 @@ msgstr "" msgid "Email" msgstr "" -#: admin/html/form-submission-restriction.php:29 wpuf-functions.php:5409 +#: admin/html/form-submission-restriction.php:29 wpuf-functions.php:5414 msgid "Guest Post" msgstr "" @@ -967,7 +970,7 @@ msgstr "" msgid "User Details" msgstr "" -#: admin/html/form-submission-restriction.php:46 wpuf-functions.php:5418 +#: admin/html/form-submission-restriction.php:46 wpuf-functions.php:5423 msgid "Require Name and Email address" msgstr "" @@ -977,7 +980,7 @@ msgid "" "name and email address" msgstr "" -#: admin/html/form-submission-restriction.php:53 wpuf-functions.php:5428 +#: admin/html/form-submission-restriction.php:53 wpuf-functions.php:5433 msgid "Name Label" msgstr "" @@ -985,7 +988,7 @@ msgstr "" msgid "Label text for name field" msgstr "" -#: admin/html/form-submission-restriction.php:63 wpuf-functions.php:5436 +#: admin/html/form-submission-restriction.php:63 wpuf-functions.php:5441 msgid "E-Mail Label" msgstr "" @@ -1026,7 +1029,7 @@ msgid "Choose which roles can submit posts." msgstr "" #: admin/html/form-submission-restriction.php:117 -#: includes/functions/settings-options.php:338 wpuf-functions.php:5460 +#: includes/functions/settings-options.php:338 wpuf-functions.php:5465 msgid "Unauthorized Message" msgstr "" @@ -1052,16 +1055,16 @@ msgstr "" msgid "Schedule Period" msgstr "" -#: admin/html/form-submission-restriction.php:140 wpuf-functions.php:5641 +#: admin/html/form-submission-restriction.php:140 wpuf-functions.php:5646 msgid "From" msgstr "" -#: admin/html/form-submission-restriction.php:151 wpuf-functions.php:5651 +#: admin/html/form-submission-restriction.php:151 wpuf-functions.php:5656 msgid "Form Pending Message" msgstr "" #: admin/html/form-submission-restriction.php:158 -#: includes/Free/Free_Loader.php:1778 wpuf-functions.php:5655 +#: includes/Free/Free_Loader.php:1778 wpuf-functions.php:5660 msgid "Form Expired Message" msgstr "" @@ -1077,11 +1080,11 @@ msgstr "" msgid "Limit the number of entries allowed for this form" msgstr "" -#: admin/html/form-submission-restriction.php:180 wpuf-functions.php:5664 +#: admin/html/form-submission-restriction.php:180 wpuf-functions.php:5669 msgid "Number of Entries" msgstr "" -#: admin/html/form-submission-restriction.php:187 wpuf-functions.php:5669 +#: admin/html/form-submission-restriction.php:187 wpuf-functions.php:5674 msgid "Limit Reached Message" msgstr "" @@ -1110,7 +1113,7 @@ msgstr "" #: admin/installer.php:84 includes/Admin/Admin_Installer.php:86 #: includes/Admin/Shortcodes_Button.php:85 -#: includes/functions/settings-options.php:24 wpuf-functions.php:2292 +#: includes/functions/settings-options.php:24 wpuf-functions.php:2297 msgid "Dashboard" msgstr "" @@ -1140,7 +1143,7 @@ msgstr "" #: includes/Admin/Shortcodes_Button.php:105 includes/Admin/Subscription.php:485 #: includes/Admin/Subscription.php:504 includes/Admin/Subscription.php:505 #: includes/Admin/Subscription.php:506 templates/dashboard/subscription.php:169 -#: wpuf-functions.php:2273 +#: wpuf-functions.php:2278 msgid "Subscription" msgstr "" @@ -1189,39 +1192,46 @@ msgstr "" #: admin/posting.php:74 class/render-form.php:1703 #: includes/Admin/Posting.php:130 includes/Admin.php:172 -#: includes/Fields/Field_Contract.php:996 includes/Frontend.php:81 +#: includes/Fields/Field_Contract.php:1023 includes/Frontend.php:81 +#: includes/Integrations/Elementor/Elementor.php:134 #: includes/Render_Form.php:1594 msgid "Are you sure?" msgstr "" #: admin/posting.php:75 includes/Admin/Forms/Admin_Form_Builder.php:342 #: includes/Admin/Posting.php:131 includes/Admin.php:173 -#: includes/Fields/Field_Contract.php:997 includes/Frontend.php:82 +#: includes/Fields/Field_Contract.php:1024 includes/Frontend.php:82 +#: includes/Integrations/Elementor/Elementor.php:135 msgid "Yes, delete it" msgstr "" #: admin/posting.php:76 includes/Admin/Posting.php:132 includes/Admin.php:174 -#: includes/Fields/Field_Contract.php:998 includes/Frontend.php:83 +#: includes/Fields/Field_Contract.php:1025 includes/Frontend.php:83 +#: includes/Integrations/Elementor/Elementor.php:136 msgid "No, cancel it" msgstr "" #: admin/posting.php:82 includes/Admin/Posting.php:138 includes/Admin.php:182 -#: includes/Fields/Field_Contract.php:1008 includes/Frontend.php:93 +#: includes/Fields/Field_Contract.php:1035 includes/Frontend.php:93 +#: includes/Integrations/Elementor/Elementor.php:144 msgid "Allowed Files" msgstr "" #: admin/posting.php:85 includes/Admin/Posting.php:141 includes/Admin.php:188 -#: includes/Fields/Field_Contract.php:1014 includes/Frontend.php:99 +#: includes/Fields/Field_Contract.php:1041 includes/Frontend.php:99 +#: includes/Integrations/Elementor/Elementor.php:150 msgid "Maximum number of files reached!" msgstr "" #: admin/posting.php:86 includes/Admin/Posting.php:142 includes/Admin.php:189 -#: includes/Fields/Field_Contract.php:1015 includes/Frontend.php:100 +#: includes/Fields/Field_Contract.php:1042 includes/Frontend.php:100 +#: includes/Integrations/Elementor/Elementor.php:151 msgid "The file you have uploaded exceeds the file size limit. Please try again." msgstr "" #: admin/posting.php:87 includes/Admin/Posting.php:143 includes/Admin.php:190 -#: includes/Fields/Field_Contract.php:1019 includes/Frontend.php:104 +#: includes/Fields/Field_Contract.php:1046 includes/Frontend.php:104 +#: includes/Integrations/Elementor/Elementor.php:152 msgid "You have uploaded an incorrect file type. Please try again." msgstr "" @@ -1293,12 +1303,12 @@ msgid "Unauthorized operation" msgstr "" #: admin/template-post.php:36 includes/Admin/Forms/Template_Post.php:39 -#: includes/Fields/Form_Field_Post_Content.php:167 +#: includes/Fields/Form_Field_Post_Content.php:169 msgid "Enable Image Insertion" msgstr "" #: admin/template-post.php:42 includes/Admin/Forms/Template_Post.php:49 -#: includes/Fields/Form_Field_Post_Content.php:169 +#: includes/Fields/Form_Field_Post_Content.php:171 msgid "Enable image upload in post area" msgstr "" @@ -1568,6 +1578,7 @@ msgstr "" #: admin/template.php:127 includes/Admin/Forms/Admin_Template.php:146 #: includes/Fields/Field_Contract.php:652 +#: includes/Integrations/Elementor/Widget.php:560 msgid "Size" msgstr "" @@ -1608,6 +1619,9 @@ msgstr "" #: admin/template.php:188 includes/Admin/Forms/Admin_Template.php:217 #: includes/Fields/Field_Contract.php:740 +#: includes/Integrations/Elementor/Widget.php:414 +#: includes/Integrations/Elementor/Widget.php:673 +#: includes/Integrations/Elementor/Widget.php:896 msgid "Normal" msgstr "" @@ -2047,8 +2061,8 @@ msgstr "" #: includes/Integrations/WPUF_ACF_Compatibility.php:90 #: includes/Integrations/WPUF_ACF_Compatibility.php:156 #: includes/Widgets/Login_Widget.php:36 includes/Widgets/Login_Widget.php:62 -#: includes/Widgets/Login_Widget.php:79 wpuf-functions.php:1716 -#: wpuf-functions.php:1989 +#: includes/Widgets/Login_Widget.php:79 wpuf-functions.php:1721 +#: wpuf-functions.php:1994 msgid "Permission denied" msgstr "" @@ -2244,7 +2258,7 @@ msgstr "" #: includes/Admin/Admin_Subscription.php:436 #: includes/Admin/Admin_Subscription.php:1053 -#: includes/Admin/views/support.php:77 wpuf-functions.php:5121 +#: includes/Admin/views/support.php:77 wpuf-functions.php:5126 msgid "Payment Settings" msgstr "" @@ -2283,7 +2297,7 @@ msgstr "" #: includes/Admin/Admin_Subscription.php:532 #: includes/Admin/Admin_Subscription.php:1085 includes/Free/Form_Element.php:59 -#: wpuf-functions.php:5147 +#: wpuf-functions.php:5152 msgid "Post Expiration" msgstr "" @@ -2410,8 +2424,8 @@ msgid "Select Package:" msgstr "" #: includes/Admin/Admin_Subscription.php:950 -#: includes/functions/settings-options.php:811 wpuf-functions.php:2041 -#: wpuf-functions.php:2309 +#: includes/functions/settings-options.php:811 wpuf-functions.php:2046 +#: wpuf-functions.php:2314 msgid "— Select —" msgstr "" @@ -2558,12 +2572,12 @@ msgid "Publish" msgstr "" #: includes/Admin/Admin_Subscription.php:1284 wpuf-functions.php:68 -#: wpuf-functions.php:5288 wpuf-functions.php:5331 +#: wpuf-functions.php:5293 wpuf-functions.php:5336 msgid "Draft" msgstr "" -#: includes/Admin/Admin_Subscription.php:1285 wpuf-functions.php:5289 -#: wpuf-functions.php:5332 +#: includes/Admin/Admin_Subscription.php:1285 wpuf-functions.php:5294 +#: wpuf-functions.php:5337 msgid "Pending Review" msgstr "" @@ -2741,8 +2755,8 @@ msgstr "" #: includes/Admin/Admin_Tools.php:55 includes/Admin/Admin_Tools.php:118 #: includes/Admin/List_Table_Subscribers.php:170 -#: includes/Admin/List_Table_Transactions.php:97 wpuf-functions.php:3744 -#: wpuf-functions.php:5722 +#: includes/Admin/List_Table_Transactions.php:97 wpuf-functions.php:3749 +#: wpuf-functions.php:5727 msgid "All" msgstr "" @@ -2908,7 +2922,7 @@ msgid "Customize WPUF Settings" msgstr "" #: includes/Admin/Customizer_Options.php:75 includes/Frontend/Payment.php:157 -#: wpuf-functions.php:2274 +#: wpuf-functions.php:2279 msgid "Billing Address" msgstr "" @@ -3193,7 +3207,7 @@ msgid "— No Template —" msgstr "" #: includes/Admin/Forms/Post/Templates/Form_Template.php:231 -#: includes/Free/Free_Loader.php:1706 wpuf-functions.php:5312 +#: includes/Free/Free_Loader.php:1706 wpuf-functions.php:5317 msgid "" "If selected a form template, it will try to execute that integration " "options when new post created and updated." @@ -3204,7 +3218,7 @@ msgstr "" #: includes/Admin/views/shortcode-builder.php:8 #: includes/Free/Free_Loader.php:1712 includes/Free/Free_Loader.php:1716 #: includes/Free/Free_Loader.php:1720 includes/Free/Free_Loader.php:1724 -#: includes/Free/Free_Loader.php:1728 wpuf-functions.php:5195 +#: includes/Free/Free_Loader.php:1728 wpuf-functions.php:5200 msgid "Post Form" msgstr "" @@ -4739,6 +4753,7 @@ msgid "Try Again" msgstr "" #: includes/Ajax/Address_Form_Ajax.php:40 includes/Frontend.php:178 +#: includes/Integrations/Elementor/Elementor.php:217 msgid "Some Required Fields are not filled!" msgstr "" @@ -5613,7 +5628,7 @@ msgstr "" msgid "Choose how you want the progressbar" msgstr "" -#: includes/Free/Form_Element.php:227 wpuf-functions.php:5546 +#: includes/Free/Form_Element.php:227 wpuf-functions.php:5551 msgid "New post created" msgstr "" @@ -5621,8 +5636,8 @@ msgstr "" msgid "A post has been edited" msgstr "" -#: includes/Free/Form_Element.php:236 wpuf-functions.php:5525 -#: wpuf-functions.php:5532 +#: includes/Free/Form_Element.php:236 wpuf-functions.php:5530 +#: wpuf-functions.php:5537 msgid "New Post Notification" msgstr "" @@ -5639,13 +5654,13 @@ msgid "Learn more about Email Notification" msgstr "" #: includes/Free/Form_Element.php:255 includes/Free/Form_Element.php:292 -#: includes/Free/Free_Loader.php:1636 wpuf-functions.php:5538 -#: wpuf-functions.php:5645 +#: includes/Free/Free_Loader.php:1636 wpuf-functions.php:5543 +#: wpuf-functions.php:5650 msgid "To" msgstr "" #: includes/Free/Form_Element.php:262 includes/Free/Form_Element.php:297 -#: includes/Free/Free_Loader.php:1641 wpuf-functions.php:5544 +#: includes/Free/Free_Loader.php:1641 wpuf-functions.php:5549 msgid "Subject" msgstr "" @@ -5653,7 +5668,7 @@ msgstr "" msgid "Message" msgstr "" -#: includes/Free/Form_Element.php:274 wpuf-functions.php:5574 +#: includes/Free/Form_Element.php:274 wpuf-functions.php:5579 msgid "Update Post Notification" msgstr "" @@ -5757,7 +5772,7 @@ msgid "" msgstr "" #: includes/Free/Free_Loader.php:285 templates/account.php:41 -#: wpuf-functions.php:2272 +#: wpuf-functions.php:2277 msgid "Edit Profile" msgstr "" @@ -6277,6 +6292,12 @@ msgid "Background color for progressbar or active step." msgstr "" #: includes/Free/Free_Loader.php:1609 +#: includes/Integrations/Elementor/Widget.php:419 +#: includes/Integrations/Elementor/Widget.php:480 +#: includes/Integrations/Elementor/Widget.php:678 +#: includes/Integrations/Elementor/Widget.php:802 +#: includes/Integrations/Elementor/Widget.php:901 +#: includes/Integrations/Elementor/Widget.php:1025 msgid "Background Color" msgstr "" @@ -6288,7 +6309,7 @@ msgstr "" msgid "Enable Update Post Notification" msgstr "" -#: includes/Free/Free_Loader.php:1646 wpuf-functions.php:5550 +#: includes/Free/Free_Loader.php:1646 wpuf-functions.php:5555 msgid "Email Body" msgstr "" @@ -6296,7 +6317,7 @@ msgstr "" msgid "Conditional Logic on Submit" msgstr "" -#: includes/Free/Free_Loader.php:1704 wpuf-functions.php:5589 +#: includes/Free/Free_Loader.php:1704 wpuf-functions.php:5594 msgid "Choose Form Style" msgstr "" @@ -7017,86 +7038,86 @@ msgstr "" msgid "Subscription Page settings not set in admin settings" msgstr "" -#: includes/Frontend.php:115 +#: includes/Frontend.php:115 includes/Integrations/Elementor/Elementor.php:166 msgid "Please fix the errors to proceed" msgstr "" -#: includes/Frontend.php:117 +#: includes/Frontend.php:117 includes/Integrations/Elementor/Elementor.php:168 msgid "Word limit reached" msgstr "" -#: includes/Frontend.php:118 +#: includes/Frontend.php:118 includes/Integrations/Elementor/Elementor.php:169 msgid "Are you sure you want to cancel your current subscription ?" msgstr "" -#: includes/Frontend.php:123 +#: includes/Frontend.php:123 includes/Integrations/Elementor/Elementor.php:172 msgid "Maximum word limit reached. Please shorten your texts." msgstr "" -#: includes/Frontend.php:126 +#: includes/Frontend.php:126 includes/Integrations/Elementor/Elementor.php:173 msgid "" "This field supports a maximum of %number% words, and the limit is reached. " "Remove a few words to reach the acceptable limit of the field." msgstr "" -#: includes/Frontend.php:130 +#: includes/Frontend.php:130 includes/Integrations/Elementor/Elementor.php:174 msgid "Minimum word required." msgstr "" -#: includes/Frontend.php:131 +#: includes/Frontend.php:131 includes/Integrations/Elementor/Elementor.php:175 msgid "This field requires minimum %number% words. Please add some more text." msgstr "" -#: includes/Frontend.php:134 +#: includes/Frontend.php:134 includes/Integrations/Elementor/Elementor.php:176 msgid "Maximum character limit reached. Please shorten your texts." msgstr "" -#: includes/Frontend.php:137 +#: includes/Frontend.php:137 includes/Integrations/Elementor/Elementor.php:177 msgid "" "This field supports a maximum of %number% characters, and the limit is " "reached. Remove a few characters to reach the acceptable limit of the field." msgstr "" -#: includes/Frontend.php:141 +#: includes/Frontend.php:141 includes/Integrations/Elementor/Elementor.php:178 msgid "Minimum character required." msgstr "" -#: includes/Frontend.php:142 +#: includes/Frontend.php:142 includes/Integrations/Elementor/Elementor.php:179 msgid "" "This field requires minimum %number% characters. Please add some more " "character." msgstr "" -#: includes/Frontend.php:148 +#: includes/Frontend.php:148 includes/Integrations/Elementor/Elementor.php:181 #. translators: %shortcode% is the shortcode name msgid "Using %shortcode% is restricted" msgstr "" -#: includes/Frontend.php:149 +#: includes/Frontend.php:149 includes/Integrations/Elementor/Elementor.php:182 msgid "Your password should be at least weak in strength" msgstr "" -#: includes/Frontend.php:150 +#: includes/Frontend.php:150 includes/Integrations/Elementor/Elementor.php:183 msgid "Your password needs to be medium strength for better protection" msgstr "" -#: includes/Frontend.php:151 +#: includes/Frontend.php:151 includes/Integrations/Elementor/Elementor.php:184 msgid "Create a strong password for maximum security" msgstr "" -#: includes/Frontend.php:157 +#: includes/Frontend.php:157 includes/Integrations/Elementor/Elementor.php:193 msgid "is required" msgstr "" -#: includes/Frontend.php:158 +#: includes/Frontend.php:158 includes/Integrations/Elementor/Elementor.php:194 msgid "does not match" msgstr "" -#: includes/Frontend.php:159 +#: includes/Frontend.php:159 includes/Integrations/Elementor/Elementor.php:195 msgid "is not valid" msgstr "" -#: includes/Frontend.php:168 +#: includes/Frontend.php:168 includes/Integrations/Elementor/Elementor.php:206 msgid "Please Cancel Your Currently Active Pack first!" msgstr "" @@ -7117,6 +7138,172 @@ msgstr "" msgid "Mark the %1$s as featured (remaining %2$d)" msgstr "" +#: includes/Integrations/Elementor/Widget.php:42 +msgid "User Frontend Form" +msgstr "" + +#: includes/Integrations/Elementor/Widget.php:120 +msgid "Content" +msgstr "" + +#: includes/Integrations/Elementor/Widget.php:127 +msgid "Select Form" +msgstr "" + +#: includes/Integrations/Elementor/Widget.php:171 +msgid "Select a Form" +msgstr "" + +#: includes/Integrations/Elementor/Widget.php:201 +msgid "Form Container" +msgstr "" + +#: includes/Integrations/Elementor/Widget.php:210 +msgid "Background" +msgstr "" + +#: includes/Integrations/Elementor/Widget.php:219 +msgid "Max Width" +msgstr "" + +#: includes/Integrations/Elementor/Widget.php:235 +#: includes/Integrations/Elementor/Widget.php:401 +#: includes/Integrations/Elementor/Widget.php:646 +#: includes/Integrations/Elementor/Widget.php:869 +msgid "Alignment" +msgstr "" + +#: includes/Integrations/Elementor/Widget.php:239 +#: includes/functions/settings-options.php:116 +msgid "Default" +msgstr "" + +#: includes/Integrations/Elementor/Widget.php:243 +#: includes/Integrations/Elementor/Widget.php:404 +#: includes/Integrations/Elementor/Widget.php:650 +#: includes/Integrations/Elementor/Widget.php:873 +#: includes/functions/settings-options.php:595 +msgid "Left" +msgstr "" + +#: includes/Integrations/Elementor/Widget.php:247 +#: includes/Integrations/Elementor/Widget.php:405 +#: includes/Integrations/Elementor/Widget.php:651 +#: includes/Integrations/Elementor/Widget.php:874 +msgid "Center" +msgstr "" + +#: includes/Integrations/Elementor/Widget.php:251 +#: includes/Integrations/Elementor/Widget.php:406 +#: includes/Integrations/Elementor/Widget.php:652 +#: includes/Integrations/Elementor/Widget.php:875 +#: includes/functions/settings-options.php:597 +msgid "Right" +msgstr "" + +#: includes/Integrations/Elementor/Widget.php:262 +#: includes/Integrations/Elementor/Widget.php:457 +#: includes/Integrations/Elementor/Widget.php:758 +#: includes/Integrations/Elementor/Widget.php:981 +msgid "Padding" +msgstr "" + +#: includes/Integrations/Elementor/Widget.php:274 +msgid "Margin" +msgstr "" + +#: includes/Integrations/Elementor/Widget.php:294 +#: includes/Integrations/Elementor/Widget.php:447 +#: includes/Integrations/Elementor/Widget.php:741 +#: includes/Integrations/Elementor/Widget.php:964 +msgid "Border Radius" +msgstr "" + +#: includes/Integrations/Elementor/Widget.php:325 +msgid "Labels" +msgstr "" + +#: includes/Integrations/Elementor/Widget.php:333 +#: includes/Integrations/Elementor/Widget.php:428 +#: includes/Integrations/Elementor/Widget.php:532 +#: includes/Integrations/Elementor/Widget.php:688 +#: includes/Integrations/Elementor/Widget.php:812 +#: includes/Integrations/Elementor/Widget.php:911 +#: includes/Integrations/Elementor/Widget.php:1035 +msgid "Text Color" +msgstr "" + +#: includes/Integrations/Elementor/Widget.php:352 +msgid "Asterisk Color" +msgstr "" + +#: includes/Integrations/Elementor/Widget.php:364 +msgid "Asterisk Size" +msgstr "" + +#: includes/Integrations/Elementor/Widget.php:393 +msgid "Input & Textarea" +msgstr "" + +#: includes/Integrations/Elementor/Widget.php:475 +msgid "Focus" +msgstr "" + +#: includes/Integrations/Elementor/Widget.php:522 +msgid "Placeholder" +msgstr "" + +#: includes/Integrations/Elementor/Widget.php:552 +msgid "Radio & Checkbox" +msgstr "" + +#: includes/Integrations/Elementor/Widget.php:574 +msgid "Spacing" +msgstr "" + +#: includes/Integrations/Elementor/Widget.php:587 +msgid "Selector Color" +msgstr "" + +#: includes/Integrations/Elementor/Widget.php:598 +msgid "Options Text Color" +msgstr "" + +#: includes/Integrations/Elementor/Widget.php:625 +msgid "Upload Button" +msgstr "" + +#: includes/Integrations/Elementor/Widget.php:633 +#: includes/Integrations/Elementor/Widget.php:662 +#: includes/Integrations/Elementor/Widget.php:856 +#: includes/Integrations/Elementor/Widget.php:885 +msgid "Width" +msgstr "" + +#: includes/Integrations/Elementor/Widget.php:637 +#: includes/Integrations/Elementor/Widget.php:860 +msgid "Full Width" +msgstr "" + +#: includes/Integrations/Elementor/Widget.php:638 +#: includes/Integrations/Elementor/Widget.php:861 +msgid "Custom" +msgstr "" + +#: includes/Integrations/Elementor/Widget.php:797 +#: includes/Integrations/Elementor/Widget.php:1020 +msgid "Hover" +msgstr "" + +#: includes/Integrations/Elementor/Widget.php:822 +#: includes/Integrations/Elementor/Widget.php:1045 +msgid "Border Color" +msgstr "" + +#: includes/Integrations/Elementor/Widget.php:848 +msgid "Submit Button" +msgstr "" + #: includes/Integrations/Events_Calendar/Templates/Event_Form_Template.php:23 msgid "The Events Calendar" msgstr "" @@ -7414,7 +7601,7 @@ msgstr "" msgid "Select the authentication type for the N8N integration." msgstr "" -#: includes/Integrations/WPUF_N8N_Integration.php:193 wpuf-functions.php:3745 +#: includes/Integrations/WPUF_N8N_Integration.php:193 wpuf-functions.php:3750 msgid "None" msgstr "" @@ -8165,10 +8352,6 @@ msgstr "" msgid "Admins, Editors, Authors, Contributors" msgstr "" -#: includes/functions/settings-options.php:116 -msgid "Default" -msgstr "" - #: includes/functions/settings-options.php:121 msgid "Override the post edit link" msgstr "" @@ -8580,14 +8763,6 @@ msgstr "" msgid "Currency Position" msgstr "" -#: includes/functions/settings-options.php:595 -msgid "Left" -msgstr "" - -#: includes/functions/settings-options.php:597 -msgid "Right" -msgstr "" - #: includes/functions/settings-options.php:599 msgid "Left with space" msgstr "" @@ -9353,11 +9528,11 @@ msgstr "" msgid "Scheduled" msgstr "" -#: wpuf-functions.php:44 wpuf-functions.php:5290 wpuf-functions.php:5333 +#: wpuf-functions.php:44 wpuf-functions.php:5295 wpuf-functions.php:5338 msgid "Private" msgstr "" -#: wpuf-functions.php:65 wpuf-functions.php:5291 wpuf-functions.php:5334 +#: wpuf-functions.php:65 wpuf-functions.php:5296 wpuf-functions.php:5339 msgid "Published" msgstr "" @@ -9393,552 +9568,552 @@ msgstr "" msgid "Directions »" msgstr "" -#: wpuf-functions.php:2543 +#: wpuf-functions.php:2548 msgid "United Arab Emirates Dirham" msgstr "" -#: wpuf-functions.php:2548 +#: wpuf-functions.php:2553 msgid "Australian Dollars" msgstr "" -#: wpuf-functions.php:2553 +#: wpuf-functions.php:2558 msgid "Argentine Peso" msgstr "" -#: wpuf-functions.php:2558 +#: wpuf-functions.php:2563 msgid "Bangladeshi Taka" msgstr "" -#: wpuf-functions.php:2563 +#: wpuf-functions.php:2568 msgid "Brazilian Real" msgstr "" -#: wpuf-functions.php:2568 +#: wpuf-functions.php:2573 msgid "Bulgarian Lev" msgstr "" -#: wpuf-functions.php:2573 +#: wpuf-functions.php:2578 msgid "Canadian Dollars" msgstr "" -#: wpuf-functions.php:2578 +#: wpuf-functions.php:2583 msgid "Chilean Peso" msgstr "" -#: wpuf-functions.php:2583 +#: wpuf-functions.php:2588 msgid "Chinese Yuan" msgstr "" -#: wpuf-functions.php:2588 +#: wpuf-functions.php:2593 msgid "Colombian Peso" msgstr "" -#: wpuf-functions.php:2593 +#: wpuf-functions.php:2598 msgid "Czech Koruna" msgstr "" -#: wpuf-functions.php:2598 +#: wpuf-functions.php:2603 msgid "Danish Krone" msgstr "" -#: wpuf-functions.php:2603 +#: wpuf-functions.php:2608 msgid "Dominican Peso" msgstr "" -#: wpuf-functions.php:2608 +#: wpuf-functions.php:2613 msgid "Algerian Dinar" msgstr "" -#: wpuf-functions.php:2613 +#: wpuf-functions.php:2618 msgid "Euros" msgstr "" -#: wpuf-functions.php:2618 +#: wpuf-functions.php:2623 msgid "Hong Kong Dollar" msgstr "" -#: wpuf-functions.php:2623 +#: wpuf-functions.php:2628 msgid "Croatia kuna" msgstr "" -#: wpuf-functions.php:2628 +#: wpuf-functions.php:2633 msgid "Hungarian Forint" msgstr "" -#: wpuf-functions.php:2633 +#: wpuf-functions.php:2638 msgid "Icelandic krona" msgstr "" -#: wpuf-functions.php:2638 +#: wpuf-functions.php:2643 msgid "Indonesia Rupiah" msgstr "" -#: wpuf-functions.php:2643 +#: wpuf-functions.php:2648 msgid "Indian Rupee" msgstr "" -#: wpuf-functions.php:2648 +#: wpuf-functions.php:2653 msgid "Mauritian Rupee" msgstr "" -#: wpuf-functions.php:2653 +#: wpuf-functions.php:2658 msgid "Nepali Rupee" msgstr "" -#: wpuf-functions.php:2658 +#: wpuf-functions.php:2663 msgid "Israeli Shekel" msgstr "" -#: wpuf-functions.php:2663 +#: wpuf-functions.php:2668 msgid "Japanese Yen" msgstr "" -#: wpuf-functions.php:2668 +#: wpuf-functions.php:2673 msgid "Lao Kip" msgstr "" -#: wpuf-functions.php:2673 +#: wpuf-functions.php:2678 msgid "South Korean Won" msgstr "" -#: wpuf-functions.php:2678 +#: wpuf-functions.php:2683 msgid "Malaysian Ringgits" msgstr "" -#: wpuf-functions.php:2683 +#: wpuf-functions.php:2688 msgid "Mexican Peso" msgstr "" -#: wpuf-functions.php:2688 +#: wpuf-functions.php:2693 msgid "Nigerian Naira" msgstr "" -#: wpuf-functions.php:2693 +#: wpuf-functions.php:2698 msgid "Norwegian Krone" msgstr "" -#: wpuf-functions.php:2698 +#: wpuf-functions.php:2703 msgid "New Zealand Dollar" msgstr "" -#: wpuf-functions.php:2703 +#: wpuf-functions.php:2708 msgid "Namibian dollar" msgstr "" -#: wpuf-functions.php:2708 +#: wpuf-functions.php:2713 msgid "Omani Rial" msgstr "" -#: wpuf-functions.php:2713 +#: wpuf-functions.php:2718 msgid "Iranian Rial" msgstr "" -#: wpuf-functions.php:2718 +#: wpuf-functions.php:2723 msgid "Pakistani Rupee" msgstr "" -#: wpuf-functions.php:2723 +#: wpuf-functions.php:2728 msgid "Paraguayan Guaraní" msgstr "" -#: wpuf-functions.php:2728 +#: wpuf-functions.php:2733 msgid "Philippine Pesos" msgstr "" -#: wpuf-functions.php:2733 +#: wpuf-functions.php:2738 msgid "Polish Zloty" msgstr "" -#: wpuf-functions.php:2738 +#: wpuf-functions.php:2743 msgid "Pounds Sterling" msgstr "" -#: wpuf-functions.php:2743 +#: wpuf-functions.php:2748 msgid "Romanian Leu" msgstr "" -#: wpuf-functions.php:2748 +#: wpuf-functions.php:2753 msgid "Russian Ruble" msgstr "" -#: wpuf-functions.php:2753 +#: wpuf-functions.php:2758 msgid "Saudi Riyal" msgstr "" -#: wpuf-functions.php:2758 +#: wpuf-functions.php:2763 msgid "Singapore Dollar" msgstr "" -#: wpuf-functions.php:2763 +#: wpuf-functions.php:2768 msgid "South African rand" msgstr "" -#: wpuf-functions.php:2768 +#: wpuf-functions.php:2773 msgid "Swedish Krona" msgstr "" -#: wpuf-functions.php:2773 +#: wpuf-functions.php:2778 msgid "Swiss Franc" msgstr "" -#: wpuf-functions.php:2778 +#: wpuf-functions.php:2783 msgid "Taiwan New Dollars" msgstr "" -#: wpuf-functions.php:2783 +#: wpuf-functions.php:2788 msgid "Thai Baht" msgstr "" -#: wpuf-functions.php:2788 +#: wpuf-functions.php:2793 msgid "Turkish Lira" msgstr "" -#: wpuf-functions.php:2793 +#: wpuf-functions.php:2798 msgid "Trinidad and Tobago Dollar" msgstr "" -#: wpuf-functions.php:2798 +#: wpuf-functions.php:2803 msgid "US Dollar" msgstr "" -#: wpuf-functions.php:2803 +#: wpuf-functions.php:2808 msgid "Vietnamese Dong" msgstr "" -#: wpuf-functions.php:2808 +#: wpuf-functions.php:2813 msgid "Egyptian Pound" msgstr "" -#: wpuf-functions.php:2813 +#: wpuf-functions.php:2818 msgid "Jordanian dinar" msgstr "" -#: wpuf-functions.php:5115 +#: wpuf-functions.php:5120 msgid "General" msgstr "" -#: wpuf-functions.php:5129 +#: wpuf-functions.php:5134 msgid "Notification Settings" msgstr "" -#: wpuf-functions.php:5135 +#: wpuf-functions.php:5140 msgid "Display Settings" msgstr "" -#: wpuf-functions.php:5141 +#: wpuf-functions.php:5146 msgid "Advanced" msgstr "" -#: wpuf-functions.php:5159 +#: wpuf-functions.php:5164 msgid "Post Settings" msgstr "" -#: wpuf-functions.php:5194 +#: wpuf-functions.php:5199 msgid "-- Select Template --" msgstr "" -#: wpuf-functions.php:5196 +#: wpuf-functions.php:5201 msgid "WooCommerce Product Form" msgstr "" -#: wpuf-functions.php:5197 +#: wpuf-functions.php:5202 msgid "EDD Download Form" msgstr "" -#: wpuf-functions.php:5198 +#: wpuf-functions.php:5203 msgid "Event Form" msgstr "" -#: wpuf-functions.php:5199 +#: wpuf-functions.php:5204 msgid "Video Form" msgstr "" -#: wpuf-functions.php:5200 +#: wpuf-functions.php:5205 msgid "Professional Video Form" msgstr "" -#: wpuf-functions.php:5201 +#: wpuf-functions.php:5206 msgid "Artwork Form" msgstr "" -#: wpuf-functions.php:5202 +#: wpuf-functions.php:5207 msgid "Press Release Form" msgstr "" -#: wpuf-functions.php:5219 +#: wpuf-functions.php:5224 msgid "Before Post Settings" msgstr "" -#: wpuf-functions.php:5220 +#: wpuf-functions.php:5225 msgid "" "Configure how the form behaves before submission, including content type, " "default category, post status, draft-saving options, and submit button " "customization" msgstr "" -#: wpuf-functions.php:5226 +#: wpuf-functions.php:5231 msgid "Show Form Title" msgstr "" -#: wpuf-functions.php:5228 +#: wpuf-functions.php:5233 msgid "Toggle whether the form title should be displayed on the frontend" msgstr "" -#: wpuf-functions.php:5231 +#: wpuf-functions.php:5236 msgid "Form Description" msgstr "" -#: wpuf-functions.php:5233 +#: wpuf-functions.php:5238 msgid "" "Add a brief message or instruction that will be displayed before the form — " "helpful for guiding users before they start filling it out" msgstr "" -#: wpuf-functions.php:5239 +#: wpuf-functions.php:5244 msgid "" "Select the content type this form will create, like a post, product, or " "custom type" msgstr "" -#: wpuf-functions.php:5248 +#: wpuf-functions.php:5253 msgid "Default Category" msgstr "" -#: wpuf-functions.php:5250 +#: wpuf-functions.php:5255 msgid "Select the default category for posts submitted through this form" msgstr "" -#: wpuf-functions.php:5256 wpuf-functions.php:5342 +#: wpuf-functions.php:5261 wpuf-functions.php:5347 msgid "Successful Redirection" msgstr "" -#: wpuf-functions.php:5258 +#: wpuf-functions.php:5263 msgid "Select where users will be redirected after successfully submitting the form" msgstr "" -#: wpuf-functions.php:5264 wpuf-functions.php:5349 +#: wpuf-functions.php:5269 wpuf-functions.php:5354 msgid "Same page" msgstr "" -#: wpuf-functions.php:5278 wpuf-functions.php:5372 +#: wpuf-functions.php:5283 wpuf-functions.php:5377 msgid "Choose the default category for the post" msgstr "" -#: wpuf-functions.php:5285 +#: wpuf-functions.php:5290 msgid "Post Submission Status" msgstr "" -#: wpuf-functions.php:5293 +#: wpuf-functions.php:5298 msgid "Select the status of the post after submission" msgstr "" -#: wpuf-functions.php:5296 +#: wpuf-functions.php:5301 msgid "Enable saving as draft" msgstr "" -#: wpuf-functions.php:5298 +#: wpuf-functions.php:5303 msgid "Allow users to save posts before final submission" msgstr "" -#: wpuf-functions.php:5303 +#: wpuf-functions.php:5308 msgid "Submit Post Button Text" msgstr "" -#: wpuf-functions.php:5305 +#: wpuf-functions.php:5310 msgid "Customize the text on the 'Submit' button for this form" msgstr "" -#: wpuf-functions.php:5310 +#: wpuf-functions.php:5315 msgid "Choose Form Template" msgstr "" -#: wpuf-functions.php:5321 +#: wpuf-functions.php:5326 msgid "After Post Settings" msgstr "" -#: wpuf-functions.php:5322 +#: wpuf-functions.php:5327 msgid "" "Manage what happens after submission, such as setting post update status, " "displaying success messages, redirecting users, limiting edit time, and " "customizing the update button" msgstr "" -#: wpuf-functions.php:5328 +#: wpuf-functions.php:5333 msgid "Post Update Status" msgstr "" -#: wpuf-functions.php:5337 +#: wpuf-functions.php:5342 msgid "Select the status the post will have after being updated" msgstr "" -#: wpuf-functions.php:5344 +#: wpuf-functions.php:5349 msgid "After successfully submit, where the page will redirect to" msgstr "" -#: wpuf-functions.php:5348 +#: wpuf-functions.php:5353 msgid "Updated post" msgstr "" -#: wpuf-functions.php:5358 +#: wpuf-functions.php:5363 msgid "" "Post has been updated successfully. View " "post" msgstr "" -#: wpuf-functions.php:5363 +#: wpuf-functions.php:5368 msgid "Customize the message displayed after a post is successfully updated" msgstr "" -#: wpuf-functions.php:5379 +#: wpuf-functions.php:5384 msgid "Lock User Editing After" msgstr "" -#: wpuf-functions.php:5381 +#: wpuf-functions.php:5386 msgid "" "Set the number of hours after which users can no longer edit their " "submitted post" msgstr "" -#: wpuf-functions.php:5386 +#: wpuf-functions.php:5391 msgid "Hours" msgstr "" -#: wpuf-functions.php:5389 +#: wpuf-functions.php:5394 msgid "Update Post Button Text" msgstr "" -#: wpuf-functions.php:5391 +#: wpuf-functions.php:5396 msgid "Customize the text on the 'Update' button for this form" msgstr "" -#: wpuf-functions.php:5398 +#: wpuf-functions.php:5403 msgid "Posting Control" msgstr "" -#: wpuf-functions.php:5399 +#: wpuf-functions.php:5404 msgid "" "Define who can submit posts using this form. Choose whether to allow guest " "submissions or restrict access based on user roles" msgstr "" -#: wpuf-functions.php:5405 +#: wpuf-functions.php:5410 msgid "Post Permission" msgstr "" -#: wpuf-functions.php:5408 +#: wpuf-functions.php:5413 msgid "- Select Post Permission -" msgstr "" -#: wpuf-functions.php:5410 +#: wpuf-functions.php:5415 msgid "Role Based Post" msgstr "" -#: wpuf-functions.php:5412 +#: wpuf-functions.php:5417 msgid "" "Select who can submit posts using this form, either guests or specific user " "roles" msgstr "" -#: wpuf-functions.php:5420 +#: wpuf-functions.php:5425 msgid "" "If enabled, guest users will be automatically registered using their name " "and email" msgstr "" -#: wpuf-functions.php:5430 +#: wpuf-functions.php:5435 msgid "Customize the label for the name field in guest submissions" msgstr "" -#: wpuf-functions.php:5438 +#: wpuf-functions.php:5443 msgid "Customize the label for the email field in guest submissions" msgstr "" -#: wpuf-functions.php:5446 +#: wpuf-functions.php:5451 msgid "Require email verification" msgstr "" -#: wpuf-functions.php:5448 +#: wpuf-functions.php:5453 msgid "If enabled, users must verify their email before submitting a post" msgstr "" -#: wpuf-functions.php:5453 +#: wpuf-functions.php:5458 msgid "Choose who can submit post" msgstr "" -#: wpuf-functions.php:5455 +#: wpuf-functions.php:5460 msgid "Select the user roles who can submit posts" msgstr "" -#: wpuf-functions.php:5462 +#: wpuf-functions.php:5467 msgid "" "Display this message to non-logged-in users. Use {login} and {register} " "placeholders to add login and registration links" msgstr "" -#: wpuf-functions.php:5479 +#: wpuf-functions.php:5484 msgid "Enable payments for this form to charge users for submissions" msgstr "" -#: wpuf-functions.php:5484 +#: wpuf-functions.php:5489 msgid "Choose Payment Option" msgstr "" -#: wpuf-functions.php:5487 +#: wpuf-functions.php:5492 msgid "Mandatory Subscription" msgstr "" -#: wpuf-functions.php:5488 +#: wpuf-functions.php:5493 msgid "Pay as you post" msgstr "" -#: wpuf-functions.php:5490 +#: wpuf-functions.php:5495 msgid "Select how users will pay for submitting posts" msgstr "" -#: wpuf-functions.php:5495 +#: wpuf-functions.php:5500 msgid "Pay-per-post billing when limit exceeds" msgstr "" -#: wpuf-functions.php:5497 +#: wpuf-functions.php:5502 msgid "Switch to pay-per-post billing if pack limit is exceeded" msgstr "" -#: wpuf-functions.php:5500 +#: wpuf-functions.php:5505 msgid "Cost for each additional post after pack limit is reached" msgstr "" -#: wpuf-functions.php:5502 +#: wpuf-functions.php:5507 msgid "" "This field is required when Pay-per-post billing when limit exceeds is " "enabled." msgstr "" -#: wpuf-functions.php:5505 +#: wpuf-functions.php:5510 msgid "Charge for each post" msgstr "" -#: wpuf-functions.php:5507 +#: wpuf-functions.php:5512 msgid "" "Set a fee for each post submission. This field is required when Pay as you " "post is selected." msgstr "" -#: wpuf-functions.php:5515 +#: wpuf-functions.php:5520 msgid "Select the page to redirect after successful payment." msgstr "" -#: wpuf-functions.php:5526 +#: wpuf-functions.php:5531 msgid "" "Enable email alerts for new post submissions via the frontend form. This " "feature keeps you updated on user activity, allowing for timely review and " "approval of content" msgstr "" -#: wpuf-functions.php:5534 +#: wpuf-functions.php:5539 msgid "Enable email alerts for new submissions through this form" msgstr "" -#: wpuf-functions.php:5575 +#: wpuf-functions.php:5580 msgid "" "Enable this feature to receive email alerts whenever an existing post is " "updated through the frontend form. This ensures you're promptly informed " @@ -9946,95 +10121,95 @@ msgid "" "updates" msgstr "" -#: wpuf-functions.php:5590 +#: wpuf-functions.php:5595 msgid "" "Customize the appearance and layout of your form. Select a form template " "that best suits your website's design for a cohesive look and feel" msgstr "" -#: wpuf-functions.php:5598 +#: wpuf-functions.php:5603 msgid "Apply your site's theme CSS for consistent styling and appearance" msgstr "" -#: wpuf-functions.php:5611 +#: wpuf-functions.php:5616 msgid "" "Customize the position of form labels for improved user navigation and " "clarity" msgstr "" -#: wpuf-functions.php:5623 +#: wpuf-functions.php:5628 msgid "Enable User Comment" msgstr "" -#: wpuf-functions.php:5625 +#: wpuf-functions.php:5630 msgid "Allow users to comment on posts submitted via this form" msgstr "" -#: wpuf-functions.php:5632 +#: wpuf-functions.php:5637 msgid "Enable Form Scheduling" msgstr "" -#: wpuf-functions.php:5634 +#: wpuf-functions.php:5639 msgid "Set specific dates and times for when the form will be accessible to users" msgstr "" -#: wpuf-functions.php:5659 +#: wpuf-functions.php:5664 msgid "Limit Form Entries" msgstr "" -#: wpuf-functions.php:5661 +#: wpuf-functions.php:5666 msgid "Limit the number of submissions allowed for the form" msgstr "" -#: wpuf-functions.php:5723 +#: wpuf-functions.php:5728 msgid "Saved" msgstr "" -#: wpuf-functions.php:5724 +#: wpuf-functions.php:5729 msgid "Trash" msgstr "" -#: wpuf-functions.php:5767 +#: wpuf-functions.php:5772 msgid "JPG" msgstr "" -#: wpuf-functions.php:5768 +#: wpuf-functions.php:5773 msgid "JPEG" msgstr "" -#: wpuf-functions.php:5769 +#: wpuf-functions.php:5774 msgid "PNG" msgstr "" -#: wpuf-functions.php:5770 +#: wpuf-functions.php:5775 msgid "GIF" msgstr "" -#: wpuf-functions.php:5915 +#: wpuf-functions.php:5920 msgid "Layout 1 - Classic" msgstr "" -#: wpuf-functions.php:5916 +#: wpuf-functions.php:5921 msgid "Layout 2 - Modern Dark" msgstr "" -#: wpuf-functions.php:5917 +#: wpuf-functions.php:5922 msgid "Layout 3 - Minimal" msgstr "" -#: wpuf-functions.php:5918 +#: wpuf-functions.php:5923 msgid "Layout 4 - Bordered" msgstr "" -#: wpuf-functions.php:5919 +#: wpuf-functions.php:5924 msgid "Layout 5 - Rounded" msgstr "" -#: wpuf-functions.php:5920 +#: wpuf-functions.php:5925 msgid "Layout 6 - Clean" msgstr "" -#: wpuf-functions.php:5921 +#: wpuf-functions.php:5926 msgid "Layout 7 - Premium" msgstr "" @@ -10050,11 +10225,11 @@ msgstr "" msgid " or greater." msgstr "" -#: wpuf.php:260 +#: wpuf.php:273 msgid "Your WP User Frontend Pro is almost ready!" msgstr "" -#: wpuf.php:264 +#: wpuf.php:277 #. translators: 1: opening anchor tag, 2: closing anchor tag. msgid "" "We've pushed a major update on both WP User Frontend Free and WP " @@ -10146,7 +10321,7 @@ msgctxt "enhanced select" msgid "Searching…" msgstr "" -#: wpuf-functions.php:1731 +#: wpuf-functions.php:1736 msgctxt "tag delimiter" msgid "," msgstr "" \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index d73f6b723..ef15c9665 100644 --- a/package-lock.json +++ b/package-lock.json @@ -929,7 +929,6 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.80.tgz", "integrity": "sha512-kEWeMwMeIvxYkeg1gTc01awpwLbfMRZXdIhwRcakd/KlK53jmRC26LqcbIt7fnAQTu5GzlnWmzA3H6+l1u6xxQ==", "dev": true, - "peer": true, "dependencies": { "undici-types": "~5.26.4" } @@ -1899,7 +1898,6 @@ "url": "https://github.com/sponsors/ai" } ], - "peer": true, "dependencies": { "caniuse-lite": "^1.0.30001646", "electron-to-chromium": "^1.5.4", @@ -4617,7 +4615,6 @@ "resolved": "https://registry.npmjs.org/grunt/-/grunt-1.5.3.tgz", "integrity": "sha512-mKwmo4X2d8/4c/BmcOETHek675uOqw0RuA/zy12jaspWqvTp4+ZeQF1W+OTpcbncnaBsfbQJ6l0l4j+Sn/GmaQ==", "dev": true, - "peer": true, "dependencies": { "dateformat": "~3.0.3", "eventemitter2": "~0.4.13", @@ -8786,7 +8783,6 @@ "url": "https://github.com/sponsors/ai" } ], - "peer": true, "dependencies": { "nanoid": "^3.3.7", "picocolors": "^1.0.1", @@ -8947,7 +8943,6 @@ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", "dev": true, - "peer": true, "bin": { "prettier": "bin/prettier.cjs" }, @@ -10487,7 +10482,6 @@ "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.11.tgz", "integrity": "sha512-qhEuBcLemjSJk5ajccN9xJFtM/h0AVCPaA6C92jNP+M2J8kX+eMJHI7R2HFKUvvAsMpcfLILMCFYSeDwpMmlUg==", "dev": true, - "peer": true, "dependencies": { "@alloc/quick-lru": "^5.2.0", "arg": "^5.0.2", @@ -11356,7 +11350,6 @@ "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.4.tgz", "integrity": "sha512-RHFCkULitycHVTtelJ6jQLd+KSAAzOgEYorV32R2q++M6COBjKJR6BxqClwp5sf0XaBDjVMuJ9wnNfyAJwjMkA==", "dev": true, - "peer": true, "dependencies": { "esbuild": "^0.21.3", "postcss": "^8.4.43", @@ -11415,7 +11408,6 @@ "version": "3.5.4", "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.4.tgz", "integrity": "sha512-3yAj2gkmiY+i7+22A1PWM+kjOVXjU74UPINcTiN7grIVPyFFI0lpGwHlV/4xydDmobaBn7/xmi+YG8HeSlCTcg==", - "peer": true, "dependencies": { "@vue/compiler-dom": "3.5.4", "@vue/compiler-sfc": "3.5.4", diff --git a/wpuf-functions.php b/wpuf-functions.php index ff883eee7..2f7c2ee40 100644 --- a/wpuf-functions.php +++ b/wpuf-functions.php @@ -1492,6 +1492,11 @@ function wpuf_shortcode_map( $location, $post_id = null, $args = [], $meta_key =