* @license PHP License * @package Wombat * @subpackage base */ /** * Instance creator: patForms * * * * Only one parameter is mandatory: 'elements' * * Optional parameter * - 'rules' rules to add to the form (instead of elements) * - 'autovalidate' named field to autovalidate form on * - 'name' as in HTML form-tag * - 'action' form action, default is the current script * - 'onsubmit' default "return WB.Ajax.Update(this, '{CONTENT_PATH}');" * - 'method' default is "get" * - 'enctype' default is "multipart/form-data" * - 'accept-charset' default is "utf-8" * * @version 0.5.0 * @package Wombat * @subpackage base */ class WBClass_Creator_patForms extends WBClass_Creator { /** * call counter * @var int */ private static $init = 0; /** * initialize form stuff * * Do all static initialisation like setting module folder, * loading patI18n and setting form encoding */ protected function init() { if (self::$init > 0) { ++self::$init; return; } ++self::$init; WBClass::load('WBErrorHandler_Pat'); // configure module base dir $incDirs = WBParam::get('wb/class/includePath'); $incDirs = array_reverse($incDirs); foreach ($incDirs as $incDir) { $moduleDir = realpath($incDir . '/patEx/Forms'); if (empty($moduleDir)) { continue; } patForms::addModuleBaseDir($moduleDir); } WBClass::create('patI18n'); patForms::setDefaultEncoding('utf-8'); } /** * instanciate new objects * * @param array $params options to create object * @return $obj */ public function instantiate($parameter = array()) { if (isset($parameter['init']) && $parameter['init']) { $this->init(); return new WBStdClass(); } $this->init(); // check element list if (!isset($parameter['elements']) || !is_array($parameter['elements'])) { WBClass::load('WBException_Argument'); throw new WBException_Argument('Element list must be an array!', 1, __CLASS__); } // create id according to form parameter's and internal counter $id = md5(serialize($parameter)); $id .= '-' . self::$init; /** @var WBConfig */ $config = WBClass::create('WBConfig'); $config->load('site'); $formAttributes = array( 'action' => null, 'onsubmit' => 'return WB.Ajax.update(this, \'{CONTENT_PATH}\');', 'name' => $id, 'id' => $id, 'method' => 'get', 'enctype' => 'multipart/form-data', 'accept-charset' => $config->get('skin/form/acceptcharset', 'UTF-8'), 'class' => $config->get('skin/form/class', '') ); // replace default attributes with parameter foreach( array_keys( $formAttributes ) as $key ) { // override if( isset( $parameter[$key] ) ) { $formAttributes[$key] = $parameter[$key]; } // remove empty parameter if( empty( $formAttributes[$key] ) ) { unset( $formAttributes[$key] ); } } // mend attributes element definition with datasource $i = 0; foreach( array_keys( $parameter['elements'] ) as $e ) { $parameter['elements'][$e]['attributes']['id'] = $id . '-' . $i; self::insertValues( $e, $parameter['elements'][$e] ); ++$i; } patErrorManager::pushExpect(1101); $form = patForms::createForm($parameter['elements'], $formAttributes); patErrorManager::popExpect(); // mangle elements foreach ($parameter['elements'] as $e => $def) { switch (strtolower($def['type'])) { // verify string elements case 'string'; case 'text': case 'html': case 'xinha': case 'wxml': if (!isset($def['attributes']['maxlength'])) { WBClass::load('WBException_Argument'); throw new WBException_Argument('Element "' . $e . '" requires maxlength attribute', 2, __CLASS__); return null; } break; // force "post" for file upload case 'file': case 'vfsfile': $form->setAttribute('method', 'post'); // $form->setAttribute('target', 'uploadIframe'); break; default: break; } // popolate values if (isset($def['attributesource']) && is_array($def['attributesource'])) { // add all rules to this field $field = $form->getElementByName($e); foreach ($def['attributesource'] as $a) { $this->populateAttributes($field, $a); } } // add rules if (isset($def['rule']) && is_array($def['rule'])) { // add all rules to this field $field = $form->getElementByName($e); foreach ($def['rule'] as $r) { $this->setupRule($r, $field); } } // add filter if (isset($def['filter']) && is_array($def['filter'])) { $field = $form->getElementByName($e); foreach($def['filter'] as $f) { $this->setupFilter($f, $field); } } } if(isset($parameter['rules']) && is_array($parameter['rules'])) { foreach ($parameter['rules'] as $r) { $this->setupRule($r, $form); } } if (!isset($parameter['renderer'])) { $parameter['renderer'] = 'Array'; } $renderer = patForms::createRenderer($parameter['renderer']); $form->setRenderer($renderer); if (isset($parameter['autovalidate'])) { $form->setAutovalidate($parameter['autovalidate']); } return $form; } /** * populate element's attribute(s) * * Create WBDatasource_FormAttribute object and use it to populate the attribute(s) * * @param patForms_Elemenbt $el * @param array $config */ protected function populateAttributes($el, $config) { if (is_string($config)) { $config = trim($config); if (empty($config)) { return; } $config = array('name' => $config); } if (!isset($config['name'])) { WBClass::load('WBException_Argument'); throw new WBException_Argument('Datasource name is required for form attribute source', 4, __CLASS__); } $obj = WBClass::create('WBDatasource_FormAttribute_' . $config['name']); /** @var $obj WBDatasource_FormValues */ $obj->populate($el, $config); } /** * setup form rule and add to target * * Create rule object and configure it. * CAUTION: Configuration is done using setConfig(), which does * not work with standard patForm rules. * * @param array|string $config * @param patForms|patForms_Element $target * @return patForms_Rule */ protected function setupRule($config, $target = null) { if (is_string($config)) { $config = array('name' => $config); } if (!isset($config['name'])) { WBClass::load('WBException_Argument'); throw new WBException_Argument('Rule name is required for form rules', 3, __CLASS__); } $rule = clone patForms::createRule($config['name']); // configure rule if (isset($config['params'])) { $rule->setConfig($config['params']); } if (!$target) { return $rule; } // put rule bofore or after target validation if (isset($config['before'])) { $target->addRule($rule, PATFORMS_RULE_BEFORE_VALIDATION); } else { $target->addRule($rule, PATFORMS_RULE_AFTER_VALIDATION); } return $rule; } /** * Setup form filter and add to target * * Create rule object and configure it with parameters and standard setter-methods * * @see patForms::createFilter() * @param array|string $config * @param patForms|patForms_Element $target * @return patForms_Filter */ protected function setupFilter($config, $target) { if (is_string($config)) { $config = array( 'name' => $config, 'params' => array() ); } if (!isset($config['name'])) { WBClass::load('WBException_Argument'); throw new WBException_Argument('Filter name is required for form element filter', 5, __CLASS__); } if (!isset($config['params']) || !is_array($config['params'])) { $config['params'] = array(); } $filter = patForms::createFilter($config['name'], $config['params']); $target->applyFilter($filter); return $filter; } /** * Insert values from datasource to element * * @param string $element name * @param array $def element definition * @return boolean true on success * @todo implement this function */ private static function insertValues( $element, &$def ) { return true; } }