Overview

Namespaces

  • None
  • Quform
    • Traduttore_Registry

Classes

  • Quform
  • Quform_Admin_InsertForm
  • Quform_Admin_Page
  • Quform_Admin_Page_Controller
  • Quform_Admin_Page_Dashboard
  • Quform_Admin_Page_Entries
  • Quform_Admin_Page_Entries_Edit
  • Quform_Admin_Page_Entries_List
  • Quform_Admin_Page_Entries_View
  • Quform_Admin_Page_Factory
  • Quform_Admin_Page_Forms_Add
  • Quform_Admin_Page_Forms_Edit
  • Quform_Admin_Page_Forms_List
  • Quform_Admin_Page_Help
  • Quform_Admin_Page_Preview
  • Quform_Admin_Page_Settings
  • Quform_Admin_Page_Tools
  • Quform_Admin_Page_Tools_ExportEntries
  • Quform_Admin_Page_Tools_ExportForm
  • Quform_Admin_Page_Tools_Home
  • Quform_Admin_Page_Tools_ImportForm
  • Quform_Admin_Page_Tools_Migrate
  • Quform_Admin_Page_Tools_Uninstall
  • Quform_Api
  • Quform_Block
  • Quform_Builder
  • Quform_Captcha
  • Quform_ClassLoader
  • Quform_Confirmation
  • Quform_Container
  • Quform_Dashboard_Widget
  • Quform_Dispatcher
  • Quform_Element
  • Quform_Element_Captcha
  • Quform_Element_Checkbox
  • Quform_Element_Column
  • Quform_Element_Container
  • Quform_Element_Container_Iterator
  • Quform_Element_Date
  • Quform_Element_Email
  • Quform_Element_Factory
  • Quform_Element_Field
  • Quform_Element_File
  • Quform_Element_Group
  • Quform_Element_Hidden
  • Quform_Element_Honeypot
  • Quform_Element_Html
  • Quform_Element_Multi
  • Quform_Element_Multiselect
  • Quform_Element_Name
  • Quform_Element_Page
  • Quform_Element_Password
  • Quform_Element_Radio
  • Quform_Element_Recaptcha
  • Quform_Element_Row
  • Quform_Element_Select
  • Quform_Element_Submit
  • Quform_Element_Text
  • Quform_Element_Textarea
  • Quform_Element_Time
  • Quform_Entry_Controller
  • Quform_Entry_Exporter
  • Quform_Entry_List_Settings
  • Quform_Entry_List_Table
  • Quform_Entry_Processor
  • Quform_Entry_UserSearcher
  • Quform_Filter_Abstract
  • Quform_Filter_Alpha
  • Quform_Filter_AlphaNumeric
  • Quform_Filter_Digits
  • Quform_Filter_Regex
  • Quform_Filter_Static
  • Quform_Filter_StripTags
  • Quform_Filter_Trim
  • Quform_Form
  • Quform_Form_Controller
  • Quform_Form_Exporter
  • Quform_Form_Factory
  • Quform_Form_Importer
  • Quform_Form_Iterator
  • Quform_Form_List_Settings
  • Quform_Form_List_Table
  • Quform_Form_Processor
  • Quform_License
  • Quform_Migrator
  • Quform_NonceRefresher
  • Quform_Notification
  • Quform_Notification_Resender
  • Quform_Options
  • Quform_Permissions
  • Quform_Repository
  • Quform_ScriptLoader
  • Quform_Session
  • Quform_Settings
  • Quform_Shortcode
  • Quform_Themes
  • Quform_TokenReplacer
  • Quform_Toolbar
  • Quform_Translations
  • Quform_Updater
  • Quform_Upgrader
  • Quform_Uploader
  • Quform_Validator_Abstract
  • Quform_Validator_Alpha
  • Quform_Validator_AlphaNumeric
  • Quform_Validator_Array
  • Quform_Validator_Captcha
  • Quform_Validator_Date
  • Quform_Validator_Digits
  • Quform_Validator_Duplicate
  • Quform_Validator_Email
  • Quform_Validator_FileUpload
  • Quform_Validator_GreaterThan
  • Quform_Validator_Honeypot
  • Quform_Validator_Identical
  • Quform_Validator_InArray
  • Quform_Validator_Length
  • Quform_Validator_LessThan
  • Quform_Validator_Recaptcha
  • Quform_Validator_Regex
  • Quform_Validator_Required
  • Quform_Validator_Static
  • Quform_Validator_Time
  • Quform_View
  • Quform_ViewFactory
  • Quform_Widget_Form
  • Quform_Widget_Popup

Interfaces

  • Quform_Attachable
  • Quform_Element_Editable
  • Quform_Filter_Interface
  • Quform_Validator_Interface

Constants

  • Quform\Traduttore_Registry\TRANSIENT_KEY_PLUGIN
  • Quform\Traduttore_Registry\TRANSIENT_KEY_THEME

Functions

  • Quform\Traduttore_Registry\add_project
  • Quform\Traduttore_Registry\clean_translations_cache
  • Quform\Traduttore_Registry\get_available_locales
  • Quform\Traduttore_Registry\get_installed_translations
  • Quform\Traduttore_Registry\get_translations
  • Quform\Traduttore_Registry\register_clean_translations_cache
  • Quform\Traduttore_Registry\sanitize_date
  • Overview
  • Namespace
  • Class
   1: <?php
   2: 
   3: /**
   4:  * @copyright Copyright (c) 2009-2022 ThemeCatcher (https://www.themecatcher.net)
   5:  */
   6: class Quform_Builder
   7: {
   8:     /**
   9:      * @var Quform_Repository
  10:      */
  11:     protected $repository;
  12: 
  13:     /**
  14:      * @var Quform_Form_Factory
  15:      */
  16:     protected $factory;
  17: 
  18:     /**
  19:      * @var Quform_Options
  20:      */
  21:     protected $options;
  22: 
  23:     /**
  24:      * @var Quform_Themes
  25:      */
  26:     protected $themes;
  27: 
  28:     /**
  29:      * @var Quform_ScriptLoader
  30:      */
  31:     protected $scriptLoader;
  32: 
  33:     /**
  34:      * @param  Quform_Repository    $repository
  35:      * @param  Quform_Form_Factory  $factory
  36:      * @param  Quform_Options       $options
  37:      * @param  Quform_Themes        $themes
  38:      * @param  Quform_ScriptLoader  $scriptLoader
  39:      */
  40:     public function __construct(Quform_Repository $repository, Quform_Form_Factory $factory, Quform_Options $options,
  41:                                 Quform_Themes $themes, Quform_ScriptLoader $scriptLoader)
  42:     {
  43:         $this->repository = $repository;
  44:         $this->factory = $factory;
  45:         $this->options = $options;
  46:         $this->themes = $themes;
  47:         $this->scriptLoader = $scriptLoader;
  48:     }
  49: 
  50:     /**
  51:      * Get the localisation / variables to pass to the builder JS
  52:      *
  53:      * @return array
  54:      */
  55:     public function getScriptL10n()
  56:     {
  57:         $data = array(
  58:             'ajaxUrl' => admin_url('admin-ajax.php'),
  59:             'pluginUrl' => Quform::url(),
  60:             'saveFormNonce' => wp_create_nonce('quform_save_form'),
  61:             'formSaved' => __('Form saved', 'quform'),
  62:             'confirmRemoveElement' => __('Are you sure you want to remove this element? Any previously submitted form data for this element will no longer be accessible.', 'quform'),
  63:             'confirmRemoveGroup' => __('Are you sure you want to remove this group? All elements inside this group will also be removed. Any previously submitted form data for elements inside this group will no longer be accessible.', 'quform'),
  64:             'confirmRemovePage' => __('Are you sure you want to remove this page? All elements inside this page will also be removed. Any previously submitted form data for elements inside this page will no longer be accessible.', 'quform'),
  65:             'confirmRemoveRow' => __('Are you sure you want to remove this row? All elements inside this row will also be removed. Any previously submitted form data for elements inside this row will no longer be accessible.', 'quform'),
  66:             'confirmRemoveColumn' => __('Are you sure you want to remove this column? All elements inside this column will also be removed. Any previously submitted form data for elements inside this column will no longer be accessible.', 'quform'),
  67:             'confirmRemoveOptgroup' => __('Are you sure you want to remove this optgroup? Any options inside of it will also be removed.', 'quform'),
  68:             'confirmRemoveSubmit' => __('Are you sure you want to remove this submit button?', 'quform'),
  69:             'nestingOptgroupError' => __('Nested optgroups are not supported.', 'quform'),
  70:             'errorSavingForm' => __('Error saving the form', 'quform'),
  71:             'atLeastOneToCcBccRequired' => __('At least one To, Cc or Bcc address is required', 'quform'),
  72:             'correctHighlightedFields' => __('Please correct the highlighted fields and save the form again', 'quform'),
  73:             'inherit' => __('Inherit', 'quform'),
  74:             'field' => __('Field', 'quform'),
  75:             'icon' => __('Icon', 'quform'),
  76:             'above' => __('Above', 'quform'),
  77:             'left' => __('Left', 'quform'),
  78:             'inside' => __('Inside', 'quform'),
  79:             'atLeastOnePage' => __('The form must have at least one page', 'quform'),
  80:             'loadedPreviewLocales' => $this->getLoadedPreviewLocales(),
  81:             'exampleTooltip' => __('This is an example tooltip!', 'quform'),
  82:             'remove' => _x('Remove', 'delete', 'quform'),
  83:             'selectOptionHtml' => $this->getOptionHtml('select'),
  84:             'checkboxOptionHtml' => $this->getOptionHtml('checkbox'),
  85:             'radioOptionHtml' => $this->getOptionHtml('radio'),
  86:             'multiselectOptionHtml' => $this->getOptionHtml('multiselect'),
  87:             'optgroupHtml' => $this->getOptgroupHtml(),
  88:             'bulkOptions' => $this->getBulkOptions(),
  89:             'defaultOptions' => $this->getDefaultOptions(),
  90:             'defaultOptgroups' => $this->getDefaultOptgroups(),
  91:             'logicRuleHtml' => $this->getLogicRuleHtml(),
  92:             'noLogicElements' => __('There are no elements available to use for logic rules.', 'quform'),
  93:             'noLogicRules' => __('There are no logic rules yet, click "Add logic rule" to add one.', 'quform'),
  94:             'logicSourceTypes' => $this->getLogicSourceTypes(),
  95:             'thisFieldMustBePositiveNumberOrZero' => __('This field must be a positive number or zero', 'quform'),
  96:             'atLeastOneLogicRuleRequired' => __('At least one logic rule is required', 'quform'),
  97:             'showThisGroup' => __('Show this group', 'quform'),
  98:             'hideThisGroup' => __('Hide this group', 'quform'),
  99:             'showThisField' => __('Show this field', 'quform'),
 100:             'hideThisField' => __('Hide this field', 'quform'),
 101:             'showThisPage' => __('Show this page', 'quform'),
 102:             'hideThisPage' => __('Hide this page', 'quform'),
 103:             'useThisConfirmationIfAll' => __('Use this confirmation if all of these rules match', 'quform'),
 104:             'useThisConfirmationIfAny' => __('Use this confirmation if any of these rules match', 'quform'),
 105:             'sendToTheseRecipientsIfAll' => __('Send to these recipients if all of these rules match', 'quform'),
 106:             'sendToTheseRecipientsIfAny' => __('Send to these recipients if any of these rules match', 'quform'),
 107:             'ifAllOfTheseRulesMatch' => __('if all of these rules match', 'quform'),
 108:             'ifAnyOfTheseRulesMatch' => __('if any of these rules match', 'quform'),
 109:             'addRecipient' => __('Add recipient', 'quform'),
 110:             'addLogicRule' => __('Add logic rule', 'quform'),
 111:             'noConditionals' => __('There are no conditionals yet, click "Add conditional" to add one.', 'quform'),
 112:             'is' => __('is', 'quform'),
 113:             'isNot' => __('is not', 'quform'),
 114:             'isEmpty' => __('is empty', 'quform'),
 115:             'isNotEmpty' => __('is not empty', 'quform'),
 116:             'greaterThan' => __('is greater than', 'quform'),
 117:             'lessThan' => __('is less than', 'quform'),
 118:             'contains' => __('contains', 'quform'),
 119:             'startsWith' => __('starts with', 'quform'),
 120:             'endsWith' => __('ends with', 'quform'),
 121:             'enterValue' => __('Enter a value', 'quform'),
 122:             'unsavedChanges' => __('You have unsaved changes.', 'quform'),
 123:             'previewError' => __('An error occurred loading the preview', 'quform'),
 124:             'untitled' =>  __('Untitled', 'quform'),
 125:             'pageTabNavHtml' => $this->getPageTabNavHtml(),
 126:             /* translators: %s: the page number */
 127:             'pageTabNavText' => __('Page %s', 'quform'),
 128:             'elements' => $this->getElements(),
 129:             'elementHtml' => $this->getDefaultElementHtml('text'),
 130:             'groupHtml' => $this->getDefaultElementHtml('group'),
 131:             'pageHtml' => $this->getDefaultElementHtml('page'),
 132:             'rowHtml' => $this->getDefaultElementHtml('row'),
 133:             'columnHtml' => $this->getDefaultElementHtml('column'),
 134:             'styles' => $this->getStyles(),
 135:             'styleHtml' => $this->getStyleHtml(),
 136:             'globalStyles' => $this->getGlobalStyles(),
 137:             'globalStyleHtml' => $this->getGlobalStyleHtml(),
 138:             'visibleStyles' => $this->getVisibleStyles(),
 139:             'filters' => $this->getFilters(),
 140:             'filterHtml' => $this->getFilterHtml(),
 141:             'visibleFilters' => $this->getVisibleFilters(),
 142:             'validators' => $this->getValidators(),
 143:             'validatorHtml' => $this->getValidatorHtml(),
 144:             'visibleValidators' => $this->getVisibleValidators(),
 145:             'notification' => Quform_Notification::getDefaultConfig(),
 146:             'notificationHtml' => $this->getNotificationHtml(),
 147:             'notificationConfirmRemove' => __('Are you sure you want to remove this notification?', 'quform'),
 148:             'sendThisNotification' => __('Send this notification', 'quform'),
 149:             'doNotSendThisNotification' => __('Do not send this notification', 'quform'),
 150:             'recipientHtml' => $this->getRecipientHtml(),
 151:             'popupTriggerText' => __('Click me', 'quform'),
 152:             'attachmentHtml' => $this->getAttachmentHtml(),
 153:             'selectFiles' => __('Select Files', 'quform'),
 154:             'selectElement' => __('Select an element', 'quform'),
 155:             'attachmentSourceTypes' => $this->getAttachmentSourceTypes(),
 156:             'noAttachmentSourcesFound' => __('No attachment sources found', 'quform'),
 157:             'noAttachments' => __('There are no attachments yet, click "Add attachment" to add one.', 'quform'),
 158:             'selectOneFile' => __('Select at least one file', 'quform'),
 159:             'confirmation' => Quform_Confirmation::getDefaultConfig(),
 160:             'confirmationHtml' => $this->getConfirmationHtml(),
 161:             'cannotRemoveDefaultConfirmation' => __('The default confirmation cannot be removed', 'quform'),
 162:             'confirmationConfirmRemove' => __('Are you sure you want to remove this confirmation?', 'quform'),
 163:             'dbPasswordHtml' => $this->getDbPasswordHtml(),
 164:             'dbColumnHtml' => $this->getDbColumnHtml(),
 165:             'areYouSure' => __('Are you sure?', 'quform'),
 166:             'emailRemoveBrackets' => __('Please remove the brackets from the email address', 'quform'),
 167:             'themes' => $this->getThemes(),
 168:             'collapse' => __('Collapse', 'quform'),
 169:             'expand' => __('Expand', 'quform'),
 170:             /* translators: %s: the column number */
 171:             'columnNumber' => __('Column %d', 'quform'),
 172:             'columnWidthMustBeNumeric' => __('Column width must be numeric', 'quform'),
 173:             'columnWidthTotalTooHigh' => __('Total of column widths must not be higher than 100', 'quform'),
 174:             'pageSettings' => __('Page settings', 'quform'),
 175:             'groupSettings' => __('Group settings', 'quform'),
 176:             'rowSettings' => __('Row settings', 'quform'),
 177:             'elementSettings' => __('Element settings', 'quform'),
 178:             'pleaseSelect' => __('Please select', 'quform'),
 179:             'buttonIcon' => __('Button icon', 'quform'),
 180:             'buttonIconPosition' => __('Button icon position', 'quform'),
 181:             'dropzoneIcon' => __('Dropzone icon', 'quform'),
 182:             'dropzoneIconPosition' => __('Dropzone icon position', 'quform'),
 183:             'displayAMessage' => __('Display a message', 'quform'),
 184:             'redirectTo' => __('Redirect to', 'quform'),
 185:             'reloadThePage' => __('Reload the page', 'quform'),
 186:             'enableCustomizeValuesToChange' => __('Enable the "Customize values" setting to change the value', 'quform'),
 187:             'everyone' => __('Everyone', 'quform'),
 188:             'adminOnly' => __('Admin only', 'quform'),
 189:             'loggedInUsersOnly' => __('Logged in users only', 'quform'),
 190:             'loggedOutUsersOnly' => __('Logged out users only', 'quform'),
 191:             /* translators: %1$s: element admin label, %2$s: element unique ID */
 192:             'adminLabelElementId' => __('%1$s (%2$s)', 'quform'),
 193:             'loadingDots' => __('Loading...', 'quform'),
 194:             /* translators: %s: the post ID */
 195:             'errorLoadingPageTitle' => __('Error loading the title for post ID %s', 'quform'),
 196:             'searchPostsNonce' => wp_create_nonce('quform_builder_search_posts'),
 197:             'getPostTitleNonce' => wp_create_nonce('quform_builder_get_post_title')
 198:         );
 199: 
 200:         $params = array(
 201:             'l10n_print_after' => 'quformBuilderL10n = ' . wp_json_encode($data)
 202:         );
 203: 
 204:         return $params;
 205:     }
 206: 
 207:     /**
 208:      * Prepare a form for editing
 209:      *
 210:      * @param   array  $form
 211:      * @return  array
 212:      */
 213:     public function prepare(array $form) {
 214:         Quform::set(
 215:             $form,
 216:             'scheduleStart',
 217:             $this->convertDateTimeToWpTimezone($this->getFormConfigValue($form, 'scheduleStart'))
 218:         );
 219: 
 220:         Quform::set(
 221:             $form,
 222:             'scheduleEnd',
 223:             $this->convertDateTimeToWpTimezone($this->getFormConfigValue($form, 'scheduleEnd'))
 224:         );
 225: 
 226:         return $form;
 227:     }
 228: 
 229:     /**
 230:      * Get the HTML for an option for a select element
 231:      *
 232:      * @param   string  $type  The element type, 'select', 'radio', 'checkbox' or 'multiselect'
 233:      * @return  string
 234:      */
 235:     protected function getOptionHtml($type)
 236:     {
 237:         $output = sprintf('<div class="qfb-option qfb-option-type-%s qfb-box qfb-cf">', $type);
 238: 
 239:         $output .= '<div class="qfb-option-left"><div class="qfb-option-left-inner">';
 240:         $output .= '<div class="qfb-settings-row qfb-settings-row-2">';
 241:         $output .= '<div class="qfb-settings-column">';
 242:         $output .= sprintf('<input class="qfb-option-label" type="text" placeholder="%s">', esc_attr__('Label', 'quform'));
 243:         $output .= '</div>';
 244:         $output .= '<div class="qfb-settings-column">';
 245:         $output .= sprintf('<input class="qfb-option-value" type="text" placeholder="%s">', esc_attr__('Value', 'quform'));
 246:         $output .= '</div>';
 247:         $output .= '</div>';
 248:         $output .= '</div></div>';
 249: 
 250:         $output .= '<div class="qfb-option-right">';
 251: 
 252:         $output .= '<div class="qfb-option-actions">';
 253: 
 254:         $output .= sprintf('<span class="qfb-option-action-set-default" title="%s"><i class="qfb-icon qfb-icon-check"></i></span>', esc_attr__('Default value', 'quform'));
 255:         $output .= '<span class="qfb-option-action-add"><i class="qfb-icon qfb-icon-plus"></i></span>';
 256:         $output .= '<span class="qfb-option-action-duplicate"><i class="qfb-mdi qfb-mdi-content_copy"></i></span>';
 257:         $output .= '<span class="qfb-option-action-remove"><i class="qfb-icon qfb-icon-trash"></i></span>';
 258:         if ($type == 'radio' || $type == 'checkbox') {
 259:             $output .= '<span class="qfb-option-action-settings"><i class="qfb-mdi qfb-mdi-settings"></i></span>';
 260:         }
 261:         $output .= '<span class="qfb-option-action-move"><i class="qfb-icon qfb-icon-arrows"></i></span>';
 262: 
 263:         $output .= '</div>';
 264:         $output .= '</div>';
 265: 
 266:         $output .= '</div>';
 267: 
 268:         return $output;
 269:     }
 270: 
 271:     /**
 272:      * Get the HTML for an optgroup for a select element
 273:      *
 274:      * @return  string
 275:      */
 276:     protected function getOptgroupHtml()
 277:     {
 278:         $output = '<div class="qfb-optgroup qfb-box qfb-cf"><div class="qfb-optgroup-top qfb-cf">';
 279:         $output .= '<div class="qfb-optgroup-left"><div class="qfb-optgroup-left-inner">';
 280:         $output .= sprintf('<input class="qfb-optgroup-label" type="text" placeholder="%s">', esc_attr__('Optgroup label', 'quform'));
 281:         $output .= '</div></div>';
 282:         $output .= '<div class="qfb-optgroup-right">';
 283:         $output .= '<div class="qfb-optgroup-actions">';
 284:         $output .= '<span class="qfb-optgroup-action-add"><i class="qfb-icon qfb-icon-plus"></i></span>';
 285:         $output .= '<span class="qfb-optgroup-action-remove"><i class="qfb-icon qfb-icon-trash"></i></span>';
 286:         $output .= '<span class="qfb-optgroup-action-move"><i class="qfb-icon qfb-icon-arrows"></i></span>';
 287:         $output .= '</div>';
 288:         $output .= '</div>';
 289:         $output .= '</div></div>';
 290: 
 291:         return $output;
 292:     }
 293: 
 294:     /**
 295:      * Get the default option config for each element type
 296:      *
 297:      * @return array
 298:      */
 299:     protected function getDefaultOptions()
 300:     {
 301:         return array(
 302:             'select' => Quform_Element_Select::getDefaultOptionConfig(),
 303:             'checkbox' => Quform_Element_Checkbox::getDefaultOptionConfig(),
 304:             'radio' => Quform_Element_Radio::getDefaultOptionConfig(),
 305:             'multiselect' => Quform_Element_Multiselect::getDefaultOptionConfig()
 306:         );
 307:     }
 308: 
 309:     /**
 310:      * Get the default optgroup config for each element type
 311:      *
 312:      * @return array
 313:      */
 314:     protected function getDefaultOptgroups()
 315:     {
 316:         return array(
 317:             'select' => Quform_Element_Select::getDefaultOptgroupConfig(),
 318:             'multiselect' => Quform_Element_Multiselect::getDefaultOptgroupConfig()
 319:         );
 320:     }
 321: 
 322:     /*
 323:      * Get the predefined bulk options
 324:      *
 325:      * @return array
 326:      */
 327:     public function getBulkOptions()
 328:     {
 329:         return apply_filters('quform_bulk_options', array(
 330:             'countries' => array(
 331:                 'name' => __('Countries', 'quform'),
 332:                 'options' => $this->getCountries()
 333:             ),
 334:             'usStates' => array(
 335:                 'name' => __('U.S. States', 'quform'),
 336:                 'options' => $this->getUsStates()
 337:             ),
 338:             'canadianProvinces' => array(
 339:                 'name' => __('Canadian Provinces', 'quform'),
 340:                 'options' => $this->getCanadianProvinces()
 341:             ),
 342:             'ukCounties' => array(
 343:                 'name' => __('UK Counties', 'quform'),
 344:                 'options' => $this->getUkCounties()
 345:             ),
 346:             'germanStates' => array(
 347:                 'name' => __('German States', 'quform'),
 348:                 'options' => array('Baden-Wurttemberg', 'Bavaria', 'Berlin', 'Brandenburg', 'Bremen', 'Hamburg', 'Hesse', 'Mecklenburg-West Pomerania', 'Lower Saxony', 'North Rhine-Westphalia', 'Rhineland-Palatinate', 'Saarland', 'Saxony', 'Saxony-Anhalt', 'Schleswig-Holstein', 'Thuringia')
 349:             ),
 350:             'dutchProvinces' => array(
 351:                 'name' => __('Dutch Provinces', 'quform'),
 352:                 'options' => array('Drente', 'Flevoland', 'Friesland', 'Gelderland', 'Groningen', 'Limburg', 'Noord-Brabant', 'Noord-Holland', 'Overijssel', 'Zuid-Holland', 'Utrecht', 'Zeeland')
 353:             ),
 354:             'continents' => array(
 355:                 'name' => __('Continents', 'quform'),
 356:                 'options' => array(__('Africa', 'quform'), __('Antarctica', 'quform'), __('Asia', 'quform'), __('Australia', 'quform'), __('Europe', 'quform'), __('North America', 'quform'), __('South America', 'quform'))
 357:             ),
 358:             'gender' => array(
 359:                 'name' => __('Gender', 'quform'),
 360:                 'options' => array(__('Male', 'quform'), __('Female', 'quform'))
 361:             ),
 362:             'age' => array(
 363:                 'name' => __('Age', 'quform'),
 364:                 'options' => array(__('Under 18', 'quform'), __('18-24', 'quform'), __('25-34', 'quform'), __('35-44', 'quform'), __('45-54', 'quform'), __('55-64', 'quform'), __('65 or over', 'quform'))
 365:             ),
 366:             'maritalStatus' => array(
 367:                 'name' => __('Marital Status', 'quform'),
 368:                 'options' => array(__('Single', 'quform'), __('Married', 'quform'), __('Divorced', 'quform'), __('Widowed', 'quform'))
 369:             ),
 370:             'income' => array(
 371:                 'name' => __('Income', 'quform'),
 372:                 'options' => array(__('Under $20,000', 'quform'), __('$20,000 - $30,000', 'quform'), __('$30,000 - $40,000', 'quform'), __('$40,000 - $50,000', 'quform'), __('$50,000 - $75,000', 'quform'), __('$75,000 - $100,000', 'quform'), __('$100,000 - $150,000', 'quform'), __('$150,000 or more', 'quform'))
 373:             ),
 374:             'days' => array(
 375:                 'name' => __('Days', 'quform'),
 376:                 'options' => array(__('Monday', 'quform'), __('Tuesday', 'quform'), __('Wednesday', 'quform'), __('Thursday', 'quform'), __('Friday', 'quform'), __('Saturday', 'quform'), __('Sunday', 'quform'))
 377:             ),
 378:             'months' => array(
 379:                 'name' => __('Months', 'quform'),
 380:                 'options' => array_values($this->getAllMonths())
 381:             )
 382:         ));
 383:     }
 384: 
 385:     /**
 386:      * Returns an array of all countries
 387:      *
 388:      * @return array
 389:      */
 390:     protected function getCountries()
 391:     {
 392:         return apply_filters('quform_countries', array(
 393:             __('Afghanistan', 'quform'), __('Albania', 'quform'), __('Algeria', 'quform'), __('American Samoa', 'quform'), __('Andorra', 'quform'), __('Angola', 'quform'), __('Anguilla', 'quform'), __('Antarctica', 'quform'), __('Antigua And Barbuda', 'quform'), __('Argentina', 'quform'), __('Armenia', 'quform'), __('Aruba', 'quform'), __('Australia', 'quform'), __('Austria', 'quform'), __('Azerbaijan', 'quform'), __('Bahamas', 'quform'), __('Bahrain', 'quform'), __('Bangladesh', 'quform'), __('Barbados', 'quform'), __('Belarus', 'quform'), __('Belgium', 'quform'),
 394:             __('Belize', 'quform'), __('Benin', 'quform'), __('Bermuda', 'quform'), __('Bhutan', 'quform'), __('Bolivia', 'quform'), __('Bosnia And Herzegovina', 'quform'), __('Botswana', 'quform'), __('Bouvet Island', 'quform'), __('Brazil', 'quform'), __('British Indian Ocean Territory', 'quform'), __('Brunei Darussalam', 'quform'), __('Bulgaria', 'quform'), __('Burkina Faso', 'quform'), __('Burundi', 'quform'), __('Cambodia', 'quform'), __('Cameroon', 'quform'), __('Canada', 'quform'), __('Cape Verde', 'quform'), __('Cayman Islands', 'quform'), __('Central African Republic', 'quform'), __('Chad', 'quform'),
 395:             __('Chile', 'quform'), __('China', 'quform'), __('Christmas Island', 'quform'), __('Cocos (Keeling) Islands', 'quform'), __('Colombia', 'quform'), __('Comoros', 'quform'), __('Congo', 'quform'), __('Congo, The Democratic Republic Of The', 'quform'), __('Cook Islands', 'quform'), __('Costa Rica', 'quform'), __('Cote D\'Ivoire', 'quform'), __('Croatia (Local Name: Hrvatska)', 'quform'), __('Cuba', 'quform'), __('Cyprus', 'quform'), __('Czech Republic', 'quform'), __('Denmark', 'quform'), __('Djibouti', 'quform'), __('Dominica', 'quform'), __('Dominican Republic', 'quform'), __('East Timor', 'quform'), __('Ecuador', 'quform'),
 396:             __('Egypt', 'quform'), __('El Salvador', 'quform'), __('Equatorial Guinea', 'quform'), __('Eritrea', 'quform'), __('Estonia', 'quform'), __('Ethiopia', 'quform'), __('Falkland Islands (Malvinas)', 'quform'), __('Faroe Islands', 'quform'), __('Fiji', 'quform'), __('Finland', 'quform'), __('France', 'quform'), __('France, Metropolitan', 'quform'), __('French Guiana', 'quform'), __('French Polynesia', 'quform'), __('French Southern Territories', 'quform'), __('Gabon', 'quform'), __('Gambia', 'quform'), __('Georgia', 'quform'), __('Germany', 'quform'), __('Ghana', 'quform'), __('Gibraltar', 'quform'),
 397:             __('Greece', 'quform'), __('Greenland', 'quform'), __('Grenada', 'quform'), __('Guadeloupe', 'quform'), __('Guam', 'quform'), __('Guatemala', 'quform'), __('Guinea', 'quform'), __('Guinea-Bissau', 'quform'), __('Guyana', 'quform'), __('Haiti', 'quform'), __('Heard And Mc Donald Islands', 'quform'), __('Holy See (Vatican City State)', 'quform'), __('Honduras', 'quform'), __('Hong Kong', 'quform'), __('Hungary', 'quform'), __('Iceland', 'quform'), __('India', 'quform'), __('Indonesia', 'quform'), __('Iran (Islamic Republic Of)', 'quform'), __('Iraq', 'quform'), __('Ireland', 'quform'),
 398:             __('Israel', 'quform'), __('Italy', 'quform'), __('Jamaica', 'quform'), __('Japan', 'quform'), __('Jordan', 'quform'), __('Kazakhstan', 'quform'), __('Kenya', 'quform'), __('Kiribati', 'quform'), __('Korea, Democratic People\'s Republic Of', 'quform'), __('Korea, Republic Of', 'quform'), __('Kuwait', 'quform'), __('Kyrgyzstan', 'quform'), __('Lao People\'s Democratic Republic', 'quform'), __('Latvia', 'quform'), __('Lebanon', 'quform'), __('Lesotho', 'quform'), __('Liberia', 'quform'), __('Libyan Arab Jamahiriya', 'quform'), __('Liechtenstein', 'quform'), __('Lithuania', 'quform'), __('Luxembourg', 'quform'),
 399:             __('Macau', 'quform'), __('Macedonia, Former Yugoslav Republic Of', 'quform'), __('Madagascar', 'quform'), __('Malawi', 'quform'), __('Malaysia', 'quform'), __('Maldives', 'quform'), __('Mali', 'quform'), __('Malta', 'quform'), __('Marshall Islands', 'quform'), __('Martinique', 'quform'), __('Mauritania', 'quform'), __('Mauritius', 'quform'), __('Mayotte', 'quform'), __('Mexico', 'quform'), __('Micronesia, Federated States Of', 'quform'), __('Moldova, Republic Of', 'quform'), __('Monaco', 'quform'), __('Mongolia', 'quform'), __('Montserrat', 'quform'), __('Morocco', 'quform'), __('Mozambique', 'quform'),
 400:             __('Myanmar', 'quform'), __('Namibia', 'quform'), __('Nauru', 'quform'), __('Nepal', 'quform'), __('Netherlands', 'quform'), __('Netherlands Antilles', 'quform'), __('New Caledonia', 'quform'), __('New Zealand', 'quform'), __('Nicaragua', 'quform'), __('Niger', 'quform'), __('Nigeria', 'quform'), __('Niue', 'quform'), __('Norfolk Island', 'quform'), __('Northern Mariana Islands', 'quform'), __('Norway', 'quform'), __('Oman', 'quform'), __('Pakistan', 'quform'), __('Palau', 'quform'), __('Panama', 'quform'), __('Papua New Guinea', 'quform'), __('Paraguay', 'quform'),
 401:             __('Peru', 'quform'), __('Philippines', 'quform'), __('Pitcairn', 'quform'), __('Poland', 'quform'), __('Portugal', 'quform'), __('Puerto Rico', 'quform'), __('Qatar', 'quform'), __('Reunion', 'quform'), __('Romania', 'quform'), __('Russian Federation', 'quform'), __('Rwanda', 'quform'), __('Saint Kitts And Nevis', 'quform'), __('Saint Lucia', 'quform'), __('Saint Vincent And The Grenadines', 'quform'), __('Samoa', 'quform'), __('San Marino', 'quform'), __('Sao Tome And Principe', 'quform'), __('Saudi Arabia', 'quform'), __('Senegal', 'quform'), __('Seychelles', 'quform'), __('Sierra Leone', 'quform'),
 402:             __('Singapore', 'quform'), __('Slovakia (Slovak Republic)', 'quform'), __('Slovenia', 'quform'), __('Solomon Islands', 'quform'), __('Somalia', 'quform'), __('South Africa', 'quform'), __('South Georgia, South Sandwich Islands', 'quform'), __('Spain', 'quform'), __('Sri Lanka', 'quform'), __('St. Helena', 'quform'), __('St. Pierre And Miquelon', 'quform'), __('Sudan', 'quform'), __('Suriname', 'quform'), __('Svalbard And Jan Mayen Islands', 'quform'), __('Swaziland', 'quform'), __('Sweden', 'quform'), __('Switzerland', 'quform'), __('Syrian Arab Republic', 'quform'), __('Taiwan', 'quform'), __('Tajikistan', 'quform'), __('Tanzania, United Republic Of', 'quform'),
 403:             __('Thailand', 'quform'), __('Togo', 'quform'), __('Tokelau', 'quform'), __('Tonga', 'quform'), __('Trinidad And Tobago', 'quform'), __('Tunisia', 'quform'), __('Turkey', 'quform'), __('Turkmenistan', 'quform'), __('Turks And Caicos Islands', 'quform'), __('Tuvalu', 'quform'), __('Uganda', 'quform'), __('Ukraine', 'quform'), __('United Arab Emirates', 'quform'), __('United Kingdom', 'quform'), __('United States', 'quform'), __('United States Minor Outlying Islands', 'quform'), __('Uruguay', 'quform'), __('Uzbekistan', 'quform'), __('Vanuatu', 'quform'), __('Venezuela', 'quform'), __('Vietnam', 'quform'),
 404:             __('Virgin Islands (British)', 'quform'), __('Virgin Islands (U.S.)', 'quform'), __('Wallis And Futuna Islands', 'quform'), __('Western Sahara', 'quform'), __('Yemen', 'quform'), __('Yugoslavia', 'quform'), __('Zambia', 'quform'), __('Zimbabwe', 'quform')
 405:         ));
 406:     }
 407: 
 408:     /**
 409:      * Returns an array of US states
 410:      *
 411:      * @return array
 412:      */
 413:     protected function getUsStates()
 414:     {
 415:         return array(
 416:             'Alabama', 'Alaska', 'Arizona', 'Arkansas', 'California', 'Colorado', 'Connecticut', 'Delaware',
 417:             'District Of Columbia', 'Florida', 'Georgia', 'Hawaii', 'Idaho', 'Illinois', 'Indiana', 'Iowa', 'Kansas',
 418:             'Kentucky', 'Louisiana', 'Maine', 'Maryland', 'Massachusetts', 'Michigan', 'Minnesota', 'Mississippi',
 419:             'Missouri', 'Montana', 'Nebraska', 'Nevada', 'New Hampshire', 'New Jersey', 'New Mexico', 'New York',
 420:             'North Carolina', 'North Dakota', 'Ohio', 'Oklahoma', 'Oregon', 'Pennsylvania', 'Rhode Island',
 421:             'South Carolina', 'South Dakota', 'Tennessee', 'Texas', 'Utah', 'Vermont', 'Virginia', 'Washington',
 422:             'West Virginia', 'Wisconsin', 'Wyoming'
 423:         );
 424:     }
 425: 
 426:     /**
 427:      * Returns an array of Canadian Provinces / Territories
 428:      *
 429:      * @return array
 430:      */
 431:     protected function getCanadianProvinces()
 432:     {
 433:         return array(
 434:             'Alberta', 'British Columbia', 'Manitoba', 'New Brunswick', 'Newfoundland & Labrador',
 435:             'Northwest Territories', 'Nova Scotia', 'Nunavut','Ontario', 'Prince Edward Island', 'Quebec',
 436:             'Saskatchewan', 'Yukon'
 437:         );
 438:     }
 439: 
 440:     /**
 441:      * Returns an array of UK counties
 442:      *
 443:      * @return array
 444:      */
 445:     protected function getUkCounties()
 446:     {
 447:         return array(
 448:             'Aberdeen City', 'Aberdeenshire', 'Angus', 'Antrim', 'Argyll and Bute', 'Armagh', 'Avon', 'Banffshire',
 449:             'Bedfordshire', 'Berkshire', 'Blaenau Gwent', 'Borders', 'Bridgend', 'Bristol', 'Buckinghamshire',
 450:             'Caerphilly', 'Cambridgeshire', 'Cardiff', 'Carmarthenshire', 'Ceredigion', 'Channel Islands', 'Cheshire',
 451:             'Clackmannan', 'Cleveland', 'Conwy', 'Cornwall', 'Cumbria', 'Denbighshire', 'Derbyshire', 'Devon', 'Dorset',
 452:             'Down', 'Dumfries and Galloway', 'Durham', 'East Ayrshire', 'East Dunbartonshire', 'East Lothian',
 453:             'East Renfrewshire', 'East Riding of Yorkshire', 'East Sussex', 'Edinburgh City', 'Essex', 'Falkirk',
 454:             'Fermanagh', 'Fife', 'Flintshire', 'Glasgow (City of)', 'Gloucestershire', 'Greater Manchester', 'Gwynedd',
 455:             'Hampshire', 'Herefordshire', 'Hertfordshire', 'Highland', 'Humberside', 'Inverclyde', 'Isle of Anglesey',
 456:             'Isle of Man', 'Isle of Wight', 'Isles of Scilly', 'Kent', 'Lancashire', 'Leicestershire', 'Lincolnshire',
 457:             'London', 'Londonderry', 'Merseyside', 'Merthyr Tydfil', 'Middlesex', 'Midlothian', 'Monmouthshire',
 458:             'Moray', 'Neath Port Talbot', 'Newport', 'Norfolk', 'North Ayrshire', 'North East Lincolnshire',
 459:             'North Lanarkshire', 'North Yorkshire', 'Northamptonshire', 'Northumberland', 'Nottinghamshire',
 460:             'Orkney', 'Oxfordshire', 'Pembrokeshire', 'Perthshire and Kinross', 'Powys', 'Renfrewshire',
 461:             'Rhondda Cynon Taff', 'Roxburghshire', 'Rutland', 'Shetland', 'Shropshire', 'Somerset', 'South Ayrshire',
 462:             'South Lanarkshire', 'South Yorkshire', 'Staffordshire', 'Stirling', 'Suffolk', 'Surrey', 'Swansea',
 463:             'The Vale of Glamorgan', 'Torfaen', 'Tyne and Wear', 'Tyrone', 'Warwickshire', 'West Dunbartonshire',
 464:             'West Lothian', 'West Midlands', 'West Sussex', 'West Yorkshire', 'Western Isles', 'Wiltshire',
 465:             'Worcestershire', 'Wrexham'
 466:         );
 467:     }
 468: 
 469:     /**
 470:      * Get all the months in the year
 471:      *
 472:      * @return array
 473:      */
 474:     protected function getAllMonths()
 475:     {
 476:         return apply_filters('quform_get_all_months', array(
 477:             1  => __('January', 'quform'),
 478:             2  => __('February', 'quform'),
 479:             3  => __('March', 'quform'),
 480:             4  => __('April', 'quform'),
 481:             5  => __('May', 'quform'),
 482:             6  => __('June', 'quform'),
 483:             7  => __('July', 'quform'),
 484:             8  => __('August', 'quform'),
 485:             9  => __('September', 'quform'),
 486:             10 => __('October', 'quform'),
 487:             11 => __('November', 'quform'),
 488:             12 => __('December', 'quform')
 489:         ));
 490:     }
 491: 
 492:     /**
 493:      * Get the core form elements config
 494:      *
 495:      * @param   string|null  $type  The element type or null for all elements
 496:      * @return  array
 497:      */
 498:     public function getElements($type = null)
 499:     {
 500:         $elements = array(
 501:             'text' => array(
 502:                 'name' => _x('Text', 'text input field', 'quform'),
 503:                 'icon' => '<i class="qfb-icon qfb-icon-pencil"></i>',
 504:                 'config' => Quform_Element_Text::getDefaultConfig()
 505:             ),
 506:             'textarea' => array(
 507:                 'name' => _x('Textarea', 'textarea input field', 'quform'),
 508:                 'icon' => '<i class="qfb-icon qfb-icon-align-left"></i>',
 509:                 'config' => Quform_Element_Textarea::getDefaultConfig()
 510:             ),
 511:             'email' => array(
 512:                 'name' => _x('Email', 'email address field', 'quform'),
 513:                 'icon' => '<i class="qfb-icon qfb-icon-envelope"></i>',
 514:                 'config' => Quform_Element_Email::getDefaultConfig()
 515:             ),
 516:             'select' => array(
 517:                 'name' => _x('Select Menu', 'select menu field', 'quform'),
 518:                 'icon' => '<i class="qfb-icon qfb-icon-caret-square-o-down"></i>',
 519:                 'config' => Quform_Element_Select::getDefaultConfig()
 520:             ),
 521:             'checkbox' => array(
 522:                 'name' => _x('Checkboxes', 'checkboxes field', 'quform'),
 523:                 'icon' => '<i class="qfb-icon qfb-icon-check-square-o"></i>',
 524:                 'config' => Quform_Element_Checkbox::getDefaultConfig()
 525:             ),
 526:             'radio' => array(
 527:                 'name' => _x('Radio Buttons', 'radio buttons field', 'quform'),
 528:                 'icon' => '<i class="qfb-mdi qfb-mdi-radio_button_checked"></i>',
 529:                 'config' => Quform_Element_Radio::getDefaultConfig()
 530:             ),
 531:             'multiselect' => array(
 532:                 'name' => _x('Multi Select', 'multi select field', 'quform'),
 533:                 'icon' => '<i class="qfb-icon qfb-icon-list-ul"></i>',
 534:                 'config' => Quform_Element_Multiselect::getDefaultConfig()
 535:             ),
 536:             'file' => array(
 537:                 'name' => __('File Upload', 'quform'),
 538:                 'icon' => '<i class="qfb-icon qfb-icon-upload"></i>',
 539:                 'config' => Quform_Element_File::getDefaultConfig()
 540:             ),
 541:             'date' => array(
 542:                 'name' => _x('Date', 'date field', 'quform'),
 543:                 'icon' => '<i class="qfb-icon qfb-icon-calendar"></i>',
 544:                 'config' => Quform_Element_Date::getDefaultConfig()
 545:             ),
 546:             'time' => array(
 547:                 'name' => _x('Time', 'time field', 'quform'),
 548:                 'icon' => '<i class="qfb-icon qfb-icon-clock-o"></i>',
 549:                 'config' => Quform_Element_Time::getDefaultConfig()
 550:             ),
 551:             'name' => array(
 552:                 'name' => _x('Name', 'name field', 'quform'),
 553:                 'icon' => '<i class="qfb-icon qfb-icon-user"></i>',
 554:                 'config' => Quform_Element_Name::getDefaultConfig()
 555:             ),
 556:             'password' => array(
 557:                 'name' => _x('Password', 'password input field', 'quform'),
 558:                 'icon' => '<i class="qfb-icon qfb-icon-lock"></i>',
 559:                 'config' => Quform_Element_Password::getDefaultConfig()
 560:             ),
 561:             'html' => array(
 562:                 'name' => __('HTML', 'quform'),
 563:                 'icon' => '<i class="qfb-icon qfb-icon-code"></i>',
 564:                 'config' => Quform_Element_Html::getDefaultConfig()
 565:             ),
 566:             'hidden' => array(
 567:                 'name' => __('Hidden', 'quform'),
 568:                 'icon' => '<i class="qfb-icon qfb-icon-eye-slash"></i>',
 569:                 'config' => Quform_Element_Hidden::getDefaultConfig()
 570:             ),
 571:             'captcha' => array(
 572:                 'name' => _x('CAPTCHA', 'captcha field', 'quform'),
 573:                 'icon' => '<i class="qfb-icon qfb-icon-handshake-o"></i>',
 574:                 'config' => Quform_Element_Captcha::getDefaultConfig()
 575:             ),
 576:             'recaptcha' => array(
 577:                 'name' => __('reCAPTCHA', 'quform'),
 578:                 'icon' => '<i class="qfb-mdi qfb-mdi-face"></i>',
 579:                 'config' => Quform_Element_Recaptcha::getDefaultConfig()
 580:             ),
 581:             'submit' => array(
 582:                 'name' => _x('Submit', 'submit button element', 'quform'),
 583:                 'icon' => '<i class="qfb-icon qfb-icon-paper-plane"></i>',
 584:                 'config' => Quform_Element_Submit::getDefaultConfig()
 585:             ),
 586:             'page' => array(
 587:                 'name' => __('Page', 'quform'),
 588:                 'icon' => '<i class="qfb-icon qfb-icon-file-o"></i>',
 589:                 'config' => Quform_Element_Page::getDefaultConfig()
 590:             ),
 591:             'group' => array(
 592:                 'name' => __('Group', 'quform'),
 593:                 'icon' => '<i class="qfb-icon qfb-icon-object-group"></i>',
 594:                 'config' => Quform_Element_Group::getDefaultConfig()
 595:             ),
 596:             'row' => array(
 597:                 'name' => __('Column Layout', 'quform'),
 598:                 'icon' => '<i class="qfb-icon qfb-icon-columns"></i>',
 599:                 'config' => Quform_Element_Row::getDefaultConfig()
 600:             ),
 601:             'column' => array(
 602:                 'name' => __('Column', 'quform'),
 603:                 'icon' => '<i class="qfb-icon qfb-icon-columns"></i>',
 604:                 'config' => Quform_Element_Column::getDefaultConfig()
 605:             )
 606:         );
 607: 
 608:         $elements = apply_filters('quform_admin_elements', $elements);
 609: 
 610:         if (is_string($type) && isset($elements[$type])) {
 611:             return $elements[$type];
 612:         }
 613: 
 614:         return $elements;
 615:     }
 616: 
 617:     /**
 618:      * Get the default config for the element of the given type
 619:      *
 620:      * @param   string  $type  The element type
 621:      * @return  array          The default element config
 622:      */
 623:     protected function getDefaultElementConfig($type)
 624:     {
 625:         $element = $this->getElements($type);
 626: 
 627:         return $element['config'];
 628:     }
 629: 
 630:     /**
 631:      * Get the element styles data
 632:      *
 633:      * @return array
 634:      */
 635:     public function getStyles()
 636:     {
 637:         $styles = array(
 638:             'element' => array('name' => __('Outer wrapper', 'quform')),
 639:             'elementSpacer' => array('name' => __('Spacer', 'quform')),
 640:             'elementLabel' => array('name' => __('Label', 'quform')),
 641:             'elementLabelText' => array('name' => __('Label text', 'quform')),
 642:             'elementRequiredText' => array('name' => __('Required text', 'quform')),
 643:             'elementInner' => array('name' => __('Inner wrapper', 'quform')),
 644:             'elementInput' => array('name' => __('Input wrapper', 'quform')),
 645:             'elementText' => array('name' => __('Text input field', 'quform')),
 646:             'elementTextHover' => array('name' => __('Text input field (hover)', 'quform')),
 647:             'elementTextFocus' => array('name' => __('Text input field (focus)', 'quform')),
 648:             'elementTextarea' => array('name' => __('Textarea field', 'quform')),
 649:             'elementTextareaHover' => array('name' => __('Textarea field (hover)', 'quform')),
 650:             'elementTextareaFocus' => array('name' => __('Textarea field (focus)', 'quform')),
 651:             'elementSelect' => array('name' => __('Select field', 'quform')),
 652:             'elementSelectHover' => array('name' => __('Select field (hover)', 'quform')),
 653:             'elementSelectFocus' => array('name' => __('Select field (focus)', 'quform')),
 654:             'elementIcon' => array('name' => __('Text input icons', 'quform')),
 655:             'elementIconHover' => array('name' => __('Text input icons (hover)', 'quform')),
 656:             'elementSubLabel' => array('name' => __('Sub label', 'quform')),
 657:             'elementDescription' => array('name' => __('Description', 'quform')),
 658:             'options' => array('name' => __('Options outer wrapper', 'quform')),
 659:             'option' => array('name' => __('Option wrapper', 'quform')),
 660:             'optionRadioButton' => array('name' => __('Option radio button', 'quform')),
 661:             'optionCheckbox' => array('name' => __('Option checkbox', 'quform')),
 662:             'optionLabel' => array('name' => __('Option label', 'quform')),
 663:             'optionLabelHover' => array('name' => __('Option label (hover)', 'quform')),
 664:             'optionLabelSelected' => array('name' => __('Option label (when selected)', 'quform')),
 665:             'optionIcon' => array('name' => __('Option icon', 'quform')),
 666:             'optionIconSelected' => array('name' => __('Option icon (when selected)', 'quform')),
 667:             'optionText' => array('name' => __('Option text', 'quform')),
 668:             'optionTextSelected' => array('name' => __('Option text (when selected)', 'quform')),
 669:             'page' => array('name' => __('Page wrapper', 'quform')),
 670:             'pageTitle' => array('name' => __('Page title', 'quform')),
 671:             'pageDescription' => array('name' => __('Page description', 'quform')),
 672:             'pageElements' => array('name' => __('Page elements wrapper', 'quform')),
 673:             'group' => array('name' => __('Group wrapper', 'quform')),
 674:             'groupSpacer' => array('name' => __('Group spacer', 'quform')),
 675:             'groupTitle' => array('name' => __('Group title', 'quform')),
 676:             'groupDescription' => array('name' => __('Group description', 'quform')),
 677:             'groupElements' => array('name' => __('Group elements wrapper', 'quform')),
 678:             'submit' => array('name' => __('Submit button outer wrapper', 'quform')),
 679:             'submitInner' => array('name' => __('Submit button wrapper', 'quform')),
 680:             'submitButton' => array('name' => __('Submit button', 'quform')),
 681:             'submitButtonHover' => array('name' => __('Submit button (hover)', 'quform')),
 682:             'submitButtonActive' => array('name' => __('Submit button (active)', 'quform')),
 683:             'submitButtonText' => array('name' => __('Submit button text', 'quform')),
 684:             'submitButtonTextHover' => array('name' => __('Submit button text (hover)', 'quform')),
 685:             'submitButtonTextActive' => array('name' => __('Submit button text (active)', 'quform')),
 686:             'submitButtonIcon' => array('name' => __('Submit button icon', 'quform')),
 687:             'submitButtonIconHover' => array('name' => __('Submit button icon (hover)', 'quform')),
 688:             'submitButtonIconActive' => array('name' => __('Submit button icon (active)', 'quform')),
 689:             'backInner' => array('name' => __('Back button wrapper', 'quform')),
 690:             'backButton' => array('name' => __('Back button', 'quform')),
 691:             'backButtonHover' => array('name' => __('Back button (hover)', 'quform')),
 692:             'backButtonActive' => array('name' => __('Back button (active)', 'quform')),
 693:             'backButtonText' => array('name' => __('Back button text', 'quform')),
 694:             'backButtonTextHover' => array('name' => __('Back button text (hover)', 'quform')),
 695:             'backButtonTextActive' => array('name' => __('Back button text (active)', 'quform')),
 696:             'backButtonIcon' => array('name' => __('Back button icon', 'quform')),
 697:             'backButtonIconHover' => array('name' => __('Back button icon (hover)', 'quform')),
 698:             'backButtonIconActive' => array('name' => __('Back button icon (active)', 'quform')),
 699:             'nextInner' => array('name' => __('Next button wrapper', 'quform')),
 700:             'nextButton' => array('name' => __('Next button', 'quform')),
 701:             'nextButtonHover' => array('name' => __('Next button (hover)', 'quform')),
 702:             'nextButtonActive' => array('name' => __('Next button (active)', 'quform')),
 703:             'nextButtonText' => array('name' => __('Next button text', 'quform')),
 704:             'nextButtonTextHover' => array('name' => __('Next button text (hover)', 'quform')),
 705:             'nextButtonTextActive' => array('name' => __('Next button text (active)', 'quform')),
 706:             'nextButtonIcon' => array('name' => __('Next button icon', 'quform')),
 707:             'nextButtonIconHover' => array('name' => __('Next button icon (hover)', 'quform')),
 708:             'nextButtonIconActive' => array('name' => __('Next button icon (active)', 'quform')),
 709:             'uploadButton' => array('name' => __('Upload button', 'quform')),
 710:             'uploadButtonHover' => array('name' => __('Upload button (hover)', 'quform')),
 711:             'uploadButtonActive' => array('name' => __('Upload button (active)', 'quform')),
 712:             'uploadButtonText' => array('name' => __('Upload button text', 'quform')),
 713:             'uploadButtonTextHover' => array('name' => __('Upload button text (hover)', 'quform')),
 714:             'uploadButtonTextActive' => array('name' => __('Upload button text (active)', 'quform')),
 715:             'uploadButtonIcon' => array('name' => __('Upload button icon', 'quform')),
 716:             'uploadButtonIconHover' => array('name' => __('Upload button icon (hover)', 'quform')),
 717:             'uploadButtonIconActive' => array('name' => __('Upload button icon (active)', 'quform')),
 718:             'uploadDropzone' => array('name' => __('Upload dropzone', 'quform')),
 719:             'uploadDropzoneHover' => array('name' => __('Upload dropzone (hover)', 'quform')),
 720:             'uploadDropzoneActive' => array('name' => __('Upload dropzone (active)', 'quform')),
 721:             'uploadDropzoneText' => array('name' => __('Upload dropzone text', 'quform')),
 722:             'uploadDropzoneTextHover' => array('name' => __('Upload dropzone text (hover)', 'quform')),
 723:             'uploadDropzoneTextActive' => array('name' => __('Upload dropzone text (active)', 'quform')),
 724:             'uploadDropzoneIcon' => array('name' => __('Upload dropzone icon', 'quform')),
 725:             'uploadDropzoneIconHover' => array('name' => __('Upload dropzone icon (hover)', 'quform')),
 726:             'uploadDropzoneIconActive' => array('name' => __('Upload dropzone icon (active)', 'quform')),
 727:             'datepickerHeader' => array('name' => __('Datepicker header', 'quform')),
 728:             'datepickerHeaderText' => array('name' => __('Datepicker header text', 'quform')),
 729:             'datepickerHeaderTextHover' => array('name' => __('Datepicker header text (hover)', 'quform')),
 730:             'datepickerFooter' => array('name' => __('Datepicker footer', 'quform')),
 731:             'datepickerFooterText' => array('name' => __('Datepicker footer text', 'quform')),
 732:             'datepickerFooterTextHover' => array('name' => __('Datepicker footer text (hover)', 'quform')),
 733:             'datepickerSelection' => array('name' => __('Datepicker selection', 'quform')),
 734:             'datepickerSelectionActive' => array('name' => __('Datepicker selection (chosen)', 'quform')),
 735:             'datepickerSelectionText' => array('name' => __('Datepicker selection text', 'quform')),
 736:             'datepickerSelectionTextHover' => array('name' => __('Datepicker selection text (hover)', 'quform')),
 737:             'datepickerSelectionActiveText' => array('name' => __('Datepicker selection text (active)', 'quform')),
 738:             'datepickerSelectionActiveTextHover' => array('name' => __('Datepicker selection text (chosen) (hover)', 'quform'))
 739:         );
 740: 
 741:         foreach ($styles as $key => $style) {
 742:             $styles[$key]['config'] = array('type' => $key, 'css' => '');
 743:         }
 744: 
 745:         return apply_filters('quform_admin_styles', $styles);
 746:     }
 747: 
 748:     /**
 749:      * Get all available global styles
 750:      *
 751:      * @param  string  $key  Only get the style with this key
 752:      * @return array
 753:      */
 754:     public function getGlobalStyles($key = null)
 755:     {
 756:         $styles = array(
 757:             'formOuter' => array('name' => _x('Form outer wrapper', 'the outermost HTML wrapper around the form', 'quform')),
 758:             'formInner' => array('name' => _x('Form inner wrapper', 'the inner HTML wrapper around the form', 'quform')),
 759:             'formSuccess' => array('name' => __('Success message', 'quform')),
 760:             'formSuccessIcon' => array('name' => __('Success message icon', 'quform')),
 761:             'formSuccessContent' => array('name' => __('Success message content', 'quform')),
 762:             'formTitle' => array('name' => __('Form title', 'quform')),
 763:             'formDescription' => array('name' => __('Form description', 'quform')),
 764:             'formElements' => array('name' => _x('Form elements wrapper', 'the HTML wrapper around the form elements', 'quform')),
 765:             'formError' => array('name' => __('Form error message', 'quform')),
 766:             'formErrorInner' => array('name' => __('Form error message inner wrapper', 'quform')),
 767:             'formErrorTitle' => array('name' => __('Form error message title', 'quform')),
 768:             'formErrorContent' => array('name' => __('Form error message content', 'quform')),
 769:             'element' => array('name' => _x('Element outer wrapper', 'outermost wrapping HTML element around an element', 'quform')),
 770:             'elementSpacer' => array('name' => __('Element spacer', 'quform')),
 771:             'elementLabel' => array('name' => __('Element label', 'quform')),
 772:             'elementLabelText' => array('name' => __('Element label text', 'quform')),
 773:             'elementRequiredText' => array('name' => __('Element required text', 'quform')),
 774:             'elementInner' => array('name' => _x('Element inner wrapper', 'the inner HTML wrapper around the element', 'quform')),
 775:             'elementInput' => array('name' => _x('Element input wrapper', 'the HTML wrapper around just the input', 'quform')),
 776:             'elementText' => array('name' => __('Text input fields', 'quform')),
 777:             'elementTextHover' => array('name' => __('Text input fields (hover)', 'quform')),
 778:             'elementTextFocus' => array('name' => __('Text input fields (focus)', 'quform')),
 779:             'elementTextarea' => array('name' => __('Textarea fields', 'quform')),
 780:             'elementTextareaHover' => array('name' => __('Textarea fields (hover)', 'quform')),
 781:             'elementTextareaFocus' => array('name' => __('Textarea fields (focus)', 'quform')),
 782:             'elementSelect' => array('name' => __('Select fields', 'quform')),
 783:             'elementSelectHover' => array('name' => __('Select fields (hover)', 'quform')),
 784:             'elementSelectFocus' => array('name' => __('Select fields (focus)', 'quform')),
 785:             'elementIcon' => array('name' => __('Text input icons', 'quform')),
 786:             'elementIconHover' => array('name' => __('Text input icons (hover)', 'quform')),
 787:             'elementSubLabel' => array('name' => __('Element sub label', 'quform')),
 788:             'elementDescription' => array('name' => __('Element description', 'quform')),
 789:             'options' => array('name' => _x('Options outer wrapper', 'the wrapper around the list of options for checkboxes and radio buttons', 'quform')),
 790:             'option' => array('name' => _x('Option wrappers', 'the wrapper around each option for checkboxes and radio buttons', 'quform')),
 791:             'optionRadioButton' => array('name' => __('Option radio button', 'quform')),
 792:             'optionCheckbox' => array('name' => __('Option checkbox', 'quform')),
 793:             'optionLabel' => array('name' => __('Option labels', 'quform')),
 794:             'optionLabelHover' => array('name' => __('Option labels (hover)', 'quform')),
 795:             'optionLabelSelected' => array('name' => __('Option labels (when selected)', 'quform')),
 796:             'optionIcon' => array('name' => __('Option icons', 'quform')),
 797:             'optionIconSelected' => array('name' => __('Option icons (when selected)', 'quform')),
 798:             'optionText' => array('name' => __('Option text', 'quform')),
 799:             'optionTextSelected' => array('name' => __('Option text (when selected)', 'quform')),
 800:             'elementError' => array('name' => __('Element error', 'quform')),
 801:             'elementErrorInner' => array('name' => __('Element error inner wrapper', 'quform')),
 802:             'elementErrorText' => array('name' => __('Element error text', 'quform')),
 803:             'page' => array('name' => __('Page wrapper', 'quform')),
 804:             'pageTitle' => array('name' => __('Page title', 'quform')),
 805:             'pageDescription' => array('name' => __('Page description', 'quform')),
 806:             'pageElements' => array('name' => __('Page elements wrapper', 'quform')),
 807:             'group' => array('name' => __('Group wrapper', 'quform')),
 808:             'groupTitle' => array('name' => __('Group title', 'quform')),
 809:             'groupDescription' => array('name' => __('Group description', 'quform')),
 810:             'groupElements' => array('name' => __('Group elements wrapper', 'quform')),
 811:             'pageProgress' => array('name' => __('Page progress wrapper', 'quform')),
 812:             'pageProgressBar' => array('name' => __('Page progress bar', 'quform')),
 813:             'pageProgressBarText' => array('name' => __('Page progress bar text', 'quform')),
 814:             'pageProgressTabs' => array('name' => __('Page progress tabs', 'quform')),
 815:             'pageProgressTab' => array('name' => __('Page progress tab', 'quform')),
 816:             'pageProgressTabActive' => array('name' => __('Page progress tab (active)', 'quform')),
 817:             'submit' => array('name' => __('Submit button outer wrapper', 'quform')),
 818:             'submitInner' => array('name' => __('Submit button wrapper', 'quform')),
 819:             'submitButton' => array('name' => __('Submit button', 'quform')),
 820:             'submitButtonHover' => array('name' => __('Submit button (hover)', 'quform')),
 821:             'submitButtonActive' => array('name' => __('Submit button (active)', 'quform')),
 822:             'submitButtonText' => array('name' => __('Submit button text', 'quform')),
 823:             'submitButtonTextHover' => array('name' => __('Submit button text (hover)', 'quform')),
 824:             'submitButtonTextActive' => array('name' => __('Submit button text (active)', 'quform')),
 825:             'submitButtonIcon' => array('name' => __('Submit button icon', 'quform')),
 826:             'submitButtonIconHover' => array('name' => __('Submit button icon (hover)', 'quform')),
 827:             'submitButtonIconActive' => array('name' => __('Submit button icon (active)', 'quform')),
 828:             'backInner' => array('name' => __('Back button wrapper', 'quform')),
 829:             'backButton' => array('name' => __('Back button', 'quform')),
 830:             'backButtonHover' => array('name' => __('Back button (hover)', 'quform')),
 831:             'backButtonActive' => array('name' => __('Back button (active)', 'quform')),
 832:             'backButtonText' => array('name' => __('Back button text', 'quform')),
 833:             'backButtonTextHover' => array('name' => __('Back button text (hover)', 'quform')),
 834:             'backButtonTextActive' => array('name' => __('Back button text (active)', 'quform')),
 835:             'backButtonIcon' => array('name' => __('Back button icon', 'quform')),
 836:             'backButtonIconHover' => array('name' => __('Back button icon (hover)', 'quform')),
 837:             'backButtonIconActive' => array('name' => __('Back button icon (active)', 'quform')),
 838:             'nextInner' => array('name' => __('Next button wrapper', 'quform')),
 839:             'nextButton' => array('name' => __('Next button', 'quform')),
 840:             'nextButtonHover' => array('name' => __('Next button (hover)', 'quform')),
 841:             'nextButtonActive' => array('name' => __('Next button (active)', 'quform')),
 842:             'nextButtonText' => array('name' => __('Next button text', 'quform')),
 843:             'nextButtonTextHover' => array('name' => __('Next button text (hover)', 'quform')),
 844:             'nextButtonTextActive' => array('name' => __('Next button text (active)', 'quform')),
 845:             'nextButtonIcon' => array('name' => __('Next button icon', 'quform')),
 846:             'nextButtonIconHover' => array('name' => __('Next button icon (hover)', 'quform')),
 847:             'nextButtonIconActive' => array('name' => __('Next button icon (active)', 'quform')),
 848:             'uploadButton' => array('name' => __('Upload button', 'quform')),
 849:             'uploadButtonHover' => array('name' => __('Upload button (hover)', 'quform')),
 850:             'uploadButtonActive' => array('name' => __('Upload button (active)', 'quform')),
 851:             'uploadButtonText' => array('name' => __('Upload button text', 'quform')),
 852:             'uploadButtonTextHover' => array('name' => __('Upload button text (hover)', 'quform')),
 853:             'uploadButtonTextActive' => array('name' => __('Upload button text (active)', 'quform')),
 854:             'uploadButtonIcon' => array('name' => __('Upload button icon', 'quform')),
 855:             'uploadButtonIconHover' => array('name' => __('Upload button icon (hover)', 'quform')),
 856:             'uploadButtonIconActive' => array('name' => __('Upload button icon (active)', 'quform')),
 857:             'uploadDropzone' => array('name' => __('Upload dropzone', 'quform')),
 858:             'uploadDropzoneHover' => array('name' => __('Upload dropzone (hover)', 'quform')),
 859:             'uploadDropzoneActive' => array('name' => __('Upload dropzone (active)', 'quform')),
 860:             'uploadDropzoneText' => array('name' => __('Upload dropzone text', 'quform')),
 861:             'uploadDropzoneTextHover' => array('name' => __('Upload dropzone text (hover)', 'quform')),
 862:             'uploadDropzoneTextActive' => array('name' => __('Upload dropzone text (active)', 'quform')),
 863:             'uploadDropzoneIcon' => array('name' => __('Upload dropzone icon', 'quform')),
 864:             'uploadDropzoneIconHover' => array('name' => __('Upload dropzone icon (hover)', 'quform')),
 865:             'uploadDropzoneIconActive' => array('name' => __('Upload dropzone icon (active)', 'quform')),
 866:             'datepickerHeader' => array('name' => __('Datepicker header', 'quform')),
 867:             'datepickerHeaderText' => array('name' => __('Datepicker header text', 'quform')),
 868:             'datepickerHeaderTextHover' => array('name' => __('Datepicker header text (hover)', 'quform')),
 869:             'datepickerFooter' => array('name' => __('Datepicker footer', 'quform')),
 870:             'datepickerFooterText' => array('name' => __('Datepicker footer text', 'quform')),
 871:             'datepickerFooterTextHover' => array('name' => __('Datepicker footer text (hover)', 'quform')),
 872:             'datepickerSelection' => array('name' => __('Datepicker selection', 'quform')),
 873:             'datepickerSelectionActive' => array('name' => __('Datepicker selection (chosen)', 'quform')),
 874:             'datepickerSelectionText' => array('name' => __('Datepicker selection text', 'quform')),
 875:             'datepickerSelectionTextHover' => array('name' => __('Datepicker selection text (hover)', 'quform')),
 876:             'datepickerSelectionActiveText' => array('name' => __('Datepicker selection text (active)', 'quform')),
 877:             'datepickerSelectionActiveTextHover' => array('name' => __('Datepicker selection text (chosen) (hover)', 'quform'))
 878:         );
 879: 
 880:         foreach ($styles as $k => $style) {
 881:             $styles[$k]['config'] = array('type' => $k, 'css' => '');
 882:         }
 883: 
 884:         $styles = apply_filters('quform_admin_global_styles', $styles);
 885: 
 886:         if (is_string($key)) {
 887:             if (isset($styles[$key])) {
 888:                 return $styles[$key];
 889:             } else {
 890:                 return null;
 891:             }
 892:         }
 893: 
 894:         return $styles;
 895:     }
 896: 
 897:     /**
 898:      * Get the HTML for a style
 899:      *
 900:      * @return string
 901:      */
 902:     protected function getStyleHtml()
 903:     {
 904:         ob_start(); ?>
 905:         <div class="qfb-style qfb-box">
 906:             <div class="qfb-style-inner qfb-cf">
 907:                 <div class="qfb-style-actions">
 908:                     <span class="qfb-style-action-remove" title="<?php esc_attr_e('Remove', 'quform'); ?>"><i class="qfb-icon qfb-icon-trash"></i></span>
 909:                     <span class="qfb-style-action-settings" title="<?php esc_attr_e('Settings', 'quform'); ?>"><i class="qfb-mdi qfb-mdi-settings"></i></span>
 910:                 </div>
 911:                 <div class="qfb-style-title"></div>
 912:             </div>
 913:         </div>
 914:         <?php
 915:         return ob_get_clean();
 916:     }
 917: 
 918:     /**
 919:      * Get the HTML for a global style
 920:      *
 921:      * @param   array   $style
 922:      * @return  string
 923:      */
 924:     public function getGlobalStyleHtml(array $style = array())
 925:     {
 926:         $styles = $this->getGlobalStyles();
 927:         $name = ! empty($style) && isset($styles[$style['type']]) ? $styles[$style['type']]['name'] : '';
 928: 
 929:         ob_start(); ?>
 930:         <div class="qfb-global-style qfb-box"<?php echo !empty($style) ? sprintf(' data-style="%s"', Quform::escape(wp_json_encode($style))) : ''; ?>>
 931:             <div class="qfb-global-style-inner qfb-cf">
 932:                 <div class="qfb-global-style-actions">
 933:                     <span class="qfb-global-style-action-remove" title="<?php esc_attr_e('Remove', 'quform'); ?>"><i class="qfb-icon qfb-icon-trash"></i></span>
 934:                     <span class="qfb-global-style-action-settings" title="<?php esc_attr_e('Settings', 'quform'); ?>"><i class="qfb-mdi qfb-mdi-settings"></i></span>
 935:                 </div>
 936:                 <div class="qfb-global-style-title"><?php echo esc_html($name); ?></div>
 937:             </div>
 938:         </div>
 939:         <?php
 940:         return ob_get_clean();
 941:     }
 942: 
 943:     /**
 944:      * Gets the list of styles that are visible for each element
 945:      *
 946:      * @return array
 947:      */
 948:     protected function getVisibleStyles()
 949:     {
 950:         $visible = array(
 951:             'text' => array('element', 'elementSpacer', 'elementLabel', 'elementLabelText', 'elementRequiredText', 'elementInner', 'elementInput', 'elementText', 'elementTextHover', 'elementTextFocus', 'elementSubLabel', 'elementDescription'),
 952:             'email' => array('element', 'elementSpacer', 'elementLabel', 'elementLabelText', 'elementRequiredText', 'elementInner', 'elementInput', 'elementText', 'elementTextHover', 'elementTextFocus', 'elementSubLabel', 'elementDescription'),
 953:             'password' => array('element', 'elementSpacer', 'elementLabel', 'elementLabelText', 'elementRequiredText', 'elementInner', 'elementInput', 'elementText', 'elementTextHover', 'elementTextFocus', 'elementSubLabel', 'elementDescription'),
 954:             'captcha' => array('element', 'elementSpacer', 'elementLabel', 'elementLabelText', 'elementRequiredText', 'elementInner', 'elementInput', 'elementText', 'elementTextHover', 'elementTextFocus', 'elementSubLabel', 'elementDescription'),
 955:             'textarea' => array('element', 'elementSpacer', 'elementLabel', 'elementLabelText', 'elementRequiredText', 'elementInner', 'elementInput', 'elementTextarea', 'elementTextareaHover', 'elementTextareaFocus', 'elementSubLabel', 'elementDescription'),
 956:             'select' => array('element', 'elementSpacer', 'elementLabel', 'elementLabelText', 'elementRequiredText', 'elementInner', 'elementInput', 'elementSelect', 'elementSelectHover', 'elementSelectFocus', 'elementSubLabel', 'elementDescription'),
 957:             'file' => array('element', 'elementSpacer', 'elementLabel', 'elementLabelText', 'elementRequiredText', 'elementInner', 'elementInput', 'uploadButton', 'uploadButtonHover', 'uploadButtonActive', 'uploadButtonText', 'uploadButtonTextHover', 'uploadButtonTextActive', 'uploadButtonIcon', 'uploadButtonIconHover', 'uploadButtonIconActive', 'uploadDropzone', 'uploadDropzoneHover', 'uploadDropzoneActive', 'uploadDropzoneText', 'uploadDropzoneTextHover', 'uploadDropzoneTextActive', 'uploadDropzoneIcon', 'uploadDropzoneIconHover', 'uploadDropzoneIconActive', 'elementSubLabel', 'elementDescription'),
 958:             'recaptcha' => array('element', 'elementSpacer', 'elementLabel', 'elementLabelText', 'elementRequiredText', 'elementInner', 'elementInput', 'elementSubLabel', 'elementDescription'),
 959:             'date' => array('element', 'elementSpacer', 'elementLabel', 'elementLabelText', 'elementRequiredText', 'elementInner', 'elementInput', 'elementText', 'elementIcon', 'elementIconHover', 'elementSubLabel', 'elementDescription', 'datepickerSelection', 'datepickerSelectionActive', 'datepickerSelectionText', 'datepickerSelectionTextHover', 'datepickerSelectionActiveText', 'datepickerSelectionActiveTextHover', 'datepickerFooter', 'datepickerFooterText', 'datepickerFooterTextHover', 'datepickerHeader', 'datepickerHeaderText', 'datepickerHeaderTextHover',),
 960:             'time' => array('element', 'elementSpacer', 'elementLabel', 'elementLabelText', 'elementRequiredText', 'elementInner', 'elementInput', 'elementText', 'elementIcon', 'elementIconHover', 'elementSubLabel', 'elementDescription'),
 961:             'radio' => array('element', 'elementSpacer', 'elementLabel', 'elementLabelText', 'elementRequiredText', 'elementInner', 'elementInput', 'options', 'option', 'optionRadioButton', 'optionLabel', 'optionLabelHover', 'optionLabelSelected', 'optionIcon', 'optionIconSelected', 'optionText', 'optionTextSelected', 'elementSubLabel', 'elementDescription'),
 962:             'checkbox' => array('element', 'elementSpacer', 'elementLabel', 'elementLabelText', 'elementRequiredText', 'elementInner', 'elementInput', 'options', 'option', 'optionCheckbox', 'optionLabel', 'optionLabelHover', 'optionLabelSelected', 'optionIcon', 'optionIconSelected', 'optionText', 'optionTextSelected', 'elementSubLabel', 'elementDescription'),
 963:             'multiselect' => array('element', 'elementSpacer', 'elementLabel', 'elementLabelText', 'elementRequiredText', 'elementInner', 'elementInput', 'elementSubLabel', 'elementDescription'),
 964:             'name' => array('element', 'elementSpacer', 'elementLabel', 'elementLabelText', 'elementRequiredText', 'elementInner', 'elementInput', 'elementSubLabel', 'elementDescription'),
 965:             'html' => array('element', 'elementSpacer'),
 966:             'page' => array('page', 'pageTitle', 'pageDescription', 'pageElements'),
 967:             'group' => array('group', 'groupSpacer', 'groupTitle', 'groupDescription', 'groupElements'),
 968:             'submit' => array('submit', 'submitInner', 'submitButton', 'submitButtonHover', 'submitButtonActive', 'submitButtonText', 'submitButtonTextHover', 'submitButtonTextActive', 'submitButtonIcon', 'submitButtonIconHover', 'submitButtonIconActive', 'backInner', 'backButton', 'backButtonHover', 'backButtonActive', 'backButtonText', 'backButtonTextHover', 'backButtonTextActive', 'backButtonIcon', 'backButtonIconHover', 'backButtonIconActive', 'nextInner', 'nextButton', 'nextButtonHover', 'nextButtonActive', 'nextButtonText', 'nextButtonTextHover', 'nextButtonTextActive', 'nextButtonIcon', 'nextButtonIconHover', 'nextButtonIconActive')
 969:         );
 970: 
 971:         $visible = apply_filters('quform_visible_styles', $visible);
 972: 
 973:         return $visible;
 974:     }
 975: 
 976:     /**
 977:      * Get the list of filters
 978:      *
 979:      * @return array
 980:      */
 981:     public function getFilters()
 982:     {
 983:         $filters = array(
 984:             'alpha' => array(
 985:                 'name' => _x('Alpha', 'the alphabet filter', 'quform'),
 986:                 'tooltip' => __('Removes any non-alphabet characters', 'quform'),
 987:                 'config' => Quform_Filter_Alpha::getDefaultConfig()
 988:             ),
 989:             'alphaNumeric' => array(
 990:                 'name' => _x('Alphanumeric', 'the alphanumeric filter', 'quform'),
 991:                 'tooltip' => __('Removes any non-alphabet characters and non-digits', 'quform'),
 992:                 'config' => Quform_Filter_AlphaNumeric::getDefaultConfig()
 993:             ),
 994:             'digits' => array(
 995:                 'name' => _x('Digits', 'the digits filter', 'quform'),
 996:                 'tooltip' => __('Removes any non-digits', 'quform'),
 997:                 'config' => Quform_Filter_Digits::getDefaultConfig()
 998:             ),
 999:             'regex' => array(
1000:                 'name' => _x('Regex', 'the regex filter', 'quform'),
1001:                 'tooltip' => __('Removes characters matching the given regular expression', 'quform'),
1002:                 'config' => Quform_Filter_Regex::getDefaultConfig()
1003:             ),
1004:             'stripTags' => array(
1005:                 'name' => _x('Strip Tags', 'the strip tags filter', 'quform'),
1006:                 'tooltip' => __('Removes any HTML tags', 'quform'),
1007:                 'config' => Quform_Filter_StripTags::getDefaultConfig()
1008:             ),
1009:             'trim' => array(
1010:                 'name' => _x('Trim', 'the trim filter', 'quform'),
1011:                 'tooltip' => __('Removes white space from the start and end', 'quform'),
1012:                 'config' => Quform_Filter_Trim::getDefaultConfig()
1013:             )
1014:         );
1015: 
1016:         $filters = apply_filters('quform_admin_filters', $filters);
1017: 
1018:         return $filters;
1019:     }
1020: 
1021:     /**
1022:      * Get the HTML for a filter
1023:      *
1024:      * @return string
1025:      */
1026:     protected function getFilterHtml()
1027:     {
1028:         ob_start();
1029:         ?>
1030:         <div class="qfb-filter qfb-box">
1031:             <div class="qfb-filter-inner qfb-cf">
1032:                 <div class="qfb-filter-actions">
1033:                     <span class="qfb-filter-action-remove" title="<?php esc_attr_e('Remove', 'quform'); ?>"><i class="qfb-icon qfb-icon-trash"></i></span>
1034:                     <span class="qfb-filter-action-settings" title="<?php esc_attr_e('Settings', 'quform'); ?>"><i class="qfb-mdi qfb-mdi-settings"></i></span>
1035:                 </div>
1036:                 <div class="qfb-filter-title"></div>
1037:             </div>
1038:         </div>
1039:         <?php
1040:         return ob_get_clean();
1041:     }
1042: 
1043:     /**
1044:      * Get the list of visible filters for the elements
1045:      *
1046:      * @return array
1047:      */
1048:     protected function getVisibleFilters()
1049:     {
1050:         $visible = array(
1051:             'text' => array('alpha', 'alphaNumeric', 'digits', 'stripTags', 'trim', 'regex'),
1052:             'email' => array('trim'),
1053:             'textarea' => array('alpha', 'alphaNumeric', 'digits', 'stripTags', 'trim', 'regex')
1054:         );
1055: 
1056:         $visible = apply_filters('quform_visible_filters', $visible);
1057: 
1058:         return $visible;
1059:     }
1060: 
1061:     /**
1062:      * Get the validator configurations
1063:      *
1064:      * @return array
1065:      */
1066:     public function getValidators()
1067:     {
1068:         $validators = array(
1069:             'alpha' => array(
1070:                 'name' => _x('Alpha', 'the alphabet validator', 'quform'),
1071:                 'tooltip' => __('Checks that the value contains only alphabet characters', 'quform'),
1072:                 'config' => Quform_Validator_Alpha::getDefaultConfig()
1073:             ),
1074:             'alphaNumeric' => array(
1075:                 'name' => _x('Alphanumeric', 'the alphanumeric validator', 'quform'),
1076:                 'tooltip' => __('Checks that the value contains only alphabet or digits', 'quform'),
1077:                 'config' => Quform_Validator_AlphaNumeric::getDefaultConfig()
1078:             ),
1079:             'digits' => array(
1080:                 'name' => _x('Digits', 'the digits validator', 'quform'),
1081:                 'tooltip' => __('Checks that the value contains only digits', 'quform'),
1082:                 'config' => Quform_Validator_Digits::getDefaultConfig()
1083:             ),
1084:             'email' => array(
1085:                 'name' => _x('Email', 'the strip tags validator', 'quform'),
1086:                 'tooltip' => __('Checks that the value is a valid email address', 'quform'),
1087:                 'config' => Quform_Validator_Email::getDefaultConfig()
1088:             ),
1089:             'greaterThan' => array(
1090:                 'name' => _x('Greater Than', 'the greater than validator', 'quform'),
1091:                 'tooltip' => __('Checks that the value is numerically greater than the given minimum', 'quform'),
1092:                 'config' => Quform_Validator_GreaterThan::getDefaultConfig()
1093:             ),
1094:             'identical' => array(
1095:                 'name' => _x('Identical', 'the identical validator', 'quform'),
1096:                 'tooltip' => __('Checks that the value is identical to the given token', 'quform'),
1097:                 'config' => Quform_Validator_Identical::getDefaultConfig()
1098:             ),
1099:             'inArray' => array(
1100:                 'name' => _x('In Array', 'the in array validator', 'quform'),
1101:                 'tooltip' => __('Checks that the value is in a list of allowed values', 'quform'),
1102:                 'config' => Quform_Validator_InArray::getDefaultConfig()
1103:             ),
1104:             'length' => array(
1105:                 'name' => _x('Length', 'the length validator', 'quform'),
1106:                 'tooltip' => __('Checks that the length of the value is between the given maximum and minimum', 'quform'),
1107:                 'config' => Quform_Validator_Length::getDefaultConfig()
1108:             ),
1109:             'lessThan' => array(
1110:                 'name' => _x('Less Than', 'the less than validator', 'quform'),
1111:                 'tooltip' => __('Checks that the value is numerically less than the given maximum', 'quform'),
1112:                 'config' => Quform_Validator_LessThan::getDefaultConfig()
1113:             ),
1114:             'duplicate' => array(
1115:                 'name' => _x('Prevent Duplicates', 'the duplicate validator', 'quform'),
1116:                 'tooltip' => __('Checks that the same value has not already been submitted', 'quform'),
1117:                 'config' => Quform_Validator_Duplicate::getDefaultConfig()
1118:             ),
1119:             'regex' => array(
1120:                 'name' => _x('Regex', 'the regex validator', 'quform'),
1121:                 'tooltip' => __('Checks that the value matches the given regular expression', 'quform'),
1122:                 'config' => Quform_Validator_Regex::getDefaultConfig()
1123:             )
1124:         );
1125: 
1126:         $validators = apply_filters('quform_admin_validators', $validators);
1127: 
1128:         return $validators;
1129:     }
1130: 
1131:     /**
1132:      * Get the HTML for a validator
1133:      *
1134:      * @return string
1135:      */
1136:     protected function getValidatorHtml()
1137:     {
1138:         ob_start();
1139:         ?>
1140:         <div class="qfb-validator qfb-box">
1141:             <div class="qfb-validator-inner qfb-cf">
1142:                 <div class="qfb-validator-actions">
1143:                     <span class="qfb-validator-action-remove" title="<?php esc_attr_e('Remove', 'quform'); ?>"><i class="qfb-icon qfb-icon-trash"></i></span>
1144:                     <span class="qfb-validator-action-settings" title="<?php esc_attr_e('Settings', 'quform'); ?>"><i class="qfb-mdi qfb-mdi-settings"></i></span>
1145:                 </div>
1146:                 <div class="qfb-validator-title"></div>
1147:             </div>
1148:         </div>
1149:         <?php
1150:         return ob_get_clean();
1151:     }
1152: 
1153:     /**
1154:      * Get the list of visible validators for the elements
1155:      *
1156:      * @return array
1157:      */
1158:     protected function getVisibleValidators()
1159:     {
1160:         $visible = array(
1161:             'text' => array('alpha', 'alphaNumeric', 'digits', 'duplicate', 'email', 'greaterThan', 'identical', 'inArray', 'length', 'lessThan', 'regex'),
1162:             'textarea' => array('alpha', 'alphaNumeric', 'digits', 'duplicate', 'email', 'greaterThan', 'identical', 'inArray', 'length', 'lessThan', 'regex'),
1163:             'email' => array('duplicate', 'inArray', 'regex'),
1164:             'password' => array('alpha', 'alphaNumeric', 'digits', 'identical', 'inArray', 'length', 'regex'),
1165:             'select' => array('duplicate', 'greaterThan', 'identical', 'inArray', 'lessThan', 'regex'),
1166:             'checkbox' => array('duplicate'),
1167:             'radio' => array('duplicate', 'greaterThan', 'identical', 'inArray', 'lessThan', 'regex'),
1168:             'multiselect' => array('duplicate'),
1169:             'date' => array('duplicate', 'inArray'),
1170:             'time' => array('duplicate', 'inArray'),
1171:             'name' => array('duplicate')
1172:         );
1173: 
1174:         $visible = apply_filters('quform_visible_validators', $visible);
1175: 
1176:         return $visible;
1177:     }
1178: 
1179:     /**
1180:      * Get the HTML for a notification
1181:      *
1182:      * @param   array   $notification
1183:      * @return  string
1184:      */
1185:     public function getNotificationHtml($notification = null)
1186:     {
1187:         if ( ! is_array($notification)) {
1188:             $notification = Quform_Notification::getDefaultConfig();
1189:             $notification['id'] = 0;
1190:         }
1191: 
1192:         ob_start();
1193:         ?>
1194:         <div class="qfb-notification qfb-box qfb-cf" data-id="<?php echo esc_attr($notification['id']); ?>">
1195:             <div class="qfb-notification-name"><?php echo esc_html($notification['name']); ?></div>
1196:             <div class="qfb-notification-actions">
1197:                 <span class="qfb-notification-action-toggle" title="<?php esc_attr_e('Toggle enabled/disabled', 'quform'); ?>"><input type="checkbox" id="qfb-notification-toggle-<?php echo esc_attr($notification['id']); ?>" class="qfb-notification-toggle qfb-mini-toggle" <?php checked($notification['enabled']); ?>><label for="qfb-notification-toggle-<?php echo esc_attr($notification['id']); ?>"></label></span>
1198:                 <span class="qfb-notification-action-remove" title="<?php esc_attr_e('Remove', 'quform'); ?>"><i class="qfb-icon qfb-icon-trash"></i></span>
1199:                 <span class="qfb-notification-action-duplicate" title="<?php esc_attr_e('Duplicate', 'quform'); ?>"><i class="qfb-mdi qfb-mdi-content_copy"></i></span>
1200:                 <span class="qfb-notification-action-settings" title="<?php esc_attr_e('Settings', 'quform'); ?>"><i class="qfb-mdi qfb-mdi-settings"></i></span>
1201:             </div>
1202:             <div class="qfb-notification-subject"><span class="qfb-notification-subject-text"><?php echo esc_html($notification['subject']); ?></span></div>
1203:         </div>
1204:         <?php
1205:         return ob_get_clean();
1206:     }
1207: 
1208:     /**
1209:      * Get the HTML for an email recipient
1210:      *
1211:      * @return  string
1212:      */
1213:     public function getRecipientHtml()
1214:     {
1215:         ob_start();
1216:         ?>
1217:         <div class="qfb-recipient">
1218:             <div class="qfb-recipient-inner qfb-cf">
1219:                 <div class="qfb-recipient-left">
1220:                     <select class="qfb-recipient-type">
1221:                         <option value="to"><?php echo esc_html_x('To', 'email', 'quform'); ?></option>
1222:                         <option value="cc"><?php esc_html_e('Cc', 'quform'); ?></option>
1223:                         <option value="bcc"><?php esc_html_e('Bcc', 'quform'); ?></option>
1224:                         <option value="reply"><?php esc_html_e('Reply-To', 'quform'); ?></option>
1225:                     </select>
1226:                 </div>
1227:                 <div class="qfb-recipient-right">
1228:                     <div class="qfb-recipient-right-inner">
1229:                         <div class="qfb-settings-row qfb-settings-row-2">
1230:                             <div class="qfb-settings-column">
1231:                                 <div class="qfb-input-variable">
1232:                                     <input class="qfb-recipient-address" type="text" placeholder="<?php esc_attr_e('Email address (required)', 'quform'); ?>">
1233:                                     <?php echo $this->getInsertVariableHtml(); ?>
1234:                                 </div>
1235:                             </div>
1236:                             <div class="qfb-settings-column">
1237:                                 <div class="qfb-input-variable">
1238:                                     <input class="qfb-recipient-name" type="text" placeholder="<?php esc_attr_e('Name (optional)', 'quform'); ?>">
1239:                                     <?php echo $this->getInsertVariableHtml(); ?>
1240:                                 </div>
1241:                             </div>
1242:                         </div>
1243:                     </div>
1244:                 </div>
1245:                 <span class="qfb-small-remove-button qfb-icon qfb-icon-trash" title="<?php esc_attr_e('Remove', 'quform'); ?>"></span>
1246:                 <span class="qfb-small-add-button qfb-mdi qfb-mdi-add_circle" title="<?php esc_attr_e('Add', 'quform'); ?>"></span>
1247:             </div>
1248:         </div>
1249:         <?php
1250:         return ob_get_clean();
1251:     }
1252: 
1253:     /**
1254:      * Get the HTML for the insert variable button
1255:      *
1256:      * @param   string  $targetId    The unique ID of the target field
1257:      * @param   bool    $preProcess  Whether it is the pre process variables
1258:      * @return  string
1259:      */
1260:     public function getInsertVariableHtml($targetId = '', $preProcess = false)
1261:     {
1262:         return sprintf(
1263:             '<span class="qfb-insert-variable%s" title="%s"%s><i class="qfb-icon qfb-icon-code"></i></span>',
1264:             $preProcess ? ' qfb-insert-variable-pre-process' : '',
1265:             esc_attr__('Insert variable...', 'quform'),
1266:             $targetId ? ' data-target-id="' . esc_attr($targetId) . '"' : ''
1267:         );
1268:     }
1269: 
1270:     /**
1271:      * Get the HTML for a confirmation
1272:      *
1273:      * @param   array   $confirmation
1274:      * @return  string
1275:      */
1276:     public function getConfirmationHtml($confirmation = null)
1277:     {
1278:         if ( ! is_array($confirmation)) {
1279:             $confirmation = Quform_Confirmation::getDefaultConfig();
1280:             $confirmation['id'] = 0;
1281:         }
1282: 
1283:         ob_start();
1284:         ?>
1285:         <div class="qfb-confirmation qfb-box qfb-cf" data-id="<?php echo esc_attr($confirmation['id']); ?>">
1286:             <div class="qfb-confirmation-name"><?php echo esc_html($confirmation['name']); ?></div>
1287:             <div class="qfb-confirmation-actions">
1288:                 <?php if ($confirmation['id'] != 1) : ?>
1289:                     <span class="qfb-confirmation-action-toggle" title="<?php esc_attr_e('Toggle enabled/disabled', 'quform'); ?>"><input type="checkbox" id="qfb-confirmation-toggle-<?php echo esc_attr($confirmation['id']); ?>" class="qfb-confirmation-toggle qfb-mini-toggle" <?php checked($confirmation['enabled']); ?>><label for="qfb-confirmation-toggle-<?php echo esc_attr($confirmation['id']); ?>"></label></span>
1290:                     <span class="qfb-confirmation-action-remove" title="<?php esc_attr_e('Remove', 'quform'); ?>"><i class="qfb-icon qfb-icon-trash"></i></span>
1291:                 <?php endif; ?>
1292:                 <span class="qfb-confirmation-action-duplicate" title="<?php esc_attr_e('Duplicate', 'quform'); ?>"><i class="qfb-mdi qfb-mdi-content_copy"></i></span>
1293:                 <span class="qfb-confirmation-action-settings" title="<?php esc_attr_e('Settings', 'quform'); ?>"><i class="qfb-mdi qfb-mdi-settings"></i></span>
1294:             </div>
1295:             <div class="qfb-confirmation-description"><?php echo $this->getConfirmationDescription($confirmation); ?></div>
1296:         </div>
1297:         <?php
1298:         return ob_get_clean();
1299:     }
1300: 
1301:     /**
1302:      * Get the confirmation description
1303:      *
1304:      * Changes should be mirrored in builder.confirmations.js:getConfirmationDescription
1305:      *
1306:      * @param   array   $confirmation
1307:      * @return  string
1308:      */
1309:     protected function getConfirmationDescription(array $confirmation)
1310:     {
1311:         $type = $confirmation['type'];
1312: 
1313:         $output = sprintf(
1314:             '<div class="qfb-settings-row%s">',
1315:             $type == 'message-redirect-page' || $type == 'message-redirect-url' ? ' qfb-settings-row-2' : ''
1316:         );
1317: 
1318:         $output .= '<div class="qfb-settings-column">';
1319: 
1320:         switch ($type) {
1321:             case 'message':
1322:             case 'message-redirect-page':
1323:             case 'message-redirect-url':
1324:                 $output .= sprintf('<i class="qfb-mdi qfb-mdi-message" title="%s"></i>', esc_attr__('Display a message', 'quform'));
1325:                 $output .= sprintf(
1326:                     '<span class="qfb-confirmation-description-message">%s</span>',
1327:                     Quform::escape(mb_substr(strip_tags($confirmation['message']), 0, 64))
1328:                 );
1329:                 break;
1330:             case 'redirect-page';
1331:                 $output .= sprintf('<i class="qfb-mdi qfb-mdi-arrow_forward" title="%s"></i>', esc_attr__('Redirect to', 'quform'));
1332:                 $output .= sprintf(
1333:                     '<span class="qfb-confirmation-description-redirect-page">%s</span>',
1334:                     Quform::escape(Quform::getPostTitleById((int) $confirmation['redirectPage']))
1335:                 );
1336:                 break;
1337:             case 'redirect-url';
1338:                 $output .= sprintf('<i class="qfb-mdi qfb-mdi-arrow_forward" title="%s"></i>', esc_attr__('Redirect to', 'quform'));
1339:                 $output .= sprintf(
1340:                     '<span class="qfb-confirmation-description-redirect-url">%s</span>',
1341:                     Quform::escape($confirmation['redirectUrl'])
1342:                 );
1343:                 break;
1344:             case 'reload';
1345:                 $output .= sprintf('<i class="qfb-mdi qfb-mdi-refresh" title="%s"></i>', esc_attr__('Reload the page', 'quform'));
1346:                 break;
1347:         }
1348: 
1349:         $output .= '</div>';
1350: 
1351:         if ($type == 'message-redirect-page' || $type == 'message-redirect-url') {
1352:             $output .= '<div class="qfb-settings-column">';
1353: 
1354:             switch ($type) {
1355:                 case 'message-redirect-page';
1356:                     $output .= sprintf('<i class="qfb-mdi qfb-mdi-arrow_forward" title="%s"></i>', esc_attr__('Redirect to', 'quform'));
1357:                     $output .= sprintf(
1358:                         '<span class="qfb-confirmation-description-redirect-page">%s</span>',
1359:                         Quform::escape(Quform::getPostTitleById((int) $confirmation['redirectPage']))
1360:                     );
1361:                     break;
1362:                 case 'message-redirect-url';
1363:                     $output .= sprintf('<i class="qfb-mdi qfb-mdi-arrow_forward" title="%s"></i>', esc_attr__('Redirect to', 'quform'));
1364:                     $output .= sprintf(
1365:                         '<span class="qfb-confirmation-description-redirect-url">%s</span>',
1366:                         Quform::escape($confirmation['redirectUrl'])
1367:                     );
1368:                     break;
1369:             }
1370: 
1371:             $output .= '</div>';
1372:         }
1373: 
1374:         $output .= '</div>';
1375: 
1376:         return $output;
1377:     }
1378: 
1379:     /**
1380:      * Get the HTML for a select menu of available title tag options
1381:      *
1382:      * @param   string  $id        The ID of the field
1383:      * @param   string  $selected  The selected value
1384:      * @return  string
1385:      */
1386:     public function getTitleTagSelectHtml($id, $selected = '')
1387:     {
1388:         $tags = array('h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'span');
1389:         $output = sprintf('<select id="%s">', $id);
1390: 
1391:         foreach ($tags as $tag) {
1392:             $output .= sprintf('<option value="%1$s"%2$s>%1$s</option>', Quform::escape($tag), $selected == $tag ? ' selected="selected"' : '');
1393:         }
1394: 
1395:         $output .= '</select>';
1396: 
1397:         return $output;
1398:     }
1399: 
1400:     /**
1401:      * The supported autocomplete attributes from https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofill
1402:      *
1403:      * @return array
1404:      */
1405:     public function getAutocompleteValues()
1406:     {
1407:         $values = array(
1408:             'off', 'on', 'name', 'honorific-prefix', 'given-name', 'additional-name', 'family-name', 'honorific-suffix',
1409:             'nickname', 'username', 'new-password', 'current-password', 'one-time-code', 'organization-title',
1410:             'organization', 'street-address', 'address-line1', 'address-line2', 'address-line3', 'address-level4',
1411:             'address-level3', 'address-level2', 'address-level1', 'country', 'country-name', 'postal-code', 'cc-name',
1412:             'cc-given-name', 'cc-additional-name', 'cc-family-name', 'cc-number', 'cc-exp', 'cc-exp-month',
1413:             'cc-exp-year', 'cc-csc', 'cc-type', 'transaction-currency', 'transaction-amount', 'language', 'bday',
1414:             'bday-day', 'bday-month', 'bday-year', 'sex', 'url', 'photo', 'home', 'work', 'mobile', 'fax', 'pager',
1415:             'tel', 'tel-country-code', 'tel-national', 'tel-area-code', 'tel-local', 'tel-local-prefix',
1416:             'tel-local-suffix', 'tel-extension', 'email', 'impp', 'webauthn', 'shipping', 'billing',
1417:         );
1418: 
1419:         $values = apply_filters('quform_autocomplete_values', $values);
1420: 
1421:         sort($values);
1422: 
1423:         return $values;
1424:     }
1425: 
1426:     /**
1427:      * Get the HTML for the custom database column settings
1428:      *
1429:      * @param   array|null  $column  The existing column config
1430:      * @return  string
1431:      */
1432:     public function getDbColumnHtml($column = null)
1433:     {
1434:         if ( ! is_array($column)) {
1435:             $column = array(
1436:                 'name' => '',
1437:                 'value' => ''
1438:             );
1439:         }
1440: 
1441:         $variableId = uniqid('q');
1442:         ob_start();
1443:         ?>
1444:         <div class="qfb-form-db-column qfb-cf">
1445:             <input type="text" class="qfb-form-db-column-name" placeholder="<?php esc_attr_e('Column', 'quform'); ?>" value="<?php echo esc_attr($column['name']); ?>">
1446:             <input id="<?php echo esc_attr($variableId); ?>" type="text" class="qfb-form-db-column-value" placeholder="<?php esc_attr_e('Value', 'quform'); ?>" value="<?php echo esc_attr($column['value']); ?>">
1447:             <?php echo $this->getInsertVariableHtml($variableId); ?>
1448:             <span class="qfb-small-remove-button qfb-icon qfb-icon-trash" title="<?php esc_attr_e('Remove', 'quform'); ?>"></span>
1449:         </div>
1450:         <?php
1451:         return ob_get_clean();
1452:     }
1453: 
1454:     /**
1455:      * Get the default form configuration array with populated default settings
1456:      *
1457:      * @return array
1458:      */
1459:     public function getDefaultForm()
1460:     {
1461:         $page = $this->getDefaultElementConfig('page');
1462:         $page['id'] = 1;
1463:         $page['parentId'] = 0;
1464:         $page['position'] = 0;
1465: 
1466:         $submit = $this->getDefaultElementConfig('submit');
1467:         $submit['id'] = 2;
1468:         $submit['parentId'] = 1;
1469:         $submit['position'] = 0;
1470: 
1471:         $page['elements'] = array($submit);
1472: 
1473:         $notification = Quform_Notification::getDefaultConfig();
1474:         $notification['id'] = 1;
1475:         $notification['name'] = __('Admin notification', 'quform');
1476: 
1477:         $confirmation = Quform_Confirmation::getDefaultConfig();
1478:         $confirmation['id'] = 1;
1479:         $confirmation['name'] = __('Default confirmation', 'quform');
1480:         $confirmation['message'] = __('Your message has been sent, thanks.', 'quform');
1481:         $confirmation['messageIcon'] = 'qicon-check';
1482: 
1483:         $form = Quform_Form::getDefaultConfig();
1484:         $form['nextElementId'] = 3;
1485:         $form['elements'] = array($page);
1486:         $form['nextNotificationId'] = 2;
1487:         $form['notifications'] = array($notification);
1488:         $form['nextConfirmationId'] = 2;
1489:         $form['confirmations'] = array($confirmation);
1490: 
1491:         $form = apply_filters('quform_default_form', $form);
1492: 
1493:         return $form;
1494:     }
1495: 
1496:     /**
1497:      * @param   array   $form
1498:      * @param   string  $key
1499:      * @return  mixed
1500:      */
1501:     public function getFormConfigValue($form, $key)
1502:     {
1503:         $value = Quform::get($form, $key);
1504: 
1505:         if ($value === null) {
1506:             $value = Quform::get(Quform_Form::getDefaultConfig(), $key);
1507:         }
1508: 
1509:         return $value;
1510:     }
1511: 
1512:     /**
1513:      * Get the HTML for all pages and elements for the form builder
1514:      *
1515:      * @param   array   $elements  The array of element configs
1516:      * @return  string
1517:      */
1518:     public function renderFormElements($elements)
1519:     {
1520:         $output = '';
1521: 
1522:         foreach ($elements as $element) {
1523:             $output .= $this->getElementHtml($element);
1524:         }
1525: 
1526:         return $output;
1527:     }
1528: 
1529:     /**
1530:      * Get the HTML for an element in the form builder
1531:      *
1532:      * @param   array   $element  The element config
1533:      * @return  string
1534:      */
1535:     protected function getElementHtml(array $element)
1536:     {
1537:         switch ($element['type']) {
1538:             case 'page':
1539:                 $output = $this->getPageHtml($element);
1540:                 break;
1541:             case 'group':
1542:                 $output = $this->getGroupHtml($element);
1543:                 break;
1544:             case 'row':
1545:                 $output = $this->getRowHtml($element);
1546:                 break;
1547:             case 'column':
1548:                 $output = $this->getColumnHtml($element);
1549:                 break;
1550:             default:
1551:                 $output = $this->getFieldHtml($element);
1552:                 break;
1553:         }
1554: 
1555:         return $output;
1556:     }
1557: 
1558:     /**
1559:      * Get the HTML for a page for the form builder
1560:      *
1561:      * @param   array   $element  The page config
1562:      * @return  string
1563:      */
1564:     protected function getPageHtml(array $element)
1565:     {
1566:         ob_start(); ?>
1567:         <div id="qfb-element-<?php echo esc_attr($element['id']); ?>" class="qfb-element qfb-element-page" data-id="<?php echo esc_attr($element['id']); ?>" data-type="page">
1568:             <div id="qfb-child-elements-<?php echo esc_attr($element['id']); ?>" class="qfb-child-elements qfb-cf">
1569:                 <?php
1570:                     foreach ($element['elements'] as $child) {
1571:                         echo $this->getElementHtml($child);
1572:                     }
1573:                 ?>
1574:             </div>
1575:         </div>
1576:         <?php
1577:         return ob_get_clean();
1578:     }
1579: 
1580:     /**
1581:      * Get the HTML for a group for the form builder
1582:      *
1583:      * @param   array  $element  The group config
1584:      * @return  string           The HTML
1585:      */
1586:     protected function getGroupHtml(array $element)
1587:     {
1588:         ob_start(); ?>
1589:         <div id="qfb-element-<?php echo esc_attr($element['id']); ?>" class="qfb-element qfb-element-group" data-id="<?php echo esc_attr($element['id']); ?>" data-type="group">
1590:             <div class="qfb-element-inner qfb-cf">
1591:                 <span class="qfb-element-type-icon"><i class="qfb-icon qfb-icon-object-group"></i></span>
1592:                 <label class="qfb-preview-label<?php echo ( ! Quform::isNonEmptyString($element['label']) ? ' qfb-hidden' : ''); ?>"><span id="qfb-plc-<?php echo esc_attr($element['id']); ?>" class="qfb-preview-label-content"><?php echo Quform::escape($element['label']); ?></span></label>
1593:                 <div class="qfb-element-actions">
1594:                     <span class="qfb-element-action-collapse" title="<?php esc_attr_e('Collapse', 'quform'); ?>"><i class="qfb-mdi qfb-mdi-remove_circle_outline"></i></span>
1595:                     <span class="qfb-element-action-remove" title="<?php esc_attr_e('Remove', 'quform'); ?>"><i class="qfb-icon qfb-icon-trash"></i></span>
1596:                     <span class="qfb-element-action-duplicate" title="<?php esc_attr_e('Duplicate', 'quform'); ?>"><i class="qfb-mdi qfb-mdi-content_copy"></i></span>
1597:                     <span class="qfb-element-action-settings" title="<?php esc_attr_e('Settings', 'quform'); ?>"><i class="qfb-mdi qfb-mdi-settings"></i></span>
1598:                 </div>
1599:             </div>
1600:             <div id="qfb-child-elements-<?php echo esc_attr($element['id']); ?>" class="qfb-child-elements qfb-cf">
1601:                 <?php
1602:                     foreach ($element['elements'] as $child) {
1603:                         echo $this->getElementHtml($child);
1604:                     }
1605:                 ?>
1606:             </div>
1607:             <div class="qfb-element-group-empty-indicator"><span class="qfb-element-group-empty-indicator-arrow"><i class="qfb-icon qfb-icon-arrow-down"></i></span><span class="qfb-element-group-empty-add-row" title="<?php esc_attr_e('Add column layout', 'quform'); ?>"><i class="qfb-icon qfb-icon-columns"></i><i class="qfb-mdi qfb-mdi-add_circle"></i></span></div>
1608:         </div>
1609:         <?php
1610:         return ob_get_clean();
1611:     }
1612: 
1613:     /**
1614:      * Get the HTML for a row for the form builder
1615:      *
1616:      * @param   array   $element  The row config
1617:      * @return  string
1618:      */
1619:     protected function getRowHtml(array $element)
1620:     {
1621:         ob_start(); ?>
1622:         <div id="qfb-element-<?php echo esc_attr($element['id']); ?>" class="qfb-element qfb-element-row" data-id="<?php echo esc_attr($element['id']); ?>" data-type="row">
1623:             <div id="qfb-child-elements-<?php echo esc_attr($element['id']); ?>" class="qfb-child-elements qfb-cf qfb-<?php echo esc_attr(count($element['elements'])); ?>-columns">
1624:             <?php
1625:                 foreach ($element['elements'] as $child) {
1626:                     echo $this->getElementHtml($child);
1627:                 }
1628:             ?>
1629:             </div>
1630:             <div class="qfb-row-actions">
1631:                 <span class="qfb-row-action-add-column" title="<?php esc_attr_e('Add column', 'quform'); ?>"><i class="qfb-mdi qfb-mdi-add_circle"></i></span>
1632:                 <span class="qfb-row-action-remove-column" title="<?php esc_attr_e('Remove column', 'quform'); ?>"><i class="qfb-mdi qfb-mdi-remove_circle"></i></span>
1633:                 <span class="qfb-row-action-remove" title="<?php esc_attr_e('Remove row', 'quform'); ?>"><i class="qfb-icon qfb-icon-trash"></i></span>
1634:                 <span class="qfb-row-action-duplicate" title="<?php esc_attr_e('Duplicate row', 'quform'); ?>"><i class="qfb-mdi qfb-mdi-content_copy"></i></span>
1635:                 <span class="qfb-row-action-settings" title="<?php esc_attr_e('Row settings', 'quform'); ?>"><i class="qfb-mdi qfb-mdi-settings"></i></span>
1636:                 <span class="qfb-row-action-move" title="<?php esc_attr_e('Move row', 'quform'); ?>"><i class="qfb-icon qfb-icon-arrows"></i></span>
1637:             </div>
1638:         </div>
1639:         <?php
1640:         return ob_get_clean();
1641:     }
1642: 
1643:     /**
1644:      * Get the HTML for a column for the form builder
1645:      *
1646:      * @param   array   $element  The column config
1647:      * @return  string
1648:      */
1649:     protected function getColumnHtml(array $element)
1650:     {
1651:         ob_start(); ?>
1652:         <div id="qfb-element-<?php echo esc_attr($element['id']); ?>" class="qfb-element qfb-element-column" data-id="<?php echo esc_attr($element['id']); ?>" data-type="column">
1653:             <div id="qfb-child-elements-<?php echo esc_attr($element['id']); ?>" class="qfb-child-elements qfb-cf">
1654:                 <?php
1655:                 foreach ($element['elements'] as $child) {
1656:                     echo $this->getElementHtml($child);
1657:                 }
1658:                 ?>
1659:             </div>
1660:             <div class="qfb-column-actions">
1661:                 <span class="qfb-column-action-remove" title="<?php esc_attr_e('Remove column', 'quform'); ?>"><i class="qfb-icon qfb-icon-trash"></i></span>
1662:                 <span class="qfb-column-action-duplicate" title="<?php esc_attr_e('Duplicate column', 'quform'); ?>"><i class="qfb-mdi qfb-mdi-content_copy"></i></span>
1663:                 <span class="qfb-column-action-move" title="<?php esc_attr_e('Move column', 'quform'); ?>"><i class="qfb-icon qfb-icon-arrows"></i></span>
1664:             </div>
1665:         </div>
1666:         <?php
1667:         return ob_get_clean();
1668:     }
1669: 
1670:     /**
1671:      * Get the HTML for a field for the form builder
1672:      *
1673:      * @param   array  $element  The element config
1674:      * @return  string           The HTML
1675:      */
1676:     protected function getFieldHtml(array $element)
1677:     {
1678:         $data = $this->getElements($element['type']);
1679: 
1680:         ob_start(); ?>
1681:         <div id="qfb-element-<?php echo esc_attr($element['id']); ?>" class="qfb-element qfb-element-<?php echo esc_attr($element['type']) . (isset($element['required']) && $element['required'] ? ' qfb-element-required' : ''); ?>" data-id="<?php echo esc_attr($element['id']); ?>" data-type="<?php echo esc_attr($element['type']); ?>">
1682:             <div class="qfb-element-inner qfb-cf">
1683:                 <span class="qfb-element-type-icon"><?php echo $data['icon']; ?></span>
1684:                 <label class="qfb-preview-label<?php echo ( ! Quform::isNonEmptyString($element['label']) ? ' qfb-hidden' : ''); ?>"><span id="qfb-plc-<?php echo esc_attr($element['id']); ?>" class="qfb-preview-label-content"><?php echo Quform::escape($element['label']); ?></span></label>
1685:                 <div class="qfb-element-actions">
1686:                     <span class="qfb-element-action-required" title="<?php esc_attr_e('Toggle required', 'quform'); ?>"><i class="qfb-mdi qfb-mdi-done"></i></span>
1687:                     <span class="qfb-element-action-remove" title="<?php esc_attr_e('Remove', 'quform'); ?>"><i class="qfb-icon qfb-icon-trash"></i></span>
1688:                     <span class="qfb-element-action-duplicate" title="<?php esc_attr_e('Duplicate', 'quform'); ?>"><i class="qfb-mdi qfb-mdi-content_copy"></i></span>
1689:                     <span class="qfb-element-action-settings" title="<?php esc_attr_e('Settings', 'quform'); ?>"><i class="qfb-mdi qfb-mdi-settings"></i></span>
1690:                 </div>
1691:             </div>
1692:         </div>
1693:         <?php
1694:         return ob_get_clean();
1695:     }
1696: 
1697:     /**
1698:      * Get the HTML for a default element with the given type
1699:      *
1700:      * @param   string  $type  The element type
1701:      * @return  string
1702:      */
1703:     protected function getDefaultElementHtml($type)
1704:     {
1705:         $element = $this->getDefaultElementConfig($type);
1706:         $element['id'] = 0;
1707: 
1708:         return $this->getElementHtml($element);
1709:     }
1710: 
1711:     /**
1712:      * Get the HTML for a single page tab nav
1713:      *
1714:      * @param   int     $key
1715:      * @param   array   $elementId
1716:      * @param   string  $label
1717:      * @return  string
1718:      */
1719:     public function getPageTabNavHtml($key = null, $elementId = null, $label = null)
1720:     {
1721:         $output = '<li class="qfb-page-tab-nav k-item' . ($key === 0 ? ' qfb-current-page k-state-active' : '') . '"' . (is_numeric($elementId) ? sprintf(' data-id="%d"', esc_attr($elementId)) : '') . '>';
1722:         $output .= '<span class="qfb-page-tab-nav-label">';
1723: 
1724:         if (Quform::isNonEmptyString($label)) {
1725:             $output .= esc_html($label);
1726:         } else if (is_numeric($key)) {
1727:             $output .= esc_html(sprintf(__('Page %s', 'quform'), $key + 1));
1728:         }
1729: 
1730:         $output .= '</span>';
1731:         $output .= '<span class="qfb-page-actions">';
1732:         $output .= '<span class="qfb-page-action-settings" title="' . esc_attr__('Settings', 'quform') . '"><i class="qfb-mdi qfb-mdi-settings"></i></span>';
1733:         $output .= '<span class="qfb-page-action-duplicate" title="' . esc_attr__('Duplicate', 'quform') . '"><i class="qfb-mdi qfb-mdi-content_copy"></i></span>';
1734:         $output .= '<span class="qfb-page-action-remove" title="' . esc_attr__('Remove', 'quform') . '"><i class="qfb-icon qfb-icon-trash"></i></span>';
1735:         $output .= '</span></li>';
1736: 
1737:         return $output;
1738:     }
1739: 
1740:     /**
1741:      * @return array
1742:      */
1743:     public function getVariables()
1744:     {
1745:         $variables = $this->getPreProcessVariables();
1746: 
1747:         $variables['general']['variables']['{entry_id}'] = __('Entry ID', 'quform');
1748:         $variables['general']['variables']['{form_name}'] = __('Form Name', 'quform');
1749:         $variables['general']['variables']['{all_form_data}'] = __('All Form Data', 'quform');
1750:         $variables['general']['variables']['{default_email_address}'] = __('Default Email Address', 'quform');
1751:         $variables['general']['variables']['{default_email_name}'] = __('Default Email Name', 'quform');
1752:         $variables['general']['variables']['{default_from_email_address}'] = __('Default "From" Email Address', 'quform');
1753:         $variables['general']['variables']['{default_from_email_name}'] = __('Default "From" Email Name', 'quform');
1754:         $variables['general']['variables']['{admin_email}'] = __('Admin Email', 'quform');
1755: 
1756:         return apply_filters('quform_variables', $variables);
1757:     }
1758: 
1759:     /**
1760:      * @return array
1761:      */
1762:     public function getPreProcessVariables()
1763:     {
1764:         return apply_filters('quform_pre_process_variables', array(
1765:             'general' => array(
1766:                 'heading' => __('General', 'quform'),
1767:                 'variables' => array(
1768:                     '{url}' => __('Form URL', 'quform'),
1769:                     '{referring_url}' => __('Referring URL', 'quform'),
1770:                     '{post|ID}' => __('Post ID', 'quform'),
1771:                     '{post|post_title}' => __('Post Title', 'quform'),
1772:                     '{custom_field|my_custom_field}' => __('Custom Field', 'quform'),
1773:                     '{date}' => __('Date', 'quform'),
1774:                     '{time}' => __('Time', 'quform'),
1775:                     '{datetime}' => __('DateTime', 'quform'),
1776:                     '{site_title}' => __('Site Title', 'quform'),
1777:                     '{site_tagline}' => __('Site Description', 'quform'),
1778:                     '{uniqid}' => __('Random Unique ID', 'quform')
1779:                 )
1780:             ),
1781:             'user' => array(
1782:                 'heading' => __('User', 'quform'),
1783:                 'variables' => array(
1784:                     '{ip}' => __('IP Address', 'quform'),
1785:                     '{user_agent}' => __('User Agent', 'quform'),
1786:                     '{user|display_name}' => __('Display Name', 'quform'),
1787:                     '{user|user_email}' => __('Email', 'quform'),
1788:                     '{user|user_login}' => __('Login', 'quform'),
1789:                     '{user_meta|my_user_meta_key}' => __('User Metadata', 'quform')
1790:                 )
1791:             )
1792:         ));
1793:     }
1794: 
1795:     /**
1796:      * The supported reCAPTCHA languages from https://developers.google.com/recaptcha/docs/language
1797:      *
1798:      * @return array
1799:      */
1800:     public function getRecaptchaLanguages()
1801:     {
1802:         return array(
1803:             '' => __('Autodetect', 'quform'),
1804:             'ar' => 'Arabic',
1805:             'af' => 'Afrikaans',
1806:             'am' => 'Amharic',
1807:             'hy' => 'Armenian',
1808:             'az' => 'Azerbaijani',
1809:             'eu' => 'Basque',
1810:             'bn' => 'Bengali',
1811:             'bg' => 'Bulgarian',
1812:             'ca' => 'Catalan',
1813:             'zh-HK' => 'Chinese (Hong Kong)',
1814:             'zh-CN' => 'Chinese (Simplified)',
1815:             'zh-TW' => 'Chinese (Traditional)',
1816:             'hr' => 'Croatian',
1817:             'cs' => 'Czech',
1818:             'da' => 'Danish',
1819:             'nl' => 'Dutch',
1820:             'en-GB' => 'English (UK)',
1821:             'en' => 'English (US)',
1822:             'et' => 'Estonian',
1823:             'fil' => 'Filipino',
1824:             'fi' => 'Finnish',
1825:             'fr' => 'French',
1826:             'fr-CA' => 'French (Canadian)',
1827:             'gl' => 'Galician',
1828:             'ka' => 'Georgian',
1829:             'de' => 'German',
1830:             'de-AT' => 'German (Austria)',
1831:             'de-CH' => 'German (Switzerland)',
1832:             'el' => 'Greek',
1833:             'gu' => 'Gujarati',
1834:             'iw' => 'Hebrew',
1835:             'hi' => 'Hindi',
1836:             'hu' => 'Hungarain',
1837:             'is' => 'Icelandic',
1838:             'id' => 'Indonesian',
1839:             'it' => 'Italian',
1840:             'ja' => 'Japanese',
1841:             'kn' => 'Kannada',
1842:             'ko' => 'Korean',
1843:             'lo' => 'Laothian',
1844:             'lv' => 'Latvian',
1845:             'lt' => 'Lithuanian',
1846:             'ms' => 'Malay',
1847:             'ml' => 'Malayalam',
1848:             'mr' => 'Marathi',
1849:             'mn' => 'Mongolian',
1850:             'no' => 'Norwegian',
1851:             'fa' => 'Persian',
1852:             'pl' => 'Polish',
1853:             'pt' => 'Portuguese',
1854:             'pt-BR' => 'Portuguese (Brazil)',
1855:             'pt-PT' => 'Portuguese (Portugal)',
1856:             'ro' => 'Romanian',
1857:             'ru' => 'Russian',
1858:             'sr' => 'Serbian',
1859:             'si' => 'Sinhalese',
1860:             'sk' => 'Slovak',
1861:             'sl' => 'Slovenian',
1862:             'es' => 'Spanish',
1863:             'es-419' => 'Spanish (Latin America)',
1864:             'sw' => 'Swahili',
1865:             'sv' => 'Swedish',
1866:             'ta' => 'Tamil',
1867:             'te' => 'Telugu',
1868:             'th' => 'Thai',
1869:             'tr' => 'Turkish',
1870:             'uk' => 'Ukrainian',
1871:             'ur' => 'Urdu',
1872:             'vi' => 'Vietnamese',
1873:             'zu' => 'Zulu',
1874:         );
1875:     }
1876: 
1877:     /**
1878:      * The supported hCaptcha languages from https://docs.hcaptcha.com/languages/
1879:      *
1880:      * @return array
1881:      */
1882:     public function getHcaptchaLanguages()
1883:     {
1884:         return array(
1885:             '' => __('Autodetect', 'quform'),
1886:             'af' => 'Afrikaans',
1887:             'sq' => 'Albanian',
1888:             'am' => 'Amharic',
1889:             'ar' => 'Arabic',
1890:             'hy' => 'Armenian',
1891:             'az' => 'Azerbaijani',
1892:             'eu' => 'Basque',
1893:             'be' => 'Belarusian',
1894:             'bn' => 'Bengali',
1895:             'bg' => 'Bulgarian',
1896:             'bs' => 'Bosnian',
1897:             'my' => 'Burmese',
1898:             'ca' => 'Catalan',
1899:             'ceb' => 'Cebuano',
1900:             'zh' => 'Chinese',
1901:             'zh-CN' => 'Chinese Simplified',
1902:             'zh-TW' => 'Chinese Traditional',
1903:             'co' => 'Corsican',
1904:             'hr' => 'Croatian',
1905:             'cs' => 'Czech',
1906:             'da' => 'Danish',
1907:             'nl' => 'Dutch',
1908:             'en' => 'English',
1909:             'eo' => 'Esperanto',
1910:             'et' => 'Estonian',
1911:             'fa' => 'Farsi / Persian',
1912:             'fi' => 'Finnish',
1913:             'fr' => 'French',
1914:             'fy' => 'Frisian',
1915:             'gd' => 'Gaelic',
1916:             'gl' => 'Galacian',
1917:             'ka' => 'Georgian',
1918:             'de' => 'German',
1919:             'el' => 'Greek',
1920:             'gu' => 'Gujurati',
1921:             'ht' => 'Haitian',
1922:             'ha' => 'Hausa',
1923:             'haw' => 'Hawaiian',
1924:             'he' => 'Hebrew',
1925:             'hi' => 'Hindi',
1926:             'hmn' => 'Hmong',
1927:             'hu' => 'Hungarian',
1928:             'is' => 'Icelandic',
1929:             'ig' => 'Igbo',
1930:             'id' => 'Indonesian',
1931:             'ga' => 'Irish',
1932:             'it' => 'Italian',
1933:             'ja' => 'Japanese',
1934:             'jw' => 'Javanese',
1935:             'kn' => 'Kannada',
1936:             'kk' => 'Kazakh',
1937:             'km' => 'Khmer',
1938:             'rw' => 'Kinyarwanda',
1939:             'ky' => 'Kirghiz',
1940:             'ko' => 'Korean',
1941:             'ku' => 'Kurdish',
1942:             'lo' => 'Lao',
1943:             'la' => 'Latin',
1944:             'lv' => 'Latvian',
1945:             'lt' => 'Lithuanian',
1946:             'lb' => 'Luxembourgish',
1947:             'mk' => 'Macedonian',
1948:             'mg' => 'Malagasy',
1949:             'ms' => 'Malay',
1950:             'ml' => 'Malayalam',
1951:             'mt' => 'Maltese',
1952:             'mi' => 'Maori',
1953:             'mr' => 'Marathi',
1954:             'mn' => 'Mongolian',
1955:             'ne' => 'Nepali',
1956:             'no' => 'Norwegian',
1957:             'ny' => 'Nyanja',
1958:             'or' => 'Oriya',
1959:             'pl' => 'Polish',
1960:             'pt' => 'Portuguese',
1961:             'ps' => 'Pashto',
1962:             'pa' => 'Punjabi',
1963:             'ro' => 'Romanian',
1964:             'ru' => 'Russian',
1965:             'sm' => 'Samoan',
1966:             'sn' => 'Shona',
1967:             'sd' => 'Sindhi',
1968:             'si' => 'Singhalese',
1969:             'sr' => 'Serbian',
1970:             'sk' => 'Slovak',
1971:             'sl' => 'Slovenian',
1972:             'so' => 'Somani',
1973:             'st' => 'Southern Sotho',
1974:             'es' => 'Spanish',
1975:             'su' => 'Sundanese',
1976:             'sw' => 'Swahili',
1977:             'sv' => 'Swedish',
1978:             'tl' => 'Tagalog',
1979:             'tg' => 'Tajik',
1980:             'ta' => 'Tamil',
1981:             'tt' => 'Tatar',
1982:             'te' => 'Teluga',
1983:             'th' => 'Thai',
1984:             'tr' => 'Turkish',
1985:             'tk' => 'Turkmen',
1986:             'ug' => 'Uyghur',
1987:             'uk' => 'Ukrainian',
1988:             'ur' => 'Urdu',
1989:             'uz' => 'Uzbek',
1990:             'vi' => 'Vietnamese',
1991:             'cy' => 'Welsh',
1992:             'xh' => 'Xhosa',
1993:             'yi' => 'Yiddish',
1994:             'yo' => 'Yoruba',
1995:             'zu' => 'Zulu',
1996:         );
1997:     }
1998: 
1999:     /**
2000:      * The supported Turnstile languages from https://developers.cloudflare.com/turnstile/get-started/client-side-rendering/#configurations
2001:      *
2002:      * @return array
2003:      */
2004:     public function getTurnstileLanguages()
2005:     {
2006:         return array(
2007:             '' => __('Autodetect', 'quform'),
2008:             'ar-EG' => 'Arabic (Egypt)',
2009:             'zh-CN' => 'Chinese Simplified',
2010:             'zh-TW' => 'Chinese Traditional',
2011:             'nl' => 'Dutch',
2012:             'en' => 'English',
2013:             'fa' => 'Farsi / Persian',
2014:             'fr' => 'French',
2015:             'de' => 'German',
2016:             'id' => 'Indonesian',
2017:             'it' => 'Italian',
2018:             'ja' => 'Japanese',
2019:             'ko' => 'Korean',
2020:             'pl' => 'Polish',
2021:             'pt-BR' => 'Portuguese (Brazil)',
2022:             'ru' => 'Russian',
2023:             'es' => 'Spanish',
2024:             'tr' => 'Turkish',
2025:         );
2026:     }
2027: 
2028:     /**
2029:      * Get the HTML for a blank logic rule
2030:      *
2031:      * @return string
2032:      */
2033:     protected function getLogicRuleHtml()
2034:     {
2035:         $output = '<div class="qfb-logic-rule qfb-box">';
2036:         $output .= '<div class="qfb-logic-rule-columns qfb-cf">';
2037:         $output .= '<div class="qfb-logic-rule-column qfb-logic-rule-column-element"></div>';
2038:         $output .= '<div class="qfb-logic-rule-column qfb-logic-rule-column-operator"></div>';
2039:         $output .= '<div class="qfb-logic-rule-column qfb-logic-rule-column-value"></div>';
2040:         $output .= '</div>';
2041:         $output .= sprintf('<span class="qfb-small-add-button qfb-mdi qfb-mdi-add_circle" title="%s"></span>', esc_attr__('Add new logic rule', 'quform'));
2042:         $output .= sprintf('<span class="qfb-small-remove-button qfb-icon qfb-icon-trash" title="%s"></span>', esc_attr__('Remove logic rule', 'quform'));
2043:         $output .= '</div>';
2044: 
2045:         return $output;
2046:     }
2047: 
2048:     /**
2049:      * Get the element types that can be used as a source for conditional logic
2050:      *
2051:      * @return array
2052:      */
2053:     protected function getLogicSourceTypes()
2054:     {
2055:         return apply_filters('quform_logic_source_types', array(
2056:             'text', 'textarea', 'email', 'select', 'radio', 'checkbox', 'multiselect', 'file', 'date', 'time', 'hidden', 'password'
2057:         ));
2058:     }
2059: 
2060:     /**
2061:      * Get the element types than can be used as a source for attachments
2062:      *
2063:      * @return array
2064:      */
2065:     protected function getAttachmentSourceTypes()
2066:     {
2067:         return apply_filters('quform_attachment_source_types', array(
2068:             'file'
2069:         ));
2070:     }
2071: 
2072:     /**
2073:      * Handle the request to save the form via Ajax
2074:      */
2075:     public function save()
2076:     {
2077:         $this->validateSaveRequest();
2078: 
2079:         $config = json_decode(stripslashes($_POST['form']), true);
2080: 
2081:         if ( ! is_array($config)) {
2082:             wp_send_json(array(
2083:                 'type'    => 'error',
2084:                 'message' => __('Malformed form configuration', 'quform')
2085:             ));
2086:         }
2087: 
2088:         $config = $this->sanitizeForm($config);
2089: 
2090:         $this->validateForm($config);
2091: 
2092:         $config = $this->repository->save($config);
2093: 
2094:         $this->scriptLoader->handleSaveForm($config);
2095: 
2096:         wp_send_json(array(
2097:             'type' => 'success'
2098:         ));
2099:     }
2100: 
2101:     /**
2102:      * Validate the request to save the form
2103:      */
2104:     protected function validateSaveRequest()
2105:     {
2106:         if ( ! Quform::isPostRequest() || ! isset($_POST['form'])) {
2107:             wp_send_json(array(
2108:                 'type'    => 'error',
2109:                 'message' => __('Bad request', 'quform')
2110:             ));
2111:         }
2112: 
2113:         if ( ! current_user_can('quform_edit_forms')) {
2114:             wp_send_json(array(
2115:                 'type'    => 'error',
2116:                 'message' => __('Insufficient permissions', 'quform')
2117:             ));
2118:         }
2119: 
2120:         if ( ! check_ajax_referer('quform_save_form', false, false)) {
2121:             wp_send_json(array(
2122:                 'type'    => 'error',
2123:                 'message' => __('Nonce check failed', 'quform')
2124:             ));
2125:         }
2126:     }
2127: 
2128:     /**
2129:      * Sanitize the given form config and return it
2130:      *
2131:      * @param   array  $config
2132:      * @return  array
2133:      */
2134:     public function sanitizeForm(array $config)
2135:     {
2136:         // General - Form
2137:         $config['name'] = isset($config['name']) && is_string($config['name']) ? sanitize_text_field($config['name']) : '';
2138:         $config['title'] = isset($config['title']) && is_string($config['title']) ? wp_kses_post($config['title']) : '';
2139:         $config['titleTag'] = isset($config['titleTag']) && is_string($config['titleTag']) ? sanitize_text_field($config['titleTag']) : 'h2';
2140:         $config['description'] = isset($config['description']) && is_string($config['description']) ? wp_kses_post($config['description']) : '';
2141:         $config['active'] = isset($config['active']) && is_bool($config['active']) ? $config['active'] : true;
2142:         $config['inactiveMessage'] = isset($config['inactiveMessage']) && is_string($config['inactiveMessage']) ? wp_kses_post($config['inactiveMessage']) : '';
2143:         $config['trashed'] = isset($config['trashed']) && is_bool($config['trashed']) ? $config['trashed'] : false;
2144:         $config['ajax'] = isset($config['ajax']) && is_bool($config['ajax']) ? $config['ajax'] : true;
2145:         $config['saveEntry'] = isset($config['saveEntry']) && is_bool($config['saveEntry']) ? $config['saveEntry'] : true;
2146:         $config['honeypot'] = isset($config['honeypot']) && is_bool($config['honeypot']) ? $config['honeypot'] : true;
2147:         $config['logicAnimation'] = isset($config['logicAnimation']) && is_bool($config['logicAnimation']) ? $config['logicAnimation'] : true;
2148: 
2149:         // General - Limits
2150:         $config['oneEntryPerUser'] = isset($config['oneEntryPerUser']) && is_bool($config['oneEntryPerUser']) ? $config['oneEntryPerUser'] : false;
2151:         $config['oneEntryPer'] = isset($config['oneEntryPer']) && is_string($config['oneEntryPer']) ? sanitize_text_field($config['oneEntryPer']) : 'logged-in-user';
2152:         $config['limitEntries'] = isset($config['limitEntries']) && is_bool($config['limitEntries']) ? $config['limitEntries'] : false;
2153:         $config['entryLimit'] = isset($config['entryLimit']) && is_numeric($config['entryLimit']) && $config['entryLimit'] > 0 ? (string) (int) $config['entryLimit'] : '';
2154:         $config['entryLimitReachedMessage'] = isset($config['entryLimitReachedMessage']) && is_string($config['entryLimitReachedMessage']) ? wp_kses_post($config['entryLimitReachedMessage']) : '';
2155: 
2156:         // General - Scheduling
2157:         $config['enableSchedule'] = isset($config['enableSchedule']) && is_bool($config['enableSchedule']) ? $config['enableSchedule'] : false;
2158:         $config['scheduleStart'] = isset($config['scheduleStart']) && is_string($config['scheduleStart']) ? $this->sanitizeDateTime($config['scheduleStart']) : '';
2159:         $config['scheduleStartMessage'] = isset($config['scheduleStartMessage']) && is_string($config['scheduleStartMessage']) ? wp_kses_post($config['scheduleStartMessage']) : '';
2160:         $config['scheduleEnd'] = isset($config['scheduleEnd']) && is_string($config['scheduleEnd']) ? $this->sanitizeDateTime($config['scheduleEnd']) : '';
2161:         $config['scheduleEndMessage'] = isset($config['scheduleEndMessage']) && is_string($config['scheduleEndMessage']) ? wp_kses_post($config['scheduleEndMessage']) : '';
2162: 
2163:         // Style - Global
2164:         $config['theme'] = isset($config['theme']) && is_string($config['theme']) ? sanitize_text_field($config['theme']) : '';
2165:         $config['themePrimaryColor'] = isset($config['themePrimaryColor']) && is_string($config['themePrimaryColor']) ? sanitize_text_field($config['themePrimaryColor']) : '';
2166:         $config['themeSecondaryColor'] = isset($config['themeSecondaryColor']) && is_string($config['themeSecondaryColor']) ? sanitize_text_field($config['themeSecondaryColor']) : '';
2167:         $config['themePrimaryForegroundColor'] = isset($config['themePrimaryForegroundColor']) && is_string($config['themePrimaryForegroundColor']) ? sanitize_text_field($config['themePrimaryForegroundColor']) : '';
2168:         $config['themeSecondaryForegroundColor'] = isset($config['themeSecondaryForegroundColor']) && is_string($config['themeSecondaryForegroundColor']) ? sanitize_text_field($config['themeSecondaryForegroundColor']) : '';
2169:         $config['responsiveElements'] = isset($config['responsiveElements']) && is_string($config['responsiveElements']) ? sanitize_text_field($config['responsiveElements']) : 'phone-landscape';
2170:         $config['responsiveElementsCustom'] = isset($config['responsiveElementsCustom']) && is_string($config['responsiveElementsCustom']) ? sanitize_text_field($config['responsiveElementsCustom']) : '';
2171:         $config['responsiveColumns'] = isset($config['responsiveColumns']) && is_string($config['responsiveColumns']) ? sanitize_text_field($config['responsiveColumns']) : 'phone-landscape';
2172:         $config['responsiveColumnsCustom'] = isset($config['responsiveColumnsCustom']) && is_string($config['responsiveColumnsCustom']) ? sanitize_text_field($config['responsiveColumnsCustom']) : '';
2173:         $config['verticalElementSpacing'] = isset($config['verticalElementSpacing']) && is_string($config['verticalElementSpacing']) ? sanitize_text_field($config['verticalElementSpacing']) : '';
2174:         $config['width'] = isset($config['width']) && is_string($config['width']) ? sanitize_text_field($config['width']) : '';
2175:         $config['position'] = isset($config['position']) && is_string($config['position']) ? sanitize_text_field($config['position']) : '';
2176:         $config['previewColor'] = isset($config['previewColor']) && is_string($config['previewColor']) ? sanitize_text_field($config['previewColor']) : '';
2177:         $config['styles'] = isset($config['styles']) && is_array($config['styles']) ? $this->sanitizeGlobalStyles($config['styles']) : array();
2178: 
2179:         // Style - Labels
2180:         $config['labelTextColor'] = isset($config['labelTextColor']) && is_string($config['labelTextColor']) ? sanitize_text_field($config['labelTextColor']) : '';
2181:         $config['labelPosition'] = isset($config['labelPosition']) && is_string($config['labelPosition']) ? sanitize_text_field($config['labelPosition']) : '';
2182:         $config['labelWidth'] = isset($config['labelWidth']) && is_string($config['labelWidth']) ? sanitize_text_field($config['labelWidth']) : '150px';
2183:         $config['requiredText'] = isset($config['requiredText']) && is_string($config['requiredText']) ? sanitize_text_field($config['requiredText']) : '*';
2184:         $config['requiredTextColor'] = isset($config['requiredTextColor']) && is_string($config['requiredTextColor']) ? sanitize_text_field($config['requiredTextColor']) : '';
2185: 
2186:         // Style - Fields
2187:         $config['fieldSize'] = isset($config['fieldSize']) && is_string($config['fieldSize']) ? sanitize_text_field($config['fieldSize']) : '';
2188:         $config['fieldWidth'] = isset($config['fieldWidth']) && is_string($config['fieldWidth']) ? sanitize_text_field($config['fieldWidth']) : '';
2189:         $config['fieldWidthCustom'] = isset($config['fieldWidthCustom']) && is_string($config['fieldWidthCustom']) ? sanitize_text_field($config['fieldWidthCustom']) : '';
2190:         $config['fieldBackgroundColor'] = isset($config['fieldBackgroundColor']) && is_string($config['fieldBackgroundColor']) ? sanitize_text_field($config['fieldBackgroundColor']) : '';
2191:         $config['fieldBackgroundColorHover'] = isset($config['fieldBackgroundColorHover']) && is_string($config['fieldBackgroundColorHover']) ? sanitize_text_field($config['fieldBackgroundColorHover']) : '';
2192:         $config['fieldBackgroundColorFocus'] = isset($config['fieldBackgroundColorFocus']) && is_string($config['fieldBackgroundColorFocus']) ? sanitize_text_field($config['fieldBackgroundColorFocus']) : '';
2193:         $config['fieldBorderColor'] = isset($config['fieldBorderColor']) && is_string($config['fieldBorderColor']) ? sanitize_text_field($config['fieldBorderColor']) : '';
2194:         $config['fieldBorderColorHover'] = isset($config['fieldBorderColorHover']) && is_string($config['fieldBorderColorHover']) ? sanitize_text_field($config['fieldBorderColorHover']) : '';
2195:         $config['fieldBorderColorFocus'] = isset($config['fieldBorderColorFocus']) && is_string($config['fieldBorderColorFocus']) ? sanitize_text_field($config['fieldBorderColorFocus']) : '';
2196:         $config['fieldTextColor'] = isset($config['fieldTextColor']) && is_string($config['fieldTextColor']) ? sanitize_text_field($config['fieldTextColor']) : '';
2197:         $config['fieldTextColorHover'] = isset($config['fieldTextColorHover']) && is_string($config['fieldTextColorHover']) ? sanitize_text_field($config['fieldTextColorHover']) : '';
2198:         $config['fieldTextColorFocus'] = isset($config['fieldTextColorFocus']) && is_string($config['fieldTextColorFocus']) ? sanitize_text_field($config['fieldTextColorFocus']) : '';
2199:         $config['fieldPlaceholderStyles'] = isset($config['fieldPlaceholderStyles']) && is_string($config['fieldPlaceholderStyles']) ? wp_strip_all_tags($config['fieldPlaceholderStyles']) : '';
2200: 
2201:         // Style - Buttons
2202:         $config['buttonStyle'] = isset($config['buttonStyle']) && is_string($config['buttonStyle']) ? sanitize_text_field($config['buttonStyle']) : 'theme';
2203:         $config['buttonSize'] = isset($config['buttonSize']) && is_string($config['buttonSize']) ? sanitize_text_field($config['buttonSize']) : '';
2204:         $config['buttonWidth'] = isset($config['buttonWidth']) && is_string($config['buttonWidth']) ? sanitize_text_field($config['buttonWidth']) : '';
2205:         $config['buttonWidthCustom'] = isset($config['buttonWidthCustom']) && is_string($config['buttonWidthCustom']) ? sanitize_text_field($config['buttonWidthCustom']) : '';
2206:         $config['buttonAnimation'] = isset($config['buttonAnimation']) && is_string($config['buttonAnimation']) ? sanitize_text_field($config['buttonAnimation']) : '';
2207:         $config['buttonBackgroundColor'] = isset($config['buttonBackgroundColor']) && is_string($config['buttonBackgroundColor']) ? sanitize_text_field($config['buttonBackgroundColor']) : '';
2208:         $config['buttonBackgroundColorHover'] = isset($config['buttonBackgroundColorHover']) && is_string($config['buttonBackgroundColorHover']) ? sanitize_text_field($config['buttonBackgroundColorHover']) : '';
2209:         $config['buttonBackgroundColorActive'] = isset($config['buttonBackgroundColorActive']) && is_string($config['buttonBackgroundColorActive']) ? sanitize_text_field($config['buttonBackgroundColorActive']) : '';
2210:         $config['buttonBorderColor'] = isset($config['buttonBorderColor']) && is_string($config['buttonBorderColor']) ? sanitize_text_field($config['buttonBorderColor']) : '';
2211:         $config['buttonBorderColorHover'] = isset($config['buttonBorderColorHover']) && is_string($config['buttonBorderColorHover']) ? sanitize_text_field($config['buttonBorderColorHover']) : '';
2212:         $config['buttonBorderColorActive'] = isset($config['buttonBorderColorActive']) && is_string($config['buttonBorderColorActive']) ? sanitize_text_field($config['buttonBorderColorActive']) : '';
2213:         $config['buttonTextColor'] = isset($config['buttonTextColor']) && is_string($config['buttonTextColor']) ? sanitize_text_field($config['buttonTextColor']) : '';
2214:         $config['buttonTextColorHover'] = isset($config['buttonTextColorHover']) && is_string($config['buttonTextColorHover']) ? sanitize_text_field($config['buttonTextColorHover']) : '';
2215:         $config['buttonTextColorActive'] = isset($config['buttonTextColorActive']) && is_string($config['buttonTextColorActive']) ? sanitize_text_field($config['buttonTextColorActive']) : '';
2216:         $config['buttonIconColor'] = isset($config['buttonIconColor']) && is_string($config['buttonIconColor']) ? sanitize_text_field($config['buttonIconColor']) : '';
2217:         $config['buttonIconColorHover'] = isset($config['buttonIconColorHover']) && is_string($config['buttonIconColorHover']) ? sanitize_text_field($config['buttonIconColorHover']) : '';
2218:         $config['buttonIconColorActive'] = isset($config['buttonIconColorActive']) && is_string($config['buttonIconColorActive']) ? sanitize_text_field($config['buttonIconColorActive']) : '';
2219:         $config['submitType'] = isset($config['submitType']) && is_string($config['submitType']) ? sanitize_text_field($config['submitType']) : 'default';
2220:         $config['submitText'] = isset($config['submitText']) && is_string($config['submitText']) ? sanitize_text_field($config['submitText']) : '';
2221:         $config['submitIcon'] = isset($config['submitIcon']) && is_string($config['submitIcon']) ? sanitize_text_field($config['submitIcon']) : '';
2222:         $config['submitIconPosition'] = isset($config['submitIconPosition']) && is_string($config['submitIconPosition']) ? sanitize_text_field($config['submitIconPosition']) : 'right';
2223:         $config['submitImage'] = isset($config['submitImage']) && is_string($config['submitImage']) ? esc_url_raw($config['submitImage']) : '';
2224:         $config['submitHtml'] = isset($config['submitHtml']) && is_string($config['submitHtml']) ? wp_kses_post($config['submitHtml']) : '';
2225:         $config['nextType'] = isset($config['nextType']) && is_string($config['nextType']) ? sanitize_text_field($config['nextType']) : 'default';
2226:         $config['nextText'] = isset($config['nextText']) && is_string($config['nextText']) ? sanitize_text_field($config['nextText']) : '';
2227:         $config['nextIcon'] = isset($config['nextIcon']) && is_string($config['nextIcon']) ? sanitize_text_field($config['nextIcon']) : '';
2228:         $config['nextIconPosition'] = isset($config['nextIconPosition']) && is_string($config['nextIconPosition']) ? sanitize_text_field($config['nextIconPosition']) : 'right';
2229:         $config['nextImage'] = isset($config['nextImage']) && is_string($config['nextImage']) ? esc_url_raw($config['nextImage']) : '';
2230:         $config['nextHtml'] = isset($config['nextHtml']) && is_string($config['nextHtml']) ? wp_kses_post($config['nextHtml']) : '';
2231:         $config['backType'] = isset($config['backType']) && is_string($config['backType']) ? sanitize_text_field($config['backType']) : 'default';
2232:         $config['backText'] = isset($config['backText']) && is_string($config['backText']) ? sanitize_text_field($config['backText']) : '';
2233:         $config['backIcon'] = isset($config['backIcon']) && is_string($config['backIcon']) ? sanitize_text_field($config['backIcon']) : '';
2234:         $config['backIconPosition'] = isset($config['backIconPosition']) && is_string($config['backIconPosition']) ? sanitize_text_field($config['backIconPosition']) : 'left';
2235:         $config['backImage'] = isset($config['backImage']) && is_string($config['backImage']) ? esc_url_raw($config['backImage']) : '';
2236:         $config['backHtml'] = isset($config['backHtml']) && is_string($config['backHtml']) ? wp_kses_post($config['backHtml']) : '';
2237:         $config['backLocation'] = isset($config['backLocation']) && is_string($config['backLocation']) ? sanitize_text_field($config['backLocation']) : '';
2238:         $config['optionsStyle'] = isset($config['optionsStyle']) && is_string($config['optionsStyle']) ? sanitize_text_field($config['optionsStyle']) : '';
2239:         $config['optionsButtonStyle'] = isset($config['optionsButtonStyle']) && is_string($config['optionsButtonStyle']) ? sanitize_text_field($config['optionsButtonStyle']) : '';
2240:         $config['optionsButtonSize'] = isset($config['optionsButtonSize']) && is_string($config['optionsButtonSize']) ? sanitize_text_field($config['optionsButtonSize']) : '';
2241:         $config['optionsButtonWidth'] = isset($config['optionsButtonWidth']) && is_string($config['optionsButtonWidth']) ? sanitize_text_field($config['optionsButtonWidth']) : '';
2242:         $config['optionsButtonWidthCustom'] = isset($config['optionsButtonWidthCustom']) && is_string($config['optionsButtonWidthCustom']) ? sanitize_text_field($config['optionsButtonWidthCustom']) : '';
2243:         $config['optionsButtonIconPosition'] = isset($config['optionsButtonIconPosition']) && is_string($config['optionsButtonIconPosition']) ? sanitize_text_field($config['optionsButtonIconPosition']) : '';
2244: 
2245:         // Style - Pages
2246:         $config['pageProgressType'] = isset($config['pageProgressType']) && is_string($config['pageProgressType']) ? sanitize_text_field($config['pageProgressType']) : 'numbers';
2247: 
2248:         // Style - Loading
2249:         $config['loadingType'] = isset($config['loadingType']) && is_string($config['loadingType']) ? sanitize_text_field($config['loadingType']) : 'spinner-1';
2250:         $config['loadingCustom'] = isset($config['loadingCustom']) && is_string($config['loadingCustom']) ? wp_kses_post($config['loadingCustom']) : '';
2251:         $config['loadingPosition'] = isset($config['loadingPosition']) && is_string($config['loadingPosition']) ? sanitize_text_field($config['loadingPosition']) : 'left';
2252:         $config['loadingColor'] = isset($config['loadingColor']) && is_string($config['loadingColor']) ? sanitize_text_field($config['loadingColor']) : '';
2253:         $config['loadingOverlay'] = isset($config['loadingOverlay']) && is_bool($config['loadingOverlay']) ? $config['loadingOverlay'] : false;
2254:         $config['loadingOverlayColor'] = isset($config['loadingOverlayColor']) && is_string($config['loadingOverlayColor']) ? sanitize_text_field($config['loadingOverlayColor']) : '';
2255: 
2256:         // Style - Tooltips
2257:         $config['tooltipsEnabled'] = isset($config['tooltipsEnabled']) && is_bool($config['tooltipsEnabled']) ? $config['tooltipsEnabled'] : true;
2258:         $config['tooltipType'] = isset($config['tooltipType']) && is_string($config['tooltipType']) ? sanitize_text_field($config['tooltipType']) : 'icon';
2259:         $config['tooltipEvent'] = isset($config['tooltipEvent']) && is_string($config['tooltipEvent']) ? sanitize_text_field($config['tooltipEvent']) : 'hover';
2260:         $config['tooltipIcon'] = isset($config['tooltipIcon']) && is_string($config['tooltipIcon']) ? sanitize_text_field($config['tooltipIcon']) : 'qicon-question-circle';
2261:         $config['tooltipStyle'] = isset($config['tooltipStyle']) && is_string($config['tooltipStyle']) ? sanitize_text_field($config['tooltipStyle']) : 'qtip-quform-dark';
2262:         $config['tooltipCustom'] = isset($config['tooltipCustom']) && is_string($config['tooltipCustom']) ? Quform::sanitizeClass($config['tooltipCustom']) : '';
2263:         $config['tooltipMy'] = isset($config['tooltipMy']) && is_string($config['tooltipMy']) ? sanitize_text_field($config['tooltipMy']) : 'left center';
2264:         $config['tooltipAt'] = isset($config['tooltipAt']) && is_string($config['tooltipAt']) ? sanitize_text_field($config['tooltipAt']) : 'right center';
2265:         $config['tooltipShadow'] = isset($config['tooltipShadow']) && is_bool($config['tooltipShadow']) ? $config['tooltipShadow'] : true;
2266:         $config['tooltipRounded'] = isset($config['tooltipRounded']) && is_bool($config['tooltipRounded']) ? $config['tooltipRounded'] : false;
2267:         $config['tooltipClasses'] = isset($config['tooltipClasses']) && is_string($config['tooltipClasses']) ? Quform::sanitizeClass($config['tooltipClasses']) : 'qtip-quform-dark qtip-shadow';
2268: 
2269:         // Notifications
2270:         $config['notifications'] = isset($config['notifications']) && is_array($config['notifications']) ? $this->sanitizeNotifications($config['notifications']) : array();
2271:         $config['nextNotificationId'] = isset($config['nextNotificationId']) && is_numeric($config['nextNotificationId']) ? (int) $config['nextNotificationId'] : 1;
2272: 
2273:         // Confirmations
2274:         $config['confirmations'] = isset($config['confirmations']) && is_array($config['confirmations']) ? $this->sanitizeConfirmations($config['confirmations']) : array();
2275:         $config['nextConfirmationId'] = isset($config['nextConfirmationId']) && is_numeric($config['nextConfirmationId']) ? (int) $config['nextConfirmationId'] : 1;
2276: 
2277:         // Errors
2278:         $config['errorsPosition'] = isset($config['errorsPosition']) && is_string($config['errorsPosition']) ? sanitize_text_field($config['errorsPosition']) : '';
2279:         $config['errorsIcon'] = isset($config['errorsIcon']) && is_string($config['errorsIcon']) ? sanitize_text_field($config['errorsIcon']) : '';
2280:         $config['errorEnabled'] = isset($config['errorEnabled']) && is_bool($config['errorEnabled']) ? $config['errorEnabled'] : false;
2281:         $config['errorTitle'] = isset($config['errorTitle']) && is_string($config['errorTitle']) ? wp_kses_post($config['errorTitle']) : '';
2282:         $config['errorContent'] = isset($config['errorContent']) && is_string($config['errorContent']) ? wp_kses_post($config['errorContent']) : '';
2283: 
2284:         // Language
2285:         $config['locale'] = isset($config['locale']) && is_string($config['locale']) ? sanitize_text_field($config['locale']) : '';
2286:         $config['rtl'] = isset($config['rtl']) && is_string($config['rtl']) ? sanitize_text_field($config['rtl']) : 'global';
2287:         $config['messageRequired'] = isset($config['messageRequired']) && is_string($config['messageRequired']) ? wp_kses_post($config['messageRequired']) : '';
2288:         $config['pageProgressNumbersText'] = isset($config['pageProgressNumbersText']) && is_string($config['pageProgressNumbersText']) ? sanitize_text_field($config['pageProgressNumbersText']) : '';
2289:         $config['onlyOneSubmissionAllowed'] = isset($config['onlyOneSubmissionAllowed']) && is_string($config['onlyOneSubmissionAllowed']) ? sanitize_text_field($config['onlyOneSubmissionAllowed']) : '';
2290:         $config['thisFormIsCurrentlyClosed'] = isset($config['thisFormIsCurrentlyClosed']) && is_string($config['thisFormIsCurrentlyClosed']) ? sanitize_text_field($config['thisFormIsCurrentlyClosed']) : '';
2291:         $config['formIsNotYetOpenForSubmissions'] = isset($config['formIsNotYetOpenForSubmissions']) && is_string($config['formIsNotYetOpenForSubmissions']) ? sanitize_text_field($config['formIsNotYetOpenForSubmissions']) : '';
2292:         $config['formIsNoLongerOpenForSubmissions'] = isset($config['formIsNoLongerOpenForSubmissions']) && is_string($config['formIsNoLongerOpenForSubmissions']) ? sanitize_text_field($config['formIsNoLongerOpenForSubmissions']) : '';
2293: 
2294:         // Database
2295:         $config['databaseEnabled'] = isset($config['databaseEnabled']) && is_bool($config['databaseEnabled']) ? $config['databaseEnabled'] : false;
2296:         $config['databaseWordpress'] = isset($config['databaseWordpress']) && is_bool($config['databaseWordpress']) ? $config['databaseWordpress'] : true;
2297:         $config['databaseHost'] = isset($config['databaseHost']) && is_string($config['databaseHost']) ? wp_strip_all_tags($config['databaseHost']) : '';
2298:         $config['databaseUsername'] = isset($config['databaseUsername']) && is_string($config['databaseUsername']) ? wp_kses_no_null($config['databaseUsername'], array('slash_zero' => 'keep')) : '';
2299:         $config['databasePassword'] = isset($config['databasePassword']) && is_string($config['databasePassword']) ? wp_kses_no_null($config['databasePassword'], array('slash_zero' => 'keep')) : '';
2300:         $config['databaseDatabase'] = isset($config['databaseDatabase']) && is_string($config['databaseDatabase']) ? sanitize_text_field($config['databaseDatabase']) : '';
2301:         $config['databaseTable'] = isset($config['databaseTable']) && is_string($config['databaseTable']) ? sanitize_text_field($config['databaseTable']) : '';
2302:         $config['databaseColumns'] = isset($config['databaseColumns']) && is_array($config['databaseColumns']) ? $this->sanitizeDatabaseColumns($config['databaseColumns']) : array();
2303: 
2304:         // Feature cache & locales
2305:         $config['hasDatepicker'] = isset($config['hasDatepicker']) && is_bool($config['hasDatepicker']) ? $config['hasDatepicker'] : false;
2306:         $config['hasTimepicker'] = isset($config['hasTimepicker']) && is_bool($config['hasTimepicker']) ? $config['hasTimepicker'] : false;
2307:         $config['hasEnhancedUploader'] = isset($config['hasEnhancedUploader']) && is_bool($config['hasEnhancedUploader']) ? $config['hasEnhancedUploader'] : false;
2308:         $config['hasEnhancedSelect'] = isset($config['hasEnhancedSelect']) && is_bool($config['hasEnhancedSelect']) ? $config['hasEnhancedSelect'] : false;
2309:         $config['locales'] = isset($config['locales']) && is_array($config['locales']) ? array_map('sanitize_text_field', $config['locales']) : array();
2310: 
2311:         // Elements
2312:         if ( ! isset($config['elements']) || ! is_array($config['elements'])) {
2313:             // Every form needs at least one page
2314:             $page = $this->getDefaultElementConfig('page');
2315:             $page['id'] = 1;
2316:             $page['parentId'] = 0;
2317:             $page['position'] = 0;
2318: 
2319:             $config['elements'] = array($page);
2320:             $config['nextElementId'] = 2;
2321:         }
2322: 
2323:         foreach ($config['elements'] as $key => $page) {
2324:             if (is_array($page)) {
2325:                 $config['elements'][$key] = $this->sanitizeContainer($page);
2326:             }
2327:         }
2328: 
2329:         $config['nextElementId'] = isset($config['nextElementId']) && is_numeric($config['nextElementId']) ? (int) $config['nextElementId'] : 1;
2330: 
2331:         // Misc
2332:         $config['entriesTableColumns'] = isset($config['entriesTableColumns']) && is_array($config['entriesTableColumns']) ? array_map('sanitize_key', $config['entriesTableColumns']) : array();
2333:         $config['environment'] = isset($config['environment']) && is_string($config['environment']) ? sanitize_text_field($config['environment']) : 'frontend';
2334: 
2335:         return $config;
2336:     }
2337: 
2338:     /**
2339:      * Sanitize the given datetime value and converts it to UTC
2340:      *
2341:      * @param   string  $datetime
2342:      * @return  string
2343:      */
2344:     protected function sanitizeDateTime($datetime, $format = 'Y-m-d H:i:s')
2345:     {
2346:         if (Quform::isNonEmptyString($datetime)) {
2347:             $date = DateTime::createFromFormat($format, $datetime, Quform::getTimezone());
2348: 
2349:             if ($date instanceof DateTime && $date->format($format) == $datetime) {
2350:                 return $date->setTimezone(new DateTimeZone('UTC'))->format($format);
2351:             }
2352:         }
2353: 
2354:         return '';
2355:     }
2356: 
2357:     /**
2358:      * Converts a datetime string to the WP timezone
2359:      *
2360:      * @param   string  $datetime
2361:      * @return  string
2362:      */
2363:     protected function convertDateTimeToWpTimezone($datetime, $format = 'Y-m-d H:i:s')
2364:     {
2365:         if (Quform::isNonEmptyString($datetime)) {
2366:             $date = DateTime::createFromFormat($format, $datetime, new DateTimeZone('UTC'));
2367: 
2368:             if ($date instanceof DateTime && $date->format($format) == $datetime) {
2369:                 return $date->setTimezone(Quform::getTimezone())->format($format);
2370:             }
2371:         }
2372: 
2373:         return '';
2374:     }
2375: 
2376:     /**
2377:      * Sanitize the given form config and return it
2378:      *
2379:      * @deprecated  2.4.0
2380:      * @param       array  $config
2381:      * @return      array
2382:      */
2383:     public function sanitiseForm(array $config)
2384:     {
2385:         _deprecated_function(__METHOD__, '2.4.0', 'Quform_Builder::sanitizeForm()');
2386: 
2387:         return $this->sanitizeForm($config);
2388:     }
2389: 
2390:     /**
2391:      * Sanitize the settings for the given global styles
2392:      *
2393:      * @param   array   $styles
2394:      * @return  array
2395:      */
2396:     protected function sanitizeGlobalStyles(array $styles)
2397:     {
2398:         $allStyles = $this->getGlobalStyles();
2399:         $sanitizedStyles = array();
2400: 
2401:         foreach ($styles as $style) {
2402:             if ( ! isset($style['type']) || ! is_string($style['type']) || ! array_key_exists($style['type'], $allStyles)) {
2403:                 continue;
2404:             }
2405: 
2406:             $style['css'] = isset($style['css']) && is_string($style['css']) ? wp_strip_all_tags($style['css']) : '';
2407: 
2408:             $sanitizedStyles[] = $style;
2409:         }
2410: 
2411:         return $sanitizedStyles;
2412:     }
2413: 
2414:     /**
2415:      * Sanitize the given array of notifications
2416:      *
2417:      * @param   array  $notifications
2418:      * @return  array
2419:      */
2420:     protected function sanitizeNotifications(array $notifications)
2421:     {
2422:         foreach ($notifications as $key => $notification) {
2423:             $notifications[$key]['name'] = isset($notification['name']) && is_string($notification['name']) ? sanitize_text_field($notification['name']) : '';
2424:             $notifications[$key]['enabled'] = isset($notification['enabled']) && is_bool($notification['enabled']) ? $notification['enabled'] : true;
2425:             $notifications[$key]['subject'] = isset($notification['subject']) && is_string($notification['subject']) ? wp_kses_no_null($notification['subject'], array('slash_zero' => 'keep')) : '';
2426:             $notifications[$key]['format'] = isset($notification['format']) && is_string($notification['format']) ? sanitize_text_field($notification['format']) : '';
2427:             $notifications[$key]['html'] = isset($notification['html']) && is_string($notification['html']) ? $notification['html'] : ''; // unfiltered on purpose
2428:             $notifications[$key]['autoFormat'] = isset($notification['autoFormat']) && is_bool($notification['autoFormat']) ? $notification['autoFormat'] : true;
2429:             $notifications[$key]['padding'] = isset($notification['padding']) && is_string($notification['padding']) ? sanitize_text_field($notification['padding']) : '20';
2430:             $notifications[$key]['text'] = isset($notification['text']) && is_string($notification['text']) ? $notification['text'] : ''; // unfiltered on purpose
2431:             $notifications[$key]['recipients'] = isset($notification['recipients']) && is_array($notification['recipients']) ? $this->sanitizeNotificationRecipients($notification['recipients']) : array();
2432:             $notifications[$key]['conditional'] = isset($notification['conditional']) && is_bool($notification['conditional']) ? $notification['conditional'] : false;
2433:             $notifications[$key]['conditionals'] = isset($notification['conditionals']) && is_array($notification['conditionals']) ? $this->sanitizeNotificationConditionals($notification['conditionals']) : array();
2434:             $notifications[$key]['from'] = isset($notification['from']) && is_array($notification['from']) ? $this->sanitizeNotificationFrom($notification['from']) : array('address' => '', 'name' => '');
2435:             $notifications[$key]['logicEnabled'] = isset($notification['logicEnabled']) && is_bool($notification['logicEnabled']) ? $notification['logicEnabled'] : false;
2436:             $notifications[$key]['logicAction'] = isset($notification['logicAction']) && is_bool($notification['logicAction']) ? $notification['logicAction'] : true;
2437:             $notifications[$key]['logicMatch'] = isset($notification['logicMatch']) && is_string($notification['logicMatch']) ? sanitize_text_field($notification['logicMatch']) : 'all';
2438:             $notifications[$key]['logicRules'] = isset($notification['logicRules']) && is_array($notification['logicRules']) ? $this->sanitizeLogicRules($notification['logicRules']) : array();
2439:             $notifications[$key]['attachments'] = isset($notification['attachments']) && is_array($notification['attachments']) ? $this->sanitizeNotificationAttachments($notification['attachments']) : array();
2440:         }
2441: 
2442:         return $notifications;
2443:     }
2444: 
2445:     /**
2446:      * Sanitize the given array of notification recipients
2447:      *
2448:      * @param   array  $recipients
2449:      * @return  array
2450:      */
2451:     protected function sanitizeNotificationRecipients(array $recipients)
2452:     {
2453:         foreach ($recipients as $key => $recipient) {
2454:             $recipients[$key]['type'] = isset($recipient['type']) && is_string($recipient['type']) ? sanitize_text_field($recipient['type']) : '';
2455:             $recipients[$key]['address'] = isset($recipient['address']) && is_string($recipient['address']) ? sanitize_text_field($recipient['address']) : '';
2456:             $recipients[$key]['name'] = isset($recipient['name']) && is_string($recipient['name']) ? sanitize_text_field($recipient['name']) : '';
2457:         }
2458: 
2459:         return $recipients;
2460:     }
2461: 
2462:     /**
2463:      * Sanitize the given array of notification conditionals
2464:      *
2465:      * @param   array  $conditionals
2466:      * @return  array
2467:      */
2468:     protected function sanitizeNotificationConditionals(array $conditionals)
2469:     {
2470:         foreach ($conditionals as $key => $conditional) {
2471:             $conditionals[$key]['recipients'] = isset($conditional['recipients']) && is_array($conditional['recipients']) ? $this->sanitizeNotificationRecipients($conditional['recipients']) : array();
2472:             $conditionals[$key]['logicAction'] = isset($conditional['logicAction']) && is_bool($conditional['logicAction']) ? $conditional['logicAction'] : true;
2473:             $conditionals[$key]['logicMatch'] = isset($conditional['logicMatch']) && is_string($conditional['logicMatch']) ? sanitize_text_field($conditional['logicMatch']) : 'all';
2474:             $conditionals[$key]['logicRules'] = isset($conditional['logicRules']) && is_array($conditional['logicRules']) ? $this->sanitizeLogicRules($conditional['logicRules']) : array();
2475:         }
2476: 
2477:         return $conditionals;
2478:     }
2479: 
2480:     /**
2481:      * Sanitize the given notification "From" address array
2482:      *
2483:      * @param   array  $from
2484:      * @return  array
2485:      */
2486:     protected function sanitizeNotificationFrom(array $from)
2487:     {
2488:         $from['address'] = isset($from['address']) && is_string($from['address']) ? sanitize_text_field($from['address']) : '';
2489:         $from['name'] = isset($from['name']) && is_string($from['name']) ? sanitize_text_field($from['name']) : '';
2490: 
2491:         return $from;
2492:     }
2493: 
2494:     /**
2495:      * Sanitize the given array of notification attachments
2496:      *
2497:      * @param   array  $attachments
2498:      * @return  array
2499:      */
2500:     protected function sanitizeNotificationAttachments(array $attachments)
2501:     {
2502:         foreach ($attachments as $key => $attachment) {
2503:             $attachments[$key]['source'] = isset($attachment['source']) && is_string($attachment['source']) ? sanitize_text_field($attachment['source']) : 'media';
2504:             $attachments[$key]['element'] = isset($attachment['element']) && is_numeric($attachment['element']) ? (string) (int) $attachment['element'] : '';
2505:             $attachments[$key]['media'] = isset($attachment['media']) && is_array($attachment['media']) ? $this->sanitizeNotificationAttachmentMedia($attachment['media']) : array();
2506:         }
2507: 
2508:         return $attachments;
2509:     }
2510: 
2511:     /**
2512:      * Sanitize the given array of notification attachment media
2513:      *
2514:      * @param   array  $media
2515:      * @return  array
2516:      */
2517:     protected function sanitizeNotificationAttachmentMedia(array $media)
2518:     {
2519:         foreach ($media as $key => $medium) {
2520:             $media[$key]['id'] = isset($medium['id']) && is_numeric($medium['id']) ? (int) $medium['id'] : 0;
2521:             $media[$key]['filename'] = isset($medium['filename']) && is_string($medium['filename']) ? sanitize_file_name($medium['filename']) : '';
2522:             $media[$key]['filesizeHumanReadable'] = isset($medium['filesizeHumanReadable']) && is_string($medium['filesizeHumanReadable']) ? sanitize_text_field($medium['filesizeHumanReadable']) : '0 B';
2523:             $media[$key]['icon'] = isset($medium['icon']) && is_string($medium['icon']) ? esc_url_raw($medium['icon']) : '';
2524:         }
2525: 
2526:         return $media;
2527:     }
2528: 
2529:     /**
2530:      * Sanitize the given array of confirmations
2531:      *
2532:      * @param   array  $confirmations
2533:      * @return  array
2534:      */
2535:     protected function sanitizeConfirmations(array $confirmations)
2536:     {
2537:         foreach ($confirmations as $key => $confirmation) {
2538:             $confirmations[$key]['name'] = isset($confirmation['name']) && is_string($confirmation['name']) ? sanitize_text_field($confirmation['name']) : '';
2539:             $confirmations[$key]['enabled'] = isset($confirmation['enabled']) && is_bool($confirmation['enabled']) ? $confirmation['enabled'] : true;
2540:             $confirmations[$key]['type'] = isset($confirmation['type']) && is_string($confirmation['type']) ? sanitize_text_field($confirmation['type']) : 'message';
2541:             $confirmations[$key]['message'] = isset($confirmation['message']) && is_string($confirmation['message']) ? $this->sanitizeHtml($confirmation['message']) : '';
2542:             $confirmations[$key]['messageAutoFormat'] = isset($confirmation['messageAutoFormat']) && is_bool($confirmation['messageAutoFormat']) ? $confirmation['messageAutoFormat'] : true;
2543:             $confirmations[$key]['messageIcon'] = isset($confirmation['messageIcon']) && is_string($confirmation['messageIcon']) ? sanitize_text_field($confirmation['messageIcon']) : '';
2544:             $confirmations[$key]['messagePosition'] = isset($confirmation['messagePosition']) && is_string($confirmation['messagePosition']) ? sanitize_text_field($confirmation['messagePosition']) : 'above';
2545:             $confirmations[$key]['messageTimeout'] = isset($confirmation['messageTimeout']) && is_numeric($confirmation['messageTimeout']) ? (string) Quform::clamp((float) $confirmation['messageTimeout'], 0, 3600) : '10';
2546:             $confirmations[$key]['redirectPage'] = isset($confirmation['redirectPage']) && is_numeric($confirmation['redirectPage']) ? (string) (int) $confirmation['redirectPage'] : '';
2547:             $confirmations[$key]['redirectUrl'] = isset($confirmation['redirectUrl']) && is_string($confirmation['redirectUrl']) ? sanitize_text_field($confirmation['redirectUrl']) : '';
2548:             $confirmations[$key]['redirectQuery'] = isset($confirmation['redirectQuery']) && is_string($confirmation['redirectQuery']) ? Quform::sanitizeTextareaField($confirmation['redirectQuery']) : '';
2549:             $confirmations[$key]['redirectDelay'] = isset($confirmation['redirectDelay']) && is_numeric($confirmation['redirectDelay']) ? (string) Quform::clamp((float) $confirmation['redirectDelay'], 0, 3600) : '3';
2550:             $confirmations[$key]['logicAction'] = isset($confirmation['logicAction']) && is_bool($confirmation['logicAction']) ? $confirmation['logicAction'] : true;
2551:             $confirmations[$key]['logicMatch'] = isset($confirmation['logicMatch']) && is_string($confirmation['logicMatch']) ? sanitize_text_field($confirmation['logicMatch']) : 'all';
2552:             $confirmations[$key]['logicRules'] = isset($confirmation['logicRules']) && is_array($confirmation['logicRules']) ? $this->sanitizeLogicRules($confirmation['logicRules']) : array();
2553:             $confirmations[$key]['hideForm'] = isset($confirmation['hideForm']) && is_bool($confirmation['hideForm']) ? $confirmation['hideForm'] : false;
2554:             $confirmations[$key]['resetForm'] = isset($confirmation['resetForm']) && is_string($confirmation['resetForm']) ? sanitize_text_field($confirmation['resetForm']) : '';
2555:         }
2556: 
2557:         return $confirmations;
2558:     }
2559: 
2560:     /**
2561:      * Sanitize the settings for the given database columns
2562:      *
2563:      * @param   array   $columns
2564:      * @return  array
2565:      */
2566:     protected function sanitizeDatabaseColumns(array $columns)
2567:     {
2568:         foreach ($columns as $key => $column) {
2569:             $columns[$key]['name'] = isset($column['name']) && is_string($column['name']) ? sanitize_text_field($column['name']) : '';
2570:             $columns[$key]['value'] = isset($column['value']) && is_string($column['value']) ? sanitize_text_field($column['value']) : '';
2571:         }
2572: 
2573:         return $columns;
2574:     }
2575: 
2576:     /**
2577:      * Sanitize the given container config and return it
2578:      *
2579:      * @param   array  $container
2580:      * @return  array
2581:      */
2582:     protected function sanitizeContainer(array $container)
2583:     {
2584:         $container = $this->sanitizeElement($container);
2585: 
2586:         foreach ($container['elements'] as $key => $element) {
2587:             if ($element['type'] == 'group' || $element['type'] == 'row' || $element['type'] == 'column') {
2588:                 $container['elements'][$key] = $this->sanitizeContainer($element);
2589:             } else {
2590:                 $container['elements'][$key] = $this->sanitizeElement($element);
2591:             }
2592:         }
2593: 
2594:         return $container;
2595:     }
2596: 
2597:     /**
2598:      * Sanitize the given element config and return it
2599:      *
2600:      * @param   array  $element
2601:      * @return  array
2602:      */
2603:     protected function sanitizeElement(array $element)
2604:     {
2605:         switch ($element['type']) {
2606:             case 'text':
2607:                 // Basic
2608:                 $element['label'] = isset($element['label']) && is_string($element['label']) ? wp_kses_post($element['label']) : __('Untitled', 'quform');
2609:                 $element['description'] = isset($element['description']) && is_string($element['description']) ? wp_kses_post($element['description']) : '';
2610:                 $element['descriptionAbove'] = isset($element['descriptionAbove']) && is_string($element['descriptionAbove']) ? wp_kses_post($element['descriptionAbove']) : '';
2611:                 $element['required'] = isset($element['required']) && is_bool($element['required']) ? $element['required'] : false;
2612: 
2613:                 // Styles
2614:                 $element['labelIcon'] = isset($element['labelIcon']) && is_string($element['labelIcon']) ? sanitize_text_field($element['labelIcon']) : '';
2615:                 $element['fieldIconLeft'] = isset($element['fieldIconLeft']) && is_string($element['fieldIconLeft']) ? sanitize_text_field($element['fieldIconLeft']) : '';
2616:                 $element['fieldIconRight'] = isset($element['fieldIconRight']) && is_string($element['fieldIconRight']) ? sanitize_text_field($element['fieldIconRight']) : '';
2617:                 $element['fieldSize'] = isset($element['fieldSize']) && is_string($element['fieldSize']) ? sanitize_text_field($element['fieldSize']) : 'inherit';
2618:                 $element['fieldWidth'] = isset($element['fieldWidth']) && is_string($element['fieldWidth']) ? sanitize_text_field($element['fieldWidth']) : 'inherit';
2619:                 $element['fieldWidthCustom'] = isset($element['fieldWidthCustom']) && is_string($element['fieldWidthCustom']) ? sanitize_text_field($element['fieldWidthCustom']) : '';
2620:                 $element['customClass'] = isset($element['customClass']) && is_string($element['customClass']) ? Quform::sanitizeClass($element['customClass']) : '';
2621:                 $element['customElementClass'] = isset($element['customElementClass']) && is_string($element['customElementClass']) ? Quform::sanitizeClass($element['customElementClass']) : '';
2622:                 $element['styles'] = isset($element['styles']) && is_array($element['styles']) ? $this->sanitizeStyles($element['styles'], $element['type']) : array();
2623: 
2624:                 // Labels
2625:                 $element['placeholder'] = isset($element['placeholder']) && is_string($element['placeholder']) ? sanitize_text_field($element['placeholder']) : '';
2626:                 $element['subLabel'] = isset($element['subLabel']) && is_string($element['subLabel']) ? wp_kses_post($element['subLabel']) : '';
2627:                 $element['subLabelAbove'] = isset($element['subLabelAbove']) && is_string($element['subLabelAbove']) ? wp_kses_post($element['subLabelAbove']) : '';
2628:                 $element['adminLabel'] = isset($element['adminLabel']) && is_string($element['adminLabel']) ? wp_kses_post($element['adminLabel']) : '';
2629:                 $element['tooltip'] = isset($element['tooltip']) && is_string($element['tooltip']) ? wp_kses_post($element['tooltip']) : '';
2630:                 $element['tooltipType'] = isset($element['tooltipType']) && is_string($element['tooltipType']) ? sanitize_text_field($element['tooltipType']) : 'inherit';
2631:                 $element['tooltipEvent'] = isset($element['tooltipEvent']) && is_string($element['tooltipEvent']) ? sanitize_text_field($element['tooltipEvent']) : 'inherit';
2632:                 $element['labelPosition'] = isset($element['labelPosition']) && is_string($element['labelPosition']) ? sanitize_text_field($element['labelPosition']) : 'inherit';
2633:                 $element['labelWidth'] = isset($element['labelWidth']) && is_string($element['labelWidth']) ? sanitize_text_field($element['labelWidth']) : '';
2634: 
2635:                 // Logic
2636:                 $element['logicEnabled'] = isset($element['logicEnabled']) && is_bool($element['logicEnabled']) ? $element['logicEnabled'] : false;
2637:                 $element['logicAction'] = isset($element['logicAction']) && is_bool($element['logicAction']) ? $element['logicAction'] : true;
2638:                 $element['logicMatch'] = isset($element['logicMatch']) && is_string($element['logicMatch']) ? sanitize_text_field($element['logicMatch']) : 'all';
2639:                 $element['logicRules'] = isset($element['logicRules']) && is_array($element['logicRules']) ? $this->sanitizeLogicRules($element['logicRules']) : array();
2640: 
2641:                 // Data
2642:                 $element['defaultValue'] = isset($element['defaultValue']) && is_string($element['defaultValue']) ? sanitize_text_field($element['defaultValue']) : '';
2643:                 $element['dynamicDefaultValue'] = isset($element['dynamicDefaultValue']) && is_bool($element['dynamicDefaultValue']) ? $element['dynamicDefaultValue'] : false;
2644:                 $element['dynamicKey'] = isset($element['dynamicKey']) && is_string($element['dynamicKey']) ? sanitize_text_field($element['dynamicKey']) : '';
2645:                 $element['autocomplete'] = isset($element['autocomplete']) && is_string($element['autocomplete']) ? sanitize_text_field($element['autocomplete']) : '';
2646:                 $element['maxLength'] = isset($element['maxLength']) && is_numeric($element['maxLength']) ? (string) (int) $element['maxLength'] : '';
2647:                 $element['readOnly'] = isset($element['readOnly']) && is_bool($element['readOnly']) ? $element['readOnly'] : false;
2648:                 $element['showInEmail'] = isset($element['showInEmail']) && is_bool($element['showInEmail']) ? $element['showInEmail'] : true;
2649:                 $element['saveToDatabase'] = isset($element['saveToDatabase']) && is_bool($element['saveToDatabase']) ? $element['saveToDatabase'] : true;
2650: 
2651:                 // Advanced
2652:                 $element['visibility'] = isset($element['visibility']) && is_string($element['visibility']) ? sanitize_text_field($element['visibility']) : '';
2653:                 $element['filters'] = isset($element['filters']) && is_array($element['filters']) ? $this->sanitizeFilters($element['filters'], $element['type']) : array();
2654:                 $element['validators'] = isset($element['validators']) && is_array($element['validators']) ? $this->sanitizeValidators($element['validators'], $element['type']) : array();
2655: 
2656:                 // Translations
2657:                 $element['messageRequired'] = isset($element['messageRequired']) && is_string($element['messageRequired']) ? wp_kses_post($element['messageRequired']) : '';
2658:                 $element['messageLengthTooLong'] = isset($element['messageLengthTooLong']) && is_string($element['messageLengthTooLong']) ? wp_kses_post($element['messageLengthTooLong']) : '';
2659:                 break;
2660:             case 'textarea':
2661:                 // Basic
2662:                 $element['label'] = isset($element['label']) && is_string($element['label']) ? wp_kses_post($element['label']) : __('Untitled', 'quform');
2663:                 $element['description'] = isset($element['description']) && is_string($element['description']) ? wp_kses_post($element['description']) : '';
2664:                 $element['descriptionAbove'] = isset($element['descriptionAbove']) && is_string($element['descriptionAbove']) ? wp_kses_post($element['descriptionAbove']) : '';
2665:                 $element['required'] = isset($element['required']) && is_bool($element['required']) ? $element['required'] : false;
2666: 
2667:                 // Styles
2668:                 $element['labelIcon'] = isset($element['labelIcon']) && is_string($element['labelIcon']) ? sanitize_text_field($element['labelIcon']) : '';
2669:                 $element['fieldIconLeft'] = isset($element['fieldIconLeft']) && is_string($element['fieldIconLeft']) ? sanitize_text_field($element['fieldIconLeft']) : '';
2670:                 $element['fieldIconRight'] = isset($element['fieldIconRight']) && is_string($element['fieldIconRight']) ? sanitize_text_field($element['fieldIconRight']) : '';
2671:                 $element['fieldSize'] = isset($element['fieldSize']) && is_string($element['fieldSize']) ? sanitize_text_field($element['fieldSize']) : 'inherit';
2672:                 $element['fieldWidth'] = isset($element['fieldWidth']) && is_string($element['fieldWidth']) ? sanitize_text_field($element['fieldWidth']) : 'inherit';
2673:                 $element['fieldWidthCustom'] = isset($element['fieldWidthCustom']) && is_string($element['fieldWidthCustom']) ? sanitize_text_field($element['fieldWidthCustom']) : '';
2674:                 $element['enableEditor'] = isset($element['enableEditor']) && is_bool($element['enableEditor']) ? $element['enableEditor'] : false;
2675:                 $element['customClass'] = isset($element['customClass']) && is_string($element['customClass']) ? Quform::sanitizeClass($element['customClass']) : '';
2676:                 $element['customElementClass'] = isset($element['customElementClass']) && is_string($element['customElementClass']) ? Quform::sanitizeClass($element['customElementClass']) : '';
2677:                 $element['styles'] = isset($element['styles']) && is_array($element['styles']) ? $this->sanitizeStyles($element['styles'], $element['type']) : array();
2678: 
2679:                 // Labels
2680:                 $element['placeholder'] = isset($element['placeholder']) && is_string($element['placeholder']) ? sanitize_text_field($element['placeholder']) : '';
2681:                 $element['subLabel'] = isset($element['subLabel']) && is_string($element['subLabel']) ? wp_kses_post($element['subLabel']) : '';
2682:                 $element['subLabelAbove'] = isset($element['subLabelAbove']) && is_string($element['subLabelAbove']) ? wp_kses_post($element['subLabelAbove']) : '';
2683:                 $element['adminLabel'] = isset($element['adminLabel']) && is_string($element['adminLabel']) ? wp_kses_post($element['adminLabel']) : '';
2684:                 $element['tooltip'] = isset($element['tooltip']) && is_string($element['tooltip']) ? wp_kses_post($element['tooltip']) : '';
2685:                 $element['tooltipType'] = isset($element['tooltipType']) && is_string($element['tooltipType']) ? sanitize_text_field($element['tooltipType']) : 'inherit';
2686:                 $element['tooltipEvent'] = isset($element['tooltipEvent']) && is_string($element['tooltipEvent']) ? sanitize_text_field($element['tooltipEvent']) : 'inherit';
2687:                 $element['labelPosition'] = isset($element['labelPosition']) && is_string($element['labelPosition']) ? sanitize_text_field($element['labelPosition']) : 'inherit';
2688:                 $element['labelWidth'] = isset($element['labelWidth']) && is_string($element['labelWidth']) ? sanitize_text_field($element['labelWidth']) : '';
2689: 
2690:                 // Logic
2691:                 $element['logicEnabled'] = isset($element['logicEnabled']) && is_bool($element['logicEnabled']) ? $element['logicEnabled'] : false;
2692:                 $element['logicAction'] = isset($element['logicAction']) && is_bool($element['logicAction']) ? $element['logicAction'] : true;
2693:                 $element['logicMatch'] = isset($element['logicMatch']) && is_string($element['logicMatch']) ? sanitize_text_field($element['logicMatch']) : 'all';
2694:                 $element['logicRules'] = isset($element['logicRules']) && is_array($element['logicRules']) ? $this->sanitizeLogicRules($element['logicRules']) : array();
2695: 
2696:                 // Data
2697:                 $element['defaultValue'] = isset($element['defaultValue']) && is_string($element['defaultValue']) ? Quform::sanitizeTextareaField($element['defaultValue']) : '';
2698:                 $element['dynamicDefaultValue'] = isset($element['dynamicDefaultValue']) && is_bool($element['dynamicDefaultValue']) ? $element['dynamicDefaultValue'] : false;
2699:                 $element['dynamicKey'] = isset($element['dynamicKey']) && is_string($element['dynamicKey']) ? sanitize_text_field($element['dynamicKey']) : '';
2700:                 $element['autocomplete'] = isset($element['autocomplete']) && is_string($element['autocomplete']) ? sanitize_text_field($element['autocomplete']) : '';
2701:                 $element['maxLength'] = isset($element['maxLength']) && is_numeric($element['maxLength']) ? (string) (int) $element['maxLength'] : '';
2702:                 $element['readOnly'] = isset($element['readOnly']) && is_bool($element['readOnly']) ? $element['readOnly'] : false;
2703:                 $element['showInEmail'] = isset($element['showInEmail']) && is_bool($element['showInEmail']) ? $element['showInEmail'] : true;
2704:                 $element['saveToDatabase'] = isset($element['saveToDatabase']) && is_bool($element['saveToDatabase']) ? $element['saveToDatabase'] : true;
2705: 
2706:                 // Advanced
2707:                 $element['visibility'] = isset($element['visibility']) && is_string($element['visibility']) ? sanitize_text_field($element['visibility']) : '';
2708:                 $element['filters'] = isset($element['filters']) && is_array($element['filters']) ? $this->sanitizeFilters($element['filters'], $element['type']) : array();
2709:                 $element['validators'] = isset($element['validators']) && is_array($element['validators']) ? $this->sanitizeValidators($element['validators'], $element['type']) : array();
2710: 
2711:                 // Translations
2712:                 $element['messageRequired'] = isset($element['messageRequired']) && is_string($element['messageRequired']) ? wp_kses_post($element['messageRequired']) : '';
2713:                 $element['messageLengthTooLong'] = isset($element['messageLengthTooLong']) && is_string($element['messageLengthTooLong']) ? wp_kses_post($element['messageLengthTooLong']) : '';
2714:                 break;
2715:             case 'email':
2716:                 // Basic
2717:                 $element['label'] = isset($element['label']) && is_string($element['label']) ? wp_kses_post($element['label']) : __('Email address', 'quform');
2718:                 $element['description'] = isset($element['description']) && is_string($element['description']) ? wp_kses_post($element['description']) : '';
2719:                 $element['descriptionAbove'] = isset($element['descriptionAbove']) && is_string($element['descriptionAbove']) ? wp_kses_post($element['descriptionAbove']) : '';
2720:                 $element['required'] = isset($element['required']) && is_bool($element['required']) ? $element['required'] : true;
2721: 
2722:                 // Styles
2723:                 $element['labelIcon'] = isset($element['labelIcon']) && is_string($element['labelIcon']) ? sanitize_text_field($element['labelIcon']) : '';
2724:                 $element['fieldIconLeft'] = isset($element['fieldIconLeft']) && is_string($element['fieldIconLeft']) ? sanitize_text_field($element['fieldIconLeft']) : '';
2725:                 $element['fieldIconRight'] = isset($element['fieldIconRight']) && is_string($element['fieldIconRight']) ? sanitize_text_field($element['fieldIconRight']) : '';
2726:                 $element['fieldSize'] = isset($element['fieldSize']) && is_string($element['fieldSize']) ? sanitize_text_field($element['fieldSize']) : 'inherit';
2727:                 $element['fieldWidth'] = isset($element['fieldWidth']) && is_string($element['fieldWidth']) ? sanitize_text_field($element['fieldWidth']) : 'inherit';
2728:                 $element['fieldWidthCustom'] = isset($element['fieldWidthCustom']) && is_string($element['fieldWidthCustom']) ? sanitize_text_field($element['fieldWidthCustom']) : '';
2729:                 $element['customClass'] = isset($element['customClass']) && is_string($element['customClass']) ? Quform::sanitizeClass($element['customClass']) : '';
2730:                 $element['customElementClass'] = isset($element['customElementClass']) && is_string($element['customElementClass']) ? Quform::sanitizeClass($element['customElementClass']) : '';
2731:                 $element['styles'] = isset($element['styles']) && is_array($element['styles']) ? $this->sanitizeStyles($element['styles'], $element['type']) : array();
2732: 
2733:                 // Labels
2734:                 $element['placeholder'] = isset($element['placeholder']) && is_string($element['placeholder']) ? sanitize_text_field($element['placeholder']) : '';
2735:                 $element['subLabel'] = isset($element['subLabel']) && is_string($element['subLabel']) ? wp_kses_post($element['subLabel']) : '';
2736:                 $element['subLabelAbove'] = isset($element['subLabelAbove']) && is_string($element['subLabelAbove']) ? wp_kses_post($element['subLabelAbove']) : '';
2737:                 $element['adminLabel'] = isset($element['adminLabel']) && is_string($element['adminLabel']) ? wp_kses_post($element['adminLabel']) : '';
2738:                 $element['tooltip'] = isset($element['tooltip']) && is_string($element['tooltip']) ? wp_kses_post($element['tooltip']) : '';
2739:                 $element['tooltipType'] = isset($element['tooltipType']) && is_string($element['tooltipType']) ? sanitize_text_field($element['tooltipType']) : 'inherit';
2740:                 $element['tooltipEvent'] = isset($element['tooltipEvent']) && is_string($element['tooltipEvent']) ? sanitize_text_field($element['tooltipEvent']) : 'inherit';
2741:                 $element['labelPosition'] = isset($element['labelPosition']) && is_string($element['labelPosition']) ? sanitize_text_field($element['labelPosition']) : 'inherit';
2742:                 $element['labelWidth'] = isset($element['labelWidth']) && is_string($element['labelWidth']) ? sanitize_text_field($element['labelWidth']) : '';
2743: 
2744:                 // Logic
2745:                 $element['logicEnabled'] = isset($element['logicEnabled']) && is_bool($element['logicEnabled']) ? $element['logicEnabled'] : false;
2746:                 $element['logicAction'] = isset($element['logicAction']) && is_bool($element['logicAction']) ? $element['logicAction'] : true;
2747:                 $element['logicMatch'] = isset($element['logicMatch']) && is_string($element['logicMatch']) ? sanitize_text_field($element['logicMatch']) : 'all';
2748:                 $element['logicRules'] = isset($element['logicRules']) && is_array($element['logicRules']) ? $this->sanitizeLogicRules($element['logicRules']) : array();
2749: 
2750:                 // Data
2751:                 $element['defaultValue'] = isset($element['defaultValue']) && is_string($element['defaultValue']) ? sanitize_text_field($element['defaultValue']) : '';
2752:                 $element['dynamicDefaultValue'] = isset($element['dynamicDefaultValue']) && is_bool($element['dynamicDefaultValue']) ? $element['dynamicDefaultValue'] : false;
2753:                 $element['dynamicKey'] = isset($element['dynamicKey']) && is_string($element['dynamicKey']) ? sanitize_text_field($element['dynamicKey']) : '';
2754:                 $element['autocomplete'] = isset($element['autocomplete']) && is_string($element['autocomplete']) ? sanitize_text_field($element['autocomplete']) : '';
2755:                 $element['maxLength'] = isset($element['maxLength']) && is_numeric($element['maxLength']) ? (string) (int) $element['maxLength'] : '';
2756:                 $element['readOnly'] = isset($element['readOnly']) && is_bool($element['readOnly']) ? $element['readOnly'] : false;
2757:                 $element['showInEmail'] = isset($element['showInEmail']) && is_bool($element['showInEmail']) ? $element['showInEmail'] : true;
2758:                 $element['saveToDatabase'] = isset($element['saveToDatabase']) && is_bool($element['saveToDatabase']) ? $element['saveToDatabase'] : true;
2759: 
2760:                 // Advanced
2761:                 $element['visibility'] = isset($element['visibility']) && is_string($element['visibility']) ? sanitize_text_field($element['visibility']) : '';
2762:                 $element['filters'] = isset($element['filters']) && is_array($element['filters']) ? $this->sanitizeFilters($element['filters'], $element['type']) : array();
2763:                 $element['validators'] = isset($element['validators']) && is_array($element['validators']) ? $this->sanitizeValidators($element['validators'], $element['type']) : array();
2764: 
2765:                 // Translations
2766:                 $element['messageRequired'] = isset($element['messageRequired']) && is_string($element['messageRequired']) ? wp_kses_post($element['messageRequired']) : '';
2767:                 $element['messageLengthTooLong'] = isset($element['messageLengthTooLong']) && is_string($element['messageLengthTooLong']) ? wp_kses_post($element['messageLengthTooLong']) : '';
2768:                 $element['messageEmailAddressInvalidFormat'] = isset($element['messageEmailAddressInvalidFormat']) && is_string($element['messageEmailAddressInvalidFormat']) ? wp_kses_post($element['messageEmailAddressInvalidFormat']) : '';
2769:                 break;
2770:             case 'select':
2771:                 // Basic
2772:                 $element['label'] = isset($element['label']) && is_string($element['label']) ? wp_kses_post($element['label']) : __('Untitled', 'quform');
2773:                 $element['options'] = isset($element['options']) && is_array($element['options']) ? $this->sanitizeSelectOptions($element['options']) : array();
2774:                 $element['nextOptionId'] = isset($element['nextOptionId']) && is_numeric($element['nextOptionId']) ? (int) $element['nextOptionId'] : 1;
2775:                 $element['defaultValue'] = isset($element['defaultValue']) && is_string($element['defaultValue']) ? wp_kses_post($element['defaultValue']) : '';
2776:                 $element['customiseValues'] = isset($element['customiseValues']) && is_bool($element['customiseValues']) ? $element['customiseValues'] : false;
2777:                 $element['noneOption'] = isset($element['noneOption']) && is_bool($element['noneOption']) ? $element['noneOption'] : true;
2778:                 $element['description'] = isset($element['description']) && is_string($element['description']) ? wp_kses_post($element['description']) : '';
2779:                 $element['descriptionAbove'] = isset($element['descriptionAbove']) && is_string($element['descriptionAbove']) ? wp_kses_post($element['descriptionAbove']) : '';
2780:                 $element['required'] = isset($element['required']) && is_bool($element['required']) ? $element['required'] : false;
2781: 
2782:                 // Styles
2783:                 $element['labelIcon'] = isset($element['labelIcon']) && is_string($element['labelIcon']) ? sanitize_text_field($element['labelIcon']) : '';
2784:                 $element['fieldSize'] = isset($element['fieldSize']) && is_string($element['fieldSize']) ? sanitize_text_field($element['fieldSize']) : 'inherit';
2785:                 $element['fieldWidth'] = isset($element['fieldWidth']) && is_string($element['fieldWidth']) ? sanitize_text_field($element['fieldWidth']) : 'inherit';
2786:                 $element['fieldWidthCustom'] = isset($element['fieldWidthCustom']) && is_string($element['fieldWidthCustom']) ? sanitize_text_field($element['fieldWidthCustom']) : '';
2787:                 $element['enhancedSelectEnabled'] = isset($element['enhancedSelectEnabled']) && is_bool($element['enhancedSelectEnabled']) ? $element['enhancedSelectEnabled'] : false;
2788:                 $element['enhancedSelectSearch'] = isset($element['enhancedSelectSearch']) && is_bool($element['enhancedSelectSearch']) ? $element['enhancedSelectSearch'] : true;
2789:                 $element['customClass'] = isset($element['customClass']) && is_string($element['customClass']) ? Quform::sanitizeClass($element['customClass']) : '';
2790:                 $element['customElementClass'] = isset($element['customElementClass']) && is_string($element['customElementClass']) ? Quform::sanitizeClass($element['customElementClass']) : '';
2791:                 $element['styles'] = isset($element['styles']) && is_array($element['styles']) ? $this->sanitizeStyles($element['styles'], $element['type']) : array();
2792: 
2793:                 // Labels
2794:                 $element['subLabel'] = isset($element['subLabel']) && is_string($element['subLabel']) ? wp_kses_post($element['subLabel']) : '';
2795:                 $element['subLabelAbove'] = isset($element['subLabelAbove']) && is_string($element['subLabelAbove']) ? wp_kses_post($element['subLabelAbove']) : '';
2796:                 $element['adminLabel'] = isset($element['adminLabel']) && is_string($element['adminLabel']) ? wp_kses_post($element['adminLabel']) : '';
2797:                 $element['tooltip'] = isset($element['tooltip']) && is_string($element['tooltip']) ? wp_kses_post($element['tooltip']) : '';
2798:                 $element['tooltipType'] = isset($element['tooltipType']) && is_string($element['tooltipType']) ? sanitize_text_field($element['tooltipType']) : 'icon';
2799:                 $element['tooltipEvent'] = isset($element['tooltipEvent']) && is_string($element['tooltipEvent']) ? sanitize_text_field($element['tooltipEvent']) : 'inherit';
2800:                 $element['labelPosition'] = isset($element['labelPosition']) && is_string($element['labelPosition']) ? sanitize_text_field($element['labelPosition']) : 'inherit';
2801:                 $element['labelWidth'] = isset($element['labelWidth']) && is_string($element['labelWidth']) ? sanitize_text_field($element['labelWidth']) : '';
2802: 
2803:                 // Logic
2804:                 $element['logicEnabled'] = isset($element['logicEnabled']) && is_bool($element['logicEnabled']) ? $element['logicEnabled'] : false;
2805:                 $element['logicAction'] = isset($element['logicAction']) && is_bool($element['logicAction']) ? $element['logicAction'] : true;
2806:                 $element['logicMatch'] = isset($element['logicMatch']) && is_string($element['logicMatch']) ? sanitize_text_field($element['logicMatch']) : 'all';
2807:                 $element['logicRules'] = isset($element['logicRules']) && is_array($element['logicRules']) ? $this->sanitizeLogicRules($element['logicRules']) : array();
2808: 
2809:                 // Data
2810:                 $element['inArrayValidator'] = isset($element['inArrayValidator']) && is_bool($element['inArrayValidator']) ? $element['inArrayValidator'] : true;
2811:                 $element['dynamicDefaultValue'] = isset($element['dynamicDefaultValue']) && is_bool($element['dynamicDefaultValue']) ? $element['dynamicDefaultValue'] : false;
2812:                 $element['dynamicKey'] = isset($element['dynamicKey']) && is_string($element['dynamicKey']) ? sanitize_text_field($element['dynamicKey']) : '';
2813:                 $element['autocomplete'] = isset($element['autocomplete']) && is_string($element['autocomplete']) ? sanitize_text_field($element['autocomplete']) : '';
2814:                 $element['submitOnChoice'] = isset($element['submitOnChoice']) && is_bool($element['submitOnChoice']) ? $element['submitOnChoice'] : false;
2815:                 $element['showInEmail'] = isset($element['showInEmail']) && is_bool($element['showInEmail']) ? $element['showInEmail'] : true;
2816:                 $element['saveToDatabase'] = isset($element['saveToDatabase']) && is_bool($element['saveToDatabase']) ? $element['saveToDatabase'] : true;
2817: 
2818:                 // Advanced
2819:                 $element['visibility'] = isset($element['visibility']) && is_string($element['visibility']) ? sanitize_text_field($element['visibility']) : '';
2820:                 $element['validators'] = isset($element['validators']) && is_array($element['validators']) ? $this->sanitizeValidators($element['validators'], $element['type']) : array();
2821: 
2822:                 // Translations
2823:                 $element['messageRequired'] = isset($element['messageRequired']) && is_string($element['messageRequired']) ? wp_kses_post($element['messageRequired']) : '';
2824:                 $element['noneOptionText'] = isset($element['noneOptionText']) && is_string($element['noneOptionText']) ? wp_kses_post($element['noneOptionText']) : '';
2825:                 $element['enhancedSelectNoResultsFound'] = isset($element['enhancedSelectNoResultsFound']) && is_string($element['enhancedSelectNoResultsFound']) ? wp_kses_post($element['enhancedSelectNoResultsFound']) : '';
2826:                 break;
2827:             case 'checkbox':
2828:                 // Basic
2829:                 $element['label'] = isset($element['label']) && is_string($element['label']) ? wp_kses_post($element['label']) : __('Untitled', 'quform');
2830:                 $element['options'] = isset($element['options']) && is_array($element['options']) ? $this->sanitizeCheckboxRadioOptions($element['options']) : array();
2831:                 $element['nextOptionId'] = isset($element['nextOptionId']) && is_numeric($element['nextOptionId']) ? (int) $element['nextOptionId'] : 1;
2832:                 $element['defaultValue'] = isset($element['defaultValue']) && is_array($element['defaultValue']) ? array_map('wp_kses_post', $element['defaultValue']) : array();
2833:                 $element['customiseValues'] = isset($element['customiseValues']) && is_bool($element['customiseValues']) ? $element['customiseValues'] : false;
2834:                 $element['description'] = isset($element['description']) && is_string($element['description']) ? wp_kses_post($element['description']) : '';
2835:                 $element['descriptionAbove'] = isset($element['descriptionAbove']) && is_string($element['descriptionAbove']) ? wp_kses_post($element['descriptionAbove']) : '';
2836:                 $element['required'] = isset($element['required']) && is_bool($element['required']) ? $element['required'] : false;
2837: 
2838:                 // Styles
2839:                 $element['labelIcon'] = isset($element['labelIcon']) && is_string($element['labelIcon']) ? sanitize_text_field($element['labelIcon']) : '';
2840:                 $element['optionsLayout'] = isset($element['optionsLayout']) && is_string($element['optionsLayout']) ? sanitize_text_field($element['optionsLayout']) : 'block';
2841:                 $element['optionsLayoutResponsiveColumns'] = isset($element['optionsLayoutResponsiveColumns']) && is_string($element['optionsLayoutResponsiveColumns']) ? sanitize_text_field($element['optionsLayoutResponsiveColumns']) : 'phone-landscape';
2842:                 $element['optionsLayoutResponsiveColumnsCustom'] = isset($element['optionsLayoutResponsiveColumnsCustom']) && is_string($element['optionsLayoutResponsiveColumnsCustom']) ? sanitize_text_field($element['optionsLayoutResponsiveColumnsCustom']) : '';
2843:                 $element['optionsStyle'] = isset($element['optionsStyle']) && is_string($element['optionsStyle']) ? sanitize_text_field($element['optionsStyle']) : '';
2844:                 $element['optionsButtonStyle'] = isset($element['optionsButtonStyle']) && is_string($element['optionsButtonStyle']) ? sanitize_text_field($element['optionsButtonStyle']) : '';
2845:                 $element['optionsButtonSize'] = isset($element['optionsButtonSize']) && is_string($element['optionsButtonSize']) ? sanitize_text_field($element['optionsButtonSize']) : '';
2846:                 $element['optionsButtonWidth'] = isset($element['optionsButtonWidth']) && is_string($element['optionsButtonWidth']) ? sanitize_text_field($element['optionsButtonWidth']) : '';
2847:                 $element['optionsButtonWidthCustom'] = isset($element['optionsButtonWidthCustom']) && is_string($element['optionsButtonWidthCustom']) ? sanitize_text_field($element['optionsButtonWidthCustom']) : '';
2848:                 $element['optionsButtonIconPosition'] = isset($element['optionsButtonIconPosition']) && is_string($element['optionsButtonIconPosition']) ? sanitize_text_field($element['optionsButtonIconPosition']) : 'left';
2849:                 $element['customClass'] = isset($element['customClass']) && is_string($element['customClass']) ? Quform::sanitizeClass($element['customClass']) : '';
2850:                 $element['customElementClass'] = isset($element['customElementClass']) && is_string($element['customElementClass']) ? Quform::sanitizeClass($element['customElementClass']) : '';
2851:                 $element['styles'] = isset($element['styles']) && is_array($element['styles']) ? $this->sanitizeStyles($element['styles'], $element['type']) : array();
2852: 
2853:                 // Labels
2854:                 $element['subLabel'] = isset($element['subLabel']) && is_string($element['subLabel']) ? wp_kses_post($element['subLabel']) : '';
2855:                 $element['subLabelAbove'] = isset($element['subLabelAbove']) && is_string($element['subLabelAbove']) ? wp_kses_post($element['subLabelAbove']) : '';
2856:                 $element['adminLabel'] = isset($element['adminLabel']) && is_string($element['adminLabel']) ? wp_kses_post($element['adminLabel']) : '';
2857:                 $element['tooltip'] = isset($element['tooltip']) && is_string($element['tooltip']) ? wp_kses_post($element['tooltip']) : '';
2858:                 $element['tooltipType'] = isset($element['tooltipType']) && is_string($element['tooltipType']) ? sanitize_text_field($element['tooltipType']) : 'icon';
2859:                 $element['tooltipEvent'] = isset($element['tooltipEvent']) && is_string($element['tooltipEvent']) ? sanitize_text_field($element['tooltipEvent']) : 'inherit';
2860:                 $element['labelPosition'] = isset($element['labelPosition']) && is_string($element['labelPosition']) ? sanitize_text_field($element['labelPosition']) : 'inherit';
2861:                 $element['labelWidth'] = isset($element['labelWidth']) && is_string($element['labelWidth']) ? sanitize_text_field($element['labelWidth']) : '';
2862: 
2863:                 // Logic
2864:                 $element['logicEnabled'] = isset($element['logicEnabled']) && is_bool($element['logicEnabled']) ? $element['logicEnabled'] : false;
2865:                 $element['logicAction'] = isset($element['logicAction']) && is_bool($element['logicAction']) ? $element['logicAction'] : true;
2866:                 $element['logicMatch'] = isset($element['logicMatch']) && is_string($element['logicMatch']) ? sanitize_text_field($element['logicMatch']) : 'all';
2867:                 $element['logicRules'] = isset($element['logicRules']) && is_array($element['logicRules']) ? $this->sanitizeLogicRules($element['logicRules']) : array();
2868: 
2869:                 // Data
2870:                 $element['inArrayValidator'] = isset($element['inArrayValidator']) && is_bool($element['inArrayValidator']) ? $element['inArrayValidator'] : true;
2871:                 $element['dynamicDefaultValue'] = isset($element['dynamicDefaultValue']) && is_bool($element['dynamicDefaultValue']) ? $element['dynamicDefaultValue'] : false;
2872:                 $element['dynamicKey'] = isset($element['dynamicKey']) && is_string($element['dynamicKey']) ? sanitize_text_field($element['dynamicKey']) : '';
2873:                 $element['showInEmail'] = isset($element['showInEmail']) && is_bool($element['showInEmail']) ? $element['showInEmail'] : true;
2874:                 $element['saveToDatabase'] = isset($element['saveToDatabase']) && is_bool($element['saveToDatabase']) ? $element['saveToDatabase'] : true;
2875: 
2876:                 // Advanced
2877:                 $element['visibility'] = isset($element['visibility']) && is_string($element['visibility']) ? sanitize_text_field($element['visibility']) : '';
2878:                 $element['validators'] = isset($element['validators']) && is_array($element['validators']) ? $this->sanitizeValidators($element['validators'], $element['type']) : array();
2879: 
2880:                 // Translations
2881:                 $element['messageRequired'] = isset($element['messageRequired']) && is_string($element['messageRequired']) ? wp_kses_post($element['messageRequired']) : '';
2882:                 break;
2883:             case 'radio':
2884:                 // Basic
2885:                 $element['label'] = isset($element['label']) && is_string($element['label']) ? wp_kses_post($element['label']) : __('Untitled', 'quform');
2886:                 $element['options'] = isset($element['options']) && is_array($element['options']) ? $this->sanitizeCheckboxRadioOptions($element['options']) : array();
2887:                 $element['nextOptionId'] = isset($element['nextOptionId']) && is_numeric($element['nextOptionId']) ? (int) $element['nextOptionId'] : 1;
2888:                 $element['defaultValue'] = isset($element['defaultValue']) && is_string($element['defaultValue']) ? wp_kses_post($element['defaultValue']) : '';
2889:                 $element['customiseValues'] = isset($element['customiseValues']) && is_bool($element['customiseValues']) ? $element['customiseValues'] : false;
2890:                 $element['description'] = isset($element['description']) && is_string($element['description']) ? wp_kses_post($element['description']) : '';
2891:                 $element['descriptionAbove'] = isset($element['descriptionAbove']) && is_string($element['descriptionAbove']) ? wp_kses_post($element['descriptionAbove']) : '';
2892:                 $element['required'] = isset($element['required']) && is_bool($element['required']) ? $element['required'] : false;
2893: 
2894:                 // Styles
2895:                 $element['labelIcon'] = isset($element['labelIcon']) && is_string($element['labelIcon']) ? sanitize_text_field($element['labelIcon']) : '';
2896:                 $element['optionsLayout'] = isset($element['optionsLayout']) && is_string($element['optionsLayout']) ? sanitize_text_field($element['optionsLayout']) : 'block';
2897:                 $element['optionsLayoutResponsiveColumns'] = isset($element['optionsLayoutResponsiveColumns']) && is_string($element['optionsLayoutResponsiveColumns']) ? sanitize_text_field($element['optionsLayoutResponsiveColumns']) : 'phone-landscape';
2898:                 $element['optionsLayoutResponsiveColumnsCustom'] = isset($element['optionsLayoutResponsiveColumnsCustom']) && is_string($element['optionsLayoutResponsiveColumnsCustom']) ? sanitize_text_field($element['optionsLayoutResponsiveColumnsCustom']) : '';
2899:                 $element['optionsStyle'] = isset($element['optionsStyle']) && is_string($element['optionsStyle']) ? sanitize_text_field($element['optionsStyle']) : '';
2900:                 $element['optionsButtonStyle'] = isset($element['optionsButtonStyle']) && is_string($element['optionsButtonStyle']) ? sanitize_text_field($element['optionsButtonStyle']) : '';
2901:                 $element['optionsButtonSize'] = isset($element['optionsButtonSize']) && is_string($element['optionsButtonSize']) ? sanitize_text_field($element['optionsButtonSize']) : '';
2902:                 $element['optionsButtonWidth'] = isset($element['optionsButtonWidth']) && is_string($element['optionsButtonWidth']) ? sanitize_text_field($element['optionsButtonWidth']) : '';
2903:                 $element['optionsButtonWidthCustom'] = isset($element['optionsButtonWidthCustom']) && is_string($element['optionsButtonWidthCustom']) ? sanitize_text_field($element['optionsButtonWidthCustom']) : '';
2904:                 $element['optionsButtonIconPosition'] = isset($element['optionsButtonIconPosition']) && is_string($element['optionsButtonIconPosition']) ? sanitize_text_field($element['optionsButtonIconPosition']) : 'left';
2905:                 $element['customClass'] = isset($element['customClass']) && is_string($element['customClass']) ? Quform::sanitizeClass($element['customClass']) : '';
2906:                 $element['customElementClass'] = isset($element['customElementClass']) && is_string($element['customElementClass']) ? Quform::sanitizeClass($element['customElementClass']) : '';
2907:                 $element['styles'] = isset($element['styles']) && is_array($element['styles']) ? $this->sanitizeStyles($element['styles'], $element['type']) : array();
2908: 
2909:                 // Labels
2910:                 $element['subLabel'] = isset($element['subLabel']) && is_string($element['subLabel']) ? wp_kses_post($element['subLabel']) : '';
2911:                 $element['subLabelAbove'] = isset($element['subLabelAbove']) && is_string($element['subLabelAbove']) ? wp_kses_post($element['subLabelAbove']) : '';
2912:                 $element['adminLabel'] = isset($element['adminLabel']) && is_string($element['adminLabel']) ? wp_kses_post($element['adminLabel']) : '';
2913:                 $element['tooltip'] = isset($element['tooltip']) && is_string($element['tooltip']) ? wp_kses_post($element['tooltip']) : '';
2914:                 $element['tooltipType'] = isset($element['tooltipType']) && is_string($element['tooltipType']) ? sanitize_text_field($element['tooltipType']) : 'icon';
2915:                 $element['tooltipEvent'] = isset($element['tooltipEvent']) && is_string($element['tooltipEvent']) ? sanitize_text_field($element['tooltipEvent']) : 'inherit';
2916:                 $element['labelPosition'] = isset($element['labelPosition']) && is_string($element['labelPosition']) ? sanitize_text_field($element['labelPosition']) : 'inherit';
2917:                 $element['labelWidth'] = isset($element['labelWidth']) && is_string($element['labelWidth']) ? sanitize_text_field($element['labelWidth']) : '';
2918: 
2919:                 // Logic
2920:                 $element['logicEnabled'] = isset($element['logicEnabled']) && is_bool($element['logicEnabled']) ? $element['logicEnabled'] : false;
2921:                 $element['logicAction'] = isset($element['logicAction']) && is_bool($element['logicAction']) ? $element['logicAction'] : true;
2922:                 $element['logicMatch'] = isset($element['logicMatch']) && is_string($element['logicMatch']) ? sanitize_text_field($element['logicMatch']) : 'all';
2923:                 $element['logicRules'] = isset($element['logicRules']) && is_array($element['logicRules']) ? $this->sanitizeLogicRules($element['logicRules']) : array();
2924: 
2925:                 // Data
2926:                 $element['inArrayValidator'] = isset($element['inArrayValidator']) && is_bool($element['inArrayValidator']) ? $element['inArrayValidator'] : true;
2927:                 $element['dynamicDefaultValue'] = isset($element['dynamicDefaultValue']) && is_bool($element['dynamicDefaultValue']) ? $element['dynamicDefaultValue'] : false;
2928:                 $element['dynamicKey'] = isset($element['dynamicKey']) && is_string($element['dynamicKey']) ? sanitize_text_field($element['dynamicKey']) : '';
2929:                 $element['submitOnChoice'] = isset($element['submitOnChoice']) && is_bool($element['submitOnChoice']) ? $element['submitOnChoice'] : false;
2930:                 $element['showInEmail'] = isset($element['showInEmail']) && is_bool($element['showInEmail']) ? $element['showInEmail'] : true;
2931:                 $element['saveToDatabase'] = isset($element['saveToDatabase']) && is_bool($element['saveToDatabase']) ? $element['saveToDatabase'] : true;
2932: 
2933:                 // Advanced
2934:                 $element['visibility'] = isset($element['visibility']) && is_string($element['visibility']) ? sanitize_text_field($element['visibility']) : '';
2935:                 $element['validators'] = isset($element['validators']) && is_array($element['validators']) ? $this->sanitizeValidators($element['validators'], $element['type']) : array();
2936: 
2937:                 // Translations
2938:                 $element['messageRequired'] = isset($element['messageRequired']) && is_string($element['messageRequired']) ? wp_kses_post($element['messageRequired']) : '';
2939:                 break;
2940:             case 'multiselect':
2941:                 // Basic
2942:                 $element['label'] = isset($element['label']) && is_string($element['label']) ? wp_kses_post($element['label']) : __('Untitled', 'quform');
2943:                 $element['options'] = isset($element['options']) && is_array($element['options']) ? $this->sanitizeSelectOptions($element['options']) : array();
2944:                 $element['nextOptionId'] = isset($element['nextOptionId']) && is_numeric($element['nextOptionId']) ? (int) $element['nextOptionId'] : 1;
2945:                 $element['defaultValue'] = isset($element['defaultValue']) && is_array($element['defaultValue']) ? array_map('wp_kses_post', $element['defaultValue']) : array();
2946:                 $element['customiseValues'] = isset($element['customiseValues']) && is_bool($element['customiseValues']) ? $element['customiseValues'] : false;
2947:                 $element['description'] = isset($element['description']) && is_string($element['description']) ? wp_kses_post($element['description']) : '';
2948:                 $element['descriptionAbove'] = isset($element['descriptionAbove']) && is_string($element['descriptionAbove']) ? wp_kses_post($element['descriptionAbove']) : '';
2949:                 $element['required'] = isset($element['required']) && is_bool($element['required']) ? $element['required'] : false;
2950: 
2951:                 // Styles
2952:                 $element['labelIcon'] = isset($element['labelIcon']) && is_string($element['labelIcon']) ? sanitize_text_field($element['labelIcon']) : '';
2953:                 $element['fieldSize'] = isset($element['fieldSize']) && is_string($element['fieldSize']) ? sanitize_text_field($element['fieldSize']) : 'inherit';
2954:                 $element['fieldWidth'] = isset($element['fieldWidth']) && is_string($element['fieldWidth']) ? sanitize_text_field($element['fieldWidth']) : 'inherit';
2955:                 $element['fieldWidthCustom'] = isset($element['fieldWidthCustom']) && is_string($element['fieldWidthCustom']) ? sanitize_text_field($element['fieldWidthCustom']) : '';
2956:                 $element['enhancedSelectEnabled'] = isset($element['enhancedSelectEnabled']) && is_bool($element['enhancedSelectEnabled']) ? $element['enhancedSelectEnabled'] : false;
2957:                 $element['customClass'] = isset($element['customClass']) && is_string($element['customClass']) ? Quform::sanitizeClass($element['customClass']) : '';
2958:                 $element['customElementClass'] = isset($element['customElementClass']) && is_string($element['customElementClass']) ? Quform::sanitizeClass($element['customElementClass']) : '';
2959:                 $element['sizeAttribute'] = isset($element['sizeAttribute']) && is_string($element['sizeAttribute']) ? sanitize_text_field($element['sizeAttribute']) : '';
2960:                 $element['styles'] = isset($element['styles']) && is_array($element['styles']) ? $this->sanitizeStyles($element['styles'], $element['type']) : array();
2961: 
2962:                 // Labels
2963:                 $element['subLabel'] = isset($element['subLabel']) && is_string($element['subLabel']) ? wp_kses_post($element['subLabel']) : '';
2964:                 $element['subLabelAbove'] = isset($element['subLabelAbove']) && is_string($element['subLabelAbove']) ? wp_kses_post($element['subLabelAbove']) : '';
2965:                 $element['adminLabel'] = isset($element['adminLabel']) && is_string($element['adminLabel']) ? wp_kses_post($element['adminLabel']) : '';
2966:                 $element['tooltip'] = isset($element['tooltip']) && is_string($element['tooltip']) ? wp_kses_post($element['tooltip']) : '';
2967:                 $element['tooltipType'] = isset($element['tooltipType']) && is_string($element['tooltipType']) ? sanitize_text_field($element['tooltipType']) : 'icon';
2968:                 $element['tooltipEvent'] = isset($element['tooltipEvent']) && is_string($element['tooltipEvent']) ? sanitize_text_field($element['tooltipEvent']) : 'inherit';
2969:                 $element['labelPosition'] = isset($element['labelPosition']) && is_string($element['labelPosition']) ? sanitize_text_field($element['labelPosition']) : 'inherit';
2970:                 $element['labelWidth'] = isset($element['labelWidth']) && is_string($element['labelWidth']) ? sanitize_text_field($element['labelWidth']) : '';
2971: 
2972:                 // Logic
2973:                 $element['logicEnabled'] = isset($element['logicEnabled']) && is_bool($element['logicEnabled']) ? $element['logicEnabled'] : false;
2974:                 $element['logicAction'] = isset($element['logicAction']) && is_bool($element['logicAction']) ? $element['logicAction'] : true;
2975:                 $element['logicMatch'] = isset($element['logicMatch']) && is_string($element['logicMatch']) ? sanitize_text_field($element['logicMatch']) : 'all';
2976:                 $element['logicRules'] = isset($element['logicRules']) && is_array($element['logicRules']) ? $this->sanitizeLogicRules($element['logicRules']) : array();
2977: 
2978:                 // Data
2979:                 $element['inArrayValidator'] = isset($element['inArrayValidator']) && is_bool($element['inArrayValidator']) ? $element['inArrayValidator'] : true;
2980:                 $element['dynamicDefaultValue'] = isset($element['dynamicDefaultValue']) && is_bool($element['dynamicDefaultValue']) ? $element['dynamicDefaultValue'] : false;
2981:                 $element['dynamicKey'] = isset($element['dynamicKey']) && is_string($element['dynamicKey']) ? sanitize_text_field($element['dynamicKey']) : '';
2982:                 $element['showInEmail'] = isset($element['showInEmail']) && is_bool($element['showInEmail']) ? $element['showInEmail'] : true;
2983:                 $element['saveToDatabase'] = isset($element['saveToDatabase']) && is_bool($element['saveToDatabase']) ? $element['saveToDatabase'] : true;
2984: 
2985:                 // Advanced
2986:                 $element['visibility'] = isset($element['visibility']) && is_string($element['visibility']) ? sanitize_text_field($element['visibility']) : '';
2987:                 $element['validators'] = isset($element['validators']) && is_array($element['validators']) ? $this->sanitizeValidators($element['validators'], $element['type']) : array();
2988: 
2989:                 // Translations
2990:                 $element['messageRequired'] = isset($element['messageRequired']) && is_string($element['messageRequired']) ? wp_kses_post($element['messageRequired']) : '';
2991:                 $element['enhancedSelectPlaceholder'] = isset($element['enhancedSelectPlaceholder']) && is_string($element['enhancedSelectPlaceholder']) ? wp_kses_post($element['enhancedSelectPlaceholder']) : '';
2992:                 $element['enhancedSelectNoResultsFound'] = isset($element['enhancedSelectNoResultsFound']) && is_string($element['enhancedSelectNoResultsFound']) ? wp_kses_post($element['enhancedSelectNoResultsFound']) : '';
2993:                 break;
2994:             case 'file':
2995:                 // Basic
2996:                 $element['label'] = isset($element['label']) && is_string($element['label']) ? wp_kses_post($element['label']) : __('Untitled', 'quform');
2997:                 $element['description'] = isset($element['description']) && is_string($element['description']) ? wp_kses_post($element['description']) : '';
2998:                 $element['descriptionAbove'] = isset($element['descriptionAbove']) && is_string($element['descriptionAbove']) ? wp_kses_post($element['descriptionAbove']) : '';
2999:                 $element['required'] = isset($element['required']) && is_bool($element['required']) ? $element['required'] : false;
3000: 
3001:                 // Styles
3002:                 $element['labelIcon'] = isset($element['labelIcon']) && is_string($element['labelIcon']) ? sanitize_text_field($element['labelIcon']) : '';
3003:                 $element['enhancedUploadEnabled'] = isset($element['enhancedUploadEnabled']) && is_bool($element['enhancedUploadEnabled']) ? $element['enhancedUploadEnabled'] : true;
3004:                 $element['enhancedUploadStyle'] = isset($element['enhancedUploadStyle']) && is_string($element['enhancedUploadStyle']) ? sanitize_text_field($element['enhancedUploadStyle']) : 'button';
3005:                 $element['buttonStyle'] = isset($element['buttonStyle']) && is_string($element['buttonStyle']) ? sanitize_text_field($element['buttonStyle']) : 'inherit';
3006:                 $element['buttonSize'] = isset($element['buttonSize']) && is_string($element['buttonSize']) ? sanitize_text_field($element['buttonSize']) : 'inherit';
3007:                 $element['buttonWidth'] = isset($element['buttonWidth']) && is_string($element['buttonWidth']) ? sanitize_text_field($element['buttonWidth']) : 'inherit';
3008:                 $element['buttonWidthCustom'] = isset($element['buttonWidthCustom']) && is_string($element['buttonWidthCustom']) ? sanitize_text_field($element['buttonWidthCustom']) : '';
3009:                 $element['buttonIcon'] = isset($element['buttonIcon']) && is_string($element['buttonIcon']) ? sanitize_text_field($element['buttonIcon']) : 'qicon-file_upload';
3010:                 $element['buttonIconPosition'] = isset($element['buttonIconPosition']) && is_string($element['buttonIconPosition']) ? sanitize_text_field($element['buttonIconPosition']) : 'right';
3011:                 $element['uploadListLayout'] = isset($element['uploadListLayout']) && is_string($element['uploadListLayout']) ? sanitize_text_field($element['uploadListLayout']) : '';
3012:                 $element['uploadListSize'] = isset($element['uploadListSize']) && is_string($element['uploadListSize']) ? sanitize_text_field($element['uploadListSize']) : '';
3013:                 $element['fieldWidth'] = isset($element['fieldWidth']) && is_string($element['fieldWidth']) ? sanitize_text_field($element['fieldWidth']) : 'inherit';
3014:                 $element['fieldWidthCustom'] = isset($element['fieldWidthCustom']) && is_string($element['fieldWidthCustom']) ? sanitize_text_field($element['fieldWidthCustom']) : '';
3015:                 $element['customClass'] = isset($element['customClass']) && is_string($element['customClass']) ? Quform::sanitizeClass($element['customClass']) : '';
3016:                 $element['customElementClass'] = isset($element['customElementClass']) && is_string($element['customElementClass']) ? Quform::sanitizeClass($element['customElementClass']) : '';
3017:                 $element['styles'] = isset($element['styles']) && is_array($element['styles']) ? $this->sanitizeStyles($element['styles'], $element['type']) : array();
3018: 
3019:                 // Labels
3020:                 $element['subLabel'] = isset($element['subLabel']) && is_string($element['subLabel']) ? wp_kses_post($element['subLabel']) : '';
3021:                 $element['subLabelAbove'] = isset($element['subLabelAbove']) && is_string($element['subLabelAbove']) ? wp_kses_post($element['subLabelAbove']) : '';
3022:                 $element['adminLabel'] = isset($element['adminLabel']) && is_string($element['adminLabel']) ? wp_kses_post($element['adminLabel']) : '';
3023:                 $element['tooltip'] = isset($element['tooltip']) && is_string($element['tooltip']) ? wp_kses_post($element['tooltip']) : '';
3024:                 $element['tooltipType'] = isset($element['tooltipType']) && is_string($element['tooltipType']) ? sanitize_text_field($element['tooltipType']) : 'icon';
3025:                 $element['tooltipEvent'] = isset($element['tooltipEvent']) && is_string($element['tooltipEvent']) ? sanitize_text_field($element['tooltipEvent']) : 'inherit';
3026:                 $element['labelPosition'] = isset($element['labelPosition']) && is_string($element['labelPosition']) ? sanitize_text_field($element['labelPosition']) : 'inherit';
3027:                 $element['labelWidth'] = isset($element['labelWidth']) && is_string($element['labelWidth']) ? sanitize_text_field($element['labelWidth']) : '';
3028: 
3029:                 // Logic
3030:                 $element['logicEnabled'] = isset($element['logicEnabled']) && is_bool($element['logicEnabled']) ? $element['logicEnabled'] : false;
3031:                 $element['logicAction'] = isset($element['logicAction']) && is_bool($element['logicAction']) ? $element['logicAction'] : true;
3032:                 $element['logicMatch'] = isset($element['logicMatch']) && is_string($element['logicMatch']) ? sanitize_text_field($element['logicMatch']) : 'all';
3033:                 $element['logicRules'] = isset($element['logicRules']) && is_array($element['logicRules']) ? $this->sanitizeLogicRules($element['logicRules']) : array();
3034: 
3035:                 // Data
3036:                 $element['minimumNumberOfFiles'] = isset($element['minimumNumberOfFiles']) && is_string($element['minimumNumberOfFiles']) && is_numeric($element['minimumNumberOfFiles']) ? (string) (int) $element['minimumNumberOfFiles'] : '0';
3037:                 $element['maximumNumberOfFiles'] = isset($element['maximumNumberOfFiles']) && is_string($element['maximumNumberOfFiles']) && is_numeric($element['maximumNumberOfFiles']) ? (string) (int) $element['maximumNumberOfFiles'] : '1';
3038:                 $element['allowedExtensions'] = isset($element['allowedExtensions']) && is_string($element['allowedExtensions']) ? sanitize_text_field($element['allowedExtensions']) : 'jpg, jpeg, png, gif';
3039:                 $element['maximumFileSize'] = isset($element['maximumFileSize']) && is_string($element['maximumFileSize']) && is_numeric($element['maximumFileSize']) ? sanitize_text_field($element['maximumFileSize']) : '10';
3040:                 $element['saveToServer'] = isset($element['saveToServer']) && is_bool($element['saveToServer']) ? $element['saveToServer'] : true;
3041:                 $element['savePath'] = isset($element['savePath']) && is_string($element['savePath']) ? sanitize_text_field($element['savePath']) : 'quform/{form_id}/{year}/{month}/';
3042:                 $element['showInEmail'] = isset($element['showInEmail']) && is_bool($element['showInEmail']) ? $element['showInEmail'] : true;
3043:                 $element['saveToDatabase'] = isset($element['saveToDatabase']) && is_bool($element['saveToDatabase']) ? $element['saveToDatabase'] : true;
3044: 
3045:                 // Advanced
3046:                 $element['visibility'] = isset($element['visibility']) && is_string($element['visibility']) ? sanitize_text_field($element['visibility']) : '';
3047: 
3048:                 // Translations
3049:                 $element['browseText'] = isset($element['browseText']) && is_string($element['browseText']) ? wp_kses_post($element['browseText']) : '';
3050:                 $element['messageFileUploadRequired'] = isset($element['messageFileUploadRequired']) && is_string($element['messageFileUploadRequired']) ? wp_kses_post($element['messageFileUploadRequired']) : '';
3051:                 $element['messageFileNumRequired'] = isset($element['messageFileNumRequired']) && is_string($element['messageFileNumRequired']) ? wp_kses_post($element['messageFileNumRequired']) : '';
3052:                 $element['messageFileTooMany'] = isset($element['messageFileTooMany']) && is_string($element['messageFileTooMany']) ? wp_kses_post($element['messageFileTooMany']) : '';
3053:                 $element['messageFileTooBigFilename'] = isset($element['messageFileTooBigFilename']) && is_string($element['messageFileTooBigFilename']) ? wp_kses_post($element['messageFileTooBigFilename']) : '';
3054:                 $element['messageFileTooBig'] = isset($element['messageFileTooBig']) && is_string($element['messageFileTooBig']) ? wp_kses_post($element['messageFileTooBig']) : '';
3055:                 $element['messageNotAllowedTypeFilename'] = isset($element['messageNotAllowedTypeFilename']) && is_string($element['messageNotAllowedTypeFilename']) ? wp_kses_post($element['messageNotAllowedTypeFilename']) : '';
3056:                 $element['messageNotAllowedType'] = isset($element['messageNotAllowedType']) && is_string($element['messageNotAllowedType']) ? wp_kses_post($element['messageNotAllowedType']) : '';
3057:                 break;
3058:             case 'captcha':
3059:                 // Basic
3060:                 $element['label'] = isset($element['label']) && is_string($element['label']) ? wp_kses_post($element['label']) : __('Please type the characters', 'quform');
3061:                 $element['description'] = isset($element['description']) && is_string($element['description']) ? wp_kses_post($element['description']) : __('This helps us prevent spam, thank you.', 'quform');
3062:                 $element['descriptionAbove'] = isset($element['descriptionAbove']) && is_string($element['descriptionAbove']) ? wp_kses_post($element['descriptionAbove']) : '';
3063: 
3064:                 // Styles
3065:                 $element['labelIcon'] = isset($element['labelIcon']) && is_string($element['labelIcon']) ? sanitize_text_field($element['labelIcon']) : '';
3066:                 $element['fieldIconLeft'] = isset($element['fieldIconLeft']) && is_string($element['fieldIconLeft']) ? sanitize_text_field($element['fieldIconLeft']) : '';
3067:                 $element['fieldIconRight'] = isset($element['fieldIconRight']) && is_string($element['fieldIconRight']) ? sanitize_text_field($element['fieldIconRight']) : '';
3068:                 $element['fieldSize'] = isset($element['fieldSize']) && is_string($element['fieldSize']) ? sanitize_text_field($element['fieldSize']) : 'inherit';
3069:                 $element['fieldWidth'] = isset($element['fieldWidth']) && is_string($element['fieldWidth']) ? sanitize_text_field($element['fieldWidth']) : 'inherit';
3070:                 $element['fieldWidthCustom'] = isset($element['fieldWidthCustom']) && is_string($element['fieldWidthCustom']) ? sanitize_text_field($element['fieldWidthCustom']) : '';
3071:                 $element['captchaLength'] = isset($element['captchaLength']) && is_numeric($element['captchaLength']) ? (string) Quform::clamp((int) $element['captchaLength'], 2, 32) : '5';
3072:                 $element['captchaWidth'] = isset($element['captchaWidth']) && is_numeric($element['captchaWidth']) ? (string) Quform::clamp((int) $element['captchaWidth'], 20, 300) : '115';
3073:                 $element['captchaHeight'] = isset($element['captchaHeight']) && is_numeric($element['captchaHeight']) ? (string) Quform::clamp((int) $element['captchaHeight'], 10, 300) : '40';
3074:                 $element['captchaBgColor'] = isset($element['captchaBgColor']) && Quform::isNonEmptyString($element['captchaBgColor']) ? sanitize_text_field($element['captchaBgColor']) : '#FFFFFF';
3075:                 $element['captchaBgColorRgba'] = is_array($element['captchaBgColorRgba']) ? $this->sanitizeRgbColorArray($element['captchaBgColorRgba']) : array('r' => 255, 'g' => 255, 'b' => 255);
3076:                 $element['captchaTextColor'] = isset($element['captchaTextColor']) && Quform::isNonEmptyString($element['captchaTextColor']) ? sanitize_text_field($element['captchaTextColor']) : '#222222';
3077:                 $element['captchaTextColorRgba'] = is_array($element['captchaTextColorRgba']) ? $this->sanitizeRgbColorArray($element['captchaTextColorRgba']) : array('r' => 34, 'g' => 34, 'b' => 34);
3078:                 $element['captchaFont'] = isset($element['captchaFont']) && Quform::isNonEmptyString($element['captchaFont']) ? sanitize_text_field($element['captchaFont']) : 'Typist.ttf';
3079:                 $element['captchaMinFontSize'] = isset($element['captchaMinFontSize']) && is_numeric($element['captchaMinFontSize']) ? (string) Quform::clamp((int) $element['captchaMinFontSize'], 5, 72) : '12';
3080:                 $element['captchaMaxFontSize'] = isset($element['captchaMaxFontSize']) && is_numeric($element['captchaMaxFontSize']) ? (string) Quform::clamp((int) $element['captchaMaxFontSize'], 5, 72) : '19';
3081:                 $element['captchaMinAngle'] = isset($element['captchaMinAngle']) && is_numeric($element['captchaMinAngle']) ? (string) Quform::clamp((int) $element['captchaMinAngle'], 0, 360) : '0';
3082:                 $element['captchaMaxAngle'] = isset($element['captchaMaxAngle']) && is_numeric($element['captchaMaxAngle']) ? (string) Quform::clamp((int) $element['captchaMaxAngle'], 0, 360) : '20';
3083:                 $element['captchaRetina'] = isset($element['captchaRetina']) ? (bool) $element['captchaRetina'] : true;
3084: 
3085:                 // If any minimums are greater than maximums, swap them around
3086:                 if ($element['captchaMinFontSize'] > $element['captchaMaxFontSize']) {
3087:                     $tmp = $element['captchaMaxFontSize'];
3088:                     $element['captchaMaxFontSize'] = $element['captchaMinFontSize'];
3089:                     $element['captchaMinFontSize'] = $tmp;
3090:                 }
3091: 
3092:                 if ($element['captchaMinAngle'] > $element['captchaMaxAngle']) {
3093:                     $tmp = $element['captchaMaxAngle'];
3094:                     $element['captchaMaxAngle'] = $element['captchaMinAngle'];
3095:                     $element['captchaMinAngle'] = $tmp;
3096:                 }
3097: 
3098:                 $element['customClass'] = isset($element['customClass']) && is_string($element['customClass']) ? Quform::sanitizeClass($element['customClass']) : '';
3099:                 $element['customElementClass'] = isset($element['customElementClass']) && is_string($element['customElementClass']) ? Quform::sanitizeClass($element['customElementClass']) : '';
3100:                 $element['styles'] = isset($element['styles']) && is_array($element['styles']) ? $this->sanitizeStyles($element['styles'], $element['type']) : array();
3101: 
3102:                 // Labels
3103:                 $element['placeholder'] = isset($element['placeholder']) && is_string($element['placeholder']) ? sanitize_text_field($element['placeholder']) : '';
3104:                 $element['subLabel'] = isset($element['subLabel']) && is_string($element['subLabel']) ? wp_kses_post($element['subLabel']) : '';
3105:                 $element['subLabelAbove'] = isset($element['subLabelAbove']) && is_string($element['subLabelAbove']) ? wp_kses_post($element['subLabelAbove']) : '';
3106:                 $element['tooltip'] = isset($element['tooltip']) && is_string($element['tooltip']) ? wp_kses_post($element['tooltip']) : '';
3107:                 $element['tooltipType'] = isset($element['tooltipType']) && is_string($element['tooltipType']) ? sanitize_text_field($element['tooltipType']) : 'inherit';
3108:                 $element['tooltipEvent'] = isset($element['tooltipEvent']) && is_string($element['tooltipEvent']) ? sanitize_text_field($element['tooltipEvent']) : 'inherit';
3109:                 $element['labelPosition'] = isset($element['labelPosition']) && is_string($element['labelPosition']) ? sanitize_text_field($element['labelPosition']) : 'inherit';
3110:                 $element['labelWidth'] = isset($element['labelWidth']) && is_string($element['labelWidth']) ? sanitize_text_field($element['labelWidth']) : '';
3111: 
3112:                 // Logic
3113:                 $element['logicEnabled'] = isset($element['logicEnabled']) && is_bool($element['logicEnabled']) ? $element['logicEnabled'] : false;
3114:                 $element['logicAction'] = isset($element['logicAction']) && is_bool($element['logicAction']) ? $element['logicAction'] : true;
3115:                 $element['logicMatch'] = isset($element['logicMatch']) && is_string($element['logicMatch']) ? sanitize_text_field($element['logicMatch']) : 'all';
3116:                 $element['logicRules'] = isset($element['logicRules']) && is_array($element['logicRules']) ? $this->sanitizeLogicRules($element['logicRules']) : array();
3117: 
3118:                 // Advanced
3119:                 $element['visibility'] = isset($element['visibility']) && is_string($element['visibility']) ? sanitize_text_field($element['visibility']) : '';
3120: 
3121:                 // Translations
3122:                 $element['messageRequired'] = isset($element['messageRequired']) && is_string($element['messageRequired']) ? wp_kses_post($element['messageRequired']) : '';
3123:                 $element['messageCaptchaNotMatch'] = isset($element['messageCaptchaNotMatch']) && is_string($element['messageCaptchaNotMatch']) ? wp_kses_post($element['messageCaptchaNotMatch']) : '';
3124:                 break;
3125:             case 'recaptcha':
3126:                 // Basic
3127:                 $element['label'] = isset($element['label']) && is_string($element['label']) ? wp_kses_post($element['label']) : __('Are you human?', 'quform');
3128:                 $element['description'] = isset($element['description']) && is_string($element['description']) ? wp_kses_post($element['description']) : '';
3129:                 $element['descriptionAbove'] = isset($element['descriptionAbove']) && is_string($element['descriptionAbove']) ? wp_kses_post($element['descriptionAbove']) : '';
3130:                 $element['provider'] = isset($element['provider']) && is_string($element['provider']) ? sanitize_key($element['provider']) : 'recaptcha';
3131:                 $element['recaptchaVersion'] = isset($element['recaptchaVersion']) && is_string($element['recaptchaVersion']) ? sanitize_key($element['recaptchaVersion']) : 'v2';
3132:                 $element['recaptchaSize'] = isset($element['recaptchaSize']) && is_string($element['recaptchaSize']) ? sanitize_text_field($element['recaptchaSize']) : 'normal';
3133:                 $element['recaptchaType'] = isset($element['recaptchaType']) && is_string($element['recaptchaType']) ? sanitize_text_field($element['recaptchaType']) : 'image';
3134:                 $element['recaptchaTheme'] = isset($element['recaptchaTheme']) && is_string($element['recaptchaTheme']) ? sanitize_text_field($element['recaptchaTheme']) : 'light';
3135:                 $element['recaptchaBadge'] = isset($element['recaptchaBadge']) && is_string($element['recaptchaBadge']) ? sanitize_text_field($element['recaptchaBadge']) : 'bottomright';
3136:                 $element['recaptchaLang'] = isset($element['recaptchaLang']) && is_string($element['recaptchaLang']) ? sanitize_text_field($element['recaptchaLang']) : '';
3137:                 $element['hcaptchaLang'] = isset($element['hcaptchaLang']) && is_string($element['hcaptchaLang']) ? sanitize_text_field($element['hcaptchaLang']) : '';
3138:                 $element['turnstileLang'] = isset($element['turnstileLang']) && is_string($element['turnstileLang']) ? sanitize_text_field($element['turnstileLang']) : '';
3139:                 $element['recaptchaThreshold'] = isset($element['recaptchaThreshold']) && is_numeric($element['recaptchaThreshold']) ? (string) Quform::clamp((float) $element['recaptchaThreshold'], 0, 1) : '0.5';
3140: 
3141:                 // Styles
3142:                 $element['labelIcon'] = isset($element['labelIcon']) && is_string($element['labelIcon']) ? sanitize_text_field($element['labelIcon']) : '';
3143:                 $element['customElementClass'] = isset($element['customElementClass']) && is_string($element['customElementClass']) ? Quform::sanitizeClass($element['customElementClass']) : '';
3144:                 $element['styles'] = isset($element['styles']) && is_array($element['styles']) ? $this->sanitizeStyles($element['styles'], $element['type']) : array();
3145: 
3146:                 // Labels
3147:                 $element['subLabel'] = isset($element['subLabel']) && is_string($element['subLabel']) ? wp_kses_post($element['subLabel']) : '';
3148:                 $element['subLabelAbove'] = isset($element['subLabelAbove']) && is_string($element['subLabelAbove']) ? wp_kses_post($element['subLabelAbove']) : '';
3149:                 $element['tooltip'] = isset($element['tooltip']) && is_string($element['tooltip']) ? wp_kses_post($element['tooltip']) : '';
3150:                 $element['tooltipType'] = isset($element['tooltipType']) && is_string($element['tooltipType']) ? sanitize_text_field($element['tooltipType']) : 'icon';
3151:                 $element['tooltipEvent'] = isset($element['tooltipEvent']) && is_string($element['tooltipEvent']) ? sanitize_text_field($element['tooltipEvent']) : 'inherit';
3152:                 $element['labelPosition'] = isset($element['labelPosition']) && is_string($element['labelPosition']) ? sanitize_text_field($element['labelPosition']) : 'inherit';
3153:                 $element['labelWidth'] = isset($element['labelWidth']) && is_string($element['labelWidth']) ? sanitize_text_field($element['labelWidth']) : '';
3154: 
3155:                 // Logic
3156:                 $element['logicEnabled'] = isset($element['logicEnabled']) && is_bool($element['logicEnabled']) ? $element['logicEnabled'] : false;
3157:                 $element['logicAction'] = isset($element['logicAction']) && is_bool($element['logicAction']) ? $element['logicAction'] : true;
3158:                 $element['logicMatch'] = isset($element['logicMatch']) && is_string($element['logicMatch']) ? sanitize_text_field($element['logicMatch']) : 'all';
3159:                 $element['logicRules'] = isset($element['logicRules']) && is_array($element['logicRules']) ? $this->sanitizeLogicRules($element['logicRules']) : array();
3160: 
3161:                 // Advanced
3162:                 $element['visibility'] = isset($element['visibility']) && is_string($element['visibility']) ? sanitize_text_field($element['visibility']) : '';
3163: 
3164:                 // Translations
3165:                 $element['messageRequired'] = isset($element['messageRequired']) && is_string($element['messageRequired']) ? wp_kses_post($element['messageRequired']) : '';
3166:                 $element['messageRecaptchaMissingInputSecret'] = isset($element['messageRecaptchaMissingInputSecret']) && is_string($element['messageRecaptchaMissingInputSecret']) ? wp_kses_post($element['messageRecaptchaMissingInputSecret']) : '';
3167:                 $element['messageRecaptchaInvalidInputSecret'] = isset($element['messageRecaptchaInvalidInputSecret']) && is_string($element['messageRecaptchaInvalidInputSecret']) ? wp_kses_post($element['messageRecaptchaInvalidInputSecret']) : '';
3168:                 $element['messageRecaptchaMissingInputResponse'] = isset($element['messageRecaptchaMissingInputResponse']) && is_string($element['messageRecaptchaMissingInputResponse']) ? wp_kses_post($element['messageRecaptchaMissingInputResponse']) : '';
3169:                 $element['messageRecaptchaInvalidInputResponse'] = isset($element['messageRecaptchaInvalidInputResponse']) && is_string($element['messageRecaptchaInvalidInputResponse']) ? wp_kses_post($element['messageRecaptchaInvalidInputResponse']) : '';
3170:                 $element['messageRecaptchaError'] = isset($element['messageRecaptchaError']) && is_string($element['messageRecaptchaError']) ? wp_kses_post($element['messageRecaptchaError']) : '';
3171:                 $element['messageRecaptchaScoreTooLow'] = isset($element['messageRecaptchaScoreTooLow']) && is_string($element['messageRecaptchaScoreTooLow']) ? wp_kses_post($element['messageRecaptchaScoreTooLow']) : '';
3172:                 break;
3173:             case 'html':
3174:                 // Basic
3175:                 $element['label'] = isset($element['label']) && is_string($element['label']) ? wp_kses_post($element['label']) : __('HTML', 'quform');
3176:                 $element['content'] = isset($element['content']) && is_string($element['content']) ? $this->sanitizeHtml($element['content']) : '';
3177:                 $element['autoFormat'] = isset($element['autoFormat']) && is_bool($element['autoFormat']) ? $element['autoFormat'] : false;
3178: 
3179:                 // Styles
3180:                 $element['customElementClass'] = isset($element['customElementClass']) && is_string($element['customElementClass']) ? Quform::sanitizeClass($element['customElementClass']) : '';
3181:                 $element['styles'] = isset($element['styles']) && is_array($element['styles']) ? $this->sanitizeStyles($element['styles'], $element['type']) : array();
3182: 
3183:                 // Logic
3184:                 $element['logicEnabled'] = isset($element['logicEnabled']) && is_bool($element['logicEnabled']) ? $element['logicEnabled'] : false;
3185:                 $element['logicAction'] = isset($element['logicAction']) && is_bool($element['logicAction']) ? $element['logicAction'] : true;
3186:                 $element['logicMatch'] = isset($element['logicMatch']) && is_string($element['logicMatch']) ? sanitize_text_field($element['logicMatch']) : 'all';
3187:                 $element['logicRules'] = isset($element['logicRules']) && is_array($element['logicRules']) ? $this->sanitizeLogicRules($element['logicRules']) : array();
3188: 
3189:                 // Data
3190:                 $element['showInEmail'] = isset($element['showInEmail']) && is_bool($element['showInEmail']) ? $element['showInEmail'] : false;
3191:                 $element['saveToDatabase'] = isset($element['saveToDatabase']) && is_bool($element['saveToDatabase']) ? $element['saveToDatabase'] : false;
3192: 
3193:                 // Advanced
3194:                 $element['visibility'] = isset($element['visibility']) && is_string($element['visibility']) ? sanitize_text_field($element['visibility']) : '';
3195:                 break;
3196:             case 'date':
3197:                 // Basic
3198:                 $element['label'] = isset($element['label']) && is_string($element['label']) ? wp_kses_post($element['label']) : __('Date', 'quform');
3199:                 $element['description'] = isset($element['description']) && is_string($element['description']) ? wp_kses_post($element['description']) : '';
3200:                 $element['descriptionAbove'] = isset($element['descriptionAbove']) && is_string($element['descriptionAbove']) ? wp_kses_post($element['descriptionAbove']) : '';
3201:                 $element['required'] = isset($element['required']) && is_bool($element['required']) ? $element['required'] : false;
3202: 
3203:                 // Styles
3204:                 $element['labelIcon'] = isset($element['labelIcon']) && is_string($element['labelIcon']) ? sanitize_text_field($element['labelIcon']) : '';
3205:                 $element['fieldIconLeft'] = isset($element['fieldIconLeft']) && is_string($element['fieldIconLeft']) ? sanitize_text_field($element['fieldIconLeft']) : '';
3206:                 $element['fieldIconRight'] = isset($element['fieldIconRight']) && is_string($element['fieldIconRight']) ? sanitize_text_field($element['fieldIconRight']) : 'qicon-calendar';
3207:                 $element['fieldSize'] = isset($element['fieldSize']) && is_string($element['fieldSize']) ? sanitize_text_field($element['fieldSize']) : 'inherit';
3208:                 $element['fieldWidth'] = isset($element['fieldWidth']) && is_string($element['fieldWidth']) ? sanitize_text_field($element['fieldWidth']) : 'inherit';
3209:                 $element['fieldWidthCustom'] = isset($element['fieldWidthCustom']) && is_string($element['fieldWidthCustom']) ? sanitize_text_field($element['fieldWidthCustom']) : '';
3210:                 $element['customClass'] = isset($element['customClass']) && is_string($element['customClass']) ? Quform::sanitizeClass($element['customClass']) : '';
3211:                 $element['customElementClass'] = isset($element['customElementClass']) && is_string($element['customElementClass']) ? Quform::sanitizeClass($element['customElementClass']) : '';
3212:                 $element['styles'] = isset($element['styles']) && is_array($element['styles']) ? $this->sanitizeStyles($element['styles'], $element['type']) : array();
3213: 
3214:                 // Labels
3215:                 $element['placeholder'] = isset($element['placeholder']) && is_string($element['placeholder']) ? sanitize_text_field($element['placeholder']) : '';
3216:                 $element['subLabel'] = isset($element['subLabel']) && is_string($element['subLabel']) ? wp_kses_post($element['subLabel']) : '';
3217:                 $element['subLabelAbove'] = isset($element['subLabelAbove']) && is_string($element['subLabelAbove']) ? wp_kses_post($element['subLabelAbove']) : '';
3218:                 $element['adminLabel'] = isset($element['adminLabel']) && is_string($element['adminLabel']) ? wp_kses_post($element['adminLabel']) : '';
3219:                 $element['tooltip'] = isset($element['tooltip']) && is_string($element['tooltip']) ? wp_kses_post($element['tooltip']) : '';
3220:                 $element['tooltipType'] = isset($element['tooltipType']) && is_string($element['tooltipType']) ? sanitize_text_field($element['tooltipType']) : 'inherit';
3221:                 $element['tooltipEvent'] = isset($element['tooltipEvent']) && is_string($element['tooltipEvent']) ? sanitize_text_field($element['tooltipEvent']) : 'inherit';
3222:                 $element['labelPosition'] = isset($element['labelPosition']) && is_string($element['labelPosition']) ? sanitize_text_field($element['labelPosition']) : 'inherit';
3223:                 $element['labelWidth'] = isset($element['labelWidth']) && is_string($element['labelWidth']) ? sanitize_text_field($element['labelWidth']) : '';
3224: 
3225:                 // Logic
3226:                 $element['logicEnabled'] = isset($element['logicEnabled']) && is_bool($element['logicEnabled']) ? $element['logicEnabled'] : false;
3227:                 $element['logicAction'] = isset($element['logicAction']) && is_bool($element['logicAction']) ? $element['logicAction'] : true;
3228:                 $element['logicMatch'] = isset($element['logicMatch']) && is_string($element['logicMatch']) ? sanitize_text_field($element['logicMatch']) : 'all';
3229:                 $element['logicRules'] = isset($element['logicRules']) && is_array($element['logicRules']) ? $this->sanitizeLogicRules($element['logicRules']) : array();
3230: 
3231:                 // Data
3232:                 $element['defaultValue'] = isset($element['defaultValue']) && is_string($element['defaultValue']) ? sanitize_text_field($element['defaultValue']) : '';
3233:                 $element['dynamicDefaultValue'] = isset($element['dynamicDefaultValue']) && is_bool($element['dynamicDefaultValue']) ? $element['dynamicDefaultValue'] : false;
3234:                 $element['dynamicKey'] = isset($element['dynamicKey']) && is_string($element['dynamicKey']) ? sanitize_text_field($element['dynamicKey']) : '';
3235:                 $element['dateMin'] = isset($element['dateMin']) && is_string($element['dateMin']) ? sanitize_text_field($element['dateMin']) : '';
3236:                 $element['dateMax'] = isset($element['dateMax']) && is_string($element['dateMax']) ? sanitize_text_field($element['dateMax']) : '';
3237:                 $element['dateViewStart'] = isset($element['dateViewStart']) && is_string($element['dateViewStart']) ? sanitize_text_field($element['dateViewStart']) : 'month';
3238:                 $element['dateViewDepth'] = isset($element['dateViewDepth']) && is_string($element['dateViewDepth']) ? sanitize_text_field($element['dateViewDepth']) : 'month';
3239:                 $element['dateShowFooter'] = isset($element['dateShowFooter']) && is_bool($element['dateShowFooter']) ? $element['dateShowFooter'] : false;
3240:                 $element['dateLocale'] = isset($element['dateLocale']) && is_string($element['dateLocale']) ? sanitize_text_field($element['dateLocale']) : '';
3241:                 $element['dateFormatJs'] = isset($element['dateFormatJs']) && is_string($element['dateFormatJs']) ? sanitize_text_field($element['dateFormatJs']) : '';
3242:                 $element['dateFormat'] = isset($element['dateFormat']) && is_string($element['dateFormat']) ? sanitize_text_field($element['dateFormat']) : '';
3243:                 $element['dateAutoOpen'] = isset($element['dateAutoOpen']) && is_bool($element['dateAutoOpen']) ? $element['dateAutoOpen'] : false;
3244:                 $element['readOnly'] = isset($element['readOnly']) && is_bool($element['readOnly']) ? $element['readOnly'] : false;
3245:                 $element['showInEmail'] = isset($element['showInEmail']) && is_bool($element['showInEmail']) ? $element['showInEmail'] : true;
3246:                 $element['saveToDatabase'] = isset($element['saveToDatabase']) && is_bool($element['saveToDatabase']) ? $element['saveToDatabase'] : true;
3247: 
3248:                 // Advanced
3249:                 $element['visibility'] = isset($element['visibility']) && is_string($element['visibility']) ? sanitize_text_field($element['visibility']) : '';
3250:                 $element['validators'] = isset($element['validators']) && is_array($element['validators']) ? $this->sanitizeValidators($element['validators'], $element['type']) : array();
3251: 
3252:                 // Translations
3253:                 $element['messageRequired'] = isset($element['messageRequired']) && is_string($element['messageRequired']) ? wp_kses_post($element['messageRequired']) : '';
3254:                 $element['messageDateInvalidDate'] = isset($element['messageDateInvalidDate']) && is_string($element['messageDateInvalidDate']) ? wp_kses_post($element['messageDateInvalidDate']) : '';
3255:                 $element['messageDateTooEarly'] = isset($element['messageDateTooEarly']) && is_string($element['messageDateTooEarly']) ? wp_kses_post($element['messageDateTooEarly']) : '';
3256:                 $element['messageDateTooLate'] = isset($element['messageDateTooLate']) && is_string($element['messageDateTooLate']) ? wp_kses_post($element['messageDateTooLate']) : '';
3257:                 break;
3258:             case 'time':
3259:                 // Basic
3260:                 $element['label'] = isset($element['label']) && is_string($element['label']) ? wp_kses_post($element['label']) : __('Time', 'quform');
3261:                 $element['description'] = isset($element['description']) && is_string($element['description']) ? wp_kses_post($element['description']) : '';
3262:                 $element['descriptionAbove'] = isset($element['descriptionAbove']) && is_string($element['descriptionAbove']) ? wp_kses_post($element['descriptionAbove']) : '';
3263:                 $element['required'] = isset($element['required']) && is_bool($element['required']) ? $element['required'] : false;
3264: 
3265:                 // Styles
3266:                 $element['labelIcon'] = isset($element['labelIcon']) && is_string($element['labelIcon']) ? sanitize_text_field($element['labelIcon']) : '';
3267:                 $element['fieldIconLeft'] = isset($element['fieldIconLeft']) && is_string($element['fieldIconLeft']) ? sanitize_text_field($element['fieldIconLeft']) : '';
3268:                 $element['fieldIconRight'] = isset($element['fieldIconRight']) && is_string($element['fieldIconRight']) ? sanitize_text_field($element['fieldIconRight']) : 'qicon-schedule';
3269:                 $element['fieldSize'] = isset($element['fieldSize']) && is_string($element['fieldSize']) ? sanitize_text_field($element['fieldSize']) : 'inherit';
3270:                 $element['fieldWidth'] = isset($element['fieldWidth']) && is_string($element['fieldWidth']) ? sanitize_text_field($element['fieldWidth']) : 'inherit';
3271:                 $element['fieldWidthCustom'] = isset($element['fieldWidthCustom']) && is_string($element['fieldWidthCustom']) ? sanitize_text_field($element['fieldWidthCustom']) : '';
3272:                 $element['customClass'] = isset($element['customClass']) && is_string($element['customClass']) ? Quform::sanitizeClass($element['customClass']) : '';
3273:                 $element['customElementClass'] = isset($element['customElementClass']) && is_string($element['customElementClass']) ? Quform::sanitizeClass($element['customElementClass']) : '';
3274:                 $element['styles'] = isset($element['styles']) && is_array($element['styles']) ? $this->sanitizeStyles($element['styles'], $element['type']) : array();
3275: 
3276:                 // Labels
3277:                 $element['placeholder'] = isset($element['placeholder']) && is_string($element['placeholder']) ? sanitize_text_field($element['placeholder']) : '';
3278:                 $element['subLabel'] = isset($element['subLabel']) && is_string($element['subLabel']) ? wp_kses_post($element['subLabel']) : '';
3279:                 $element['subLabelAbove'] = isset($element['subLabelAbove']) && is_string($element['subLabelAbove']) ? wp_kses_post($element['subLabelAbove']) : '';
3280:                 $element['adminLabel'] = isset($element['adminLabel']) && is_string($element['adminLabel']) ? wp_kses_post($element['adminLabel']) : '';
3281:                 $element['tooltip'] = isset($element['tooltip']) && is_string($element['tooltip']) ? wp_kses_post($element['tooltip']) : '';
3282:                 $element['tooltipType'] = isset($element['tooltipType']) && is_string($element['tooltipType']) ? sanitize_text_field($element['tooltipType']) : 'inherit';
3283:                 $element['tooltipEvent'] = isset($element['tooltipEvent']) && is_string($element['tooltipEvent']) ? sanitize_text_field($element['tooltipEvent']) : 'inherit';
3284:                 $element['labelPosition'] = isset($element['labelPosition']) && is_string($element['labelPosition']) ? sanitize_text_field($element['labelPosition']) : 'inherit';
3285:                 $element['labelWidth'] = isset($element['labelWidth']) && is_string($element['labelWidth']) ? sanitize_text_field($element['labelWidth']) : '';
3286: 
3287:                 // Logic
3288:                 $element['logicEnabled'] = isset($element['logicEnabled']) && is_bool($element['logicEnabled']) ? $element['logicEnabled'] : false;
3289:                 $element['logicAction'] = isset($element['logicAction']) && is_bool($element['logicAction']) ? $element['logicAction'] : true;
3290:                 $element['logicMatch'] = isset($element['logicMatch']) && is_string($element['logicMatch']) ? sanitize_text_field($element['logicMatch']) : 'all';
3291:                 $element['logicRules'] = isset($element['logicRules']) && is_array($element['logicRules']) ? $this->sanitizeLogicRules($element['logicRules']) : array();
3292: 
3293:                 // Data
3294:                 $element['defaultValue'] = isset($element['defaultValue']) && is_string($element['defaultValue']) ? sanitize_text_field($element['defaultValue']) : '';
3295:                 $element['dynamicDefaultValue'] = isset($element['dynamicDefaultValue']) && is_bool($element['dynamicDefaultValue']) ? $element['dynamicDefaultValue'] : false;
3296:                 $element['dynamicKey'] = isset($element['dynamicKey']) && is_string($element['dynamicKey']) ? sanitize_text_field($element['dynamicKey']) : '';
3297:                 $element['timeMin'] = isset($element['timeMin']) && is_string($element['timeMin']) ? sanitize_text_field($element['timeMin']) : '';
3298:                 $element['timeMax'] = isset($element['timeMax']) && is_string($element['timeMax']) ? sanitize_text_field($element['timeMax']) : '';
3299:                 $element['timeInterval'] = isset($element['timeInterval']) && is_numeric($element['timeInterval']) ? (string) Quform::clamp((int) $element['timeInterval'], 1, 60) : '';
3300:                 $element['timeLocale'] = isset($element['timeLocale']) && is_string($element['timeLocale']) ? sanitize_text_field($element['timeLocale']) : '';
3301:                 $element['timeFormatJs'] = isset($element['timeFormatJs']) && is_string($element['timeFormatJs']) ? sanitize_text_field($element['timeFormatJs']) : '';
3302:                 $element['timeFormat'] = isset($element['timeFormat']) && is_string($element['timeFormat']) ? sanitize_text_field($element['timeFormat']) : '';
3303:                 $element['timeAutoOpen'] = isset($element['timeAutoOpen']) && is_bool($element['timeAutoOpen']) ? $element['timeAutoOpen'] : false;
3304:                 $element['readOnly'] = isset($element['readOnly']) && is_bool($element['readOnly']) ? $element['readOnly'] : false;
3305:                 $element['showInEmail'] = isset($element['showInEmail']) && is_bool($element['showInEmail']) ? $element['showInEmail'] : true;
3306:                 $element['saveToDatabase'] = isset($element['saveToDatabase']) && is_bool($element['saveToDatabase']) ? $element['saveToDatabase'] : true;
3307: 
3308:                 // Advanced
3309:                 $element['visibility'] = isset($element['visibility']) && is_string($element['visibility']) ? sanitize_text_field($element['visibility']) : '';
3310:                 $element['validators'] = isset($element['validators']) && is_array($element['validators']) ? $this->sanitizeValidators($element['validators'], $element['type']) : array();
3311: 
3312:                 // Translations
3313:                 $element['messageRequired'] = isset($element['messageRequired']) && is_string($element['messageRequired']) ? wp_kses_post($element['messageRequired']) : '';
3314:                 $element['messageTimeInvalidTime'] = isset($element['messageTimeInvalidTime']) && is_string($element['messageTimeInvalidTime']) ? wp_kses_post($element['messageTimeInvalidTime']) : '';
3315:                 $element['messageTimeTooEarly'] = isset($element['messageTimeTooEarly']) && is_string($element['messageTimeTooEarly']) ? wp_kses_post($element['messageTimeTooEarly']) : '';
3316:                 $element['messageTimeTooLate'] = isset($element['messageTimeTooLate']) && is_string($element['messageTimeTooLate']) ? wp_kses_post($element['messageTimeTooLate']) : '';
3317:                 break;
3318:             case 'password':
3319:                 // Basic
3320:                 $element['label'] = isset($element['label']) && is_string($element['label']) ? wp_kses_post($element['label']) : __('Password', 'quform');
3321:                 $element['description'] = isset($element['description']) && is_string($element['description']) ? wp_kses_post($element['description']) : '';
3322:                 $element['descriptionAbove'] = isset($element['descriptionAbove']) && is_string($element['descriptionAbove']) ? wp_kses_post($element['descriptionAbove']) : '';
3323:                 $element['required'] = isset($element['required']) && is_bool($element['required']) ? $element['required'] : false;
3324: 
3325:                 // Styles
3326:                 $element['labelIcon'] = isset($element['labelIcon']) && is_string($element['labelIcon']) ? sanitize_text_field($element['labelIcon']) : '';
3327:                 $element['fieldIconLeft'] = isset($element['fieldIconLeft']) && is_string($element['fieldIconLeft']) ? sanitize_text_field($element['fieldIconLeft']) : '';
3328:                 $element['fieldIconRight'] = isset($element['fieldIconRight']) && is_string($element['fieldIconRight']) ? sanitize_text_field($element['fieldIconRight']) : '';
3329:                 $element['fieldSize'] = isset($element['fieldSize']) && is_string($element['fieldSize']) ? sanitize_text_field($element['fieldSize']) : 'inherit';
3330:                 $element['fieldWidth'] = isset($element['fieldWidth']) && is_string($element['fieldWidth']) ? sanitize_text_field($element['fieldWidth']) : 'inherit';
3331:                 $element['fieldWidthCustom'] = isset($element['fieldWidthCustom']) && is_string($element['fieldWidthCustom']) ? sanitize_text_field($element['fieldWidthCustom']) : '';
3332:                 $element['customClass'] = isset($element['customClass']) && is_string($element['customClass']) ? Quform::sanitizeClass($element['customClass']) : '';
3333:                 $element['customElementClass'] = isset($element['customElementClass']) && is_string($element['customElementClass']) ? Quform::sanitizeClass($element['customElementClass']) : '';
3334:                 $element['styles'] = isset($element['styles']) && is_array($element['styles']) ? $this->sanitizeStyles($element['styles'], $element['type']) : array();
3335: 
3336:                 // Labels
3337:                 $element['placeholder'] = isset($element['placeholder']) && is_string($element['placeholder']) ? sanitize_text_field($element['placeholder']) : '';
3338:                 $element['subLabel'] = isset($element['subLabel']) && is_string($element['subLabel']) ? wp_kses_post($element['subLabel']) : '';
3339:                 $element['subLabelAbove'] = isset($element['subLabelAbove']) && is_string($element['subLabelAbove']) ? wp_kses_post($element['subLabelAbove']) : '';
3340:                 $element['adminLabel'] = isset($element['adminLabel']) && is_string($element['adminLabel']) ? wp_kses_post($element['adminLabel']) : '';
3341:                 $element['tooltip'] = isset($element['tooltip']) && is_string($element['tooltip']) ? wp_kses_post($element['tooltip']) : '';
3342:                 $element['tooltipType'] = isset($element['tooltipType']) && is_string($element['tooltipType']) ? sanitize_text_field($element['tooltipType']) : 'inherit';
3343:                 $element['tooltipEvent'] = isset($element['tooltipEvent']) && is_string($element['tooltipEvent']) ? sanitize_text_field($element['tooltipEvent']) : 'inherit';
3344:                 $element['labelPosition'] = isset($element['labelPosition']) && is_string($element['labelPosition']) ? sanitize_text_field($element['labelPosition']) : 'inherit';
3345:                 $element['labelWidth'] = isset($element['labelWidth']) && is_string($element['labelWidth']) ? sanitize_text_field($element['labelWidth']) : '';
3346: 
3347:                 // Logic
3348:                 $element['logicEnabled'] = isset($element['logicEnabled']) && is_bool($element['logicEnabled']) ? $element['logicEnabled'] : false;
3349:                 $element['logicAction'] = isset($element['logicAction']) && is_bool($element['logicAction']) ? $element['logicAction'] : true;
3350:                 $element['logicMatch'] = isset($element['logicMatch']) && is_string($element['logicMatch']) ? sanitize_text_field($element['logicMatch']) : 'all';
3351:                 $element['logicRules'] = isset($element['logicRules']) && is_array($element['logicRules']) ? $this->sanitizeLogicRules($element['logicRules']) : array();
3352: 
3353:                 // Data
3354:                 $element['autocomplete'] = isset($element['autocomplete']) && is_string($element['autocomplete']) ? sanitize_text_field($element['autocomplete']) : '';
3355:                 $element['maxLength'] = isset($element['maxLength']) && is_numeric($element['maxLength']) ? (string) (int) $element['maxLength'] : '';
3356: 
3357:                 // Advanced
3358:                 $element['visibility'] = isset($element['visibility']) && is_string($element['visibility']) ? sanitize_text_field($element['visibility']) : '';
3359:                 $element['validators'] = isset($element['validators']) && is_array($element['validators']) ? $this->sanitizeValidators($element['validators'], $element['type']) : array();
3360: 
3361:                 // Translations
3362:                 $element['messageRequired'] = isset($element['messageRequired']) && is_string($element['messageRequired']) ? wp_kses_post($element['messageRequired']) : '';
3363:                 $element['messageLengthTooLong'] = isset($element['messageLengthTooLong']) && is_string($element['messageLengthTooLong']) ? wp_kses_post($element['messageLengthTooLong']) : '';
3364:                 break;
3365:             case 'hidden':
3366:                 // Basic
3367:                 $element['label'] = isset($element['label']) && is_string($element['label']) ? wp_kses_post($element['label']) : __('Hidden', 'quform');
3368: 
3369:                 // Styles
3370:                 $element['customClass'] = isset($element['customClass']) && is_string($element['customClass']) ? Quform::sanitizeClass($element['customClass']) : '';
3371: 
3372:                 // Data
3373:                 $element['defaultValue'] = isset($element['defaultValue']) && is_string($element['defaultValue']) ? sanitize_text_field($element['defaultValue']) : '';
3374:                 $element['dynamicDefaultValue'] = isset($element['dynamicDefaultValue']) && is_bool($element['dynamicDefaultValue']) ? $element['dynamicDefaultValue'] : false;
3375:                 $element['dynamicKey'] = isset($element['dynamicKey']) && is_string($element['dynamicKey']) ? sanitize_text_field($element['dynamicKey']) : '';
3376:                 $element['showInEmail'] = isset($element['showInEmail']) && is_bool($element['showInEmail']) ? $element['showInEmail'] : true;
3377:                 $element['saveToDatabase'] = isset($element['saveToDatabase']) && is_bool($element['saveToDatabase']) ? $element['saveToDatabase'] : true;
3378: 
3379:                 // Advanced
3380:                 $element['visibility'] = isset($element['visibility']) && is_string($element['visibility']) ? sanitize_text_field($element['visibility']) : '';
3381:                 break;
3382:             case 'name':
3383:                 // Basic
3384:                 $element['label'] = isset($element['label']) && is_string($element['label']) ? wp_kses_post($element['label']) : __('Name', 'quform');
3385:                 $element['description'] = isset($element['description']) && is_string($element['description']) ? wp_kses_post($element['description']) : '';
3386:                 $element['descriptionAbove'] = isset($element['descriptionAbove']) && is_string($element['descriptionAbove']) ? wp_kses_post($element['descriptionAbove']) : '';
3387:                 $element['prefixEnabled'] = isset($element['prefixEnabled']) && is_bool($element['prefixEnabled']) ? $element['prefixEnabled'] : false;
3388:                 $element['prefixRequired'] = isset($element['prefixRequired']) && is_bool($element['prefixRequired']) ? $element['prefixRequired'] : false;
3389:                 $element['prefixOptions'] = isset($element['prefixOptions']) && is_array($element['prefixOptions']) ? $this->sanitizeSelectOptions($element['prefixOptions']) : array();
3390:                 $element['prefixNextOptionId'] = isset($element['prefixNextOptionId']) && is_numeric($element['prefixNextOptionId']) ? (int) $element['prefixNextOptionId'] : 1;
3391:                 $element['prefixDefaultValue'] = isset($element['prefixDefaultValue']) && is_string($element['prefixDefaultValue']) ? wp_kses_post($element['prefixDefaultValue']) : '';
3392:                 $element['prefixCustomiseValues'] = isset($element['prefixCustomiseValues']) && is_bool($element['prefixCustomiseValues']) ? $element['prefixCustomiseValues'] : false;
3393:                 $element['prefixNoneOption'] = isset($element['prefixNoneOption']) && is_bool($element['prefixNoneOption']) ? $element['prefixNoneOption'] : true;
3394:                 $element['prefixSubLabel'] = isset($element['prefixSubLabel']) && is_string($element['prefixSubLabel']) ? wp_kses_post($element['prefixSubLabel']) : __('Prefix', 'quform');
3395:                 $element['prefixSubLabelAbove'] = isset($element['prefixSubLabelAbove']) && is_string($element['prefixSubLabelAbove']) ? wp_kses_post($element['prefixSubLabelAbove']) : '';
3396:                 $element['prefixCustomClass'] = isset($element['prefixCustomClass']) && is_string($element['prefixCustomClass']) ? Quform::sanitizeClass($element['prefixCustomClass']) : '';
3397:                 $element['prefixCustomElementClass'] = isset($element['prefixCustomElementClass']) && is_string($element['prefixCustomElementClass']) ? Quform::sanitizeClass($element['prefixCustomElementClass']) : '';
3398:                 $element['firstEnabled'] = isset($element['firstEnabled']) && is_bool($element['firstEnabled']) ? $element['firstEnabled'] : true;
3399:                 $element['firstRequired'] = isset($element['firstRequired']) && is_bool($element['firstRequired']) ? $element['firstRequired'] : false;
3400:                 $element['firstPlaceholder'] = isset($element['firstPlaceholder']) && is_string($element['firstPlaceholder']) ? sanitize_text_field($element['firstPlaceholder']) : '';
3401:                 $element['firstSubLabel'] = isset($element['firstSubLabel']) && is_string($element['firstSubLabel']) ? wp_kses_post($element['firstSubLabel']) : __('First', 'quform');
3402:                 $element['firstSubLabelAbove'] = isset($element['firstSubLabelAbove']) && is_string($element['firstSubLabelAbove']) ? wp_kses_post($element['firstSubLabelAbove']) : '';
3403:                 $element['firstDefaultValue'] = isset($element['firstDefaultValue']) && is_string($element['firstDefaultValue']) ? sanitize_text_field($element['firstDefaultValue']) : '';
3404:                 $element['firstCustomClass'] = isset($element['firstCustomClass']) && is_string($element['firstCustomClass']) ? Quform::sanitizeClass($element['firstCustomClass']) : '';
3405:                 $element['firstCustomElementClass'] = isset($element['firstCustomElementClass']) && is_string($element['firstCustomElementClass']) ? Quform::sanitizeClass($element['firstCustomElementClass']) : '';
3406:                 $element['firstAutocomplete'] = isset($element['firstAutocomplete']) && is_string($element['firstAutocomplete']) ? sanitize_text_field($element['firstAutocomplete']) : '';
3407:                 $element['middleEnabled'] = isset($element['middleEnabled']) && is_bool($element['middleEnabled']) ? $element['middleEnabled'] : false;
3408:                 $element['middleRequired'] = isset($element['middleRequired']) && is_bool($element['middleRequired']) ? $element['middleRequired'] : false;
3409:                 $element['middlePlaceholder'] = isset($element['middlePlaceholder']) && is_string($element['middlePlaceholder']) ? sanitize_text_field($element['middlePlaceholder']) : '';
3410:                 $element['middleSubLabel'] = isset($element['middleSubLabel']) && is_string($element['middleSubLabel']) ? wp_kses_post($element['middleSubLabel']) : __('Middle', 'quform');
3411:                 $element['middleSubLabelAbove'] = isset($element['middleSubLabelAbove']) && is_string($element['middleSubLabelAbove']) ? wp_kses_post($element['middleSubLabelAbove']) : '';
3412:                 $element['middleDefaultValue'] = isset($element['middleDefaultValue']) && is_string($element['middleDefaultValue']) ? sanitize_text_field($element['middleDefaultValue']) : '';
3413:                 $element['middleCustomClass'] = isset($element['middleCustomClass']) && is_string($element['middleCustomClass']) ? Quform::sanitizeClass($element['middleCustomClass']) : '';
3414:                 $element['middleCustomElementClass'] = isset($element['middleCustomElementClass']) && is_string($element['middleCustomElementClass']) ? Quform::sanitizeClass($element['middleCustomElementClass']) : '';
3415:                 $element['middleAutocomplete'] = isset($element['middleAutocomplete']) && is_string($element['middleAutocomplete']) ? sanitize_text_field($element['middleAutocomplete']) : '';
3416:                 $element['lastEnabled'] = isset($element['lastEnabled']) && is_bool($element['lastEnabled']) ? $element['lastEnabled'] : true;
3417:                 $element['lastRequired'] = isset($element['lastRequired']) && is_bool($element['lastRequired']) ? $element['lastRequired'] : false;
3418:                 $element['lastPlaceholder'] = isset($element['lastPlaceholder']) && is_string($element['lastPlaceholder']) ? sanitize_text_field($element['lastPlaceholder']) : '';
3419:                 $element['lastSubLabel'] = isset($element['lastSubLabel']) && is_string($element['lastSubLabel']) ? wp_kses_post($element['lastSubLabel']) : __('Last', 'quform');
3420:                 $element['lastSubLabelAbove'] = isset($element['lastSubLabelAbove']) && is_string($element['lastSubLabelAbove']) ? wp_kses_post($element['lastSubLabelAbove']) : '';
3421:                 $element['lastDefaultValue'] = isset($element['lastDefaultValue']) && is_string($element['lastDefaultValue']) ? sanitize_text_field($element['lastDefaultValue']) : '';
3422:                 $element['lastCustomClass'] = isset($element['lastCustomClass']) && is_string($element['lastCustomClass']) ? Quform::sanitizeClass($element['lastCustomClass']) : '';
3423:                 $element['lastCustomElementClass'] = isset($element['lastCustomElementClass']) && is_string($element['lastCustomElementClass']) ? Quform::sanitizeClass($element['lastCustomElementClass']) : '';
3424:                 $element['lastAutocomplete'] = isset($element['lastAutocomplete']) && is_string($element['lastAutocomplete']) ? sanitize_text_field($element['lastAutocomplete']) : '';
3425:                 $element['suffixEnabled'] = isset($element['suffixEnabled']) && is_bool($element['suffixEnabled']) ? $element['suffixEnabled'] : false;
3426:                 $element['suffixRequired'] = isset($element['suffixRequired']) && is_bool($element['suffixRequired']) ? $element['suffixRequired'] : false;
3427:                 $element['suffixPlaceholder'] = isset($element['suffixPlaceholder']) && is_string($element['suffixPlaceholder']) ? sanitize_text_field($element['suffixPlaceholder']) : '';
3428:                 $element['suffixSubLabel'] = isset($element['suffixSubLabel']) && is_string($element['suffixSubLabel']) ? wp_kses_post($element['suffixSubLabel']) : __('Suffix', 'quform');
3429:                 $element['suffixSubLabelAbove'] = isset($element['suffixSubLabelAbove']) && is_string($element['suffixSubLabelAbove']) ? wp_kses_post($element['suffixSubLabelAbove']) : '';
3430:                 $element['suffixDefaultValue'] = isset($element['suffixDefaultValue']) && is_string($element['suffixDefaultValue']) ? sanitize_text_field($element['suffixDefaultValue']) : '';
3431:                 $element['suffixCustomClass'] = isset($element['suffixCustomClass']) && is_string($element['suffixCustomClass']) ? Quform::sanitizeClass($element['suffixCustomClass']) : '';
3432:                 $element['suffixCustomElementClass'] = isset($element['suffixCustomElementClass']) && is_string($element['suffixCustomElementClass']) ? Quform::sanitizeClass($element['suffixCustomElementClass']) : '';
3433: 
3434:                 // Styles
3435:                 $element['labelIcon'] = isset($element['labelIcon']) && is_string($element['labelIcon']) ? sanitize_text_field($element['labelIcon']) : '';
3436:                 $element['fieldSize'] = isset($element['fieldSize']) && is_string($element['fieldSize']) ? sanitize_text_field($element['fieldSize']) : 'inherit';
3437:                 $element['fieldWidth'] = isset($element['fieldWidth']) && is_string($element['fieldWidth']) ? sanitize_text_field($element['fieldWidth']) : 'inherit';
3438:                 $element['fieldWidthCustom'] = isset($element['fieldWidthCustom']) && is_string($element['fieldWidthCustom']) ? sanitize_text_field($element['fieldWidthCustom']) : '';
3439:                 $element['responsiveColumns'] = isset($element['responsiveColumns']) && is_string($element['responsiveColumns']) ? sanitize_text_field($element['responsiveColumns']) : 'inherit';
3440:                 $element['responsiveColumnsCustom'] = isset($element['responsiveColumnsCustom']) && is_string($element['responsiveColumnsCustom']) ? sanitize_text_field($element['responsiveColumnsCustom']) : '';
3441:                 $element['customClass'] = isset($element['customClass']) && is_string($element['customClass']) ? Quform::sanitizeClass($element['customClass']) : '';
3442:                 $element['customElementClass'] = isset($element['customElementClass']) && is_string($element['customElementClass']) ? Quform::sanitizeClass($element['customElementClass']) : '';
3443:                 $element['styles'] = isset($element['styles']) && is_array($element['styles']) ? $this->sanitizeStyles($element['styles'], $element['type']) : array();
3444: 
3445:                 // Labels
3446:                 $element['subLabel'] = isset($element['subLabel']) && is_string($element['subLabel']) ? wp_kses_post($element['subLabel']) : '';
3447:                 $element['subLabelAbove'] = isset($element['subLabelAbove']) && is_string($element['subLabelAbove']) ? wp_kses_post($element['subLabelAbove']) : '';
3448:                 $element['adminLabel'] = isset($element['adminLabel']) && is_string($element['adminLabel']) ? wp_kses_post($element['adminLabel']) : '';
3449:                 $element['tooltip'] = isset($element['tooltip']) && is_string($element['tooltip']) ? wp_kses_post($element['tooltip']) : '';
3450:                 $element['tooltipType'] = isset($element['tooltipType']) && is_string($element['tooltipType']) ? sanitize_text_field($element['tooltipType']) : 'icon';
3451:                 $element['tooltipEvent'] = isset($element['tooltipEvent']) && is_string($element['tooltipEvent']) ? sanitize_text_field($element['tooltipEvent']) : 'inherit';
3452:                 $element['labelPosition'] = isset($element['labelPosition']) && is_string($element['labelPosition']) ? sanitize_text_field($element['labelPosition']) : 'inherit';
3453:                 $element['labelWidth'] = isset($element['labelWidth']) && is_string($element['labelWidth']) ? sanitize_text_field($element['labelWidth']) : '';
3454: 
3455:                 // Logic
3456:                 $element['logicEnabled'] = isset($element['logicEnabled']) && is_bool($element['logicEnabled']) ? $element['logicEnabled'] : false;
3457:                 $element['logicAction'] = isset($element['logicAction']) && is_bool($element['logicAction']) ? $element['logicAction'] : true;
3458:                 $element['logicMatch'] = isset($element['logicMatch']) && is_string($element['logicMatch']) ? sanitize_text_field($element['logicMatch']) : 'all';
3459:                 $element['logicRules'] = isset($element['logicRules']) && is_array($element['logicRules']) ? $this->sanitizeLogicRules($element['logicRules']) : array();
3460: 
3461:                 // Data
3462:                 $element['dynamicDefaultValue'] = isset($element['dynamicDefaultValue']) && is_bool($element['dynamicDefaultValue']) ? $element['dynamicDefaultValue'] : false;
3463:                 $element['dynamicKey'] = isset($element['dynamicKey']) && is_string($element['dynamicKey']) ? sanitize_text_field($element['dynamicKey']) : '';
3464:                 $element['showInEmail'] = isset($element['showInEmail']) && is_bool($element['showInEmail']) ? $element['showInEmail'] : true;
3465:                 $element['saveToDatabase'] = isset($element['saveToDatabase']) && is_bool($element['saveToDatabase']) ? $element['saveToDatabase'] : true;
3466: 
3467:                 // Advanced
3468:                 $element['visibility'] = isset($element['visibility']) && is_string($element['visibility']) ? sanitize_text_field($element['visibility']) : '';
3469:                 $element['validators'] = isset($element['validators']) && is_array($element['validators']) ? $this->sanitizeValidators($element['validators'], $element['type']) : array();
3470: 
3471:                 // Translations
3472:                 $element['prefixNoneOptionText'] = isset($element['prefixNoneOptionText']) && is_string($element['prefixNoneOptionText']) ? wp_kses_post($element['prefixNoneOptionText']) : '';
3473:                 $element['messageRequired'] = isset($element['messageRequired']) && is_string($element['messageRequired']) ? wp_kses_post($element['messageRequired']) : '';
3474:                 break;
3475:             case 'group':
3476:                 // Basic
3477:                 $element['label'] = isset($element['label']) && is_string($element['label']) ? wp_kses_post($element['label']) : __('Untitled group', 'quform');
3478:                 $element['title'] = isset($element['title']) && is_string($element['title']) ? wp_kses_post($element['title']) : '';
3479:                 $element['titleTag'] = isset($element['titleTag']) && is_string($element['titleTag']) ? sanitize_text_field($element['titleTag']) : 'h4';
3480:                 $element['description'] = isset($element['description']) && is_string($element['description']) ? wp_kses_post($element['description']) : '';
3481: 
3482:                 // Styles
3483:                 $element['fieldSize'] = isset($element['fieldSize']) && is_string($element['fieldSize']) ? sanitize_text_field($element['fieldSize']) : 'inherit';
3484:                 $element['fieldWidth'] = isset($element['fieldWidth']) && is_string($element['fieldWidth']) ? sanitize_text_field($element['fieldWidth']) : 'inherit';
3485:                 $element['fieldWidthCustom'] = isset($element['fieldWidthCustom']) && is_string($element['fieldWidthCustom']) ? sanitize_text_field($element['fieldWidthCustom']) : '';
3486:                 $element['groupStyle'] = isset($element['groupStyle']) && is_string($element['groupStyle']) ? sanitize_text_field($element['groupStyle']) : 'plain';
3487:                 $element['borderColor'] = isset($element['borderColor']) && is_string($element['borderColor']) ? sanitize_text_field($element['borderColor']) : '';
3488:                 $element['backgroundColor'] = isset($element['backgroundColor']) && is_string($element['backgroundColor']) ? sanitize_text_field($element['backgroundColor']) : '';
3489:                 $element['customElementClass'] = isset($element['customElementClass']) && is_string($element['customElementClass']) ? Quform::sanitizeClass($element['customElementClass']) : '';
3490:                 $element['styles'] = isset($element['styles']) && is_array($element['styles']) ? $this->sanitizeStyles($element['styles'], $element['type']) : array();
3491: 
3492:                 // Labels
3493:                 $element['tooltipType'] = isset($element['tooltipType']) && is_string($element['tooltipType']) ? sanitize_text_field($element['tooltipType']) : 'inherit';
3494:                 $element['tooltipEvent'] = isset($element['tooltipEvent']) && is_string($element['tooltipEvent']) ? sanitize_text_field($element['tooltipEvent']) : 'inherit';
3495:                 $element['labelPosition'] = isset($element['labelPosition']) && is_string($element['labelPosition']) ? sanitize_text_field($element['labelPosition']) : 'inherit';
3496:                 $element['labelWidth'] = isset($element['labelWidth']) && is_string($element['labelWidth']) ? sanitize_text_field($element['labelWidth']) : '';
3497:                 $element['showLabelInEmail'] = isset($element['showLabelInEmail']) && is_bool($element['showLabelInEmail']) ? $element['showLabelInEmail'] : false;
3498:                 $element['showLabelInEntry'] = isset($element['showLabelInEntry']) && is_bool($element['showLabelInEntry']) ? $element['showLabelInEntry'] : false;
3499: 
3500:                 // Logic
3501:                 $element['logicEnabled'] = isset($element['logicEnabled']) && is_bool($element['logicEnabled']) ? $element['logicEnabled'] : false;
3502:                 $element['logicAction'] = isset($element['logicAction']) && is_bool($element['logicAction']) ? $element['logicAction'] : true;
3503:                 $element['logicMatch'] = isset($element['logicMatch']) && is_string($element['logicMatch']) ? sanitize_text_field($element['logicMatch']) : 'all';
3504:                 $element['logicRules'] = isset($element['logicRules']) && is_array($element['logicRules']) ? $this->sanitizeLogicRules($element['logicRules']) : array();
3505: 
3506:                 if ( ! isset($element['elements']) || ! is_array($element['elements'])) {
3507:                     $element['elements'] = array();
3508:                 }
3509:                 break;
3510:             case 'page':
3511:                 // Basic
3512:                 $element['label'] = isset($element['label']) && is_string($element['label']) ? wp_kses_post($element['label']) : '';
3513:                 $element['title'] = isset($element['title']) && is_string($element['title']) ? wp_kses_post($element['title']) : '';
3514:                 $element['titleTag'] = isset($element['titleTag']) && is_string($element['titleTag']) ? sanitize_text_field($element['titleTag']) : 'h3';
3515:                 $element['description'] = isset($element['description']) && is_string($element['description']) ? wp_kses_post($element['description']) : '';
3516: 
3517:                 // Styles
3518:                 $element['fieldSize'] = isset($element['fieldSize']) && is_string($element['fieldSize']) ? sanitize_text_field($element['fieldSize']) : 'inherit';
3519:                 $element['fieldWidth'] = isset($element['fieldWidth']) && is_string($element['fieldWidth']) ? sanitize_text_field($element['fieldWidth']) : 'inherit';
3520:                 $element['fieldWidthCustom'] = isset($element['fieldWidthCustom']) && is_string($element['fieldWidthCustom']) ? sanitize_text_field($element['fieldWidthCustom']) : '';
3521:                 $element['groupStyle'] = isset($element['groupStyle']) && is_string($element['groupStyle']) ? sanitize_text_field($element['groupStyle']) : 'plain';
3522:                 $element['borderColor'] = isset($element['borderColor']) && is_string($element['borderColor']) ? sanitize_text_field($element['borderColor']) : '';
3523:                 $element['backgroundColor'] = isset($element['backgroundColor']) && is_string($element['backgroundColor']) ? sanitize_text_field($element['backgroundColor']) : '';
3524:                 $element['styles'] = isset($element['styles']) && is_array($element['styles']) ? $this->sanitizeStyles($element['styles'], $element['type']) : array();
3525: 
3526:                 // Labels
3527:                 $element['tooltipType'] = isset($element['tooltipType']) && is_string($element['tooltipType']) ? sanitize_text_field($element['tooltipType']) : 'inherit';
3528:                 $element['tooltipEvent'] = isset($element['tooltipEvent']) && is_string($element['tooltipEvent']) ? sanitize_text_field($element['tooltipEvent']) : 'inherit';
3529:                 $element['labelPosition'] = isset($element['labelPosition']) && is_string($element['labelPosition']) ? sanitize_text_field($element['labelPosition']) : 'inherit';
3530:                 $element['labelWidth'] = isset($element['labelWidth']) && is_string($element['labelWidth']) ? sanitize_text_field($element['labelWidth']) : '';
3531:                 $element['showLabelInEmail'] = isset($element['showLabelInEmail']) && is_bool($element['showLabelInEmail']) ? $element['showLabelInEmail'] : false;
3532:                 $element['showLabelInEntry'] = isset($element['showLabelInEntry']) && is_bool($element['showLabelInEntry']) ? $element['showLabelInEntry'] : false;
3533: 
3534:                 // Logic
3535:                 $element['logicEnabled'] = isset($element['logicEnabled']) && is_bool($element['logicEnabled']) ? $element['logicEnabled'] : false;
3536:                 $element['logicAction'] = isset($element['logicAction']) && is_bool($element['logicAction']) ? $element['logicAction'] : true;
3537:                 $element['logicMatch'] = isset($element['logicMatch']) && is_string($element['logicMatch']) ? sanitize_text_field($element['logicMatch']) : 'all';
3538:                 $element['logicRules'] = isset($element['logicRules']) && is_array($element['logicRules']) ? $this->sanitizeLogicRules($element['logicRules']) : array();
3539: 
3540:                 if ( ! isset($element['elements']) || ! is_array($element['elements'])) {
3541:                     $element['elements'] = array();
3542:                 }
3543:                 break;
3544:             case 'submit':
3545:                 // Basic
3546:                 $element['label'] = isset($element['label']) && is_string($element['label']) ? wp_kses_post($element['label']) : __('Submit', 'quform');
3547:                 $element['submitType'] = isset($element['submitType']) && is_string($element['submitType']) ? sanitize_text_field($element['submitType']) : 'inherit';
3548:                 $element['submitText'] = isset($element['submitText']) && is_string($element['submitText']) ? sanitize_text_field($element['submitText']) : '';
3549:                 $element['submitIcon'] = isset($element['submitIcon']) && is_string($element['submitIcon']) ? sanitize_text_field($element['submitIcon']) : '';
3550:                 $element['submitIconPosition'] = isset($element['submitIconPosition']) && is_string($element['submitIconPosition']) ? sanitize_text_field($element['submitIconPosition']) : 'inherit';
3551:                 $element['submitImage'] = isset($element['submitImage']) && is_string($element['submitImage']) ? esc_url_raw($element['submitImage']) : '';
3552:                 $element['submitHtml'] = isset($element['submitHtml']) && is_string($element['submitHtml']) ? wp_kses_post($element['submitHtml']) : '';
3553:                 $element['nextType'] = isset($element['nextType']) && is_string($element['nextType']) ? sanitize_text_field($element['nextType']) : 'inherit';
3554:                 $element['nextText'] = isset($element['nextText']) && is_string($element['nextText']) ? sanitize_text_field($element['nextText']) : '';
3555:                 $element['nextIcon'] = isset($element['nextIcon']) && is_string($element['nextIcon']) ? sanitize_text_field($element['nextIcon']) : '';
3556:                 $element['nextIconPosition'] = isset($element['nextIconPosition']) && is_string($element['nextIconPosition']) ? sanitize_text_field($element['nextIconPosition']) : 'inherit';
3557:                 $element['nextImage'] = isset($element['nextImage']) && is_string($element['nextImage']) ? esc_url_raw($element['nextImage']) : '';
3558:                 $element['nextHtml'] = isset($element['nextHtml']) && is_string($element['nextHtml']) ? wp_kses_post($element['nextHtml']) : '';
3559:                 $element['backType'] = isset($element['backType']) && is_string($element['backType']) ? sanitize_text_field($element['backType']) : 'inherit';
3560:                 $element['backText'] = isset($element['backText']) && is_string($element['backText']) ? sanitize_text_field($element['backText']) : '';
3561:                 $element['backIcon'] = isset($element['backIcon']) && is_string($element['backIcon']) ? sanitize_text_field($element['backIcon']) : '';
3562:                 $element['backIconPosition'] = isset($element['backIconPosition']) && is_string($element['backIconPosition']) ? sanitize_text_field($element['backIconPosition']) : 'inherit';
3563:                 $element['backImage'] = isset($element['backImage']) && is_string($element['backImage']) ? esc_url_raw($element['backImage']) : '';
3564:                 $element['backHtml'] = isset($element['backHtml']) && is_string($element['backHtml']) ? wp_kses_post($element['backHtml']) : '';
3565: 
3566:                 // Styles
3567:                 $element['buttonStyle'] = isset($element['buttonStyle']) && is_string($element['buttonStyle']) ? sanitize_text_field($element['buttonStyle']) : 'inherit';
3568:                 $element['buttonSize'] = isset($element['buttonSize']) && is_string($element['buttonSize']) ? sanitize_text_field($element['buttonSize']) : 'inherit';
3569:                 $element['buttonWidth'] = isset($element['buttonWidth']) && is_string($element['buttonWidth']) ? sanitize_text_field($element['buttonWidth']) : 'inherit';
3570:                 $element['buttonWidthCustom'] = isset($element['buttonWidthCustom']) && is_string($element['buttonWidthCustom']) ? sanitize_text_field($element['buttonWidthCustom']) : '';
3571:                 $element['customElementClass'] = isset($element['customElementClass']) && is_string($element['customElementClass']) ? Quform::sanitizeClass($element['customElementClass']) : '';
3572:                 $element['styles'] = isset($element['styles']) && is_array($element['styles']) ? $this->sanitizeStyles($element['styles'], $element['type']) : array();
3573: 
3574:                 // Logic
3575:                 $element['logicEnabled'] = isset($element['logicEnabled']) && is_bool($element['logicEnabled']) ? $element['logicEnabled'] : false;
3576:                 $element['logicAction'] = isset($element['logicAction']) && is_bool($element['logicAction']) ? $element['logicAction'] : true;
3577:                 $element['logicMatch'] = isset($element['logicMatch']) && is_string($element['logicMatch']) ? sanitize_text_field($element['logicMatch']) : 'all';
3578:                 $element['logicRules'] = isset($element['logicRules']) && is_array($element['logicRules']) ? $this->sanitizeLogicRules($element['logicRules']) : array();
3579:                 break;
3580:             case 'row':
3581:                 $element['columnSize'] = isset($element['columnSize']) && is_string($element['columnSize']) ? sanitize_text_field($element['columnSize']) : 'fixed';
3582:                 $element['responsiveColumns'] = isset($element['responsiveColumns']) && is_string($element['responsiveColumns']) ? sanitize_text_field($element['responsiveColumns']) : 'inherit';
3583:                 $element['responsiveColumnsCustom'] = isset($element['responsiveColumnsCustom']) && is_string($element['responsiveColumnsCustom']) ? sanitize_text_field($element['responsiveColumnsCustom']) : '';
3584: 
3585:                 if ( ! isset($element['elements']) || ! is_array($element['elements'])) {
3586:                     $element['elements'] = array();
3587:                 }
3588:                 break;
3589:             case 'column':
3590:                 $element['width'] = isset($element['width']) && is_string($element['width']) && is_numeric($element['width']) ? (string) (float) $element['width'] : '';
3591: 
3592:                 if ( ! isset($element['elements']) || ! is_array($element['elements'])) {
3593:                     $element['elements'] = array();
3594:                 }
3595:                 break;
3596:         }
3597: 
3598:         return $element;
3599:     }
3600: 
3601:     /**
3602:      * Sanitize the HTML in the given string
3603:      *
3604:      * @param   string  $value
3605:      * @return  string
3606:      */
3607:     protected function sanitizeHtml($value)
3608:     {
3609:         return current_user_can('unfiltered_html') ? $value : wp_kses_post($value);
3610:     }
3611: 
3612:     /**
3613:      * Sanitize the settings for the given styles
3614:      *
3615:      * @param   array   $styles
3616:      * @param   string  $elementType
3617:      * @return  array
3618:      */
3619:     protected function sanitizeStyles(array $styles, $elementType)
3620:     {
3621:         $allStyles = $this->getStyles();
3622:         $visibleStyles = $this->getVisibleStyles();
3623:         $sanitizedStyles = array();
3624: 
3625:         foreach ($styles as $key => $style) {
3626:             if ( ! isset($style['type']) ||
3627:                  ! is_string($style['type']) ||
3628:                  ! array_key_exists($style['type'], $allStyles) ||
3629:                  ! array_key_exists($elementType, $visibleStyles) ||
3630:                  ! in_array($style['type'], $visibleStyles[$elementType], true)
3631:             ) {
3632:                 continue;
3633:             }
3634: 
3635:             $style['css'] = isset($style['css']) && is_string($style['css']) ? wp_strip_all_tags($style['css']) : '';
3636: 
3637:             $sanitizedStyles[] = $style;
3638:         }
3639: 
3640:         return $sanitizedStyles;
3641:     }
3642: 
3643:     /**
3644:      * Sanitize the settings for the given logic rules
3645:      *
3646:      * @param   array  $rules  The logic rules to sanitize
3647:      * @return  array          The sanitized logic rules
3648:      */
3649:     protected function sanitizeLogicRules(array $rules)
3650:     {
3651:         foreach ($rules as $key => $rule) {
3652:             $rules[$key]['elementId'] = isset($rule['elementId']) && is_numeric($rule['elementId']) ? (string) (int) $rule['elementId'] : '';
3653:             $rules[$key]['operator'] = isset($rule['operator']) && is_string($rule['operator']) ? sanitize_text_field($rule['operator']) : 'eq';
3654:             $rules[$key]['optionId'] = isset($rule['optionId']) && is_numeric($rule['optionId']) ? (string) (int) $rule['optionId'] : null;
3655:             $rules[$key]['value'] = isset($rule['value']) && is_string($rule['value']) ? wp_kses_no_null($rule['value'], array('slash_zero' => 'keep')) : '';
3656:         }
3657: 
3658:         return $rules;
3659:     }
3660: 
3661:     /**
3662:      * Sanitize the settings for the given filters
3663:      *
3664:      * @param   array   $filters      The filters to sanitize
3665:      * @param   string  $elementType  The element type
3666:      * @return  array                 The sanitized filters
3667:      */
3668:     protected function sanitizeFilters(array $filters, $elementType)
3669:     {
3670:         $allFilters = $this->getFilters();
3671:         $visibleFilters = $this->getVisibleFilters();
3672:         $sanitizedFilters = array();
3673: 
3674:         foreach ($filters as $key => $filter) {
3675:             if ( ! isset($filter['type']) ||
3676:                  ! is_string($filter['type']) ||
3677:                  ! array_key_exists($filter['type'], $allFilters) ||
3678:                  ! array_key_exists($elementType, $visibleFilters) ||
3679:                  ! in_array($filter['type'], $visibleFilters[$elementType], true)
3680:             ) {
3681:                 continue;
3682:             }
3683: 
3684:             switch ($filter['type']) {
3685:                 case 'alpha':
3686:                     $filter['allowWhiteSpace'] = isset($filter['allowWhiteSpace']) && is_bool($filter['allowWhiteSpace']) ? $filter['allowWhiteSpace'] : false;
3687:                     break;
3688:                 case 'alphaNumeric':
3689:                     $filter['allowWhiteSpace'] = isset($filter['allowWhiteSpace']) && is_bool($filter['allowWhiteSpace']) ? $filter['allowWhiteSpace'] : false;
3690:                     break;
3691:                 case 'digits':
3692:                     $filter['allowWhiteSpace'] = isset($filter['allowWhiteSpace']) && is_bool($filter['allowWhiteSpace']) ? $filter['allowWhiteSpace'] : false;
3693:                     break;
3694:                 case 'stripTags':
3695:                     $filter['allowableTags'] = isset($filter['allowableTags']) && is_string($filter['allowableTags']) ? wp_kses_post($filter['allowableTags']) : '';
3696:                     break;
3697:                 case 'regex':
3698:                     $filter['pattern'] = isset($filter['pattern']) && is_string($filter['pattern']) ? wp_kses_no_null($filter['pattern'], array('slash_zero' => 'keep')) : '';
3699:                     break;
3700:             }
3701: 
3702:             $sanitizedFilters[] = $filter;
3703:         }
3704: 
3705:         return $sanitizedFilters;
3706:     }
3707: 
3708:     /**
3709:      * Sanitize the settings for the given validators
3710:      *
3711:      * @param   array   $validators   The validators to sanitize
3712:      * @param   string  $elementType  The element type
3713:      * @return  array                 The sanitized validators
3714:      */
3715:     protected function sanitizeValidators(array $validators, $elementType)
3716:     {
3717:         $allValidators = $this->getValidators();
3718:         $visibleValidators = $this->getVisibleValidators();
3719:         $sanitizedValidators = array();
3720: 
3721:         foreach ($validators as $validator) {
3722:             if ( ! isset($validator['type']) ||
3723:                 ! is_string($validator['type']) ||
3724:                 ! array_key_exists($validator['type'], $allValidators) ||
3725:                 ! array_key_exists($elementType, $visibleValidators) ||
3726:                 ! in_array($validator['type'], $visibleValidators[$elementType], true)
3727:             ) {
3728:                 continue;
3729:             }
3730: 
3731:             switch ($validator['type']) {
3732:                 case 'alpha':
3733:                     $validator['allowWhiteSpace'] = isset($validator['allowWhiteSpace']) && is_bool($validator['allowWhiteSpace']) ? $validator['allowWhiteSpace'] : false;
3734: 
3735:                     if ( ! isset($validator['messages']) || ! is_array($validator['messages'])) {
3736:                         $validator['messages'] = array();
3737:                     }
3738: 
3739:                     $validator['messages']['notAlpha'] = isset($validator['messages']['notAlpha']) && is_string($validator['messages']['notAlpha']) ? wp_kses_post($validator['messages']['notAlpha']) : '';
3740:                     break;
3741:                 case 'alphaNumeric':
3742:                     $validator['allowWhiteSpace'] = isset($validator['allowWhiteSpace']) && is_bool($validator['allowWhiteSpace']) ? $validator['allowWhiteSpace'] : false;
3743: 
3744:                     if ( ! isset($validator['messages']) || ! is_array($validator['messages'])) {
3745:                         $validator['messages'] = array();
3746:                     }
3747: 
3748:                     $validator['messages']['notAlphaNumeric'] = isset($validator['messages']['notAlphaNumeric']) && is_string($validator['messages']['notAlphaNumeric']) ? wp_kses_post($validator['messages']['notAlphaNumeric']) : '';
3749:                     break;
3750:                 case 'digits':
3751:                     $validator['allowWhiteSpace'] = isset($validator['allowWhiteSpace']) && is_bool($validator['allowWhiteSpace']) ? $validator['allowWhiteSpace'] : false;
3752: 
3753:                     if ( ! isset($validator['messages']) || ! is_array($validator['messages'])) {
3754:                         $validator['messages'] = array();
3755:                     }
3756: 
3757:                     $validator['messages']['notDigits'] = isset($validator['messages']['notDigits']) && is_string($validator['messages']['notDigits']) ? wp_kses_post($validator['messages']['notDigits']) : '';
3758:                     break;
3759:                 case 'duplicate':
3760:                     if ( ! isset($validator['messages']) || ! is_array($validator['messages'])) {
3761:                         $validator['messages'] = array();
3762:                     }
3763: 
3764:                     $validator['messages']['isDuplicate'] = isset($validator['messages']['isDuplicate']) && is_string($validator['messages']['isDuplicate']) ? wp_kses_post($validator['messages']['isDuplicate']) : '';
3765:                     break;
3766:                 case 'email':
3767:                     if ( ! isset($validator['messages']) || ! is_array($validator['messages'])) {
3768:                         $validator['messages'] = array();
3769:                     }
3770: 
3771:                     $validator['messages']['emailAddressInvalidFormat'] = isset($validator['messages']['emailAddressInvalidFormat']) && is_string($validator['messages']['emailAddressInvalidFormat']) ? wp_kses_post($validator['messages']['emailAddressInvalidFormat']) : '';
3772:                     break;
3773:                 case 'greaterThan':
3774:                     $validator['min'] = isset($validator['min']) && is_numeric($validator['min']) ? (string) (float) $validator['min'] : '0';
3775:                     $validator['inclusive'] = isset($validator['inclusive']) && is_bool($validator['inclusive']) ? $validator['inclusive'] : false;
3776: 
3777:                     if ( ! isset($validator['messages']) || ! is_array($validator['messages'])) {
3778:                         $validator['messages'] = array();
3779:                     }
3780: 
3781:                     $validator['messages']['notGreaterThan'] = isset($validator['messages']['notGreaterThan']) && is_string($validator['messages']['notGreaterThan']) ? wp_kses_post($validator['messages']['notGreaterThan']) : '';
3782:                     $validator['messages']['notGreaterThanInclusive'] = isset($validator['messages']['notGreaterThanInclusive']) && is_string($validator['messages']['notGreaterThanInclusive']) ? wp_kses_post($validator['messages']['notGreaterThanInclusive']) : '';
3783:                     break;
3784:                 case 'identical':
3785:                     $validator['token'] = isset($validator['token']) && is_string($validator['token']) ? wp_kses_no_null($validator['token'], array('slash_zero' => 'keep')) : '';
3786: 
3787:                     if ( ! isset($validator['messages']) || ! is_array($validator['messages'])) {
3788:                         $validator['messages'] = array();
3789:                     }
3790: 
3791:                     $validator['messages']['notSame'] = isset($validator['messages']['notSame']) && is_string($validator['messages']['notSame']) ? wp_kses_post($validator['messages']['notSame']) : '';
3792:                     break;
3793:                 case 'inArray':
3794:                     if (isset($validator['haystack']) && is_array($validator['haystack'])) {
3795:                         foreach ($validator['haystack'] as $key => $item) {
3796:                             $validator['haystack'][$key] = is_string($item) ? wp_kses_no_null($item, array('slash_zero' => 'keep')) : '';
3797:                         }
3798:                     } else {
3799:                         $validator['haystack'] = array();
3800:                     }
3801: 
3802:                     $validator['invert'] = isset($validator['invert']) && is_bool($validator['invert']) ? $validator['invert'] : false;
3803: 
3804:                     if ( ! isset($validator['messages']) || ! is_array($validator['messages'])) {
3805:                         $validator['messages'] = array();
3806:                     }
3807: 
3808:                     $validator['messages']['notInArray'] = isset($validator['messages']['notInArray']) && is_string($validator['messages']['notInArray']) ? wp_kses_post($validator['messages']['notInArray']) : '';
3809:                     break;
3810:                 case 'length':
3811:                     $validator['min'] = isset($validator['min']) && is_numeric($validator['min']) ? (string) (int) $validator['min'] : '0';
3812:                     $validator['max'] = isset($validator['max']) && is_numeric($validator['max']) ? (string) (int) $validator['max'] : '';
3813: 
3814:                     if ( ! isset($validator['messages']) || ! is_array($validator['messages'])) {
3815:                         $validator['messages'] = array();
3816:                     }
3817: 
3818:                     $validator['messages']['lengthTooShort'] = isset($validator['messages']['lengthTooShort']) && is_string($validator['messages']['lengthTooShort']) ? wp_kses_post($validator['messages']['lengthTooShort']) : '';
3819:                     $validator['messages']['lengthTooLong'] = isset($validator['messages']['lengthTooLong']) && is_string($validator['messages']['lengthTooLong']) ? wp_kses_post($validator['messages']['lengthTooLong']) : '';
3820:                     break;
3821:                 case 'lessThan':
3822:                     $validator['max'] = isset($validator['max']) && is_numeric($validator['max']) ? (string) (float) $validator['max'] : '10';
3823:                     $validator['inclusive'] = isset($validator['inclusive']) && is_bool($validator['inclusive']) ? $validator['inclusive'] : false;
3824: 
3825:                     if ( ! isset($validator['messages']) || ! is_array($validator['messages'])) {
3826:                         $validator['messages'] = array();
3827:                     }
3828: 
3829:                     $validator['messages']['notLessThan'] = isset($validator['messages']['notLessThan']) && is_string($validator['messages']['notLessThan']) ? wp_kses_post($validator['messages']['notLessThan']) : '';
3830:                     $validator['messages']['notLessThanInclusive'] = isset($validator['messages']['notLessThanInclusive']) && is_string($validator['messages']['notLessThanInclusive']) ? wp_kses_post($validator['messages']['notLessThanInclusive']) : '';
3831:                     break;
3832:                 case 'regex':
3833:                     $validator['pattern'] = isset($validator['pattern']) && is_string($validator['pattern']) ? wp_kses_no_null($validator['pattern'], array('slash_zero' => 'keep')) : '';
3834:                     $validator['invert'] = isset($validator['invert']) && is_bool($validator['invert']) ? $validator['invert'] : false;
3835: 
3836:                     if ( ! isset($validator['messages']) || ! is_array($validator['messages'])) {
3837:                         $validator['messages'] = array();
3838:                     }
3839: 
3840:                     $validator['messages']['regexNotMatch'] = isset($validator['messages']['regexNotMatch']) && is_string($validator['messages']['regexNotMatch']) ? wp_kses_post($validator['messages']['regexNotMatch']) : '';
3841:                     break;
3842:             }
3843: 
3844:             $sanitizedValidators[] = $validator;
3845:         }
3846: 
3847:         return $sanitizedValidators;
3848:     }
3849: 
3850:     /**
3851:      * Sanitize the given select/multiselect options
3852:      *
3853:      * @param   array   $options The options to sanitize
3854:      * @return  array            The sanitized options
3855:      */
3856:     protected function sanitizeSelectOptions(array $options)
3857:     {
3858:         $sanitizedOptions = array();
3859: 
3860:         foreach ($options as $key => $option) {
3861:             if ( ! is_array($option)) {
3862:                 continue;
3863:             }
3864: 
3865:             if (isset($option['options'])) {
3866:                 $option['id'] = isset($option['id']) && is_numeric($option['id']) ? (int) $option['id'] : 0;
3867:                 $option['label'] = isset($option['label']) && is_string($option['label']) ? wp_kses_no_null($option['label'], array('slash_zero' => 'keep')) : __('Untitled', 'quform');
3868: 
3869:                 if (is_array($option['options'])) {
3870:                     foreach ($option['options'] as $optgroupOptionKey => $optgroupOption) {
3871:                         $option['options'][$optgroupOptionKey] = $this->sanitizeSelectOption($optgroupOption);
3872:                     }
3873:                 } else {
3874:                     $option['options'] = array();
3875:                 }
3876:             } else {
3877:                 $option = $this->sanitizeSelectOption($option);
3878:             }
3879: 
3880:             $sanitizedOptions[] = $option;
3881:         }
3882: 
3883:         return $sanitizedOptions;
3884:     }
3885: 
3886:     /**
3887:      * Sanitize the given select/multiselect option
3888:      *
3889:      * @param   array   $option  The option to sanitize
3890:      * @return  array            The sanitized option
3891:      */
3892:     protected function sanitizeSelectOption(array $option)
3893:     {
3894:         $option['id'] = isset($option['id']) && is_numeric($option['id']) ? (int) $option['id'] : 0;
3895:         $option['label'] = isset($option['label']) && is_string($option['label']) ? wp_kses_no_null($option['label'], array('slash_zero' => 'keep')) : '';
3896:         $option['value'] = isset($option['value']) && is_string($option['value']) ? wp_kses_no_null($option['value'], array('slash_zero' => 'keep')) : '';
3897: 
3898:         return $option;
3899:     }
3900: 
3901:     /**
3902:      * Sanitize the given checkbox/radio element options
3903:      *
3904:      * @param   array   $options  The options to sanitize
3905:      * @return  array             The sanitized options
3906:      */
3907:     protected function sanitizeCheckboxRadioOptions(array $options)
3908:     {
3909:         foreach ($options as $key => $option) {
3910:             $options[$key]['id'] = isset($option['id']) && is_numeric($option['id']) ? (int) $option['id'] : 0;
3911:             $options[$key]['label'] = isset($option['label']) && is_string($option['label']) ? wp_kses_post($option['label']) : '';
3912:             $options[$key]['value'] = isset($option['value']) && is_string($option['value']) ? wp_kses_no_null($option['value'], array('slash_zero' => 'keep')) : '';
3913:             $options[$key]['image'] = isset($option['image']) && is_string($option['image']) ? esc_url_raw($option['image']) : '';
3914:             $options[$key]['imageSelected'] = isset($option['imageSelected']) && is_string($option['imageSelected']) ? esc_url_raw($option['imageSelected']) : '';
3915:             $options[$key]['width'] = isset($option['width']) && is_string($option['width']) ? sanitize_text_field($option['width']) : '';
3916:             $options[$key]['height'] = isset($option['height']) && is_string($option['height']) ? sanitize_text_field($option['height']) : '';
3917:             $options[$key]['icon'] = isset($option['icon']) && is_string($option['icon']) ? sanitize_text_field($option['icon']) : '';
3918:             $options[$key]['iconSelected'] = isset($option['iconSelected']) && is_string($option['iconSelected']) ? sanitize_text_field($option['iconSelected']) : '';
3919:         }
3920: 
3921:         return $options;
3922:     }
3923: 
3924:     /**
3925:      * Sanitize the given RGB color array
3926:      *
3927:      * @param   array  $color
3928:      * @return  array
3929:      */
3930:     protected function sanitizeRgbColorArray(array $color)
3931:     {
3932:         $color = array(
3933:             'r' => Quform::clamp((int) $color['r'], 0, 255),
3934:             'g' => Quform::clamp((int) $color['g'], 0, 255),
3935:             'b' => Quform::clamp((int) $color['b'], 0, 255),
3936:             'a' => Quform::clamp((float) $color['a'], 0, 1)
3937:         );
3938: 
3939:         return $color;
3940:     }
3941: 
3942:     /**
3943:      * Handle the Ajax request to add a new form
3944:      */
3945:     public function add()
3946:     {
3947:         $this->validateAddRequest();
3948: 
3949:         $name = sanitize_text_field(wp_unslash($_POST['name']));
3950: 
3951:         $nameLength = Quform::strlen($name);
3952: 
3953:         if ($nameLength == 0) {
3954:             wp_send_json(array(
3955:                 'type' => 'error',
3956:                 'errors' => array(
3957:                     'qfb-forms-add-name' => __('This field is required', 'quform')
3958:                 )
3959:             ));
3960:         } elseif ($nameLength > 64) {
3961:             wp_send_json(array(
3962:                 'type' => 'error',
3963:                 'errors' => array(
3964:                     'qfb-forms-add-name' => __('The form name must be no longer than 64 characters', 'quform')
3965:                 )
3966:             ));
3967:         }
3968: 
3969:         $config = $this->getDefaultForm();
3970:         $config['name'] = $name;
3971: 
3972:         $config = $this->repository->add($config);
3973: 
3974:         if ( ! is_array($config)) {
3975:             wp_send_json(array(
3976:                 'type' => 'error',
3977:                 'message' => wp_kses(sprintf(
3978:                     /* translators: %1$s: open link tag, %2$s: close link tag */
3979:                     __('Failed to insert into database, check the %1$serror log%2$s for more information', 'quform'),
3980:                     '<a href="https://support.themecatcher.net/quform-wordpress-v2/guides/advanced/enabling-debug-logging">',
3981:                     '</a>'
3982:                 ), array('a' => array('href' => array())))
3983:             ));
3984:         }
3985: 
3986:         wp_send_json(array(
3987:             'type' => 'success',
3988:             'url' => admin_url('admin.php?page=quform.forms&sp=edit&id=' . $config['id'])
3989:         ));
3990:     }
3991: 
3992:     /**
3993:      * Validate the request to add a new form
3994:      */
3995:     protected function validateAddRequest()
3996:     {
3997:         if ( ! Quform::isPostRequest() || ! isset($_POST['name']) || ! is_string($_POST['name'])) {
3998:             wp_send_json(array(
3999:                 'type'    => 'error',
4000:                 'message' => __('Bad request', 'quform')
4001:             ));
4002:         }
4003: 
4004:         if ( ! current_user_can('quform_add_forms')) {
4005:             wp_send_json(array(
4006:                 'type'    => 'error',
4007:                 'message' => __('Insufficient permissions', 'quform')
4008:             ));
4009:         }
4010: 
4011:         if ( ! check_ajax_referer('quform_add_form', false, false)) {
4012:             wp_send_json(array(
4013:                 'type'    => 'error',
4014:                 'message' => __('Nonce check failed', 'quform')
4015:             ));
4016:         }
4017:     }
4018: 
4019:     /**
4020:      * Handle the request to preview the form via Ajax
4021:      */
4022:     public function preview()
4023:     {
4024:         $this->validatePreviewRequest();
4025: 
4026:         $config = json_decode(stripslashes(Quform::get($_POST, 'form')), true);
4027: 
4028:         if ( ! is_array($config)) {
4029:             wp_send_json(array(
4030:                 'type'    => 'error',
4031:                 'message' => __('Bad request', 'quform')
4032:             ));
4033:         }
4034: 
4035:         // Ajax must be enable to submit the form in the preview
4036:         $config = $this->sanitizeForm($config);
4037:         $config['ajax'] = true;
4038:         $config['environment'] = 'preview';
4039: 
4040:         $form = $this->factory->create($config);
4041:         $form->setCurrentPageById(Quform::get($_POST, 'page'));
4042: 
4043:         wp_send_json(array(
4044:             'type' => 'success',
4045:             'form' => $form->render(),
4046:             'css' => $form->getCss()
4047:         ));
4048:     }
4049: 
4050:     /**
4051:      * Validate the request to preview the form
4052:      */
4053:     protected function validatePreviewRequest()
4054:     {
4055:         if ( ! Quform::isPostRequest() || ! isset($_POST['form'])) {
4056:             wp_send_json(array(
4057:                 'type'    => 'error',
4058:                 'message' => __('Bad request', 'quform')
4059:             ));
4060:         }
4061: 
4062:         if ( ! current_user_can('quform_edit_forms')) {
4063:             wp_send_json(array(
4064:                 'type'    => 'error',
4065:                 'message' => __('Insufficient permissions', 'quform')
4066:             ));
4067:         }
4068:     }
4069: 
4070:     /**
4071:      * @param array $config
4072:      */
4073:     protected function validateForm(array $config)
4074:     {
4075:         if ( ! Quform::isNonEmptyString($config['name'])) {
4076:             wp_send_json(array(
4077:                 'type'    => 'error',
4078:                 'message' => __('A form name is required.', 'quform')
4079:             ));
4080:         }
4081:     }
4082: 
4083:     /**
4084:      * @return array
4085:      */
4086:     public function getThemes()
4087:     {
4088:         return $this->themes->getThemes();
4089:     }
4090: 
4091:     /**
4092:      * return array
4093:      */
4094:     public function getLocales()
4095:     {
4096:         return array('' => array('name' => __('Default', 'quform'))) + Quform::getLocales();
4097:     }
4098: 
4099:     /**
4100:      * @return array
4101:      */
4102:     protected function getLoadedPreviewLocales()
4103:     {
4104:         $activeLocales = array();
4105: 
4106:         foreach ($this->options->get('activeLocales') as $locales) {
4107:             $activeLocales = array_merge($activeLocales, $locales);
4108:         }
4109: 
4110:         return $activeLocales;
4111:     }
4112: 
4113:     /**
4114:      * @return string
4115:      */
4116:     protected function getAttachmentHtml()
4117:     {
4118:         ob_start();
4119:         ?>
4120:         <div class="qfb-attachment qfb-box qfb-cf">
4121:             <div class="qfb-attachment-inner">
4122:                 <span class="qfb-attachment-remove qfb-small-remove-button qfb-icon qfb-icon-trash" title="<?php esc_attr_e('Remove', 'quform'); ?>"></span>
4123:                 <div class="qfb-sub-setting">
4124:                     <div class="qfb-sub-setting-label">
4125:                         <label><?php esc_html_e('Source', 'quform'); ?></label>
4126:                     </div>
4127:                     <div class="qfb-sub-setting-inner">
4128:                         <div class="qfb-sub-setting-input">
4129:                             <select class="qfb-attachment-source">
4130:                                 <option value="media"><?php esc_html_e('Media library', 'quform'); ?></option>
4131:                                 <option value="element"><?php esc_html_e('Form element', 'quform'); ?></option>
4132:                             </select>
4133:                         </div>
4134:                     </div>
4135:                 </div>
4136:                 <div class="qfb-sub-setting">
4137:                     <div class="qfb-sub-setting-label">
4138:                         <label><?php esc_html_e('Element', 'quform'); ?></label>
4139:                     </div>
4140:                     <div class="qfb-sub-setting-inner">
4141:                         <div class="qfb-sub-setting-input">
4142:                             <select class="qfb-attachment-element"></select>
4143:                         </div>
4144:                     </div>
4145:                 </div>
4146:                 <div class="qfb-sub-setting">
4147:                     <div class="qfb-sub-setting-label">
4148:                         <label><?php esc_html_e('File(s)', 'quform'); ?></label>
4149:                     </div>
4150:                     <div class="qfb-sub-setting-inner">
4151:                         <div class="qfb-sub-setting-input">
4152:                             <div class="qfb-cf">
4153:                                 <span class="qfb-button-blue qfb-attachment-browse"><i class="qfb-mdi qfb-mdi-panorama"></i><?php esc_html_e('Browse', 'quform'); ?></span>
4154:                             </div>
4155:                             <div class="qfb-attachment-media"></div>
4156:                         </div>
4157:                     </div>
4158:                 </div>
4159:             </div>
4160:         </div>
4161:         <?php
4162:         return ob_get_clean();
4163:     }
4164: 
4165:     /**
4166:      * Get the HTML for the database password field
4167:      *
4168:      * @return string
4169:      */
4170:     public function getDbPasswordHtml()
4171:     {
4172:         ob_start();
4173:         ?>
4174:         <input type="text" id="qfb_form_db_password" value="">
4175:         <p class="qfb-description"><?php esc_html_e('The password for the user above.', 'quform'); ?></p>
4176:         <?php
4177:         return ob_get_clean();
4178:     }
4179: 
4180:     /**
4181:      * Get the HTML for a select menu
4182:      *
4183:      * @param   string  $id             The ID of the field
4184:      * @param   array   $options        The select options
4185:      * @param   string  $selectedValue  The selected value
4186:      * @return  string
4187:      */
4188:     protected function getSelectHtml($id, array $options, $selectedValue = '')
4189:     {
4190:         $output = sprintf('<select id="%s">', Quform::escape($id));
4191: 
4192:         foreach ($options as $value => $label) {
4193:             $output .= sprintf(
4194:                 '<option value="%s"%s>%s</option>',
4195:                 Quform::escape($value),
4196:                 $selectedValue == $value ? ' selected="selected"' : '',
4197:                 Quform::escape($label)
4198:             );
4199:         }
4200: 
4201:         $output .= '</select>';
4202: 
4203:         return $output;
4204:     }
4205: 
4206:     /**
4207:      * Get the HTML for the responsive setting select menu
4208:      *
4209:      * @param   string  $id                 The ID of the field
4210:      * @param   string  $selectedValue           The selected value
4211:      * @param   bool    $showInheritOption  Shows the "Inherit" option if true
4212:      * @return  string
4213:      */
4214:     public function getResponsiveSelectHtml($id, $selectedValue = '', $showInheritOption = true)
4215:     {
4216:         $options = array(
4217:             '' => __('Off', 'quform'),
4218:             'phone-portrait' => __('Phone portrait (479px)', 'quform'),
4219:             'phone-landscape' => __('Phone landscape (767px)', 'quform'),
4220:             'tablet-landscape' => __('Tablet landscape (1024px)', 'quform'),
4221:             'custom' => __('Custom...', 'quform')
4222:         );
4223: 
4224:         if ($showInheritOption) {
4225:             $options = array('inherit' => __('Inherit', 'quform')) + $options;
4226:         }
4227: 
4228:         return $this->getSelectHtml($id, $options, $selectedValue);
4229:     }
4230: 
4231:     /**
4232:      * Get the HTML for the element size setting select menu
4233:      *
4234:      * @param   string  $id                 The ID of the field
4235:      * @param   string  $selectedValue      The selected value
4236:      * @param   bool    $showInheritOption  Shows the "Inherit" option if true
4237:      * @return  string
4238:      */
4239:     public function getSizeSelectHtml($id, $selectedValue = '', $showInheritOption = true)
4240:     {
4241:         $options = array(
4242:             '' => __('Default', 'quform'),
4243:             'slim' => __('Slim', 'quform'),
4244:             'medium' => __('Medium', 'quform'),
4245:             'fat' => __('Fat', 'quform'),
4246:             'huge' => __('Huge', 'quform')
4247:         );
4248: 
4249:         if ($showInheritOption) {
4250:             $options = array('inherit' => __('Inherit', 'quform')) + $options;
4251:         }
4252: 
4253:         return $this->getSelectHtml($id, $options, $selectedValue);
4254:     }
4255: 
4256:     /**
4257:      * Get the HTML for the field width setting select menu
4258:      *
4259:      * @param   string  $id                 The ID of the field
4260:      * @param   string  $selectedValue      The selected value
4261:      * @param   bool    $showInheritOption  Shows the "Inherit" option if true
4262:      * @return  string
4263:      */
4264:     public function getFieldWidthSelectHtml($id, $selectedValue = '', $showInheritOption = true)
4265:     {
4266:         $options = array(
4267:             'tiny' => __('Tiny', 'quform'),
4268:             'small' => __('Small', 'quform'),
4269:             'medium' => __('Medium', 'quform'),
4270:             'large' => __('Large', 'quform'),
4271:             '' => __('100% (default)', 'quform'),
4272:             'custom' => __('Custom...', 'quform')
4273:         );
4274: 
4275:         if ($showInheritOption) {
4276:             $options = array('inherit' => __('Inherit', 'quform')) + $options;
4277:         }
4278: 
4279:         return $this->getSelectHtml($id, $options, $selectedValue);
4280:     }
4281: 
4282:     /**
4283:      * Get the HTML for the button style setting select menu
4284:      *
4285:      * @param   string       $id                 The ID of the field
4286:      * @param   string       $selectedValue      The selected value
4287:      * @param   bool         $showInheritOption  Shows the "Inherit" option if true
4288:      * @param   string|null  $emptyOptionText    The text for the empty option
4289:      * @return  string
4290:      */
4291:     public function getButtonStyleSelectHtml($id, $selectedValue = '', $showInheritOption = true, $emptyOptionText = null)
4292:     {
4293:         $options = array(
4294:             '' => is_string($emptyOptionText) ? $emptyOptionText : __('Default', 'quform'),
4295:             'theme' => __('Use form theme button style', 'quform'),
4296:             'sexy-silver' => __('Sexy Silver', 'quform'),
4297:             'classic' => __('Classic', 'quform'),
4298:             'background-blending-gradient' => __('Blending Gradient', 'quform'),
4299:             'shine-gradient' => __('Shine Gradient', 'quform'),
4300:             'blue-3d' => __('3D', 'quform'),
4301:             'hollow' => __('Hollow', 'quform'),
4302:             'hollow-rounded' => __('Hollow Rounded', 'quform'),
4303:             'chilled' => __('Chilled', 'quform'),
4304:             'pills' => __('Pill', 'quform'),
4305:             'bootstrap' => __('Bootstrap', 'quform'),
4306:             'bootstrap-primary' => __('Bootstrap Primary', 'quform')
4307:         );
4308: 
4309:         if ($showInheritOption) {
4310:             $options = array('inherit' => __('Inherit', 'quform')) + $options;
4311:         }
4312: 
4313:         return $this->getSelectHtml($id, $options, $selectedValue);
4314:     }
4315: 
4316:     /**
4317:      * Get the HTML for the button width setting select menu
4318:      *
4319:      * @param   string  $id                 The ID of the field
4320:      * @param   string  $selectedValue      The selected value
4321:      * @param   bool    $showInheritOption  Shows the "Inherit" option if true
4322:      * @return  string
4323:      */
4324:     public function getButtonWidthSelectHtml($id, $selectedValue = '', $showInheritOption = true)
4325:     {
4326:         $options = array(
4327:             '' => __('Auto (default)', 'quform'),
4328:             'tiny' => __('Tiny', 'quform'),
4329:             'small' => __('Small', 'quform'),
4330:             'medium' => __('Medium', 'quform'),
4331:             'large' => __('Large', 'quform'),
4332:             'full' => __('100%', 'quform'),
4333:             'custom' => __('Custom...', 'quform')
4334:         );
4335: 
4336:         if ($showInheritOption) {
4337:             $options = array('inherit' => __('Inherit', 'quform')) + $options;
4338:         }
4339: 
4340:         return $this->getSelectHtml($id, $options, $selectedValue);
4341:     }
4342: 
4343:     /**
4344:      * Get the HTML for the options style setting select menu
4345:      *
4346:      * @param   string  $id                 The ID of the field
4347:      * @param   string  $selectedValue      The selected value
4348:      * @param   bool    $showInheritOption  Shows the "Inherit" option if true
4349:      * @return  string
4350:      */
4351:     public function getOptionsStyleSelectHtml($id, $selectedValue = '', $showInheritOption = true)
4352:     {
4353:         $options = array(
4354:             '' => __('Default', 'quform'),
4355:             'input-hidden' => __('Hide input', 'quform'),
4356:             'button' => __('Button', 'quform')
4357:         );
4358: 
4359:         if ($showInheritOption) {
4360:             $options = array('inherit' => __('Inherit', 'quform')) + $options;
4361:         }
4362: 
4363:         return $this->getSelectHtml($id, $options, $selectedValue);
4364:     }
4365: 
4366:     /**
4367:      * Get the HTML for the select icon field
4368:      *
4369:      * @param   string  $id        The ID of the field
4370:      * @param   string  $selected  The selected icon
4371:      * @return  string
4372:      */
4373:     public function getSelectIconHtml($id, $selected = '')
4374:     {
4375:         $output = '<div class="qfb-select-icon qfb-cf">';
4376: 
4377:         $output .= sprintf(
4378:             '<input type="text" id="%s"%s class="qfb-select-icon-value">',
4379:             esc_attr($id),
4380:             Quform::isNonEmptyString($selected) ? sprintf(' value="%s"', esc_attr($selected)) : ''
4381:         );
4382: 
4383:         $isCoreIcon = $this->isCoreIcon($selected);
4384:         $output .= sprintf('<div class="qfb-select-icon-button qfb-button">%s</div>', esc_html__('Choose', 'quform'));
4385:         $output .= sprintf('<div class="qfb-select-icon-preview%s">', $isCoreIcon ? '' : ' qfb-hidden');
4386: 
4387:         if ($isCoreIcon) {
4388:             $output .= sprintf('<i class="%s"></i>', esc_attr(preg_replace('/^fa fa-/', 'qfb-icon qfb-icon-', $selected)));
4389:         }
4390: 
4391:         $output .= '</div>';
4392: 
4393:         $output .= sprintf(
4394:             '<div class="qfb-select-icon-clear%s">%s</div>',
4395:             ! Quform::isNonEmptyString($selected) ? ' qfb-hidden' : '',
4396:             esc_html__('Clear', 'quform')
4397:         );
4398: 
4399:         $output .= '</div>';
4400: 
4401:         return $output;
4402:     }
4403: 
4404:     /**
4405:      * Is the given icon class one of the core plugin icons?
4406:      *
4407:      * @param   string  $icon  The icon classes e.g. 'fa fa-check'
4408:      * @return  bool
4409:      */
4410:     protected function isCoreIcon($icon)
4411:     {
4412:         if (!Quform::isNonEmptyString($icon)) {
4413:             return false;
4414:         }
4415: 
4416:         $icon = trim(str_replace('fa ', '', $icon));
4417: 
4418:         if (!Quform::isNonEmptyString($icon)) {
4419:             return false;
4420:         }
4421: 
4422:         $quformIcons = $this->getQuformIcons();
4423:         $fontAwesomeIcons = $this->getFontAwesomeIcons();
4424: 
4425:         return in_array($icon, $quformIcons) || in_array($icon, $fontAwesomeIcons);
4426:     }
4427: 
4428:     /**
4429:      * Get the HTML for the icon position select
4430:      *
4431:      * @param   string  $id                 The ID of the field
4432:      * @param   string  $selectedValue      The selected value
4433:      * @param   bool    $showInheritOption  Shows the "Inherit" option if true
4434:      * @return  string
4435:      */
4436:     public function getIconPositionSelectHtml($id, $selectedValue = '', $showInheritOption = true)
4437:     {
4438:         $options = array(
4439:             'left' => __('Left', 'quform'),
4440:             'right' => __('Right', 'quform'),
4441:             'above' => __('Above', 'quform')
4442:         );
4443: 
4444:         if ($showInheritOption) {
4445:             $options = array('inherit' => __('Inherit', 'quform')) + $options;
4446:         }
4447: 
4448:         $output = sprintf('<select id="%s">', Quform::escape($id));
4449: 
4450:         foreach ($options as $value => $label) {
4451:             $output .= sprintf(
4452:                 '<option value="%s"%s>%s</option>',
4453:                 Quform::escape($value),
4454:                 $selectedValue == $value ? ' selected="selected"' : '',
4455:                 Quform::escape($label)
4456:             );
4457:         }
4458: 
4459:         $output .= '</select>';
4460: 
4461:         return $output;
4462:     }
4463: 
4464:     /**
4465:      * Get the HTML for the CSS helper widget
4466:      *
4467:      * @return string
4468:      */
4469:     public function getCssHelperHtml()
4470:     {
4471:         $output = '';
4472: 
4473:         $helpers = array(
4474:             array('css' => 'background-color: ;', 'icon' => 'qfb-mdi qfb-mdi-format_color_fill', 'title' => __('Background color', 'quform')),
4475:             array('css' => 'background: url() top left no-repeat;', 'icon' => 'qfb-mdi qfb-mdi-wallpaper', 'title' => __('Background image', 'quform')),
4476:             array('css' => 'border-color: ;', 'icon' => 'qfb-mdi qfb-mdi-border_color', 'title' => __('Border color', 'quform')),
4477:             array('css' => 'color: ;', 'icon' => 'qfb-mdi qfb-mdi-format_color_text', 'title' => __('Text color', 'quform')),
4478: 
4479:             array('css' => 'padding: ;', 'icon' => 'qfb-icon-external-link-square', 'title' => __('Padding', 'quform')),
4480:             array('css' => 'margin: ;', 'icon' => 'qfb-icon-external-link', 'title' => __('Margin', 'quform')),
4481:             array('css' => 'border-radius: ;', 'icon' => 'qfb-mdi qfb-mdi-crop_free', 'title' => __('Border radius', 'quform')),
4482: 
4483:             array('css' => 'font-size: ;', 'icon' => 'qfb-mdi qfb-mdi-format_size', 'title' => __('Font size', 'quform')),
4484:             array('css' => 'line-height: ;', 'icon' => 'qfb-mdi qfb-mdi-format_line_spacing', 'title' => __('Line height', 'quform')),
4485:             array('css' => 'font-weight: bold;', 'icon' => 'qfb-mdi qfb-mdi-format_bold', 'title' => __('Bold', 'quform')),
4486:             array('css' => 'text-decoration: underline;', 'icon' => 'qfb-mdi qfb-mdi-format_underlined', 'title' => __('Underline', 'quform')),
4487:             array('css' => 'text-transform: uppercase;', 'icon' => 'qfb-mdi qfb-mdi-title', 'title' => __('Uppercase', 'quform')),
4488: 
4489:             array('css' => 'text-align: left;', 'icon' => 'qfb-mdi qfb-mdi-format_align_left', 'title' => __('Text align left', 'quform')),
4490:             array('css' => 'text-align: center;', 'icon' => 'qfb-mdi qfb-mdi-format_align_center', 'title' => __('Text align center', 'quform')),
4491:             array('css' => 'text-align: right;', 'icon' => 'qfb-mdi qfb-mdi-format_align_right', 'title' => __('Text align right', 'quform')),
4492: 
4493:             array('css' => 'width: ;', 'icon' => 'qfb-mdi qfb-mdi-keyboard_tab', 'title' => __('Width', 'quform')),
4494:             array('css' => 'height: ;', 'icon' => 'qfb-mdi qfb-mdi-vertical_align_top', 'title' => __('Height', 'quform')),
4495: 
4496:             array('css' => 'display: none;', 'icon' => 'qfb-mdi qfb-mdi-visibility_off', 'title' => __('Hide', 'quform')),
4497:         );
4498: 
4499:         foreach ($helpers as $helper) {
4500:             $output .= sprintf(
4501:                 '<span class="qfb-css-helper" data-css="%s" title="%s"><i class="%s"></i></span>',
4502:                 esc_attr($helper['css']),
4503:                 esc_attr($helper['title']),
4504:                 esc_attr($helper['icon'])
4505:             );
4506:         }
4507: 
4508:         return $output;
4509:     }
4510: 
4511:     /**
4512:      * Format the given variables array to display in a &lt;pre&gt; tag
4513:      *
4514:      * @param   array   $variables
4515:      * @return  string
4516:      */
4517:     public function formatVariables(array $variables)
4518:     {
4519:         $lines = array();
4520: 
4521:         foreach ($variables as $tag => $description) {
4522:             $lines[] = sprintf('%s = %s', $tag, $description);
4523:         }
4524: 
4525:         return join("\n", $lines);
4526:     }
4527: 
4528:     /**
4529:      * Handle the request to search posts via Ajax
4530:      */
4531:     public function searchPosts()
4532:     {
4533:         $this->validateSearchPostsRequest();
4534: 
4535:         $search = sanitize_text_field(wp_unslash($_GET['search']));
4536:         $results = array();
4537: 
4538:         foreach (Quform::searchPosts($search) as $post) {
4539:             $results[] = array('id' => $post->ID, 'text' => $post->post_title);
4540:         }
4541: 
4542:         wp_send_json(array(
4543:             'type' => 'success',
4544:             'results' => $results
4545:         ));
4546:     }
4547: 
4548:     /**
4549:      * Validate the request to search posts via Ajax
4550:      */
4551:     protected function validateSearchPostsRequest()
4552:     {
4553:         if ( ! Quform::isGetRequest() || ! isset($_GET['search']) || ! is_string($_GET['search'])) {
4554:             wp_send_json(array(
4555:                 'type'    => 'error',
4556:                 'message' => __('Bad request', 'quform')
4557:             ));
4558:         }
4559: 
4560:         if ( ! current_user_can('quform_edit_forms')) {
4561:             wp_send_json(array(
4562:                 'type'    => 'error',
4563:                 'message' => __('Insufficient permissions', 'quform')
4564:             ));
4565:         }
4566: 
4567:         if ( ! check_ajax_referer('quform_builder_search_posts', false, false)) {
4568:             wp_send_json(array(
4569:                 'type'    => 'error',
4570:                 'message' => __('Nonce check failed', 'quform')
4571:             ));
4572:         }
4573:     }
4574: 
4575:     /**
4576:      * Handle the request to get a post title via Ajax
4577:      */
4578:     public function getPostTitle()
4579:     {
4580:         $this->validateGetPostTitleRequest();
4581: 
4582:         wp_send_json(array(
4583:             'type' => 'success',
4584:             'title' => Quform::getPostTitleById((int) $_GET['id'])
4585:         ));
4586:     }
4587: 
4588:     /**
4589:      * Validate the request to get a post title via Ajax
4590:      */
4591:     protected function validateGetPostTitleRequest()
4592:     {
4593:         if ( ! Quform::isGetRequest() || ! isset($_GET['id']) || ! is_numeric($_GET['id'])) {
4594:             wp_send_json(array(
4595:                 'type'    => 'error',
4596:                 'message' => __('Bad request', 'quform')
4597:             ));
4598:         }
4599: 
4600:         if ( ! current_user_can('quform_edit_forms')) {
4601:             wp_send_json(array(
4602:                 'type'    => 'error',
4603:                 'message' => __('Insufficient permissions', 'quform')
4604:             ));
4605:         }
4606: 
4607:         if ( ! check_ajax_referer('quform_builder_get_post_title', false, false)) {
4608:             wp_send_json(array(
4609:                 'type'    => 'error',
4610:                 'message' => __('Nonce check failed', 'quform')
4611:             ));
4612:         }
4613:     }
4614: 
4615:     /**
4616:      * Get the array of available Quform icons
4617:      *
4618:      * @return array
4619:      */
4620:     public function getQuformIcons()
4621:     {
4622:         return array(
4623:             'qicon-add_circle', 'qicon-arrow_back', 'qicon-arrow_forward', 'qicon-check', 'qicon-close',
4624:             'qicon-remove_circle', 'qicon-schedule', 'qicon-mode_edit', 'qicon-favorite_border', 'qicon-file_upload', 'qicon-star',
4625:             'qicon-keyboard_arrow_down', 'qicon-keyboard_arrow_up', 'qicon-send', 'qicon-thumb_down', 'qicon-thumb_up',
4626:             'qicon-refresh', 'qicon-question-circle', 'qicon-calendar', 'qicon-qicon-star-half', 'qicon-paper-plane',
4627:             'qicon-search'
4628:         );
4629:     }
4630: 
4631:     /**
4632:      * Get the array of available FontAwesome icons
4633:      *
4634:      * Updated for v4.7.0
4635:      *
4636:      * @return array
4637:      */
4638:     public function getFontAwesomeIcons()
4639:     {
4640:         return array('fa-glass', 'fa-music', 'fa-search', 'fa-envelope-o', 'fa-heart', 'fa-star', 'fa-star-o',
4641:             'fa-user', 'fa-film', 'fa-th-large', 'fa-th', 'fa-th-list', 'fa-check', 'fa-remove', 'fa-close',
4642:             'fa-times', 'fa-search-plus', 'fa-search-minus', 'fa-power-off', 'fa-signal', 'fa-gear', 'fa-cog',
4643:             'fa-trash-o', 'fa-home', 'fa-file-o', 'fa-clock-o', 'fa-road', 'fa-download', 'fa-arrow-circle-o-down',
4644:             'fa-arrow-circle-o-up', 'fa-inbox', 'fa-play-circle-o', 'fa-rotate-right', 'fa-repeat', 'fa-refresh',
4645:             'fa-list-alt', 'fa-lock', 'fa-flag', 'fa-headphones', 'fa-volume-off', 'fa-volume-down', 'fa-volume-up',
4646:             'fa-qrcode', 'fa-barcode', 'fa-tag', 'fa-tags', 'fa-book', 'fa-bookmark', 'fa-print', 'fa-camera',
4647:             'fa-font', 'fa-bold', 'fa-italic', 'fa-text-height', 'fa-text-width', 'fa-align-left', 'fa-align-center',
4648:             'fa-align-right', 'fa-align-justify', 'fa-list', 'fa-dedent', 'fa-outdent', 'fa-indent', 'fa-video-camera',
4649:             'fa-photo', 'fa-image', 'fa-picture-o', 'fa-pencil', 'fa-map-marker', 'fa-adjust', 'fa-tint', 'fa-edit',
4650:             'fa-pencil-square-o', 'fa-share-square-o', 'fa-check-square-o', 'fa-arrows', 'fa-step-backward',
4651:             'fa-fast-backward', 'fa-backward', 'fa-play', 'fa-pause', 'fa-stop', 'fa-forward', 'fa-fast-forward',
4652:             'fa-step-forward', 'fa-eject', 'fa-chevron-left', 'fa-chevron-right', 'fa-plus-circle', 'fa-minus-circle',
4653:             'fa-times-circle', 'fa-check-circle', 'fa-question-circle', 'fa-info-circle', 'fa-crosshairs',
4654:             'fa-times-circle-o', 'fa-check-circle-o', 'fa-ban', 'fa-arrow-left', 'fa-arrow-right', 'fa-arrow-up',
4655:             'fa-arrow-down', 'fa-mail-forward', 'fa-share', 'fa-expand', 'fa-compress', 'fa-plus', 'fa-minus',
4656:             'fa-asterisk', 'fa-exclamation-circle', 'fa-gift', 'fa-leaf', 'fa-fire', 'fa-eye', 'fa-eye-slash',
4657:             'fa-warning', 'fa-exclamation-triangle', 'fa-plane', 'fa-calendar', 'fa-random', 'fa-comment', 'fa-magnet',
4658:             'fa-chevron-up', 'fa-chevron-down', 'fa-retweet', 'fa-shopping-cart', 'fa-folder', 'fa-folder-open',
4659:             'fa-arrows-v', 'fa-arrows-h', 'fa-bar-chart-o', 'fa-bar-chart', 'fa-twitter-square', 'fa-facebook-square',
4660:             'fa-camera-retro', 'fa-key', 'fa-gears', 'fa-cogs', 'fa-comments', 'fa-thumbs-o-up', 'fa-thumbs-o-down',
4661:             'fa-star-half', 'fa-heart-o', 'fa-sign-out', 'fa-linkedin-square', 'fa-thumb-tack', 'fa-external-link',
4662:             'fa-sign-in', 'fa-trophy', 'fa-github-square', 'fa-upload', 'fa-lemon-o', 'fa-phone', 'fa-square-o',
4663:             'fa-bookmark-o', 'fa-phone-square', 'fa-twitter', 'fa-facebook-f', 'fa-facebook', 'fa-github', 'fa-unlock',
4664:             'fa-credit-card', 'fa-feed', 'fa-rss', 'fa-hdd-o', 'fa-bullhorn', 'fa-bell', 'fa-certificate',
4665:             'fa-hand-o-right', 'fa-hand-o-left', 'fa-hand-o-up', 'fa-hand-o-down', 'fa-arrow-circle-left',
4666:             'fa-arrow-circle-right', 'fa-arrow-circle-up', 'fa-arrow-circle-down', 'fa-globe', 'fa-wrench', 'fa-tasks',
4667:             'fa-filter', 'fa-briefcase', 'fa-arrows-alt', 'fa-group', 'fa-users', 'fa-chain', 'fa-link', 'fa-cloud',
4668:             'fa-flask', 'fa-cut', 'fa-scissors', 'fa-copy', 'fa-files-o', 'fa-paperclip', 'fa-save', 'fa-floppy-o',
4669:             'fa-square', 'fa-navicon', 'fa-reorder', 'fa-bars', 'fa-list-ul', 'fa-list-ol', 'fa-strikethrough',
4670:             'fa-underline', 'fa-table', 'fa-magic', 'fa-truck', 'fa-pinterest', 'fa-pinterest-square',
4671:             'fa-google-plus-square', 'fa-google-plus', 'fa-money', 'fa-caret-down', 'fa-caret-up', 'fa-caret-left',
4672:             'fa-caret-right', 'fa-columns', 'fa-unsorted', 'fa-sort', 'fa-sort-down', 'fa-sort-desc', 'fa-sort-up',
4673:             'fa-sort-asc', 'fa-envelope', 'fa-linkedin', 'fa-rotate-left', 'fa-undo', 'fa-legal', 'fa-gavel',
4674:             'fa-dashboard', 'fa-tachometer', 'fa-comment-o', 'fa-comments-o', 'fa-flash', 'fa-bolt', 'fa-sitemap',
4675:             'fa-umbrella', 'fa-paste', 'fa-clipboard', 'fa-lightbulb-o', 'fa-exchange', 'fa-cloud-download',
4676:             'fa-cloud-upload', 'fa-user-md', 'fa-stethoscope', 'fa-suitcase', 'fa-bell-o', 'fa-coffee', 'fa-cutlery',
4677:             'fa-file-text-o', 'fa-building-o', 'fa-hospital-o', 'fa-ambulance', 'fa-medkit', 'fa-fighter-jet',
4678:             'fa-beer', 'fa-h-square', 'fa-plus-square', 'fa-angle-double-left', 'fa-angle-double-right',
4679:             'fa-angle-double-up', 'fa-angle-double-down', 'fa-angle-left', 'fa-angle-right', 'fa-angle-up',
4680:             'fa-angle-down', 'fa-desktop', 'fa-laptop', 'fa-tablet', 'fa-mobile-phone', 'fa-mobile', 'fa-circle-o',
4681:             'fa-quote-left', 'fa-quote-right', 'fa-spinner', 'fa-circle', 'fa-mail-reply', 'fa-reply', 'fa-github-alt',
4682:             'fa-folder-o', 'fa-folder-open-o', 'fa-smile-o', 'fa-frown-o', 'fa-meh-o', 'fa-gamepad', 'fa-keyboard-o',
4683:             'fa-flag-o', 'fa-flag-checkered', 'fa-terminal', 'fa-code', 'fa-mail-reply-all', 'fa-reply-all',
4684:             'fa-star-half-empty', 'fa-star-half-full', 'fa-star-half-o', 'fa-location-arrow', 'fa-crop', 'fa-code-fork',
4685:             'fa-unlink', 'fa-chain-broken', 'fa-question', 'fa-info', 'fa-exclamation', 'fa-superscript',
4686:             'fa-subscript', 'fa-eraser', 'fa-puzzle-piece', 'fa-microphone', 'fa-microphone-slash', 'fa-shield',
4687:             'fa-calendar-o', 'fa-fire-extinguisher', 'fa-rocket', 'fa-maxcdn', 'fa-chevron-circle-left',
4688:             'fa-chevron-circle-right', 'fa-chevron-circle-up', 'fa-chevron-circle-down', 'fa-html5', 'fa-css3',
4689:             'fa-anchor', 'fa-unlock-alt', 'fa-bullseye', 'fa-ellipsis-h', 'fa-ellipsis-v', 'fa-rss-square',
4690:             'fa-play-circle', 'fa-ticket', 'fa-minus-square', 'fa-minus-square-o', 'fa-level-up', 'fa-level-down',
4691:             'fa-check-square', 'fa-pencil-square', 'fa-external-link-square', 'fa-share-square', 'fa-compass',
4692:             'fa-toggle-down', 'fa-caret-square-o-down', 'fa-toggle-up', 'fa-caret-square-o-up', 'fa-toggle-right',
4693:             'fa-caret-square-o-right', 'fa-euro', 'fa-eur', 'fa-gbp', 'fa-dollar', 'fa-usd', 'fa-rupee', 'fa-inr',
4694:             'fa-cny', 'fa-rmb', 'fa-yen', 'fa-jpy', 'fa-ruble', 'fa-rouble', 'fa-rub', 'fa-won', 'fa-krw', 'fa-bitcoin',
4695:             'fa-btc', 'fa-file', 'fa-file-text', 'fa-sort-alpha-asc', 'fa-sort-alpha-desc', 'fa-sort-amount-asc',
4696:             'fa-sort-amount-desc', 'fa-sort-numeric-asc', 'fa-sort-numeric-desc', 'fa-thumbs-up', 'fa-thumbs-down',
4697:             'fa-youtube-square', 'fa-youtube', 'fa-xing', 'fa-xing-square', 'fa-youtube-play', 'fa-dropbox',
4698:             'fa-stack-overflow', 'fa-instagram', 'fa-flickr', 'fa-adn', 'fa-bitbucket', 'fa-bitbucket-square',
4699:             'fa-tumblr', 'fa-tumblr-square', 'fa-long-arrow-down', 'fa-long-arrow-up', 'fa-long-arrow-left',
4700:             'fa-long-arrow-right', 'fa-apple', 'fa-windows', 'fa-android', 'fa-linux', 'fa-dribbble', 'fa-skype',
4701:             'fa-foursquare', 'fa-trello', 'fa-female', 'fa-male', 'fa-gittip', 'fa-gratipay', 'fa-sun-o', 'fa-moon-o',
4702:             'fa-archive', 'fa-bug', 'fa-vk', 'fa-weibo', 'fa-renren', 'fa-pagelines', 'fa-stack-exchange',
4703:             'fa-arrow-circle-o-right', 'fa-arrow-circle-o-left', 'fa-toggle-left', 'fa-caret-square-o-left',
4704:             'fa-dot-circle-o', 'fa-wheelchair', 'fa-vimeo-square', 'fa-turkish-lira', 'fa-try', 'fa-plus-square-o',
4705:             'fa-space-shuttle', 'fa-slack', 'fa-envelope-square', 'fa-wordpress', 'fa-openid', 'fa-institution',
4706:             'fa-bank', 'fa-university', 'fa-mortar-board', 'fa-graduation-cap', 'fa-yahoo', 'fa-google', 'fa-reddit',
4707:             'fa-reddit-square', 'fa-stumbleupon-circle', 'fa-stumbleupon', 'fa-delicious', 'fa-digg',
4708:             'fa-pied-piper-pp', 'fa-pied-piper-alt', 'fa-drupal', 'fa-joomla', 'fa-language', 'fa-fax', 'fa-building',
4709:             'fa-child', 'fa-paw', 'fa-spoon', 'fa-cube', 'fa-cubes', 'fa-behance', 'fa-behance-square', 'fa-steam',
4710:             'fa-steam-square', 'fa-recycle', 'fa-automobile', 'fa-car', 'fa-cab', 'fa-taxi', 'fa-tree', 'fa-spotify',
4711:             'fa-deviantart', 'fa-soundcloud', 'fa-database', 'fa-file-pdf-o', 'fa-file-word-o', 'fa-file-excel-o',
4712:             'fa-file-powerpoint-o', 'fa-file-photo-o', 'fa-file-picture-o', 'fa-file-image-o', 'fa-file-zip-o',
4713:             'fa-file-archive-o', 'fa-file-sound-o', 'fa-file-audio-o', 'fa-file-movie-o', 'fa-file-video-o',
4714:             'fa-file-code-o', 'fa-vine', 'fa-codepen', 'fa-jsfiddle', 'fa-life-bouy', 'fa-life-buoy', 'fa-life-saver',
4715:             'fa-support', 'fa-life-ring', 'fa-circle-o-notch', 'fa-ra', 'fa-resistance', 'fa-rebel', 'fa-ge',
4716:             'fa-empire', 'fa-git-square', 'fa-git', 'fa-y-combinator-square', 'fa-yc-square', 'fa-hacker-news',
4717:             'fa-tencent-weibo', 'fa-qq', 'fa-wechat', 'fa-weixin', 'fa-send', 'fa-paper-plane', 'fa-send-o',
4718:             'fa-paper-plane-o', 'fa-history', 'fa-circle-thin', 'fa-header', 'fa-paragraph', 'fa-sliders',
4719:             'fa-share-alt', 'fa-share-alt-square', 'fa-bomb', 'fa-soccer-ball-o', 'fa-futbol-o', 'fa-tty',
4720:             'fa-binoculars', 'fa-plug', 'fa-slideshare', 'fa-twitch', 'fa-yelp', 'fa-newspaper-o', 'fa-wifi',
4721:             'fa-calculator', 'fa-paypal', 'fa-google-wallet', 'fa-cc-visa', 'fa-cc-mastercard', 'fa-cc-discover',
4722:             'fa-cc-amex', 'fa-cc-paypal', 'fa-cc-stripe', 'fa-bell-slash', 'fa-bell-slash-o', 'fa-trash', 'fa-copyright',
4723:             'fa-at', 'fa-eyedropper', 'fa-paint-brush', 'fa-birthday-cake', 'fa-area-chart', 'fa-pie-chart',
4724:             'fa-line-chart', 'fa-lastfm', 'fa-lastfm-square', 'fa-toggle-off', 'fa-toggle-on', 'fa-bicycle', 'fa-bus',
4725:             'fa-ioxhost', 'fa-angellist', 'fa-cc', 'fa-shekel', 'fa-sheqel', 'fa-ils', 'fa-meanpath', 'fa-buysellads',
4726:             'fa-connectdevelop', 'fa-dashcube', 'fa-forumbee', 'fa-leanpub', 'fa-sellsy', 'fa-shirtsinbulk',
4727:             'fa-simplybuilt', 'fa-skyatlas', 'fa-cart-plus', 'fa-cart-arrow-down', 'fa-diamond', 'fa-ship',
4728:             'fa-user-secret', 'fa-motorcycle', 'fa-street-view', 'fa-heartbeat', 'fa-venus', 'fa-mars', 'fa-mercury',
4729:             'fa-intersex', 'fa-transgender', 'fa-transgender-alt', 'fa-venus-double', 'fa-mars-double', 'fa-venus-mars',
4730:             'fa-mars-stroke', 'fa-mars-stroke-v', 'fa-mars-stroke-h', 'fa-neuter', 'fa-genderless',
4731:             'fa-facebook-official', 'fa-pinterest-p', 'fa-whatsapp', 'fa-server', 'fa-user-plus', 'fa-user-times',
4732:             'fa-hotel', 'fa-bed', 'fa-viacoin', 'fa-train', 'fa-subway', 'fa-medium', 'fa-yc', 'fa-y-combinator',
4733:             'fa-optin-monster', 'fa-opencart', 'fa-expeditedssl', 'fa-battery-4', 'fa-battery', 'fa-battery-full',
4734:             'fa-battery-3', 'fa-battery-three-quarters', 'fa-battery-2', 'fa-battery-half', 'fa-battery-1',
4735:             'fa-battery-quarter', 'fa-battery-0', 'fa-battery-empty', 'fa-mouse-pointer', 'fa-i-cursor',
4736:             'fa-object-group', 'fa-object-ungroup', 'fa-sticky-note', 'fa-sticky-note-o', 'fa-cc-jcb',
4737:             'fa-cc-diners-club', 'fa-clone', 'fa-balance-scale', 'fa-hourglass-o', 'fa-hourglass-1',
4738:             'fa-hourglass-start', 'fa-hourglass-2', 'fa-hourglass-half', 'fa-hourglass-3', 'fa-hourglass-end',
4739:             'fa-hourglass', 'fa-hand-grab-o', 'fa-hand-rock-o', 'fa-hand-stop-o', 'fa-hand-paper-o',
4740:             'fa-hand-scissors-o', 'fa-hand-lizard-o', 'fa-hand-spock-o', 'fa-hand-pointer-o', 'fa-hand-peace-o',
4741:             'fa-trademark', 'fa-registered', 'fa-creative-commons', 'fa-gg', 'fa-gg-circle', 'fa-tripadvisor',
4742:             'fa-odnoklassniki', 'fa-odnoklassniki-square', 'fa-get-pocket', 'fa-wikipedia-w', 'fa-safari', 'fa-chrome',
4743:             'fa-firefox', 'fa-opera', 'fa-internet-explorer', 'fa-tv', 'fa-television', 'fa-contao', 'fa-500px',
4744:             'fa-amazon', 'fa-calendar-plus-o', 'fa-calendar-minus-o', 'fa-calendar-times-o', 'fa-calendar-check-o',
4745:             'fa-industry', 'fa-map-pin', 'fa-map-signs', 'fa-map-o', 'fa-map', 'fa-commenting', 'fa-commenting-o',
4746:             'fa-houzz', 'fa-vimeo', 'fa-black-tie', 'fa-fonticons', 'fa-reddit-alien', 'fa-edge', 'fa-credit-card-alt',
4747:             'fa-codiepie', 'fa-modx', 'fa-fort-awesome', 'fa-usb', 'fa-product-hunt', 'fa-mixcloud', 'fa-scribd',
4748:             'fa-pause-circle', 'fa-pause-circle-o', 'fa-stop-circle', 'fa-stop-circle-o', 'fa-shopping-bag',
4749:             'fa-shopping-basket', 'fa-hashtag', 'fa-bluetooth', 'fa-bluetooth-b', 'fa-percent', 'fa-gitlab',
4750:             'fa-wpbeginner', 'fa-wpforms', 'fa-envira', 'fa-universal-access', 'fa-wheelchair-alt',
4751:             'fa-question-circle-o', 'fa-blind', 'fa-audio-description', 'fa-volume-control-phone', 'fa-braille',
4752:             'fa-assistive-listening-systems', 'fa-asl-interpreting', 'fa-american-sign-language-interpreting',
4753:             'fa-deafness', 'fa-hard-of-hearing', 'fa-deaf', 'fa-glide', 'fa-glide-g', 'fa-signing', 'fa-sign-language',
4754:             'fa-low-vision', 'fa-viadeo', 'fa-viadeo-square', 'fa-snapchat', 'fa-snapchat-ghost', 'fa-snapchat-square',
4755:             'fa-pied-piper', 'fa-first-order', 'fa-yoast', 'fa-themeisle', 'fa-google-plus-circle',
4756:             'fa-google-plus-official', 'fa-fa', 'fa-font-awesome', 'fa-handshake-o', 'fa-envelope-open',
4757:             'fa-envelope-open-o', 'fa-linode', 'fa-address-book', 'fa-address-book-o', 'fa-vcard', 'fa-address-card',
4758:             'fa-vcard-o', 'fa-address-card-o', 'fa-user-circle', 'fa-user-circle-o', 'fa-user-o', 'fa-id-badge',
4759:             'fa-drivers-license', 'fa-id-card', 'fa-drivers-license-o', 'fa-id-card-o', 'fa-quora', 'fa-free-code-camp',
4760:             'fa-telegram', 'fa-thermometer-4', 'fa-thermometer', 'fa-thermometer-full', 'fa-thermometer-3',
4761:             'fa-thermometer-three-quarters', 'fa-thermometer-2', 'fa-thermometer-half', 'fa-thermometer-1',
4762:             'fa-thermometer-quarter', 'fa-thermometer-0', 'fa-thermometer-empty', 'fa-shower', 'fa-bathtub',
4763:             'fa-s15', 'fa-bath', 'fa-podcast', 'fa-window-maximize', 'fa-window-minimize', 'fa-window-restore',
4764:             'fa-times-rectangle', 'fa-window-close', 'fa-times-rectangle-o', 'fa-window-close-o', 'fa-bandcamp',
4765:             'fa-grav', 'fa-etsy', 'fa-imdb', 'fa-ravelry', 'fa-eercast', 'fa-microchip', 'fa-snowflake-o',
4766:             'fa-superpowers', 'fa-wpexplorer', 'fa-meetup'
4767:         );
4768:     }
4769: }
4770: 
API documentation generated by ApiGen