1: <?php
   2: 
   3:    4:    5: 
   6: class Quform_Element_Factory
   7: {
   8:        9:   10: 
  11:     protected $options;
  12: 
  13:       14:   15: 
  16:     protected $session;
  17: 
  18:       19:   20: 
  21:     protected $repository;
  22: 
  23:       24:   25:   26:   27: 
  28:     public function __construct(Quform_Options $options, Quform_Session $session, Quform_Repository $repository)
  29:     {
  30:         $this->options = $options;
  31:         $this->session = $session;
  32:         $this->repository = $repository;
  33:     }
  34: 
  35:       36:   37:   38:   39:   40:   41: 
  42:     public function create(array $config, Quform_Form $form)
  43:     {
  44:         if (isset($config['type'])) {
  45:             $type = $config['type'];
  46: 
  47:             $method = 'create' . ucfirst($type) . 'Element';
  48:             if (method_exists($this, $method)) {
  49:                 return call_user_func_array(array($this, $method), array($config, $form));
  50:             }
  51: 
  52:             $element = apply_filters('quform_create_element_' . $type, null, $config, $form, $this);
  53: 
  54:             if ( ! $element instanceof Quform_Element) {
  55:                 throw new InvalidArgumentException(sprintf("Method not found to create element of type '%s'", $type));
  56:             }
  57: 
  58:             return $element;
  59:         }
  60: 
  61:         return null;
  62:     }
  63: 
  64:       65:   66:   67:   68: 
  69:     protected function createTextElement(array $config, Quform_Form $form)
  70:     {
  71:         $element = new Quform_Element_Text($config['id'], $form);
  72: 
  73:         $this->configureField($element, $config, $form);
  74: 
  75:         $this->setConfig($element, $config);
  76: 
  77:         return $element;
  78:     }
  79: 
  80:       81:   82:   83:   84: 
  85:     protected function createTextareaElement(array $config, Quform_Form $form)
  86:     {
  87:         $element = new Quform_Element_Textarea($config['id'], $form);
  88: 
  89:         $this->configureField($element, $config, $form);
  90: 
  91:         $this->setConfig($element, $config);
  92: 
  93:         return $element;
  94:     }
  95: 
  96:       97:   98:   99:  100: 
 101:     protected function createEmailElement(array $config, Quform_Form $form)
 102:     {
 103:         $element = new Quform_Element_Email($config['id'], $form);
 104: 
 105:         $this->configureField($element, $config, $form);
 106: 
 107:         $options = array();
 108:         $invalidEmailMessage = $this->getConfigValue($config, 'messageEmailAddressInvalidFormat', $element);
 109:         if (Quform::isNonEmptyString($invalidEmailMessage)) {
 110:             $options['messages'][Quform_Validator_Email::INVALID_FORMAT] = $invalidEmailMessage;
 111:         }
 112: 
 113:         $element->addValidator(new Quform_Validator_Email($options));
 114: 
 115:         $this->setConfig($element, $config);
 116: 
 117:         return $element;
 118:     }
 119: 
 120:      121:  122:  123:  124: 
 125:     protected function createSelectElement(array $config, Quform_Form $form)
 126:     {
 127:         $element = new Quform_Element_Select($config['id'], $form);
 128: 
 129:         $this->configureField($element, $config, $form);
 130: 
 131:         $this->configureMultiOptions($element, $config);
 132: 
 133:         $this->setConfig($element, $config);
 134: 
 135:         return $element;
 136:     }
 137: 
 138:      139:  140:  141:  142: 
 143:     protected function createCheckboxElement(array $config, Quform_Form $form)
 144:     {
 145:         $element = new Quform_Element_Checkbox($config['id'], $form);
 146: 
 147:         $this->configureField($element, $config, $form);
 148: 
 149:         $this->configureMultiOptions($element, $config);
 150: 
 151:         $this->setConfig($element, $config);
 152: 
 153:         return $element;
 154:     }
 155: 
 156:      157:  158:  159:  160: 
 161:     protected function createRadioElement(array $config, Quform_Form $form)
 162:     {
 163:         $element = new Quform_Element_Radio($config['id'], $form);
 164: 
 165:         $this->configureField($element, $config, $form);
 166: 
 167:         $this->configureMultiOptions($element, $config);
 168: 
 169:         $this->setConfig($element, $config);
 170: 
 171:         return $element;
 172:     }
 173: 
 174:      175:  176:  177:  178: 
 179:     protected function createMultiselectElement(array $config, Quform_Form $form)
 180:     {
 181:         $element = new Quform_Element_Multiselect($config['id'], $form);
 182: 
 183:         $this->configureField($element, $config, $form);
 184: 
 185:         $this->configureMultiOptions($element, $config);
 186: 
 187:         $this->setConfig($element, $config);
 188: 
 189:         return $element;
 190:     }
 191: 
 192:      193:  194:  195:  196: 
 197:     protected function createCaptchaElement(array $config, Quform_Form $form)
 198:     {
 199:         $element = new Quform_Element_Captcha($config['id'], $form, $this->session);
 200: 
 201:         $element->addValidator(new Quform_Validator_Required());
 202: 
 203:         $options = array(
 204:             'session' => $this->session,
 205:             'sessionKey' => $form->getSessionKey() . '.captcha.' . $element->getName()
 206:         );
 207: 
 208:         $notMatchMessage = $this->getConfigValue($config, 'messageCaptchaNotMatch', $element);
 209:         if (Quform::isNonEmptyString($notMatchMessage)) {
 210:             $options['messages'][Quform_Validator_Captcha::NOT_MATCH] = $notMatchMessage;
 211:         }
 212: 
 213:         $element->addValidator(new Quform_Validator_Captcha($options));
 214: 
 215:         $this->configureField($element, $config, $form);
 216: 
 217:         unset($config['showInEmail'], $config['saveToDatabase']); 
 218: 
 219:         $this->setConfig($element, $config);
 220: 
 221:         return $element;
 222:     }
 223: 
 224:      225:  226:  227:  228: 
 229:     protected function createPageElement(array $config, Quform_Form $form)
 230:     {
 231:         $element = new Quform_Element_Page($config['id'], $form);
 232: 
 233:         $this->configureContainer($element, $config, $form);
 234: 
 235:         $this->setConfig($element, $config);
 236: 
 237:         return $element;
 238:     }
 239: 
 240:      241:  242:  243:  244: 
 245:     protected function createGroupElement(array $config, Quform_Form $form)
 246:     {
 247:         $element = new Quform_Element_Group($config['id'], $form);
 248: 
 249:         $this->configureContainer($element, $config, $form);
 250: 
 251:         $this->setConfig($element, $config);
 252: 
 253:         return $element;
 254:     }
 255: 
 256:      257:  258:  259:  260: 
 261:     protected function createRowElement(array $config, Quform_Form $form)
 262:     {
 263:         $element = new Quform_Element_Row($config['id'], $form);
 264: 
 265:         $this->configureContainer($element, $config, $form);
 266: 
 267:         $this->setConfig($element, $config);
 268: 
 269:         return $element;
 270:     }
 271: 
 272:      273:  274:  275:  276: 
 277:     protected function createColumnElement(array $config, Quform_Form $form)
 278:     {
 279:         $element = new Quform_Element_Column($config['id'], $form);
 280: 
 281:         $this->configureContainer($element, $config, $form);
 282: 
 283:         $this->setConfig($element, $config);
 284: 
 285:         return $element;
 286:     }
 287: 
 288:      289:  290:  291:  292: 
 293:     protected function createSubmitElement(array $config, Quform_Form $form)
 294:     {
 295:         $element = new Quform_Element_Submit($config['id'], $form);
 296: 
 297:         $this->setConfig($element, $config);
 298: 
 299:         return $element;
 300:     }
 301: 
 302:      303:  304:  305:  306: 
 307:     protected function createFileElement(array $config, Quform_Form $form)
 308:     {
 309:         $element = new Quform_Element_File($config['id'], $form);
 310: 
 311:         $this->configureField($element, $config, $form);
 312: 
 313:         $options = array(
 314:             'name' => $element->getName(),
 315:             'required' => $this->getConfigValue($config, 'required', $element),
 316:             'allowAllFileTypes' => $this->options->get('allowAllFileTypes')
 317:         );
 318: 
 319:         $allowedExtensions = array();
 320:         $allowedExtensionsStr = $this->getConfigValue($config, 'allowedExtensions', $element);
 321: 
 322:         if (Quform::isNonEmptyString($allowedExtensionsStr)) {
 323:             $allowedExtensions = explode(',', $allowedExtensionsStr);
 324:             $allowedExtensions = array_map('trim', array_map('strtolower', $allowedExtensions));
 325:         }
 326: 
 327:         $options['allowedExtensions'] = $allowedExtensions;
 328: 
 329:         $maximumFileSize = $this->getConfigValue($config, 'maximumFileSize', $element);
 330:         if (is_numeric($maximumFileSize)) {
 331:             $options['maximumFileSize'] = $maximumFileSize * 1048576;
 332:         }
 333: 
 334:         $minimumNumberOfFiles = $this->getConfigValue($config, 'minimumNumberOfFiles', $element);
 335:         if (is_numeric($minimumNumberOfFiles)) {
 336:             $options['minimumNumberOfFiles'] = (int) $minimumNumberOfFiles;
 337: 
 338:             if ($options['minimumNumberOfFiles'] > 0) {
 339:                 $options['required'] = true;
 340:             }
 341:         }
 342: 
 343:         $maximumNumberOfFiles = $this->getConfigValue($config, 'maximumNumberOfFiles', $element);
 344:         if (is_numeric($maximumNumberOfFiles)) {
 345:             $options['maximumNumberOfFiles'] = (int) $maximumNumberOfFiles;
 346:         }
 347: 
 348:         $messageMap = array(
 349:             'messageFileUploadRequired' => Quform_Validator_FileUpload::REQUIRED,
 350:             'messageFileNumRequired' => Quform_Validator_FileUpload::NUM_REQUIRED,
 351:             'messageFileTooMany' => Quform_Validator_FileUpload::TOO_MANY,
 352:             'messageFileTooBigFilename' => Quform_Validator_FileUpload::TOO_BIG_FILENAME,
 353:             'messageFileTooBig' => Quform_Validator_FileUpload::TOO_BIG,
 354:             'messageNotAllowedTypeFilename' => Quform_Validator_FileUpload::NOT_ALLOWED_TYPE_FILENAME,
 355:             'messageNotAllowedType' => Quform_Validator_FileUpload::NOT_ALLOWED_TYPE
 356:         );
 357: 
 358:         foreach ($messageMap as $configKey => $messageKey) {
 359:             $message = $this->getConfigValue($config, $configKey, $element);
 360: 
 361:             if (Quform::isNonEmptyString($message)) {
 362:                 $options['messages'][$messageKey] = $message;
 363:             }
 364:         }
 365: 
 366:         $element->addValidator(new Quform_Validator_FileUpload($options));
 367: 
 368:         $this->setConfig($element, $config);
 369: 
 370:         return $element;
 371:     }
 372: 
 373:      374:  375:  376:  377: 
 378:     protected function createRecaptchaElement(array $config, Quform_Form $form)
 379:     {
 380:         $element = new Quform_Element_Recaptcha($config['id'], $form);
 381: 
 382:         $element->addValidator(new Quform_Validator_Required());
 383: 
 384:         $provider = $this->getConfigValue($config, 'provider', $element);
 385: 
 386:         if ($provider == 'hcaptcha') {
 387:             $options = array(
 388:                 'provider' => $provider,
 389:                 'secretKey' => $this->options->get('hcaptchaSecretKey'),
 390:             );
 391: 
 392:             $config['hcaptchaSiteKey'] = $this->options->get('hcaptchaSiteKey');
 393:         } elseif ($provider == 'turnstile') {
 394:             $options = array(
 395:                 'provider' => $provider,
 396:                 'secretKey' => $this->options->get('turnstileSecretKey'),
 397:             );
 398: 
 399:             $config['turnstileSiteKey'] = $this->options->get('turnstileSiteKey');
 400:         } else {
 401:             $version = $this->getConfigValue($config, 'recaptchaVersion', $element);
 402: 
 403:             if ($version == 'v3') {
 404:                 $config['recaptchaSize'] = 'invisible';
 405:             }
 406: 
 407:             $options = array(
 408:                 'provider' => $provider,
 409:                 'secretKey' => $this->options->get('recaptchaSecretKey'),
 410:                 'version' => $version,
 411:                 'threshold' => $this->getConfigValue($config, 'recaptchaThreshold', $element)
 412:             );
 413: 
 414:             $config['recaptchaSiteKey'] = $this->options->get('recaptchaSiteKey');
 415:         }
 416: 
 417:         $messageMap = array(
 418:             'messageRecaptchaMissingInputSecret' => Quform_Validator_Recaptcha::MISSING_INPUT_SECRET,
 419:             'messageRecaptchaInvalidInputSecret' => Quform_Validator_Recaptcha::INVALID_INPUT_SECRET,
 420:             'messageRecaptchaMissingInputResponse' => Quform_Validator_Recaptcha::MISSING_INPUT_RESPONSE,
 421:             'messageRecaptchaInvalidInputResponse' => Quform_Validator_Recaptcha::INVALID_INPUT_RESPONSE,
 422:             'messageRecaptchaError' => Quform_Validator_Recaptcha::ERROR,
 423:             'messageRecaptchaScoreTooLow' => Quform_Validator_Recaptcha::SCORE_TOO_LOW
 424:         );
 425: 
 426:         foreach ($messageMap as $configKey => $messageKey) {
 427:             $message = Quform::get($config, $configKey);
 428: 
 429:             if (Quform::isNonEmptyString($message)) {
 430:                 $options['messages'][$messageKey] = $message;
 431:             }
 432:         }
 433: 
 434:         $element->addValidator(new Quform_Validator_Recaptcha($options));
 435: 
 436:         $this->configureField($element, $config, $form);
 437: 
 438:         $this->setConfig($element, $config);
 439: 
 440:         return $element;
 441:     }
 442: 
 443:      444:  445:  446:  447: 
 448:     protected function createHtmlElement(array $config, Quform_Form $form)
 449:     {
 450:         $element = new Quform_Element_Html($config['id'], $form);
 451: 
 452:         $this->setConfig($element, $config);
 453: 
 454:         return $element;
 455:     }
 456: 
 457:      458:  459:  460:  461: 
 462:     protected function createDateElement(array $config, Quform_Form $form)
 463:     {
 464:         $element = new Quform_Element_Date($config['id'], $form);
 465: 
 466:         $this->configureRequired($element, $config);
 467:         $this->configureRequiredMessage($element, $config, $form);
 468: 
 469:         $defaultValue = $this->getConfigValue($config, 'defaultValue', $element);
 470:         if (Quform::isNonEmptyString($defaultValue)) {
 471:             $defaultValue = $this->parseDate($defaultValue);
 472:             $element->setDefaultValue($defaultValue);
 473:             $element->setValue($element->getDefaultValue());
 474:         }
 475: 
 476:         $this->configureDynamicDefaultValue($element, $config);
 477:         $this->configureValidators($element, $config, $form);
 478: 
 479:         $dateLocale = $this->getConfigValue($config, 'dateLocale', $element);
 480:         $config['dateLocale'] = Quform::isNonEmptyString($dateLocale) ? $dateLocale : $form->getLocale();
 481: 
 482:         $dateFormatJs = $this->getConfigValue($config, 'dateFormatJs', $element);
 483:         $config['dateFormatJs'] = Quform::isNonEmptyString($dateFormatJs) ? $dateFormatJs : $form->getDateFormatJs();
 484: 
 485:         $dateFormat = $this->getConfigValue($config, 'dateFormat', $element);
 486:         $config['dateFormat'] = Quform::isNonEmptyString($dateFormat) ? $dateFormat : $form->getDateFormat();
 487: 
 488:         if ( ! Quform::isNonEmptyString($config['dateFormat'])) {
 489:             $locale = Quform::getLocale($config['dateLocale']);
 490:             $config['dateFormat'] = $locale['dateFormat'];
 491:         }
 492: 
 493:         $validatorOptions = array('format' => $config['dateFormat']);
 494: 
 495:         $dateMin = $this->getConfigValue($config, 'dateMin', $element);
 496:         if (Quform::isNonEmptyString($dateMin)) {
 497:             $dateMin = $this->parseDate($dateMin);
 498:             $config['dateMin'] = $dateMin;
 499:             $validatorOptions['min'] = $dateMin;
 500:         }
 501: 
 502:         $dateMax = $this->getConfigValue($config, 'dateMax', $element);
 503:         if (Quform::isNonEmptyString($dateMax)) {
 504:             $dateMax = $this->parseDate($dateMax);
 505:             $config['dateMax'] = $dateMax;
 506:             $validatorOptions['max'] = $dateMax;
 507:         }
 508: 
 509:         $messageMap = array(
 510:             'messageDateInvalidDate' => Quform_Validator_Date::INVALID_DATE,
 511:             'messageDateTooEarly' => Quform_Validator_Date::TOO_EARLY,
 512:             'messageDateTooLate' => Quform_Validator_Date::TOO_LATE
 513:         );
 514: 
 515:         foreach ($messageMap as $configKey => $messageKey) {
 516:             $message = Quform::get($config, $configKey);
 517: 
 518:             if (Quform::isNonEmptyString($message)) {
 519:                 $validatorOptions['messages'][$messageKey] = $message;
 520:             }
 521:         }
 522: 
 523:         $element->addValidator(new Quform_Validator_Date($validatorOptions));
 524: 
 525:         $this->setConfig($element, $config);
 526: 
 527:         return $element;
 528:     }
 529: 
 530:      531:  532:  533:  534:  535: 
 536:     protected function parseDate($date)
 537:     {
 538:         if (preg_match('/^\{today(|.+)?\}$/', $date,$matches)) {
 539:             try {
 540:                 $date = new DateTime('now', new DateTimeZone('UTC'));
 541:                 $date->setTimezone(Quform::getTimezone());
 542: 
 543:                 if (Quform::isNonEmptyString($matches[1])) {
 544:                     $date->modify(substr($matches[1], 1));
 545:                 }
 546: 
 547:                 $date = $date->format('Y-m-d');
 548:             } catch (Exception $e) {
 549:                 $date = '';
 550:             }
 551:         }
 552: 
 553:         return $date;
 554:     }
 555: 
 556:      557:  558:  559:  560: 
 561:     protected function createTimeElement(array $config, Quform_Form $form)
 562:     {
 563:         $element = new Quform_Element_Time($config['id'], $form);
 564: 
 565:         $this->configureRequired($element, $config);
 566:         $this->configureRequiredMessage($element, $config, $form);
 567: 
 568:         $interval = $this->getConfigValue($config, 'timeInterval', $element);
 569:         if (Quform::isNonEmptyString($interval)) {
 570:             $interval = (string) Quform::clamp($interval, 1, 60);
 571:             $config['timeInterval'] = $interval;
 572:         } else {
 573:             $config['timeInterval'] = '30';
 574:         }
 575: 
 576:         $defaultValue = $this->getConfigValue($config, 'defaultValue', $element);
 577:         if (Quform::isNonEmptyString($defaultValue)) {
 578:             $defaultValue = $this->parseTime($defaultValue, $config['timeInterval']);
 579:             $element->setDefaultValue($defaultValue);
 580:             $element->setValue($element->getDefaultValue());
 581:         }
 582: 
 583:         $this->configureDynamicDefaultValue($element, $config);
 584:         $this->configureValidators($element, $config, $form);
 585: 
 586:         $timeLocale = $this->getConfigValue($config, 'timeLocale', $element);
 587:         $config['timeLocale'] = Quform::isNonEmptyString($timeLocale) ? $timeLocale : $form->getLocale();
 588: 
 589:         $timeFormatJs = $this->getConfigValue($config, 'timeFormatJs', $element);
 590:         $config['timeFormatJs'] = Quform::isNonEmptyString($timeFormatJs) ? $timeFormatJs : $form->getTimeFormatJs();
 591: 
 592:         $timeFormat = $this->getConfigValue($config, 'timeFormat', $element);
 593:         $config['timeFormat'] = Quform::isNonEmptyString($timeFormat) ? $timeFormat : $form->getTimeFormat();
 594: 
 595:         if ( ! Quform::isNonEmptyString($config['timeFormat'])) {
 596:             $locale = Quform::getLocale($config['timeLocale']);
 597:             $config['timeFormat'] = $locale['timeFormat'];
 598:         }
 599: 
 600:         $validatorOptions = array(
 601:             'format' => $config['timeFormat'],
 602:             'interval' => $config['timeInterval']
 603:         );
 604: 
 605:         $timeMin = $this->getConfigValue($config, 'timeMin', $element);
 606:         if (Quform::isNonEmptyString($timeMin)) {
 607:             $timeMin = $this->parseTime($timeMin, $config['timeInterval']);
 608:             $config['timeMin'] = $timeMin;
 609:             $validatorOptions['min'] = $timeMin;
 610:         }
 611: 
 612:         $timeMax = $this->getConfigValue($config, 'timeMax', $element);
 613:         if (Quform::isNonEmptyString($timeMax)) {
 614:             $timeMax = $this->parseTime($timeMax, $config['timeInterval']);
 615:             $config['timeMax'] = $timeMax;
 616:             $validatorOptions['max'] = $config['timeMax'];
 617:         }
 618: 
 619:         $messageMap = array(
 620:             'messageTimeInvalidTime' => Quform_Validator_Time::INVALID_TIME,
 621:             'messageTimeTooEarly' => Quform_Validator_Time::TOO_EARLY,
 622:             'messageTimeTooLate' => Quform_Validator_Time::TOO_LATE
 623:         );
 624: 
 625:         foreach ($messageMap as $configKey => $messageKey) {
 626:             $message = Quform::get($config, $configKey);
 627: 
 628:             if (Quform::isNonEmptyString($message)) {
 629:                 $validatorOptions['messages'][$messageKey] = $message;
 630:             }
 631:         }
 632: 
 633:         $element->addValidator(new Quform_Validator_Time($validatorOptions));
 634: 
 635:         $this->setConfig($element, $config);
 636: 
 637:         return $element;
 638:     }
 639: 
 640:      641:  642:  643:  644:  645:  646: 
 647:     protected function parseTime($time, $interval)
 648:     {
 649:         if (preg_match('/^\{now(|.+)?\}$/', $time,$matches)) {
 650:             try {
 651:                 $time = new DateTime('now', new DateTimeZone('UTC'));
 652:                 $time->setTimezone(Quform::getTimezone());
 653: 
 654:                 if (Quform::isNonEmptyString($matches[1])) {
 655:                     $time->modify(substr($matches[1], 1));
 656:                 }
 657:             } catch (Exception $e) {
 658:                 $time = '';
 659:             }
 660:         } else {
 661:             try {
 662:                 $time = new DateTime($time);
 663:             } catch (Exception $e) {
 664:                 $time = '';
 665:             }
 666:         }
 667: 
 668:         
 669:         if ($time instanceof DateTime) {
 670:             $interval = (int) $interval;
 671:             $hours = (int) $time->format('H');
 672:             $minutes = (int) $time->format('i');
 673:             $minutes = ceil($minutes / $interval) * $interval;
 674:             $time->setTime($hours, $minutes);
 675:             $time = $time->format('H:i');
 676:         }
 677: 
 678:         return $time;
 679:     }
 680: 
 681:      682:  683:  684:  685: 
 686:     protected function createHiddenElement(array $config, Quform_Form $form)
 687:     {
 688:         $element = new Quform_Element_Hidden($config['id'], $form);
 689: 
 690:         $this->configureField($element, $config, $form);
 691: 
 692:         $this->setConfig($element, $config);
 693: 
 694:         return $element;
 695:     }
 696: 
 697:      698:  699:  700:  701: 
 702:     protected function createHoneypotElement(array $config, Quform_Form $form)
 703:     {
 704:         $element = new Quform_Element_Honeypot($config['id'], $form);
 705: 
 706:         $element->addValidator(new Quform_Validator_Honeypot());
 707: 
 708:         $this->configureField($element, $config, $form);
 709: 
 710:         $this->setConfig($element, $config);
 711: 
 712:         return $element;
 713:     }
 714: 
 715:      716:  717:  718:  719: 
 720:     protected function createPasswordElement(array $config, Quform_Form $form)
 721:     {
 722:         $element = new Quform_Element_Password($config['id'], $form);
 723: 
 724:         $this->configureField($element, $config, $form);
 725: 
 726:         $this->setConfig($element, $config);
 727: 
 728:         return $element;
 729:     }
 730: 
 731:      732:  733:  734:  735: 
 736:     protected function createNameElement(array $config, Quform_Form $form)
 737:     {
 738:         $element = new Quform_Element_Name($config['id'], $form);
 739: 
 740:         $this->configureValidators($element, $config, $form);
 741: 
 742:         $this->setConfig($element, $config);
 743: 
 744:         if ($element->config('prefixEnabled')) {
 745:             $prefixElement = $this->createSelectElement(array(
 746:                 'id' => 1,
 747:                 'label' => '',
 748:                 'required' => $element->config('prefixRequired'),
 749:                 'options' => $element->config('prefixOptions'),
 750:                 'noneOption' => $element->config('prefixNoneOption'),
 751:                 'noneOptionText' => $element->config('prefixNoneOptionText'),
 752:                 'subLabel' => $element->config('prefixSubLabel'),
 753:                 'subLabelAbove' => $element->config('prefixSubLabelAbove'),
 754:                 'defaultValue' => $element->config('prefixDefaultValue'),
 755:                 'customClass' => Quform::sanitizeClass(array($element->config('customClass'), $element->config('prefixCustomClass'))),
 756:                 'customElementClass' => $element->config('prefixCustomElementClass'),
 757:                 'messageRequired' => $element->config('messageRequired'),
 758:             ), $form);
 759: 
 760:             $prefixElement->setBelongsTo($element);
 761: 
 762:             $element->setPart('1', $prefixElement);
 763:         }
 764: 
 765:         if ($element->config('firstEnabled')) {
 766:             $firstNameElement = $this->createTextElement(array(
 767:                 'id' => 2,
 768:                 'label' => '',
 769:                 'required' => $element->config('firstRequired'),
 770:                 'placeholder' => $element->config('firstPlaceholder'),
 771:                 'subLabel' => $element->config('firstSubLabel'),
 772:                 'subLabelAbove' => $element->config('firstSubLabelAbove'),
 773:                 'defaultValue' => $element->config('firstDefaultValue'),
 774:                 'customClass' => Quform::sanitizeClass(array($element->config('customClass'), $element->config('firstCustomClass'))),
 775:                 'customElementClass' => $element->config('firstCustomElementClass'),
 776:                 'autocomplete' => $element->config('firstAutocomplete'),
 777:                 'messageRequired' => $element->config('messageRequired')
 778:             ), $form);
 779: 
 780:             $firstNameElement->setBelongsTo($element);
 781: 
 782:             $element->setPart('2', $firstNameElement);
 783:         }
 784: 
 785:         if ($element->config('middleEnabled')) {
 786:             $middleNameElement = $this->createTextElement(array(
 787:                 'id' => 3,
 788:                 'label' => '',
 789:                 'required' => $element->config('middleRequired'),
 790:                 'placeholder' => $element->config('middlePlaceholder'),
 791:                 'subLabel' => $element->config('middleSubLabel'),
 792:                 'subLabelAbove' => $element->config('middleSubLabelAbove'),
 793:                 'defaultValue' => $element->config('middleDefaultValue'),
 794:                 'customClass' => Quform::sanitizeClass(array($element->config('customClass'), $element->config('middleCustomClass'))),
 795:                 'customElementClass' => $element->config('middleCustomElementClass'),
 796:                 'autocomplete' => $element->config('middleAutocomplete'),
 797:                 'messageRequired' => $element->config('messageRequired')
 798:             ), $form);
 799: 
 800:             $middleNameElement->setBelongsTo($element);
 801: 
 802:             $element->setPart('3', $middleNameElement);
 803:         }
 804: 
 805:         if ($element->config('lastEnabled')) {
 806:             $lastNameElement = $this->createTextElement(array(
 807:                 'id' => 4,
 808:                 'label' => '',
 809:                 'required' => $element->config('lastRequired'),
 810:                 'placeholder' => $element->config('lastPlaceholder'),
 811:                 'subLabel' => $element->config('lastSubLabel'),
 812:                 'subLabelAbove' => $element->config('lastSubLabelAbove'),
 813:                 'defaultValue' => $element->config('lastDefaultValue'),
 814:                 'customClass' => Quform::sanitizeClass(array($element->config('customClass'), $element->config('lastCustomClass'))),
 815:                 'customElementClass' => $element->config('lastCustomElementClass'),
 816:                 'autocomplete' => $element->config('lastAutocomplete'),
 817:                 'messageRequired' => $element->config('messageRequired')
 818:             ), $form);
 819: 
 820:             $lastNameElement->setBelongsTo($element);
 821: 
 822:             $element->setPart('4', $lastNameElement);
 823:         }
 824: 
 825:         if ($element->config('suffixEnabled')) {
 826:             $suffixElement = $this->createTextElement(array(
 827:                 'id' => 5,
 828:                 'label' => '',
 829:                 'required' => $element->config('suffixRequired'),
 830:                 'placeholder' => $element->config('suffixPlaceholder'),
 831:                 'subLabel' => $element->config('suffixSubLabel'),
 832:                 'subLabelAbove' => $element->config('suffixSubLabelAbove'),
 833:                 'defaultValue' => $element->config('suffixDefaultValue'),
 834:                 'customClass' => Quform::sanitizeClass(array($element->config('customClass'), $element->config('suffixCustomClass'))),
 835:                 'customElementClass' => $element->config('suffixCustomElementClass'),
 836:                 'messageRequired' => $element->config('messageRequired')
 837:             ), $form);
 838: 
 839:             $suffixElement->setBelongsTo($element);
 840: 
 841:             $element->setPart('5', $suffixElement);
 842:         }
 843: 
 844:         $this->configureDynamicDefaultValue($element, $config); 
 845: 
 846:         return $element;
 847:     }
 848: 
 849:      850:  851:  852:  853:  854:  855:  856: 
 857:     protected function configureContainer(Quform_Element_Container $container, array $config, Quform_Form $form)
 858:     {
 859:         $elements = $this->getConfigValue($config, 'elements', $container);
 860: 
 861:         if (is_array($elements)) {
 862:             foreach ($elements as $eConfig) {
 863:                 $element = $this->create($eConfig, $form);
 864: 
 865:                 if ($element instanceof Quform_Element) {
 866:                     if (in_array($form->config('environment'), array('viewEntry', 'editEntry', 'listEntry')) && in_array(get_class($element), array('Quform_Element_Captcha', 'Quform_Element_Recaptcha'))) {
 867:                         
 868:                         continue;
 869:                     }
 870: 
 871:                     $container->addElement($element);
 872:                 }
 873:             }
 874:         }
 875: 
 876:         return $config;
 877:     }
 878: 
 879:      880:  881:  882:  883:  884:  885: 
 886:     public function configureField(Quform_Element_Field $element, array $config, Quform_Form $form)
 887:     {
 888:         if ( ! in_array(get_class($element), array('Quform_Element_Captcha', 'Quform_Element_Recaptcha', 'Quform_Element_File'))) { 
 889:             $this->configureRequired($element, $config);
 890:         }
 891: 
 892:         $this->configureRequiredMessage($element, $config, $form);
 893:         $this->configureDefaultValue($element, $config);
 894:         $this->configureDynamicDefaultValue($element, $config);
 895:         $this->configureMaxLength($element, $config, $form);
 896:         $this->configureFilters($element, $config);
 897:         $this->configureValidators($element, $config, $form);
 898:     }
 899: 
 900:      901:  902:  903: 
 904:     protected function configureRequired(Quform_Element_Field $element, array $config)
 905:     {
 906:         if ($this->getConfigValue($config, 'required', $element)) {
 907:             $element->addValidator(new Quform_Validator_Required());
 908:         }
 909:     }
 910: 
 911:      912:  913:  914:  915: 
 916:     protected function configureRequiredMessage(Quform_Element_Field $element, array $config, Quform_Form $form)
 917:     {
 918:         if ($element->hasValidator('required')) {
 919:             $requiredMessage = $this->getConfigValue($config, 'messageRequired', $element);
 920: 
 921:             if ( ! Quform::isNonEmptyString($requiredMessage)) {
 922:                 $requiredMessage = $form->config('messageRequired');
 923:             }
 924: 
 925:             if (Quform::isNonEmptyString($requiredMessage)) {
 926:                 $element->getValidator('required')->setConfig('messages.' . Quform_Validator_Required::REQUIRED, $requiredMessage);
 927:             }
 928:         }
 929:     }
 930: 
 931:      932:  933:  934: 
 935:     protected function configureDefaultValue(Quform_Element_Field $element, array $config)
 936:     {
 937:         $defaultValue = $this->getConfigValue($config, 'defaultValue', $element);
 938:         if ($defaultValue !== null) {
 939:             $element->setDefaultValue($defaultValue);
 940:             $element->setValue($element->getDefaultValue());
 941:         }
 942:     }
 943: 
 944:      945:  946:  947: 
 948:     protected function configureDynamicDefaultValue(Quform_Element_Field $element, array $config)
 949:     {
 950:         if ($this->getConfigValue($config, 'dynamicDefaultValue', $element)) {
 951:             $dynamicKey = $this->getConfigValue($config, 'dynamicKey', $element);
 952:             if (Quform::isNonEmptyString($dynamicKey)) {
 953:                 $element->setDynamicDefaultValue($dynamicKey);
 954:             }
 955:         }
 956:     }
 957: 
 958:      959:  960:  961:  962: 
 963:     protected function configureMaxLength(Quform_Element_Field $element, array $config, Quform_Form $form)
 964:     {
 965:         $maxLength = $this->getConfigValue($config, 'maxLength', $element);
 966:         if (is_numeric($maxLength)) {
 967:             $lengthValidator = new Quform_Validator_Length(array(
 968:                 'max' => $maxLength
 969:             ));
 970: 
 971:             $lengthValidatorMessage = $this->getConfigValue($config, 'messageLengthTooLong', $element);
 972: 
 973:             if (Quform::isNonEmptyString($lengthValidatorMessage)) {
 974:                 $lengthValidator->setConfig('messages.' . Quform_Validator_Length::TOO_LONG, $lengthValidatorMessage);
 975:             }
 976: 
 977:             $element->addValidator($lengthValidator);
 978:         }
 979:     }
 980: 
 981:      982:  983:  984: 
 985:     protected function configureFilters(Quform_Element_Field $element, array $config)
 986:     {
 987:         $filters = $this->getConfigValue($config, 'filters', $element);
 988:         if (is_array($filters)) {
 989:             foreach ($filters as $fConfig) {
 990:                 if (isset($fConfig['type'])) {
 991:                     $fClass = 'Quform_Filter_' . ucfirst($fConfig['type']);
 992:                     if (class_exists($fClass)) {
 993:                         $element->addFilter(new $fClass($fConfig));
 994:                     }
 995:                 }
 996:             }
 997:         }
 998:     }
 999: 
1000:     1001: 1002: 1003: 1004: 
1005:     protected function configureValidators(Quform_Element_Field $element, array $config, Quform_Form $form)
1006:     {
1007:         $validators = $this->getConfigValue($config, 'validators', $element);
1008: 
1009:         if (is_array($validators)) {
1010:             foreach ($validators as $vConfig) {
1011:                 if (isset($vConfig['type'])) {
1012:                     $vClass = 'Quform_Validator_' . ucfirst($vConfig['type']);
1013: 
1014:                     if (class_exists($vClass)) {
1015:                         if ($vClass == 'Quform_Validator_Email') {
1016:                             $vConfig['charset'] = $form->getCharset();
1017:                         } else if ($vClass == 'Quform_Validator_Duplicate') {
1018:                             $vConfig['element'] = $element;
1019:                             $vConfig['repository'] = $this->repository;
1020:                         }
1021: 
1022:                         $element->addValidator(new $vClass($vConfig));
1023:                     }
1024:                 }
1025:             }
1026:         }
1027:     }
1028: 
1029:     1030: 1031: 1032: 1033: 
1034:     protected function configureMultiOptions(Quform_Element_Multi $element, array $config)
1035:     {
1036:         $options = $this->getConfigValue($config, 'options', $element);
1037:         if (is_array($options)) {
1038:             $element->addOptions($options);
1039:         }
1040: 
1041:         if ($this->getConfigValue($config, 'inArrayValidator', $element)) {
1042:             $haystack = array();
1043: 
1044:             foreach ($element->getOptions() as $option) {
1045:                 if (isset($option['options'])) {
1046:                     foreach ($option['options'] as $optgroupOption) {
1047:                         $haystack[] = $optgroupOption['value'];
1048:                     }
1049:                 } else {
1050:                     $haystack[] = $option['value'];
1051:                 }
1052:             }
1053: 
1054:             if ($element instanceof Quform_Element_Checkbox || $element instanceof Quform_Element_Multiselect) {
1055:                 $element->addValidator(new Quform_Validator_Array(array(
1056:                     'validator' => new Quform_Validator_InArray(array(
1057:                         'haystack' => $haystack
1058:                     ))
1059:                 )));
1060:             } else {
1061:                 $element->addValidator(new Quform_Validator_InArray(array(
1062:                     'haystack' => $haystack
1063:                 )));
1064:             }
1065:         }
1066: 
1067:         return $config;
1068:     }
1069: 
1070:     1071: 1072: 1073: 1074: 1075: 
1076:     public function setConfig(Quform_Element $element, array $config)
1077:     {
1078:         unset($config['elements'], $config['filters'], $config['validators']);
1079: 
1080:         $element->setConfig($config);
1081:     }
1082: 
1083:     1084: 1085: 1086: 1087: 1088: 1089: 1090: 
1091:     public function getConfigValue(array $config, $key, Quform_Element $element)
1092:     {
1093:         $value = Quform::get($config, $key);
1094: 
1095:         if ($value === null) {
1096:             $value = Quform::get(call_user_func(array(get_class($element), 'getDefaultConfig')), $key);
1097:         }
1098: 
1099:         return $value;
1100:     }
1101: }
1102: