nyroFwk  0.2
form.class.php
Go to the documentation of this file.
1 <?php
10 class form extends object {
11 
17  protected $elements = array();
18 
24  protected $i18nElements = array();
25 
31  protected $section = array();
32 
38  protected $elementsSection = array();
39 
45  protected $curSection = 0;
46 
52  protected $hasFiles = 0;
53 
59  protected $isBound = false;
60 
66  protected $errors = array();
67 
73  protected $customErrors = array();
74 
80  protected $captchaAdded = false;
81 
85  protected function afterInit() {
86  $this->addSection($this->cfg->sectionName);
87  }
88 
94  public function setSubmitText($text) {
95  $this->cfg->submitText = $text;
96  }
97 
103  public function setSubmitPlus($text) {
104  $this->cfg->submitPlus = $text;
105  }
106 
112  public function __toString() {
113  try {
114  return $this->to(request::get('out'));
115  } catch (Exception $e) {
116  if (DEV) {
117  debug::trace($e, 2);
118  } else
119  throw $e;
120  }
121  }
122 
129  public function to($type) {
130  $this->addCaptcha();
131  $ret = null;
132 
133  $prm = $this->cfg->get($type);
134  if ($this->cfg->check($tmp = $type.ucfirst($this->cfg->mode)))
135  $prm = array_merge($prm, $this->cfg->get($tmp));
136 
137  if (!$this->cfg->showSection) {
138  $prm = array_merge($prm, $this->cfg->get($type.'NoSection'));
139  if ($this->cfg->check($tmp = $type.'NoSection'.ucfirst($this->cfg->mode)))
140  $prm = array_merge($prm, $this->cfg->get($tmp));
141  }
142 
143  $hiddenGlobal = is_array($prm) && (array_key_exists('noHidden', $prm) && $prm['noHidden']) || !(strpos($prm['global'], '[hidden]') === false);
144  $hiddens = null;
145 
146  $errorPos = $prm['errorPos'];
147  $errorsGlobal = array();
148 
149  foreach($this->section as $kSection=>$sectionName) {
150  $fields = null;
151  $errorsSection = array();
152  foreach($this->elements[$kSection] as $name=>$e) {
153  $des = $e->description? str_replace('[des]', $e->getDescription(), $prm['des']) : null;
154  $line = $e->isHidden()? 'lineHidden' : 'line';
155 
156  $errors = null;
157  if ($this->isBound() && !$e->isValid() && !$e->isHidden()) {
158  $tmp = array();
159  foreach($e->getErrors() as $err) {
160  $tmp[] = str_replace('[error]', $err, $prm['lineErrorLine']);
161  $errorsSection[] = str_replace('[error]', $err, $prm['sectionErrorLine']);
162  $errorsGlobal[] = str_replace('[error]', $err, $prm['globalErrorLine']);
163  }
164  $errors = $errorPos == 'field' ? str_replace('[errors]', implode('', $tmp), $prm['lineErrorWrap']) : null;
165  $line = 'lineError';
166  }
167 
168  $requiredMoreLabel = $e->getValidRule('required') ? $this->cfg->requiredMoreLabel : null;
169  $label = $e->label
170  ? $e->label.$requiredMoreLabel.$this->cfg->sepLabel
171  : $this->cfg->emptyLabel;
172  $tmp = str_replace(
173  array('[des]', '[label]', '[field]', '[errors]', '[id]', '[classLine]'),
174  array($des, $label, $e->to($type), $errors, $e->id, $e->classLine),
175  $prm[$line]);
176  if ($e->isHidden() && $hiddenGlobal)
177  $hiddens.= $tmp;
178  else
179  $fields.= $tmp;
180  }
181  if ($fields) {
182  $errors = null;
183  $section = 'section';
184  if (!empty($errorsSection) && $errorPos == 'section') {
185  $errors = implode('', $errorsSection);
186  $section.= 'Error';
187  }
188  $ret.= str_replace(
189  array('[errors]', '[fields]', '[label]'),
190  array($errors, $fields, $this->cfg->outSection ? utils::htmlOut($sectionName) : $sectionName),
191  $prm[$section]);
192  }
193  }
194 
195  $plus = null;
196  if ($type == 'html') {
197  if (array_key_exists('incFiles', $prm))
198  foreach($prm['incFiles'] as $f)
199  response::getInstance()->add($f);
200 
201  $plus = 'action="'.$this->cfg->action.'" method="'.$this->cfg->method.'"';
202  if ($this->hasFiles)
203  $plus.= ' enctype="multipart/form-data"';
204  }
205  $plus.= $this->cfg->formPlus;
206 
207  $errors = null;
208  if (!empty($errorsGlobal) && $errorPos == 'global') {
209  $errors = str_replace('[errors]', implode('', $errorsGlobal), $prm['globalError']);
210  }
211  return str_replace(
212  array('[hidden]', '[errors]', '[content]', '[plus]', '[submit]', '[submitText]', '[submitPlus]'),
213  array($hiddens, $errors, $ret, $plus, $prm['submit'], $this->cfg->submitText, $this->cfg->submitPlus),
214  $prm['global']);
215  }
216 
220  public function finalize() {
221  if ($this->isI18n()) {
222  $this->cfg->showSection = true;
223  $nb = 0;
224  if ($this->cfg->forceOnlyOneLang || $this->cfg->noForceLang)
225  $requiredFields = array();
226  foreach(request::avlLang(true) as $lg=>$lang) {
227  $this->addSection($lang);
228  $groupedFieldsAdded = false;
229  foreach($this->i18nElements as $e) {
230  $e['prm']['isI18n'] = true;
231  $initName = $e['prm']['name'];
232  $e['prm']['name'] = db::getCfg('i18n').'['.$lg.']['.$initName.']';
233  if ($this->cfg->forceOnlyOneLang || $this->cfg->noForceLang) {
234  if ($nb == 0) {
235  if ($e['prm']['valid']['required'])
236  $requiredFields[] = $initName;
237  } else {
238  if (!$groupedFieldsAdded && $e['prm']['valid']['required'] && count($requiredFields)) {
239  $fields = array();
240  foreach($requiredFields as $v)
241  $fields[] = db::getCfg('i18n').'['.$lg.']['.$v.']';
242  $e['prm']['valid']['groupedFields'] = array(
243  'form'=>$this,
244  'fields'=>$fields
245  );
246  $groupedFieldsAdded = true;
247  }
248  }
249  if ($nb > 0 || $this->cfg->noForceLang)
250  $e['prm']['valid']['required'] = false;
251  }
252  $this->add($e['type'], $e['prm']);
253  }
254  $nb++;
255  }
256  }
257  }
258 
262  public function toHtml() {
263  return $this->to('html');
264  }
265 
269  public function toXul() {
270  return $this->to('xul');
271  }
272 
278  public function isValid() {
279  $validRet = empty($this->customErrors);
280  $this->errors = array();
281  foreach($this->section as $kSection=>$sectionName) {
282  foreach($this->elements[$kSection] as $name=>$e) {
283  $valid = $e->isValid();
284  if (!$valid)
285  $this->errors[$name] = $e->getErrors();
286  $validRet = $validRet && $valid;
287  }
288  }
289  return $validRet;
290  }
291 
297  public function isI18n() {
298  return !empty($this->i18nElements);
299  }
300 
306  public function getErrors() {
307  return array_merge_recursive($this->errors, $this->customErrors);
308  }
309 
315  public function hasErrors() {
316  return !empty($this->errors) || !empty($this->customErrors);
317  }
318 
325  public function addCustomError($field, $error) {
326  if ($elt = $this->get($field)) {
327  $elt->addCustomError($error);
328  return;
329  }
330  if (!array_key_exists($field, $this->customErrors))
331  $this->customErrors[$field] = array();
332  $this->customErrors[$field][] = $error;
333  }
334 
343  public function add($type, array $prm=array(), $isI18n=false) {
344  if ($isI18n) {
345  $this->i18nElements[] = array('type'=>$type, 'prm'=>$prm);
346  return null;
347  }
348  $inst = null;
349  $name = null;
350  if ($type instanceof form_abstract && !$this->has($name = $type->getName())) {
351  $inst = $type;
352  $inst->renew();
353  } else if (is_string($type) && array_key_exists('name', $prm) && !$this->has($name = $prm['name'])) {
354  $inst = $this->getNew($type, $prm);
355  }
356  if ($inst) {
357  $this->elements[$this->curSection][$name] = $inst;
358  $this->elementsSection[$name] = $this->curSection;
359 
360  if ($inst instanceof form_file)
361  $this->hasFiles++;
362 
363  return $inst;
364  } else
365  return null;
366  }
367 
374  public function has($name) {
375  return array_key_exists($name, $this->elementsSection);
376  }
377 
384  public function get($name) {
385  if ($this->has($name))
386  return $this->elements[$this->elementsSection[$name]][$name];
387  return null;
388  }
389 
395  public function del($name) {
396  if ($this->has($name)) {
397  unset($this->elements[$this->elementsSection[$name]][$name]);
398  unset($this->elementsSection[$name]);
399  }
400  }
401 
407  public function reOrder(array $order) {
408  $tmp = array();
409  foreach($order as $v) {
410  if (isset($this->elementsSection[$v]) && $this->elementsSection[$v] == $this->curSection) {
411  $e = $this->get($v);
412  if ($e)
413  $tmp[$v] = $e;
414  }
415  }
416  foreach($this->elements[$this->curSection] as $name=>$elt) {
417  if (!isset($tmp[$name]))
418  $tmp[$name] = $elt;
419  }
420  $this->elements[$this->curSection] = $tmp;
421  }
422 
428  public function reOrderSection(array $order) {
429  $section = $elements = $elementsSection = $trans = array();
430  $cur = 0;
431  foreach($order as $v) {
432  $old = is_int($v) ? $v : array_search($v, $this->section);
433  if (!is_null($old) && $old !== false && isset($this->section[$old])) {
434  $new = $cur;
435  $trans[$old] = $new;
436  $section[$new] = $this->section[$old];
437  $elements[$new] = $this->elements[$old];
438  foreach(array_keys($elements[$new]) as $k)
439  $elementsSection[$k] = $new;
440  $cur++;
441  }
442  }
443  if (count($section) < count($this->section)) {
444  foreach($this->section as $old=>$v) {
445  if (!isset($trans[$old])) {
446  $new = $cur;
447  $trans[$old] = $new;
448  $section[$new] = $this->section[$old];
449  $elements[$new] = $this->elements[$old];
450  foreach(array_keys($elements[$new]) as $k)
451  $elementsSection[$k] = $new;
452  $cur++;
453  }
454  }
455  }
456 
457  $this->section = $section;
458  $this->elements = $elements;
459  $this->elementsSection = $elementsSection;
460  }
461 
462 
469  public function getValue($name) {
470  if ($elm = $this->get($name)) {
471  return $elm->getValue();
472  }
473  return null;
474  }
475 
483  public function getValues($onlyFilled=false, $ignoreWhitePassword=true) {
484  $ret = array();
485 
486  foreach($this->elementsSection as $name=>$section) {
487  if (!($ignoreWhitePassword && $this->get($name) instanceof form_password && !$this->getValue($name)))
488  $ret[$name] = $this->getValue($name);
489  }
490 
491  $ret = array_diff_key($ret, $this->cfg->notValue);
492 
493  if ($onlyFilled)
494  $ret = array_filter($ret, create_function('$v', 'return $v ? true : false;'));
495 
496  $tmp = array();
497  foreach($ret as $k=>$v) {
498  $matches = explode('|', str_replace(
499  array('][', '[', ']'),
500  array('|', '|', ''),
501  $k
502  ));
503  if (count($matches) > 1) {
504  $t = &$tmp;
505  for($i = 0; $i < count($matches); $i++) {
506  if (!isset($matches[$i+1]))
507  $t[$matches[$i]] = $v;
508  else {
509  if (!array_key_exists($matches[$i], $t) || !is_array($t[$matches[$i]]))
510  $t[$matches[$i]] = array();
511  $t = &$t[$matches[$i]];
512  }
513  }
514  } else
515  $tmp[$matches[0]] = $v;
516  }
517  return $tmp;
518  }
519 
525  public function addNotValue($name) {
526  $this->cfg->setInArray('notValue', $name, true);
527  }
528 
534  public function getNames() {
535  return array_keys($this->elementsSection);
536  }
537 
546  public function setValue($name, $value, $refill=false) {
547  if ($elm = $this->get($name)) {
548  $elm->setValue($value, $refill);
549  $this->isBound = true;
550  return true;
551  }
552  return false;
553  }
554 
562  public function setValues(array $data, $refill=false) {
563  $i = 0;
564  foreach($data as $name=>$value) {
565  if ($this->setValue($name, $value, $refill))
566  $i++;
567  }
568  return $i;
569  }
570 
576  public function isBound() {
577  return $this->isBound;
578  }
579 
585  public function setBound($bound) {
586  $this->isBound = $bound;
587  }
588 
592  public function refill() {
593  $this->addCaptcha();
594  $htVars = http_vars::getInstance();
595  foreach($this->elementsSection as $name=>$section) {
596  $val = $htVars->getVar(array(
597  'name'=>str_replace('.', '_', $name),
598  'method'=>$this->cfg->method
599  ));
600  $this->setValue($name, $val, true);
601  }
602  }
603 
611  public function getNew($type, array $prm) {
612  if (!array_key_exists('mode', $prm))
613  $prm['mode'] = $this->cfg->mode;
614  return factory::get('form_'.$type, $prm);
615  }
616 
623  public function addSection($name) {
624  $this->curSection = count($this->section);
625  $this->section[$this->curSection] = $name;
626  $this->elements[$this->curSection] = array();
627  return $this->curSection;
628  }
629 
636  public function setSection($search) {
637  $find = false;
638  if (!is_int($search)) {
639  foreach($this->section as $k=>&$s) {
640  if ($s == $search)
641  $find = $k;
642  }
643  } else
644  $find = $search;
645 
646  if (is_int($find) && $find < count($this->section))
647  $this->curSection = $find;
648 
649  return $find;
650  }
651 
659  public function setSectionName($name, $search = null) {
660  $find = false;
661  if (is_null($search)) {
662  $find = $this->curSection;
663  } else if (is_int($search)) {
664  $find = $search;
665  } else {
666  foreach($this->section as $k=>&$s) {
667  if ($s == $search)
668  $find = $k;
669  }
670  }
671 
672  if (is_int($find) && $find < count($this->section)) {
673  $this->section[$find] = $name;
674  return true;
675  }
676  return false;
677  }
678 
686  public function moveToSection($name, $section=null) {
687  $f = $this->get($name);
688  if ($f) {
689  $curSection = $this->elementsSection[$name];
691  $this->elements[$section][$name] = $f;
692  $this->elementsSection[$name] = $section;
693  unset($this->elements[$curSection][$name]);
694  return true;
695  }
696  return false;
697  }
698 
705  public function setMode($mode, $force=true) {
706  $this->cfg->mode = $mode;
707  if ($force) {
708  foreach($this->section as $kSection=>$sectionName)
709  foreach($this->elements[$kSection] as $name=>$e)
710  $e->mode = $mode;
711  }
712  }
713 
717  public function firstSection() {
718  $this->curSection = 0;
719  }
720 
724  public function lastSection() {
725  $this->curSection = count($this->elements)-1;
726  }
727 
733  public function getSection() {
734  return $this->curSection;
735  }
736 
740  public function addCaptcha() {
741  if (!$this->captchaAdded) {
742  if (($typeCpt = $this->cfg->getInarray('captcha', 'type')) && ($nameCpt = $this->cfg->getInarray('captcha', 'name'))) {
743  $this->add($typeCpt, $this->cfg->captcha);
744  $this->captchaAdded = true;
745  $this->cfg->setInArray('notValue', $nameCpt, $nameCpt);
746  }
747  }
748  }
749 
757  public function set($key1, $key2, $val) {
758  $this->cfg->setInArray($key1, $key2, $val);
759  }
760 
761  public function __set($key, $val) {
762  $this->cfg->set($key, $val);
763  }
764 
768  public function __clone() {
769  $this->cfg = new config($this->cfg->getAll());
770  $bound = $this->isBound;
771  foreach($this->section as $kSection=>$sectionName) {
772  foreach($this->elements[$kSection] as $name=>$e) {
773  $this->elements[$kSection][$name] = factory::get(get_class($e), unserialize(serialize($e->getCfg()->getAll())));
774  if (!is_object($e->getValue()))
775  $this->setValue($name, $e->getValue());
776  }
777  }
778  $this->isBound = $bound;
779  }
780 
781 }
$elementsSection
Definition: form.class.php:38
addCaptcha()
Definition: form.class.php:740
hasErrors()
Definition: form.class.php:315
getValue($name)
Definition: form.class.php:469
static get($get=null)
$captchaAdded
Definition: form.class.php:80
static htmlOut($val, $key=false)
__set($key, $val)
Definition: form.class.php:761
$elements
Definition: form.class.php:17
reOrder(array $order)
Definition: form.class.php:407
firstSection()
Definition: form.class.php:717
$section
Definition: form.class.php:31
addNotValue($name)
Definition: form.class.php:525
toXul()
Definition: form.class.php:269
__clone()
Definition: form.class.php:768
finalize()
Definition: form.class.php:220
setBound($bound)
Definition: form.class.php:585
$hasFiles
Definition: form.class.php:52
setSubmitPlus($text)
Definition: form.class.php:103
getNames()
Definition: form.class.php:534
moveToSection($name, $section=null)
Definition: form.class.php:686
isI18n()
Definition: form.class.php:297
to($type)
Definition: form.class.php:129
reOrderSection(array $order)
Definition: form.class.php:428
getErrors()
Definition: form.class.php:306
isValid()
Definition: form.class.php:278
static getCfg($key)
Definition: db.class.php:125
getValues($onlyFilled=false, $ignoreWhitePassword=true)
Definition: form.class.php:483
refill()
Definition: form.class.php:592
del($name)
Definition: form.class.php:395
$i18nElements
Definition: form.class.php:24
static getInstance()
static avlLang($withName=false)
$isBound
Definition: form.class.php:59
setSubmitText($text)
Definition: form.class.php:94
setSectionName($name, $search=null)
Definition: form.class.php:659
setValue($name, $value, $refill=false)
Definition: form.class.php:546
$curSection
Definition: form.class.php:45
has($name)
Definition: form.class.php:374
addSection($name)
Definition: form.class.php:623
getNew($type, array $prm)
Definition: form.class.php:611
add($type, array $prm=array(), $isI18n=false)
Definition: form.class.php:343
toHtml()
Definition: form.class.php:262
setSection($search)
Definition: form.class.php:636
setMode($mode, $force=true)
Definition: form.class.php:705
lastSection()
Definition: form.class.php:724
setValues(array $data, $refill=false)
Definition: form.class.php:562
getSection()
Definition: form.class.php:733
addCustomError($field, $error)
Definition: form.class.php:325
__toString()
Definition: form.class.php:112
$f
Definition: list.php:6
static getInstance()
Definition: vars.class.php:29
static get($className, array $cfg=array())
afterInit()
Definition: form.class.php:85
$customErrors
Definition: form.class.php:73
isBound()
Definition: form.class.php:576
static trace($obj, $printExit=false)
Definition: debug.class.php:54
Generated on Sun Oct 15 2017 22:25:20 for nyroFwk by doxygen 1.8.13