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: abstract class Quform_Element_Field extends Quform_Element
   7: {
   8:     /**
   9:      * The default value
  10:      * @var mixed
  11:      */
  12:     protected $defaultValue;
  13: 
  14:     /**
  15:      * Element value
  16:      * @var mixed
  17:      */
  18:     protected $value;
  19: 
  20:     /**
  21:      * Element filters
  22:      * @var array
  23:      */
  24:     protected $filters = array();
  25: 
  26:     /**
  27:      * Element validators
  28:      * @var array
  29:      */
  30:     protected $validators = array();
  31: 
  32:     /**
  33:      * The current validation errors
  34:      * @var array
  35:      */
  36:     protected $errors = array();
  37: 
  38:     /**
  39:      * Is the element multiple input e.g. multiple select
  40:      * @var boolean
  41:      */
  42:     protected $isMultiple = false;
  43: 
  44:     /**
  45:      * The name of the element that this belongs to
  46:      * @var Quform_Element
  47:      */
  48:     protected $belongsTo;
  49: 
  50:     /**
  51:      * Get the unique element ID
  52:      *
  53:      * @return string
  54:      */
  55:     public function getUniqueId()
  56:     {
  57:         return sprintf('quform_%s_%s', $this->getIdentifier(), $this->form->getUniqueId());
  58:     }
  59: 
  60:     /**
  61:      * Get the name of the element
  62:      *
  63:      * @return string
  64:      */
  65:     public function getName()
  66:     {
  67:         if ($this->getBelongsTo() instanceof Quform_Element) {
  68:             return $this->getId();
  69:         }
  70: 
  71:         return parent::getName();
  72:     }
  73: 
  74:     /**
  75:      * Get the element identifier (e.g. 1_1)
  76:      *
  77:      * @return string
  78:      */
  79:     public function getIdentifier()
  80:     {
  81:         if ($this->getBelongsTo() instanceof Quform_Element) {
  82:             return sprintf('%d_%d_%d', $this->form->getId(), $this->getBelongsTo()->getId(), $this->getId());
  83:         }
  84: 
  85:         return parent::getIdentifier();
  86:     }
  87: 
  88:     /**
  89:      * Get the fully qualified name of the element
  90:      *
  91:      * @return string
  92:      */
  93:     public function getFullyQualifiedName()
  94:     {
  95:         $name = $this->getName();
  96: 
  97:         if ($this->getBelongsTo() instanceof Quform_Element) {
  98:             $name = sprintf('%s[%s]', $this->getBelongsTo()->getName(), $name);
  99:         }
 100: 
 101:         if ($this->isMultiple()) {
 102:             $name .= '[]';
 103:         }
 104: 
 105:         return $name;
 106:     }
 107: 
 108:     /**
 109:      * Get the HTML for the element
 110:      *
 111:      * @param   array   $context
 112:      * @return  string
 113:      */
 114:     public function render(array $context = array())
 115:     {
 116:         $context = $this->prepareContext($context);
 117:         $output = '';
 118: 
 119:         if ($this->isVisible()) {
 120:             $output .= sprintf('<div class="%s">', Quform::escape(Quform::sanitizeClass($this->getElementClasses($context))));
 121:             $output .= '<div class="quform-spacer">';
 122:             $output .= $this->getLabelHtml($context);
 123:             $output .= sprintf('<div class="%s">', Quform::escape(Quform::sanitizeClass($this->getInnerClasses($context))));
 124:             $output .= $this->getDescriptionHtml('above') . $this->getSubLabelHtml('above');
 125:             $output .= $this->getInputHtml($context);
 126:             $output .= $this->getErrorHtml() . $this->getSubLabelHtml() . $this->getDescriptionHtml();
 127:             $output .= '</div></div></div>';
 128:         } else if ($this->shouldConvertToHidden()) {
 129:             $output .= Quform::getHtmlTag('input', array(
 130:                 'type' => 'hidden',
 131:                 'name' => $this->getFullyQualifiedName(),
 132:                 'value' => $this->getValue()
 133:             ));
 134:         }
 135: 
 136:         return $output;
 137:     }
 138: 
 139:     /**
 140:      * Get the classes for the outermost element wrapper
 141:      *
 142:      * @param   array  $context
 143:      * @return  array
 144:      */
 145:     protected function getElementClasses(array $context = array())
 146:     {
 147:         $classes = array(
 148:             'quform-element',
 149:             sprintf('quform-element-%s', $this->config('type')),
 150:             sprintf('quform-element-%s', $this->getIdentifier()),
 151:             'quform-cf'
 152:         );
 153: 
 154:         if (Quform::isNonEmptyString($context['labelPosition'])) {
 155:             $classes[] = sprintf('quform-labels-%s', $context['labelPosition']);
 156:         }
 157: 
 158:         if ($this->isRequired()) {
 159:             $classes[] = 'quform-element-required';
 160:         } else {
 161:             $classes[] = 'quform-element-optional';
 162:         }
 163: 
 164:         if (Quform::isNonEmptyString($this->config('customElementClass'))) {
 165:             $classes[] = $this->config('customElementClass');
 166:         }
 167: 
 168:         $classes = apply_filters('quform_element_classes', $classes, $this, $context);
 169:         $classes = apply_filters('quform_element_classes_' . $this->getIdentifier(), $classes, $this, $context);
 170: 
 171:         return $classes;
 172:     }
 173: 
 174:     /**
 175:      * Get the HTML for the element label
 176:      *
 177:      * @param   array        $context
 178:      * @param   string|bool  $forAttribute  Set the "for" attribute to the element unique ID
 179:      * @param   bool         $id            Add a unique ID to the label
 180:      * @return  string
 181:      */
 182:     protected function getLabelHtml(array $context = array(), $forAttribute = true, $id = false)
 183:     {
 184:         $label = $this->getLabel($context);
 185: 
 186:         if ( ! Quform::isNonEmptyString($label)) {
 187:             return '';
 188:         }
 189: 
 190:         if ($forAttribute === true) {
 191:             $forValue = $this->getUniqueId();
 192:         } elseif (Quform::isNonEmptyString($forAttribute)) {
 193:             $forValue = $forAttribute;
 194:         }
 195: 
 196:         $output = sprintf('<div class="quform-label quform-label-%s">', $this->getIdentifier());
 197: 
 198:         if (Quform::isNonEmptyString($this->config('labelIcon'))) {
 199:             $output .= sprintf('<span class="quform-label-icon"><i class="%s"></i></span>', $this->config('labelIcon'));
 200:         }
 201: 
 202:         // Use filter for multi-input fields (no `for` attribute), otherwise always use 'label'
 203:         $labelTag = isset($forValue) ? 'label' : apply_filters('quform_multi_input_label_tag', 'label', $this, $this->getForm());
 204: 
 205:         $output .= sprintf(
 206:             '<%1$s class="quform-label-text"%2$s%3$s>%4$s%5$s</%1$s>',
 207:             $labelTag,
 208:             ($id ? ' id="' . Quform::escape($this->getUniqueId() . '_label') . '"' : ''),
 209:             (isset($forValue) ? ' for="' . Quform::escape($forValue) . '"' : ''),
 210:             $label,
 211:             $this->isRequired() && Quform::isNonEmptyString($requiredText = $this->form->config('requiredText')) ? '<span class="quform-required">' . esc_html($requiredText) . '</span>' : ''
 212:         );
 213: 
 214:         if ($this->form->config('tooltipsEnabled') && Quform::isNonEmptyString($this->form->config('tooltipIcon')) && Quform::isNonEmptyString($tooltip = $this->getTooltip()) && $context['tooltipType'] == 'icon') {
 215:             $output .= sprintf('<div class="quform-tooltip-icon quform-tooltip-icon-%s">', esc_attr($context['tooltipEvent']));
 216:             $output .= sprintf('<i class="%s"></i>', $this->form->config('tooltipIcon'));
 217:             $output .= sprintf('<div class="quform-tooltip-icon-content">%s</div>', $tooltip);
 218:             $output .= '</div>';
 219:         }
 220: 
 221:         $output .= '</div>';
 222: 
 223:         $output = apply_filters('quform_field_label_html_' . $this->getIdentifier(), $output, $this, $this->getForm(), $context);
 224: 
 225:         return $output;
 226:     }
 227: 
 228:     /**
 229:      * Get the field label text
 230:      *
 231:      * @param   array   $context
 232:      * @return  string
 233:      */
 234:     public function getLabel(array $context = array())
 235:     {
 236:         return apply_filters('quform_field_label_' . $this->getIdentifier(), $this->config('label'), $this, $this->getForm(), $context);
 237:     }
 238: 
 239:     /**
 240:      * Get the classes for the element inner wrapper
 241:      *
 242:      * @param   array  $context
 243:      * @return  array
 244:      */
 245:     protected function getInnerClasses(array $context = array())
 246:     {
 247:         $classes = array(
 248:             'quform-inner',
 249:             sprintf('quform-inner-%s', $this->config('type')),
 250:             sprintf('quform-inner-%s', $this->getIdentifier())
 251:         );
 252: 
 253:         if (Quform::isNonEmptyString($context['fieldSize'])) {
 254:             $classes[] = sprintf('quform-field-size-%s', $context['fieldSize']);
 255:         }
 256: 
 257:         if (Quform::isNonEmptyString($context['fieldWidth']) && $context['fieldWidth'] != 'custom') {
 258:             $classes[] = sprintf('quform-field-width-%s', $context['fieldWidth']);
 259:         }
 260: 
 261:         return $classes;
 262:     }
 263: 
 264:     /**
 265:      * Get the HTML for the element description
 266:      *
 267:      * @param   string  $which  Which description to get ('above' or 'below')
 268:      * @return  string
 269:      */
 270:     protected function getDescriptionHtml($which = 'below')
 271:     {
 272:         $output = '';
 273:         $description = $which == 'above' ? $this->config('descriptionAbove') : $this->config('description');
 274: 
 275:         if (Quform::isNonEmptyString($description)) {
 276:             $output = sprintf(
 277:                 '<p class="quform-description quform-description-%s">%s</p>',
 278:                 esc_attr($which),
 279:                 do_shortcode($description)
 280:             );
 281:         }
 282: 
 283:         return $output;
 284:     }
 285: 
 286:     /**
 287:      * Get the HTML for the element input wrapper
 288:      *
 289:      * @param   array   $context
 290:      * @return  string
 291:      */
 292:     protected function getInputHtml(array $context = array())
 293:     {
 294:         $output = sprintf('<div class="%s">', Quform::escape(Quform::sanitizeClass($this->getInputClasses($context))));
 295:         $output .= $this->getFieldHtml($context);
 296:         $output .= $this->getFieldIconsHtml();
 297: 
 298:         if ($this->form->config('tooltipsEnabled') && Quform::isNonEmptyString($tooltip = $this->getTooltip()) && Quform::get($context, 'tooltipType') == 'field') {
 299:             $output .= sprintf('<div class="quform-tooltip-content">%s</div>', $tooltip);
 300:         }
 301: 
 302:         $output .= '</div>';
 303: 
 304:         return $output;
 305:     }
 306: 
 307:     /**
 308:      * Get the field tooltip
 309:      *
 310:      * @return  string
 311:      */
 312:     protected function getTooltip() {
 313:         return apply_filters('quform_field_tooltip_' . $this->getIdentifier(), $this->config('tooltip'), $this, $this->getForm());
 314:     }
 315: 
 316:     /**
 317:      * Get the classes for the element input wrapper
 318:      *
 319:      * @param   array  $context
 320:      * @return  array
 321:      */
 322:     protected function getInputClasses(array $context = array())
 323:     {
 324:         $classes = array(
 325:             'quform-input',
 326:             sprintf('quform-input-%s', $this->config('type')),
 327:             sprintf('quform-input-%s', $this->getIdentifier()),
 328:             'quform-cf'
 329:         );
 330: 
 331:         if (Quform::isNonEmptyString($this->config('fieldIconLeft'))) {
 332:             $classes[] = 'quform-has-field-icon-left';
 333:         }
 334: 
 335:         if (Quform::isNonEmptyString($this->config('fieldIconRight'))) {
 336:             $classes[] = 'quform-has-field-icon-right';
 337:         }
 338: 
 339:         return $classes;
 340:     }
 341: 
 342:     /**
 343:      * Get the HTML for the field
 344:      *
 345:      * @param   array  $context
 346:      * @return  string
 347:      */
 348:     abstract protected function getFieldHtml(array $context = array());
 349: 
 350:     /**
 351:      * Get the HTML for the field icons
 352:      *
 353:      * @return string
 354:      */
 355:     protected function getFieldIconsHtml()
 356:     {
 357:         $output = '';
 358: 
 359:         if (Quform::isNonEmptyString($this->config('fieldIconLeft'))) {
 360:             $output .= '<span class="quform-field-icon quform-field-icon-left">';
 361:             $output .= sprintf('<i class="%s"></i>', $this->config('fieldIconLeft'));
 362:             $output .= '</span>';
 363:         }
 364: 
 365:         if (Quform::isNonEmptyString($this->config('fieldIconRight'))) {
 366:             $output .= '<span class="quform-field-icon quform-field-icon-right">';
 367:             $output .= sprintf('<i class="%s"></i>', $this->config('fieldIconRight'));
 368:             $output .= '</span>';
 369:         }
 370: 
 371:         return $output;
 372:     }
 373: 
 374:     /**
 375:      * Get the admin label
 376:      *
 377:      * @return string
 378:      */
 379:     public function getAdminLabel()
 380:     {
 381:         $adminLabel = apply_filters('quform_field_admin_label_' . $this->getIdentifier(), $this->config('adminLabel'), $this, $this->getForm());
 382: 
 383:         if ( ! Quform::isNonEmptyString($adminLabel)) {
 384:             $adminLabel = $this->getLabel();
 385:         }
 386: 
 387:         return $adminLabel;
 388:     }
 389: 
 390:     /**
 391:      * @return string
 392:      */
 393:     public function getEditLabelHtml()
 394:     {
 395:         $output = Quform::escape($this->getAdminLabel());
 396: 
 397:         if ($this->isRequired()) {
 398:             $output .= '<span class="qfb-required">*</span>';
 399:         }
 400: 
 401:         return $output;
 402:     }
 403: 
 404:     /**
 405:      * Set the flag that the element can have multiple values.
 406:      *
 407:      * @param boolean $flag
 408:      */
 409:     public function setIsMultiple($flag = true)
 410:     {
 411:         $this->isMultiple = (bool) $flag;
 412:     }
 413: 
 414:     /**
 415:      * Does this element have multiple values?
 416:      *
 417:      * @return boolean
 418:      */
 419:     public function isMultiple()
 420:     {
 421:         return $this->isMultiple;
 422:     }
 423: 
 424:     /**
 425:      * Set the parent element to which this one belongs to
 426:      *
 427:      * @param   Quform_Element  $belongsTo
 428:      * @return  $this
 429:      */
 430:     public function setBelongsTo($belongsTo)
 431:     {
 432:         $this->belongsTo = $belongsTo;
 433: 
 434:         return $this;
 435:     }
 436: 
 437:     /**
 438:      * Get the name of the parent element to which this one belongs
 439:      *
 440:      * @return Quform_Element
 441:      */
 442:     public function getBelongsTo()
 443:     {
 444:         return $this->belongsTo;
 445:     }
 446: 
 447:     /**
 448:      * Add a filter
 449:      *
 450:      * @param Quform_Filter_Interface $filter The instance of the filter
 451:      */
 452:     public function addFilter(Quform_Filter_Interface $filter)
 453:     {
 454:         $name = get_class($filter);
 455:         $this->filters[$name] = $filter;
 456:     }
 457: 
 458:     /**
 459:      * Remove all filters
 460:      */
 461:     public function clearFilters()
 462:     {
 463:         $this->filters = array();
 464:     }
 465: 
 466:     /**
 467:      * Does this element have filters?
 468:      *
 469:      * @return bool
 470:      */
 471:     public function hasFilters()
 472:     {
 473:         return count($this->getFilters()) > 0;
 474:     }
 475: 
 476:     /**
 477:      * Get the filters
 478:      *
 479:      * @return array The array of filters
 480:      */
 481:     public function getFilters()
 482:     {
 483:         return $this->filters;
 484:     }
 485: 
 486:     /**
 487:      * Does the element have the given filter?
 488:      *
 489:      * @param   string|Quform_Filter_Interface  $filter  The name or instance of the filter
 490:      * @return  bool
 491:      */
 492:     public function hasFilter($filter)
 493:     {
 494:         $result = false;
 495: 
 496:         if ($filter instanceof Quform_Filter_Interface) {
 497:             $filter = get_class($filter);
 498:         }
 499: 
 500:         if (is_string($filter)) {
 501:             if (strpos($filter, 'Quform_Filter_') === false) {
 502:                 $filter = 'Quform_Filter_' . ucfirst($filter);
 503:             }
 504: 
 505:             $result = array_key_exists($filter, $this->getFilters());
 506:         }
 507: 
 508:         return $result;
 509:     }
 510: 
 511:     /**
 512:      * Get the filter with the given name
 513:      *
 514:      * @param string $filter The name of the filter
 515:      * @return Quform_Filter_Interface|null The filter or null if the element does not have the filter
 516:      */
 517:     public function getFilter($filter)
 518:     {
 519:         $instance = null;
 520: 
 521:         if (strpos($filter, 'Quform_Filter_') === false) {
 522:             $filter = 'Quform_Filter_' . ucfirst($filter);
 523:         }
 524: 
 525:         $filters = $this->getFilters();
 526:         if (array_key_exists($filter, $filters)) {
 527:             $instance = $filters[$filter];
 528:         }
 529: 
 530:         return $instance;
 531:     }
 532: 
 533:     /**
 534:      * Remove a filter with the given name
 535:      *
 536:      * @param  string  $filter  The name of the filter
 537:      */
 538:     public function removeFilter($filter)
 539:     {
 540:         if (strpos($filter, 'Quform_Filter_') === false) {
 541:             $filter = 'Quform_Filter_' . ucfirst($filter);
 542:         }
 543: 
 544:         if (array_key_exists($filter, $this->filters)) {
 545:             unset($this->filters[$filter]);
 546:         }
 547:     }
 548: 
 549:     /**
 550:      * Add a validator
 551:      *
 552:      * @param   Quform_Validator_Interface  $validator  The validator instance to add
 553:      */
 554:     public function addValidator(Quform_Validator_Interface $validator)
 555:     {
 556:         $name = get_class($validator);
 557:         $this->validators[$name] = $validator;
 558:     }
 559: 
 560:     /**
 561:      * Remove all validators
 562:      */
 563:     public function clearValidators()
 564:     {
 565:         $this->validators = array();
 566:     }
 567: 
 568:     /**
 569:      * Does the element have any validators?
 570:      *
 571:      * @return bool
 572:      */
 573:     public function hasValidators()
 574:     {
 575:         return count($this->getValidators()) > 0;
 576:     }
 577: 
 578:     /**
 579:      * Get the validators
 580:      *
 581:      * @return Quform_Validator_Abstract[] The validators
 582:      */
 583:     public function getValidators()
 584:     {
 585:         return $this->validators;
 586:     }
 587: 
 588:     /**
 589:      * Does the element have the given validator?
 590:      *
 591:      * @param   string|Quform_Validator_Abstract  $validator  The name or instance of the validator
 592:      * @return  boolean
 593:      */
 594:     public function hasValidator($validator)
 595:     {
 596:         $result = false;
 597: 
 598:         if ($validator instanceof Quform_Validator_Interface) {
 599:             $validator = get_class($validator);
 600:         }
 601: 
 602:         if (is_string($validator)) {
 603:             if (strpos($validator, 'Quform_Validator_') === false) {
 604:                 $validator = 'Quform_Validator_' . ucfirst($validator);
 605:             }
 606: 
 607:             $result = array_key_exists($validator, $this->getValidators());
 608:         }
 609: 
 610:         return $result;
 611:     }
 612: 
 613:     /**
 614:      * Get the validator with the given name
 615:      *
 616:      * @param   string $validator               The name of the validator
 617:      * @return  Quform_Validator_Abstract|null  The validator or null if the element does not have the validator
 618:      */
 619:     public function getValidator($validator)
 620:     {
 621:         $instance = null;
 622: 
 623:         if (strpos($validator, 'Quform_Validator_') === false) {
 624:             $validator = 'Quform_Validator_' . ucfirst($validator);
 625:         }
 626: 
 627:         $validators = $this->getValidators();
 628:         if (array_key_exists($validator, $validators)) {
 629:             $instance = $validators[$validator];
 630:         }
 631: 
 632:         return $instance;
 633:     }
 634: 
 635:     /**
 636:      * Remove a validator with the given name
 637:      *
 638:      * @param string $validator The name of the validator
 639:      */
 640:     public function removeValidator($validator)
 641:     {
 642:         if (strpos($validator, 'Quform_Validator_') === false) {
 643:             $validator = 'Quform_Validator_' . ucfirst($validator);
 644:         }
 645: 
 646:         if (array_key_exists($validator, $this->validators)) {
 647:             unset($this->validators[$validator]);
 648:         }
 649:     }
 650: 
 651:     /**
 652:      * Gets whether the element is required or not
 653:      *
 654:      * @return boolean
 655:      */
 656:     public function isRequired()
 657:     {
 658:         return $this->hasValidator('required');
 659:     }
 660: 
 661:     /**
 662:      * @param mixed $value
 663:      */
 664:     public function setDefaultValue($value)
 665:     {
 666:         $this->defaultValue = $value;
 667:     }
 668: 
 669:     /**
 670:      * @return mixed
 671:      */
 672:     public function getDefaultValue()
 673:     {
 674:         return apply_filters('quform_field_default_value_' . $this->getIdentifier(), $this->defaultValue, $this, $this->getForm());
 675:     }
 676: 
 677:     /**
 678:      * @return bool
 679:      */
 680:     public function hasDefaultValue()
 681:     {
 682:         return $this->getDefaultValue() !== $this->getEmptyValue();
 683:     }
 684: 
 685:     /**
 686:      * Set the value
 687:      *
 688:      * @param mixed $value
 689:      */
 690:     public function setValue($value)
 691:     {
 692:         $this->value = $this->isValidValue($value) ? $value : $this->getEmptyValue();
 693:     }
 694: 
 695:     /**
 696:      * Set the value from the database storage
 697:      *
 698:      * @param   string  $value
 699:      * @return  $this
 700:      */
 701:     public function setValueFromStorage($value)
 702:     {
 703:         $value = apply_filters('quform_set_value_from_storage', $value, $this, $this->form);
 704:         $value = apply_filters('quform_set_value_from_storage_' . $this->form->getId(), $value, $this, $this->form);
 705:         $value = apply_filters('quform_set_value_from_storage_' . $this->getIdentifier(), $value, $this, $this->form);
 706: 
 707:         $value = $this->convertValueFromStorage($value);
 708: 
 709:         $this->setValue($value);
 710: 
 711:         return $this;
 712:     }
 713: 
 714:     /**
 715:      * Convert the value from storage format to element format
 716:      *
 717:      * @param   string  $value
 718:      * @return  string
 719:      */
 720:     protected function convertValueFromStorage($value)
 721:     {
 722:         return $value;
 723:     }
 724: 
 725:     /**
 726:      * Is the given value valid for this element type
 727:      *
 728:      * @param   string  $value
 729:      * @return  bool
 730:      */
 731:     protected function isValidValue($value)
 732:     {
 733:         return is_string($value);
 734:     }
 735: 
 736:     /**
 737:      * Get the unfiltered (raw) value
 738:      *
 739:      * @return string|array
 740:      */
 741:     public function getValueRaw()
 742:     {
 743:         $value = apply_filters('quform_get_value_raw_' . $this->getIdentifier(), $this->value, $this, $this->getForm());
 744: 
 745:         return $value;
 746:     }
 747: 
 748:     /**
 749:      * Get the filtered value
 750:      *
 751:      * @return string
 752:      */
 753:     public function getValue()
 754:     {
 755:         $value = (string) $this->value;
 756: 
 757:         $this->filterValue($value);
 758: 
 759:         $value = apply_filters('quform_get_value_' . $this->getIdentifier(), $value, $this, $this->getForm());
 760: 
 761:         return $value;
 762:     }
 763: 
 764:     /**
 765:      * Get the value formatted in HTML
 766:      *
 767:      * @return string
 768:      */
 769:     public function getValueHtml()
 770:     {
 771:         $value = Quform::escape($this->getValue());
 772: 
 773:         $value = apply_filters('quform_get_value_html_' . $this->getIdentifier(), $value, $this, $this->getForm());
 774: 
 775:         return $value;
 776:     }
 777: 
 778:     /**
 779:      * Get the value formatted in plain text
 780:      *
 781:      * @param   string  $separator  The separator for array types (used by child classes)
 782:      * @return  string
 783:      */
 784:     public function getValueText($separator = ', ')
 785:     {
 786:         $value = $this->getValue();
 787: 
 788:         $value = apply_filters('quform_get_value_text_' . $this->getIdentifier(), $value, $this, $this->getForm());
 789: 
 790:         return $value;
 791:     }
 792: 
 793:     /**
 794:      * Get the value for storage in the database
 795:      *
 796:      * @return string
 797:      */
 798:     public function getValueForStorage()
 799:     {
 800:         $value = $this->getConvertedValueForStorage();
 801: 
 802:         $value = apply_filters('quform_get_value_for_storage', $value, $this, $this->form);
 803:         $value = apply_filters('quform_get_value_for_storage_' . $this->form->getId(), $value, $this, $this->form);
 804:         $value = apply_filters('quform_get_value_for_storage_' . $this->getIdentifier(), $value, $this, $this->form);
 805: 
 806:         return $value;
 807:     }
 808: 
 809:     /**
 810:      * Convert the value from element format to storage format
 811:      *
 812:      * @return string
 813:      */
 814:     protected function getConvertedValueForStorage()
 815:     {
 816:         return $this->getValue();
 817:     }
 818: 
 819:     /**
 820:      * Should this element be converted to a hidden field?
 821:      *
 822:      * Currently, this only applies when non-visible fields have a dynamic default value
 823:      *
 824:      * @return bool
 825:      */
 826:     protected function shouldConvertToHidden()
 827:     {
 828:         return ! $this->isVisible() && $this->config('dynamicDefaultValue') && Quform::isNonEmptyString($this->config('dynamicKey'));
 829:     }
 830: 
 831:     /**
 832:      * Is the data given for this element valid?
 833:      *
 834:      * @return boolean True if valid, false otherwise
 835:      */
 836:     public function isValid()
 837:     {
 838:         $this->clearErrors();
 839:         $skipValidation = false;
 840:         $valid = true;
 841: 
 842:         // Skip validation if the value is empty and the element is not required
 843:         if ( ! $this->hasValidator('required') && $this->getValueText() === '') {
 844:             $skipValidation = true;
 845:         }
 846: 
 847:         // Skip validation if the element is conditionally hidden, or the element is not visible (e.g. admin only)
 848:         if ($this->isConditionallyHidden() || ! $this->isVisible()) {
 849:             $skipValidation = true;
 850:         }
 851: 
 852:         if ( ! $skipValidation) {
 853:             $value = $this->getValue();
 854: 
 855:             foreach ($this->getValidators() as $validator) {
 856:                 if ($validator->isValid($value)) {
 857:                     continue;
 858:                 }
 859: 
 860:                 $this->addError($validator->getMessage());
 861:                 $valid = false;
 862:                 break;
 863:             }
 864: 
 865:             $valid = apply_filters('quform_element_valid', $valid, $value, $this);
 866:             $valid = apply_filters('quform_element_valid_' . $this->getIdentifier(), $valid, $value, $this);
 867:         }
 868: 
 869:         return $valid;
 870:     }
 871: 
 872:     /**
 873:      * Does the element have a validation error?
 874:      *
 875:      * @return boolean
 876:      */
 877:     public function hasError()
 878:     {
 879:         return count($this->errors) > 0;
 880:     }
 881: 
 882:     /**
 883:      * Set the validation error message
 884:      *
 885:      * @deprecated 2.2.0 Use addError
 886:      * @param string $message
 887:      */
 888:     public function setError($message)
 889:     {
 890:         _deprecated_function(__METHOD__, '2.2.0', 'addError');
 891: 
 892:         $this->addError($message);
 893:     }
 894: 
 895:     /**
 896:      * Add a validation error message
 897:      *
 898:      * @param string $message
 899:      */
 900:     public function addError($message)
 901:     {
 902:         $this->errors[] = $message;
 903:     }
 904: 
 905:     /**
 906:      * @deprecated 2.2.0 Use clearErrors
 907:      */
 908:     public function clearError()
 909:     {
 910:         _deprecated_function(__METHOD__, '2.2.0', 'clearErrors');
 911: 
 912:         $this->clearErrors();
 913:     }
 914: 
 915:     /**
 916:      * Clear the validation error messages
 917:      */
 918:     public function clearErrors()
 919:     {
 920:         $this->errors = array();
 921:     }
 922: 
 923:     /**
 924:      * Get the first validation error message
 925:      *
 926:      * @return string
 927:      */
 928:     public function getError()
 929:     {
 930:         $errors = $this->getErrors();
 931: 
 932:         return count($errors) > 0 ? $errors[0] : '';
 933:     }
 934: 
 935:     /**
 936:      * Get the validation error messages
 937:      *
 938:      * @return array
 939:      */
 940:     public function getErrors()
 941:     {
 942:         return $this->errors;
 943:     }
 944: 
 945:     /**
 946:      * Get the validation error message for the front JS to process
 947:      */
 948:     public function getErrorArray()
 949:     {
 950:         return array($this->getIdentifier() => $this->getError());
 951:     }
 952: 
 953:     /**
 954:      * Reset the value to default
 955:      */
 956:     public function reset()
 957:     {
 958:         $this->setValue($this->getDefaultValue());
 959:     }
 960: 
 961:     /**
 962:      * Sets the default value dynamically
 963:      *
 964:      * @param string $key
 965:      */
 966:     public function setDynamicDefaultValue($key)
 967:     {
 968:         $value = '';
 969: 
 970:         $dynamicValues = $this->form->getDynamicValues();
 971: 
 972:         if (isset($dynamicValues[$key])) {
 973:             $value = $dynamicValues[$key];
 974:         }
 975: 
 976:         if (isset($_GET[$key])) {
 977:             $value = $_GET[$key];
 978:         }
 979: 
 980:         $value = $this->prepareDynamicValue($value);
 981: 
 982:         $value = apply_filters('quform_element_value', $value, $key);
 983:         $value = apply_filters('quform_element_value_' . $key, $value, $key);
 984: 
 985:         if ($this->isValidValue($value) && $value !== $this->getEmptyValue()) {
 986:             $this->setDefaultValue($value, false);
 987:             $this->setValue($this->getDefaultValue());
 988:         }
 989:     }
 990: 
 991:     /**
 992:      * Subclasses can alter the dynamic default value to suit
 993:      *
 994:      * @param   string  $value
 995:      * @return  string  $value
 996:      */
 997:     public function prepareDynamicValue($value)
 998:     {
 999:         return $value;
1000:     }
1001: 
1002:     /**
1003:      * Filter the given value by reference
1004:      *
1005:      * @param string $value
1006:      */
1007:     protected function filterValue(&$value)
1008:     {
1009:         foreach ($this->getFilters() as $filter) {
1010:             $value = $filter->filter($value);
1011:         }
1012:     }
1013: 
1014:     /**
1015:      * Recursively filter the given value by reference
1016:      *
1017:      * @param array $value
1018:      */
1019:     protected function filterValueRecursive(&$value)
1020:     {
1021:         if (is_array($value)) {
1022:             array_walk($value, array($this, 'filterValueRecursive'));
1023:         } else {
1024:             $this->filterValue($value);
1025:         }
1026:     }
1027: 
1028:     /**
1029:      * Does this element have the given value?
1030:      *
1031:      * @param mixed $value
1032:      * @return boolean
1033:      */
1034:     public function hasValue($value)
1035:     {
1036:         return $this->getValue() === $value;
1037:     }
1038: 
1039:     /**
1040:      * @return string
1041:      */
1042:     public function getEmptyValue()
1043:     {
1044:         return '';
1045:     }
1046: 
1047:     /**
1048:      * Does this element have an empty value?
1049:      *
1050:      * @return boolean
1051:      */
1052:     public function isEmpty()
1053:     {
1054:         return $this->getValue() === $this->getEmptyValue();
1055:     }
1056: 
1057:     /**
1058:      * Get the HTML for the sub label
1059:      *
1060:      * @param string $which
1061:      * @return string
1062:      */
1063:     protected function getSubLabelHtml($which = 'below')
1064:     {
1065:         $output = '';
1066:         $subLabel = $which == 'above' ? $this->config('subLabelAbove') : $this->config('subLabel');
1067: 
1068:         if (Quform::isNonEmptyString($subLabel)) {
1069:             $output = sprintf(
1070:                 '<label id="%1$s_sub_label_%2$s" class="quform-sub-label quform-sub-label-%2$s">%3$s</label>',
1071:                 esc_attr($this->getUniqueId()),
1072:                 esc_attr($which),
1073:                 do_shortcode($subLabel)
1074:             );
1075:         }
1076: 
1077:         return $output;
1078:     }
1079: 
1080:     /**
1081:      * Get the HTML for this element's error (only shown when useAjax is false)
1082:      *
1083:      * @return string
1084:      */
1085:     protected function getErrorHtml()
1086:     {
1087:         if ( ! $this->hasError()) {
1088:             return '';
1089:         }
1090: 
1091:         $output = '<div class="quform-error quform-cf"><div class="quform-error-inner">';
1092: 
1093:         if (Quform::isNonEmptyString($this->form->config('errorsIcon'))) {
1094:             $output .= sprintf('<span class="quform-error-icon"><i class="%s"></i></span>', Quform::escape($this->form->config('errorsIcon')));
1095:         }
1096: 
1097:         $output .= sprintf('<span class="quform-error-text">%s</span>', $this->getError());
1098: 
1099:         $output .= '</div></div>';
1100: 
1101:         return $output;
1102:     }
1103: 
1104:     /**
1105:      * Render the CSS for this field
1106:      *
1107:      * @param   array   $context
1108:      * @return  string
1109:      */
1110:     protected function renderCss(array $context = array())
1111:     {
1112:         $css = '';
1113: 
1114:         if ($context['labelPosition'] == 'left' && $context['labelWidth'] != '150px') {
1115:             $css .= sprintf('.quform-labels-left.quform-element-%1$s > .quform-spacer > .quform-label, .quform-rtl .quform-labels-left.quform-element-%1$s > .quform-spacer > .quform-inner { width: %2$s; }', $this->getIdentifier(), Quform::addCssUnit($context['labelWidth']));
1116:             $css .= sprintf('.quform-labels-left.quform-element-%1$s > .quform-spacer > .quform-inner { margin-left: %2$s; }', $this->getIdentifier(), Quform::addCssUnit($context['labelWidth']));
1117:             $css .= sprintf('.quform-rtl .quform-labels-left.quform-element-%1$s > .quform-spacer > .quform-inner { margin-right: %2$s; margin-left: 0; }', $this->getIdentifier(), Quform::addCssUnit($context['labelWidth']));
1118:         }
1119: 
1120:         $css .= parent::renderCss($context);
1121: 
1122:         return $css;
1123:     }
1124: 
1125:     /**
1126:      * Get the list of CSS selectors
1127:      *
1128:      * @return array
1129:      */
1130:     protected function getCssSelectors()
1131:     {
1132:         return array(
1133:             'element' => '%s .quform-element-%s',
1134:             'elementSpacer' => '%s .quform-element-%s > .quform-spacer',
1135:             'elementLabel' => '%s .quform-label-%s',
1136:             'elementLabelText' => '%s .quform-label-%s > label',
1137:             'elementRequiredText' => '%s .quform-label-%s > label > .quform-required',
1138:             'elementInner' => '%s .quform-inner-%s',
1139:             'elementInput' => '%s .quform-input-%s',
1140:             'elementText' => '%s .quform-field-%s',
1141:             'elementTextHover' => '%s .quform-field-%s:hover',
1142:             'elementTextFocus' => '%1$s .quform-field-%2$s:focus, %1$s .quform-field-%2$s:active',
1143:             'elementTextarea' => '%s .quform-field-%s',
1144:             'elementTextareaHover' => '%s .quform-field-%s:hover',
1145:             'elementTextareaFocus' => '%1$s .quform-field-%2$s:focus, %1$s .quform-field-%2$s:active',
1146:             'elementSelect' => '%s .quform-field-%s',
1147:             'elementSelectHover' => '%s .quform-field-%s:hover',
1148:             'elementSelectFocus' => '%1$s .quform-field-%2$s:focus, %1$s .quform-field-%2$s:active',
1149:             'elementIcon' => '%s .quform-field-icon',
1150:             'elementIconHover' => '%s .quform-field-icon:hover',
1151:             'elementSubLabel' => '%s .quform-element-%s .quform-sub-label',
1152:             'elementDescription' => '%s .quform-element-%s .quform-description'
1153:         );
1154:     }
1155: 
1156:     /**
1157:      * Does the given logic rule match the current value?
1158:      *
1159:      * This is overridden in child classes
1160:      *
1161:      * @param   array  $rule
1162:      * @return  bool
1163:      */
1164:     public function isLogicRuleMatch(array $rule)
1165:     {
1166:         return $this->isLogicValueMatch($this->getValue(), $rule);
1167:     }
1168: 
1169:     /**
1170:      * Does the given logic rule match the given value?
1171:      *
1172:      * @param   mixed  $value
1173:      * @param   array  $rule
1174:      * @return  bool
1175:      */
1176:     protected function isLogicValueMatch($value, array $rule)
1177:     {
1178:         switch ($rule['operator']) {
1179:             case 'eq':
1180:                 return $value === $rule['value'];
1181:             case 'neq':
1182:                 return $value !== $rule['value'];
1183:             case 'empty':
1184:                 return $value === $this->getEmptyValue();
1185:             case 'not_empty':
1186:                 return $value !== $this->getEmptyValue();
1187:             case 'gt':
1188:                 return is_numeric($value) && is_numeric($rule['value']) && (float) $value > (float) $rule['value'];
1189:             case 'lt':
1190:                 return is_numeric($value) && is_numeric($rule['value']) && (float) $value < (float) $rule['value'];
1191:             case 'contains':
1192:                 return preg_match('/' . preg_quote($rule['value'], '/') . '/', $value);
1193:             case 'starts_with':
1194:                 return preg_match('/^' . preg_quote($rule['value'], '/') . '/', $value);
1195:             case 'ends_with':
1196:                 return preg_match('/' . preg_quote($rule['value'], '/') . '$/', $value);
1197:         }
1198: 
1199:         return false;
1200:     }
1201: }
1202: 
API documentation generated by ApiGen