Overview

Packages

  • Onion::Controllers
  • Onion::Core
  • Onion::UI
  • Onion::Utils

Classes

  • Form
  • Grid
  • Html
  • IconsGrid
  • Paginator
  • Template
  • Widget
  • Overview
  • Package
  • Class
  • Tree
   1: <?php
   2: 
   3: /**
   4:  * Onion Framework - Vytváranie formulárov
   5:  *
   6:  * Copyright (c) 2011 Jano Gašpar (http://webstranky.net)
   7:  *
   8:  * @author    Jano Gašpar
   9:  * @copyright Copyright (c) 2011 Jano Gašpar
  10:  * @package   Onion::UI
  11:  **/
  12: 
  13: class Form implements Iterator, Countable, ArrayAccess
  14: {
  15:     private $app;
  16: 
  17: 
  18:     /**
  19:      * @var string adresa, kam odoslať formulár
  20:      */
  21:     private $action;
  22: 
  23: 
  24:     /**
  25:      * @var string kotva ktorá sa má pridať k adrese na odoslanie
  26:      */
  27:     private $anchor;
  28: 
  29: 
  30:     /**
  31:      * @var string #id
  32:      */
  33:     public $css_id;
  34: 
  35: 
  36:     /**
  37:      * @var string #class
  38:      */
  39:     public $css_class;
  40: 
  41: 
  42:     /**
  43:      * @var string metóda odoslania formulára
  44:      */
  45:     private $method;
  46: 
  47:     /**
  48:      * @var string kódovanie odoslaných dát
  49:      */
  50:     private $enctype;
  51: 
  52: 
  53:     /**
  54:      * @var int maximálna veľkosť odoslaných súborov
  55:      */
  56:     private $max_file_size;
  57: 
  58: 
  59:     /**
  60:      * @var string token na identifikáciu formulára
  61:      */
  62:     private $token;
  63: 
  64: 
  65:     /**
  66:      * @var array aktuálna položka formulára
  67:      */
  68:     private $current_item;
  69: 
  70: 
  71:     /**
  72:      * @var array položky formulára
  73:      */
  74:     private $items;
  75: 
  76: 
  77:     /**
  78:      * @var int východzia hotnota atribútu "cols" elementu "textarea"
  79:      */
  80:     private $cols = 50;
  81: 
  82: 
  83:     /**
  84:      * @var int východzia hotnota atribútu "rows" elementu "textarea"
  85:      */
  86:     private $rows = 20;
  87: 
  88: 
  89:     /**
  90:      * @var array tlačidlá formulára
  91:      */
  92:     private $buttons = array();
  93: 
  94: 
  95:     /**
  96:      * @var bool identifikácia validity všetkých položiek formulára
  97:      */
  98:     private $is_valid = FALSE;
  99: 
 100: 
 101:     /**
 102:      * @var array východzie chybové hlásenia
 103:      */
 104:     public $error_messages = array(
 105:         'required' => 'This item is required!',
 106:         'email'    => 'This item must be a valid e-mail address!',
 107:         'url'      => 'This item must be a valid url!',
 108:         'number'   => 'This item must be a real number!',
 109:         'integer'  => 'This item must be an integer number!',
 110:         'alpha'    => 'This item must be a text with alpanumeic characters!',
 111:         'min_len'  => 'Táto položka musí mať najmenej %d znakov!',
 112:         'max_len'  => 'Táto položka musí mať najviac %d znakov!',
 113:         'len'      => 'Táto položka musí mať presne %d znakov!',
 114:         'regexp'   => 'Táto položka musí mať presne daný formát!',
 115:         'range'    => 'Táto položka musí byť v intervale %d - %d!',
 116:         'min'      => 'Táto položka musí byť číslo väčšie ako %d!',
 117:         'max'      => 'Táto položka musí byť číslo menšie ako %d!',
 118:         'callback' => '!!CALBACK!!',
 119:         'equal_to' => 'Táto položka musí byť zhodná s položkou %s!',
 120:         'date'     => 'Táto položka musí byť dátum vo formáte RRRR-MM-DD, alebo DD. MM. RRRR!',
 121: 
 122:         'files_upload_error' => 'Uploading of the file(s) to the server failed!',
 123:         'files_type_error'   => 'One or more files is not of the allowed type! The allowed file types are %s.',
 124:         'files_size_error'   => 'One or more files exceeded the allowed size! The maximum allowed size of a file is %f kb.',
 125:         );
 126: 
 127: 
 128:     /**
 129:      * @var array mapa validačných pravidiel a funkcií
 130:      */
 131:     private $rules = array(
 132:         'email'     => array('Validate', 'email'),
 133:         'url'       => array('Validate', 'url'),
 134:         'integer'   => array('Validate', 'integer'),
 135:         'number'    => array('Validate', 'number'),
 136:         'alpha'     => array('Validate', 'alpha'),
 137:         'min_len'   => array('Validate', 'min_length'),
 138:         'max_len'   => array('Validate', 'max_length'),
 139:         'eq_len'    => array('Validate', 'equal_length'),
 140:         'regexp'    => array('Validate', 'regexp'),
 141:         'range'     => array('Validate', 'range'),
 142:         'min'       => array('Validate', 'min_size'),
 143:         'max'       => array('Validate', 'max_size'),
 144:         'date'      => array('Validate', 'date'),
 145:         'required'  => array('Form', 'validate_required'),
 146:         'callback'  => array('Form', 'validate_callback'),
 147:         'equal_to'  => array('Form', 'validate_equal_to'),
 148:         'file_type' => array('Form', 'validate_file_type'),
 149:         );
 150: 
 151: 
 152:     /**
 153:       * @var int
 154:       */
 155:     private $pointer = 0;
 156: 
 157: 
 158:     /**
 159:      * Konštruktor
 160:      *
 161:      * @param  string identifikátor formulára
 162:      * @return object Form pre fluent interface
 163:      */
 164:     function __construct($app, $form_id)
 165:     {
 166:         $this->app = $app;
 167: 
 168:         $this->set_action();
 169: 
 170:         //token sa generuje nanovo pre každú reláciu (session)
 171:         $token = md5(uniqid('', TRUE));
 172:         if (isset($_SESSION['form']['token'][$form_id]) === TRUE) {
 173:             $token = $_SESSION['form']['token'][$form_id];
 174:         }
 175:         $this->token = $_SESSION['form']['token'][$form_id] = $token;
 176: 
 177:         //token sa odosiela s každým formulárom v položke token
 178:         $this->add_item('hidden', 'token')
 179:             ->value($token);
 180: 
 181:         //detekcia maximálnej veľkosti odosielaných súborov z nastavení PHP
 182:         $max_file_size_1 = Utils::to_bytes(ini_get('post_max_size'));
 183:         $max_file_size_2 = Utils::to_bytes(ini_get('upload_max_filesize'));
 184:         $this->max_file_size = max($max_file_size_1, $max_file_size_2);
 185: 
 186:         return $this;
 187:     }
 188: 
 189: 
 190:     /**
 191:      * Nastavovanie atribútov položiek formulára pomocuu preťažovania
 192:      *
 193:      * @param  string meno atribútu
 194:      * @param  mixed  hodnota atribútu
 195:      * @return object Form pre fluent interface
 196:      */
 197:     final public function __call($attribute, $value)
 198:     {
 199:         if (isset($value[0]) === FALSE) {
 200:             $value = '';
 201: 
 202:         } else {
 203:             $value = $value[0];
 204:         }
 205: 
 206:         $this->current_item[$attribute] = $value;
 207: 
 208:         return $this;
 209:     }
 210: 
 211: 
 212:     /**
 213:      * Metóda volaná pri prístupe k objektu ako k reťazcu
 214:      * @return object Html s formulárom
 215:      */
 216:     final public function __tostring()
 217:     {
 218:         return $this->render();
 219:     }
 220: 
 221: 
 222:     /**
 223:      * Metóda na nastavenie metódy odoslania dát a cieľovej adresy
 224:      *
 225:      * @param  string metóda odoslania dát post/get
 226:      * @param  string cieľová adresa formulára
 227:      * @return object Form pre fluent interface
 228:      */
 229:     public function set_action($method = 'post', $url = NULL)
 230:     {
 231:         if (empty($url) === TRUE) {
 232:             $url = $this->app->request->uri;
 233:         }
 234: 
 235:         $this->action = $url;
 236:         $this->method = strtolower($method);
 237: 
 238:         return $this;
 239:     }
 240: 
 241: 
 242:     /**
 243:      * Metóda na vytvorenie nového prvku formulára, prvok je v $this->current_item
 244:      *
 245:      * @param  string typ prvku (text, textarea, password, submit, radio, select, checkbox, file, hidden
 246:      * @param  string názov prvku
 247:      * @return object Form pre fluent interface
 248:      */
 249:     public function add_item($type, $name)
 250:     {
 251:         if (empty($this->current_item['label']) === FALSE) {
 252:             $label = $this->current_item['label'];
 253: 
 254:         } else {
 255:             $label = ucfirst(strtolower($name));
 256:         }
 257: 
 258:         if (empty($this->current_item['fieldset']) === FALSE) {
 259:             $fieldset = $this->current_item['fieldset'];
 260: 
 261:         } else {
 262:             $fieldset = '!';
 263:         }
 264: 
 265:         $this->save_prev_item();
 266: 
 267:         $this->current_item = array(
 268:             'type' => $type,
 269:             'name' => $name,
 270:             'fieldset' => $fieldset,
 271:             'value' => '',
 272:             'label' => $label,
 273:             'rules' => array(),
 274:             'id' => NULL,
 275:             'css' => array(),
 276:             'attributes' => array(),
 277:             );
 278: 
 279:         if ($type === 'html') {
 280:             $this->current_item['name'] = md5($name);
 281:             $this->current_item['value'] = $name;
 282:         }
 283: 
 284:         return $this;
 285:     }
 286: 
 287: 
 288:     public function attribute($attribute, $value)
 289:     {
 290:         $this->current_item['attributes'][$attribute] = $value;
 291:         return $this;
 292:     }
 293: 
 294: 
 295:     /**
 296:      * Metóda na vytvorenie nového tlačidla formulára
 297:      *
 298:      * @param  array vlastnosti tlačidla 'type', 'value', 'name', 'on_click'
 299:      * @return object Form pre fluent interface
 300:      */
 301:     public function add_button($button) {
 302:         $this->buttons[] = $button;
 303:         return $this;
 304:     }
 305: 
 306: 
 307:     /**
 308:      * Metóda na vytvorenie novej skupiny prvkov, fieldsetu, v prípade že názov začína výkričníkom miesto tagu "fieldset" sa použije "div"
 309:      *
 310:      * @param  string vlastnosti tlačidla 'type', 'value', 'name'
 311:      * @return object Form pre fluent interface
 312:      */
 313:     public function fieldset($fieldset)
 314:     {
 315:         if ($fieldset === FALSE) {
 316:             $fieldset = '!' . uniqid();
 317:         }
 318: 
 319:         $this->current_item['fieldset'] = $fieldset;
 320: 
 321:         return $this;
 322:     }
 323: 
 324: 
 325:     /**
 326:      * Metóda na priradenie popisu (label) k prvku
 327:      *
 328:      * @param  string text popisu, ak začína výkričníkom nebude sa vykresľovať
 329:      * @return object Form pre fluent interface
 330:      */
 331:     public function label($label)
 332:     {
 333:         if ($label === FALSE) {
 334:             $label = '!' . uniqid();
 335:         }
 336: 
 337:         $this->current_item['label'] = $label;
 338: 
 339:         return $this;
 340:     }
 341: 
 342: 
 343:     /**
 344:      * Metóda na vykreslenie formulára
 345:      *
 346:      * @return object Html s formulárom
 347:      */
 348:     public function render()
 349:     {
 350:         $this->save_prev_item();
 351: 
 352:         $anchor = '';
 353:         if ($this->anchor !== NULL) {
 354:             $anchor = '#' . $this->anchor;
 355:         }
 356: 
 357:         $form = Html::element('form')
 358:             ->action($this->action . $anchor)
 359:             ->method($this->method)
 360:             ->class($this->css_class)
 361:             ->id($this->css_id);
 362: 
 363:         $hidden_items = $form->create('p')
 364:             ->class('hiddens');
 365: 
 366:         $items_html = array();
 367: 
 368:         $this->validate();
 369: 
 370:         foreach ($this->items as $key => $item) {
 371:             $item['key'] = $key;
 372: 
 373:             $html = Html::element('span');
 374: 
 375:             $html->class[] = 'item';
 376: 
 377:             if (empty($item['rules']) === FALSE) {
 378:                 foreach ($item['rules'] as $rule) {
 379:                     $html->class[] = $rule[0];
 380:                 }
 381:             }
 382: 
 383:             if (isset($item['error']) === TRUE) {
 384:                 $html->create('strong')
 385:                     ->class('error')
 386:                     ->set_text($item['error']);
 387:             }
 388: 
 389:             if (isset($item['note']) === TRUE) {
 390:                 $html->create('em')
 391:                     ->class('note')
 392:                     ->set_text($item['note']);
 393:             }
 394: 
 395:             $item_html = $this->render_item($item);
 396: 
 397:             if ($item['type'] === 'html') {
 398:                 $item_html = NULL;
 399:                 $html = $item['value'];
 400: 
 401:             } else {
 402:                 $this->render_item($item);
 403:             }
 404: 
 405:             if ($item['type'] === 'hidden') {
 406:                 $hidden_items->add($item_html);
 407:                 continue;
 408:             }
 409: 
 410:             $html->insert(0, $item_html);
 411: 
 412:             $items_html[$item['fieldset']][$item['label']][$item['name']]['data'] = $item;
 413:             $items_html[$item['fieldset']][$item['label']][$item['name']]['html'] = $html;
 414:         }
 415: 
 416:         $form->enctype($this->enctype);
 417: 
 418:         $fieldsets_counter = 0;
 419:         $rows_counter = 0;
 420: 
 421:         foreach ($items_html as $legend_text => $fieldset) {
 422:             if ($legend_text[0] === '!') {
 423:                 $fieldset_html = $form->create('div');
 424: 
 425:                 if ($legend_text <> '!') {
 426:                     $fieldset_html->create('h2')
 427:                         ->set_text(substr($legend_text, 1));
 428:                 }
 429: 
 430:             } else {
 431:                 $fieldset_html = $form->create('fieldset');
 432: 
 433:                 $fieldset_html->create('legend')
 434:                     ->set_text($legend_text);
 435: 
 436:                 $fieldset_html->class[] = Strings::webalize($legend_text);
 437:             }
 438: 
 439:             $fieldset_html->class[] = 'fieldset';
 440:             $fieldset_html->class[] = 'fieldset-' . $fieldsets_counter;
 441: 
 442:             foreach ($fieldset as $label_text => $fieldset_items) {
 443:                 $row_html = $fieldset_html->create('p');
 444: 
 445:                 $first_item = reset($fieldset_items);
 446:                 if (empty($first_item['data']['id']) === FALSE) {
 447:                     $id = $first_item['data']['id'];
 448: 
 449:                 } else {
 450:                     $id = $this->css_id . '-row-' . $rows_counter;
 451:                 }
 452: 
 453:                 $row_html->class[] = 'row-' . $rows_counter;
 454: 
 455:                 if (empty($label_text) === FALSE
 456:                     AND $label_text[0] !== '!') {
 457: 
 458:                     $row_html->create('label')
 459:                         ->set_text($label_text)
 460:                         ->for($id);
 461:                 }
 462: 
 463:                 $subitems_count = 0;
 464:                 foreach ($fieldset_items as $fieldset_item) {
 465:                     $o = $fieldset_item['html']->get_children(0);
 466:                     if (is_object($o) === TRUE) {
 467:                         $o->id($id);
 468:                     }
 469: 
 470:                     $fieldset_item['html']->class[] = 'item';
 471:                     $fieldset_item['html']->class[] = 'item-' . $subitems_count;
 472: 
 473:                     $row_html->add($fieldset_item['html']);
 474: 
 475:                     if ($fieldset_item['data']['type'] !== 'html') {
 476:                         $subitems_count++;
 477:                     }
 478: 
 479:                     if (isset($fieldset_item['data']['id']) === TRUE) {
 480:                         $row_html->id('row-' . $fieldset_item['data']['id']);
 481:                     }
 482: 
 483:                     if (isset($fieldset_item['data']['class']) === TRUE) {
 484:                         $row_html->class[] = 'row-' . $fieldset_item['data']['class'];
 485:                     }
 486:                 }
 487: 
 488:                 if ($subitems_count > 1) {
 489:                     $row_html->class[] = 'items';
 490:                     $row_html->class[] = 'items-' . $subitems_count;
 491: 
 492:                     $fieldset_items[] =  array(
 493:                         'html' => Html::element('span')
 494:                             ->class('cleaner'),
 495:                             );
 496:                 }
 497: 
 498:                 $rows_counter++;
 499:             }
 500: 
 501:             $fieldsets_counter++;
 502:         }
 503: 
 504:         // Vykreslenie tlačidiel
 505:         $buttons_html = $form->create('p')
 506:             ->class('buttons');
 507: 
 508:         foreach ($this->buttons as $button) {
 509:             $type = 'submit';
 510: 
 511:             if (isset($button['type']) === TRUE) {
 512:                 $type = $button['type'];
 513:             }
 514: 
 515:             $buttons_html->create('input')
 516:                     ->type($type)
 517:                     ->value($button['value'])
 518:                     ->name($button['name']);
 519:         }
 520: 
 521:         if ($this->is_submitted() === TRUE) {
 522:             return $this->on_submit($form);
 523:         }
 524: 
 525:         return $form->render();
 526:     }
 527: 
 528: 
 529:     private function render_item($item, $only_html = TRUE)
 530:     {
 531:         switch ($item['type']) {
 532:             case 'text':
 533:                 $item_html = $this->render_text_input($item);
 534:                 break;
 535: 
 536:             case 'textarea':
 537:                 $item_html = $this->render_textarea($item);
 538:                 break;
 539: 
 540:             case 'password':
 541:                 $item_html = $this->render_text_input($item);
 542:                 break;
 543: 
 544:             case 'submit':
 545:                 $item_html = $this->render_text_input($item);
 546:                 break;
 547: 
 548:             case 'radio':
 549:                 $item_html = $this->render_radio($item);
 550:                 break;
 551: 
 552:             case 'select':
 553:                 $item_html = $this->render_select($item);
 554:                 break;
 555: 
 556:             case 'checkbox':
 557:                 $item_html = $this->render_checkbox($item);
 558:                 break;
 559: 
 560:             case 'file':
 561:                 $item_html = $this->render_file($item);
 562:                 break;
 563: 
 564:             case 'hidden':
 565:                 $item_html = $this->render_hidden($item);
 566:                 break;
 567: 
 568:             case 'html':
 569:                 $item_html = $item['value'];
 570:                 break;
 571:         }
 572: 
 573:         if (isset($item['id']) === TRUE) {
 574:             $item_html->id($item['id']);
 575:         }
 576: 
 577:         if (isset($item['class']) === TRUE) {
 578:             $item_html->class[] = $item['class'];
 579:         }
 580: 
 581:         foreach ($item['attributes'] as $attribute => $value) {
 582:             $item_html->$attribute = $value;
 583:         }
 584: 
 585:         if ($only_html === TRUE) {
 586:             return $item_html;
 587:         }
 588: 
 589:         $out = array();
 590: 
 591:         $out['html'] = $item_html;
 592: 
 593:         $out['note'] = NULL;
 594:         if (isset($item['note']) === TRUE) {
 595:             $out['note'] = $item['note'];
 596:         }
 597: 
 598:         $out['error'] = NULL;
 599:         if (isset($item['error']) === TRUE) {
 600:             $out['error'] = $item['error'];
 601:         }
 602: 
 603:         $out['label'] = $item['label'];
 604:         if ($item['label'][0] === '!') {
 605:             $out['label'] = substr($item['label'], 1);
 606:         }
 607: 
 608:         $out['name'] = $item['name'];
 609: 
 610:         $out['fieldset'] = $item['fieldset'];
 611:         if ($item['fieldset'][0] === '!') {
 612:             $out['fieldset'] = substr($item['fieldset'], 1);
 613:         }
 614: 
 615:         return $out;
 616:     }
 617: 
 618: 
 619:     /**
 620:      * Metóda na spustenie akcie "on_submit"
 621:      *
 622:      * @param  object inštancia triedy Html s formulárom
 623:      * @return string vykreslený objekt Html
 624:      */
 625:     private function on_submit($form) {
 626:         foreach ($this->buttons as $button) {
 627:             if ($this->is_submitter($button['name']) === FALSE
 628:                 OR empty($button['on_click']) === TRUE) {
 629:                 continue;
 630:             }
 631: 
 632:             $arguments = array($this->get_values(), $form);
 633:             if (count($button['on_click']) === 4) {
 634:                 $args = (array) array_pop($button['on_click']);
 635:                 $arguments = array_merge($arguments, $args);
 636:             }
 637: 
 638:             $on_valid_form = TRUE;
 639:             if (count($button['on_click']) === 3) {
 640:                 $on_valid_form = array_pop($button['on_click']);
 641:             }
 642: 
 643:             if (($this->is_valid === TRUE
 644:                     AND $on_valid_form === TRUE)
 645:                 OR $on_valid_form === FALSE) {
 646: 
 647:                 $form = call_user_func_array($button['on_click'], $arguments);
 648:             }
 649:         }
 650: 
 651:         return $form->render();
 652:     }
 653: 
 654: 
 655:     /**
 656:      * Metóda na uloženie aktuálneho prvku do poľa s prvkami formulára
 657:      * a vytvorenie nového prázdneho aktuálneho prvku
 658:      *
 659:      * @return void
 660:      */
 661:     private function save_prev_item()
 662:     {
 663:         if (empty($this->current_item) === FALSE) {
 664:             if (isset($this->current_item['fieldset']) === FALSE) {
 665:                 $this->current_item['fieldset'] = '_';
 666:             }
 667: 
 668:             $this->items[$this->current_item['name']] = $this->current_item;
 669:             $this->current_item = array();
 670:         }
 671:     }
 672: 
 673: 
 674:     /**
 675:      * Metóda na pridanie validačného pravidla
 676:      *
 677:      * @param  string názov pravidla, použije sa na výber funkcie z tabuľky
 678:      * @param  string text chybového hlásenia
 679:      * @param  mixed  ďalšie parametre pre validačnú funkciu
 680:      * @return object Form pre fluent interface
 681:      */
 682:     public function add_rule() {
 683:         $arguments = func_get_args();
 684: 
 685:         if (empty($arguments) === TRUE) {
 686:             return FALSE;
 687:         }
 688: 
 689:         $rule = array_shift($arguments);
 690: 
 691:         $message = NULL;
 692:         if (empty($arguments) === FALSE) {
 693:             $message = array_shift($arguments);
 694:         }
 695: 
 696:         $this->current_item['rules'][] = array($rule, $message, $arguments);
 697: 
 698:         return $this;
 699:     }
 700: 
 701: 
 702:     /**
 703:      * Metóda na získanie aktuálnych hodnôt prvkov formulára
 704:      *
 705:      * @return array hodnoty odoslané formulárom
 706:      */
 707:     function get_values() {
 708:         $values = array();
 709: 
 710:         foreach ($this->items as $item) {
 711:             if ($item['type'] === 'html') {
 712:                 continue;
 713:             }
 714: 
 715:             $keys = preg_split('/(\[)|(\]\[)|(\])/', $item['name'], -1, PREG_SPLIT_NO_EMPTY);
 716: 
 717:             if (count($keys) === 1) {
 718:                 $values[$item['name']] = $item['value'];
 719: 
 720:             } else {
 721:                 $v = &$values;
 722:                 foreach ($keys as $key) {
 723:                     $v= &$v[$key];
 724:                 }
 725: 
 726:                 $v = $item['value'];
 727:             }
 728:         }
 729: 
 730:         unset($values['token']);
 731: 
 732:         return $values;
 733:     }
 734: 
 735: 
 736:     /**
 737:      * Metóda na vykreslenie prvku input text
 738:      *
 739:      * @param  array  vlastnosti prvku
 740:      * @return object inštancia triedy Html s prvkom
 741:      */
 742:     public function render_text_input($item)
 743:     {
 744:         $html = Html::element('input')
 745:             ->type($item['type'])
 746:             ->name($item['name'])
 747:             ->value($item['value']);
 748: 
 749:         $size = $this->cols;
 750:         if (isset($item['size']) === TRUE) {
 751:             $size = $item['size'];
 752:         }
 753:         $html->size($size);
 754: 
 755:         $length = NULL;
 756: 
 757:         if (isset($item['rules']['eq_len']) === TRUE) {
 758:             $length = (int) $item['rules']['eq_len'];
 759:         }
 760: 
 761:         if (isset($item['rules']['max_len']) === TRUE) {
 762:             $length = (int) $item['rules']['max_len'];
 763:         }
 764: 
 765:         $html->maxlength($length);
 766: 
 767:         return $html;
 768:     }
 769: 
 770: 
 771:     /**
 772:      * Metóda na vykreslenie prvku input hidden
 773:      *
 774:      * @param  array  vlastnosti prvku
 775:      * @return object inštancia triedy Html s prvkom
 776:      */
 777:     public function render_hidden($item)
 778:     {
 779:         $html = Html::element('input')
 780:             ->type($item['type'])
 781:             ->name($item['name'])
 782:             ->value($item['value']);
 783: 
 784:         return $html;
 785:     }
 786: 
 787: 
 788:     /**
 789:      * Metóda na vykreslenie prvku textarea
 790:      *
 791:      * @param  array  vlastnosti prvku
 792:      * @return object inštancia triedy Html s prvkom
 793:      */
 794:     public function render_textarea($item)
 795:     {
 796:         $html = Html::element('textarea')
 797:             ->name($item['name'])
 798:             ->set_text($item['value']);
 799: 
 800:         $cols = $this->cols;
 801:         if (isset($item['cols']) == TRUE) {
 802:             $cols = $item['cols'];
 803:         }
 804:         $html->cols($cols);
 805: 
 806:         $rows = $this->rows;
 807:         if (isset($item['rows']) == TRUE) {
 808:             $rows = $item['rows'];
 809:         }
 810:         $html->rows($rows);
 811: 
 812:         return $html;
 813:     }
 814: 
 815: 
 816:     /**
 817:      * Metóda na vykreslenie prvku select
 818:      *
 819:      * @param  array  vlastnosti prvku
 820:      * @return object inštancia triedy Html s prvkom
 821:      */
 822:     public function render_select($item)
 823:     {
 824:         $html = Html::element('select')
 825:             ->name($item['name']);
 826: 
 827:         if (isset($item['disabled']) === TRUE) {
 828:             $html->disabled($item['disabled']);
 829:         }
 830: 
 831:         if (isset($item['multiple']) === TRUE) {
 832:             $html->multiple($item['multiple']);
 833:         }
 834: 
 835:         if (isset($item['size']) === TRUE) {
 836:             $html->size($item['size']);
 837:         }
 838: 
 839:         foreach ($item['values'] as $key => $option) {
 840:             if (is_array($option) === TRUE) {
 841:                 if (empty($option) === TRUE) {
 842:                     continue;
 843:                 }
 844: 
 845:                 $optgroup_html = $html->create('optgroup')
 846:                     ->label($key);
 847: 
 848:                 $optgroup = $option;
 849:                 foreach ($optgroup as $key => $option) {
 850:                     $optgroup_html->create('option')
 851:                         ->value($key)
 852:                         ->set_text($option)
 853:                         ->selected($key == $item['value']);
 854:                 }
 855: 
 856:             } else {
 857:                 $html->create('option')
 858:                     ->value($key)
 859:                     ->set_text($option)
 860:                     ->selected($key == $item['value']);
 861:             }
 862:         }
 863: 
 864:         return $html;
 865:     }
 866: 
 867: 
 868:     /**
 869:      * Metóda na vykreslenie prvku input checkbox
 870:      *
 871:      * @param  array  vlastnosti prvku
 872:      * @return object inštancia triedy Html s prvkom
 873:      */
 874:     public function render_checkbox($item)
 875:     {
 876:         $html = Html::element('input')
 877:             ->type('checkbox')
 878:             ->name($item['name']);
 879: 
 880:         $html->checked(empty($item['value']) === FALSE);
 881: 
 882:         return $html;
 883:     }
 884: 
 885: 
 886:     /**
 887:      * Metóda na vykreslenie prvku input file
 888:      *
 889:      * @param  array  vlastnosti prvku
 890:      * @return object inštancia triedy Html s prvkom
 891:      */
 892:     public function render_file($item)
 893:     {
 894:         $max_file_size = $this->max_file_size;
 895:         if (isset($item['rules']['maxsize']) == TRUE) {
 896:             $max_file_size = Utils::to_bytes($item['rules']['maxsize']);
 897:         }
 898: 
 899:         $html = Html::element();
 900: 
 901:         $html->create('input')
 902:             ->type('hidden')
 903:             ->name('MAX_FILE_SIZE')
 904:             ->value($max_file_size);
 905: 
 906:         $files = 1;
 907:         $brackets = '';
 908:         if (empty($item['files']) === FALSE
 909:             AND is_numeric($item['files']) === TRUE) {
 910: 
 911:             $files = $item['files'];
 912:             $brackets = '[]';
 913:         }
 914: 
 915:         $browser = Visitor::get_browser_info();
 916: 
 917:         if ($browser['name'] === 'msie'
 918:             AND $browser['version'] < 8) {
 919: 
 920:             while ($files > 0) {
 921:                 $html->create('input')
 922:                     ->name($item['name'] . $brackets)
 923:                     ->type('file');
 924:                 $files--;
 925:             }
 926: 
 927:         } else {
 928:             $input = $html->create('input')
 929:                     ->name($item['name'] . $brackets)
 930:                     ->type('file');
 931: 
 932:                 if ($files > 1) {
 933:                     $input->multiple(TRUE);
 934:                 }
 935:         }
 936: 
 937:         $this->enctype = 'multipart/form-data';
 938: 
 939:         return $html;
 940:     }
 941: 
 942: 
 943:     /**
 944:      * Metóda na vykreslenie prvku input radio
 945:      *
 946:      * @param  array  vlastnosti prvku
 947:      * @return object inštancia triedy Html s prvkom
 948:      */
 949:     public function render_radio($item)
 950:     {
 951:         $html = Html::element();
 952: 
 953:         if (isset($item['id']) === TRUE) {
 954:             $html->id($item['id']);
 955:         }
 956: 
 957:         $counter = 0;
 958:         foreach ($item['values'] as $radio_value => $label_text) {
 959:             $id = $item['name'] . '-' . $counter;
 960: 
 961:             $html->create('label')
 962:                 ->set_text($label_text)
 963:                 ->for($id);
 964: 
 965:             $radio_html = $html->create('input')
 966:                 ->type('radio')
 967:                 ->name($item['name'])
 968:                 ->value($radio_value);
 969: 
 970:             if (isset($item['disabled']) === TRUE) {
 971:                 $radio_html->disabled($item['disabled']);
 972:             }
 973: 
 974:             $radio_html->id($id);
 975: 
 976:             if ($item['value'] == $radio_value) {
 977:                 $radio_html->checked('checked');
 978:             }
 979: 
 980:             $counter++;
 981:         }
 982: 
 983:         return $html;
 984:     }
 985: 
 986: 
 987:     public function open()
 988:     {
 989:         $anchor = '';
 990:         if ($this->anchor !== NULL) {
 991:             $anchor = '#' . $this->anchor;
 992:         }
 993: 
 994:         $out = '<form action="' . $this->action . $anchor . '" method="' . $this->method . '"';
 995: 
 996:         if (empty($this->css_class) === FALSE) {
 997:             $out .= ' class="' . $this->css_class . '"';
 998:         }
 999: 
1000:         if (empty($this->css_id) === FALSE) {
1001:             $out .= ' id="' . $this->css_id . '"';
1002:         }
1003: 
1004:         $out .= '>';
1005: 
1006:         echo $out;
1007:     }
1008: 
1009: 
1010:     public function close()
1011:     {
1012:         echo '</form>';
1013:     }
1014: 
1015: 
1016:     /**
1017:      * Metóda na zistenie či aktuána požiadavka (request) bol odoslnie aktuálneho formulára
1018:      *
1019:      * @return bool
1020:      */
1021:     public function is_submitted()
1022:     {
1023:         if ($this->app->request->method !== $this->method) {
1024:             return FALSE;
1025:         }
1026: 
1027:         if ($this->app->request->get_current_method_data('token') !== $this->token) {
1028:             return FALSE;
1029:         }
1030: 
1031:         return TRUE;
1032:     }
1033: 
1034: 
1035:     /**
1036:      * Metóda na zistenie tlačidla ktorým bol formlár odoslaný
1037:      *
1038:      * @return string|FALSE meno odosielacieho tlačidla, alebo FALSE, ak formulár nebol odoslaný, alebo sa nepodarilo určiť ktoré tlačidlo to bolo
1039:      */
1040:     public function submitted_by()
1041:     {
1042:         if ($this->is_submitted() === FALSE) {
1043:             return FALSE;
1044:         }
1045: 
1046:         foreach ($this->buttons as $button) {
1047:             if ($this->app->request->get_current_method_data($button['name']) !== NULL) {
1048:                 return $button['name'];
1049:             }
1050:         }
1051: 
1052:         return FALSE;
1053:     }
1054: 
1055: 
1056:     /**
1057:      * Metóda na overenie či tlačidlo bolo odosielacie
1058:      *
1059:      * @param  string meno tlačidla
1060:      * @return string
1061:      */
1062:     public function is_submitter($name) {
1063:         if ($this->is_submitted() === FALSE) {
1064:             return FALSE;
1065:         }
1066: 
1067:         if ($this->app->request->get_current_method_data($name) !== NULL) {
1068:             return TRUE;
1069:         }
1070: 
1071:         return FALSE;
1072:     }
1073: 
1074: 
1075:     /**
1076:      * Metóda na získanie aktuálnej hodnoty položky, buď odoslanú, alebo predvolenú ak formulár ešte nebol odoslaný
1077:      *
1078:      * @param  string meno položky
1079:      * @return mixed
1080:      */
1081:     private function get_item_value($item)
1082:     {
1083:         $value = NULL;
1084: 
1085:         if ($item['type'] === 'file') {
1086:             $value = Arrays::get_value($this->app->request->files, $item['name']);
1087: 
1088:         } else {
1089:             if ($this->is_submitted() === TRUE) {
1090:                 $keys = preg_split('/(\[)|(\]\[)|(\])/', $item['name'], -1, PREG_SPLIT_NO_EMPTY);
1091:                 if (count($keys) === 1) {
1092:                     $value = $this->app->request->get_current_method_data($item['name']);
1093: 
1094:                 } else {
1095:                     $value = $this->app->request->get_current_method_data();
1096:                     $value = Arrays::get_value($value, $keys);
1097:                 }
1098: 
1099:                 if ($item['type'] === 'checkbox') {
1100:                     $value = ($value === 'on');
1101:                 }
1102:             }
1103:         }
1104: 
1105:         if ($value === NULL) {
1106:             $value = $item['value'];
1107:         }
1108: 
1109:         return $value;
1110:     }
1111: 
1112: 
1113:     /**
1114:      * Metóda na overenie odoslaných hodnôt formulára
1115:      *
1116:      * @return bool
1117:      */
1118:     public function validate()
1119:     {
1120:         if ($this->is_submitted() === FALSE) {
1121:             $this->is_valid = FALSE;
1122:             return FALSE;
1123:         }
1124: 
1125:         $valid = TRUE;
1126: 
1127:         foreach ($this->items as $key => &$item) {
1128:             $item['value'] = $this->get_item_value($item);
1129: 
1130:             if (empty($item['rules']) === TRUE) {
1131:                 continue;
1132:             }
1133: 
1134:             $valid_item = TRUE;
1135: 
1136:             $required = FALSE;
1137: 
1138:             foreach ($item['rules'] as $rule) {
1139:                 $rule_name = $rule[0];
1140:                 $message = $rule[1];
1141:                 $arguments = array_merge(array($item['value']), $rule[2]);
1142: 
1143:                 if ($rule_name === 'required') {
1144:                     $required = TRUE;
1145:                 }
1146: 
1147:                 $function = $this->rules[$rule_name];
1148: 
1149:                 if (empty($message) === TRUE) {
1150:                     $message = $this->error_messages[$rule_name];
1151:                 }
1152: 
1153:                 if (empty($message) === TRUE) {
1154:                     $message = 'ERROR';
1155:                 }
1156: 
1157:                 if (call_user_func_array($function, $arguments) === FALSE) {
1158:                     $valid_item = FALSE;
1159:                     $item['error'] = $message;
1160:                     break;
1161:                 }
1162:             }
1163: 
1164:             if (Validate::is_empty($item['value']) === TRUE
1165:                 AND $required === FALSE
1166:                 AND $rule_name !== 'callback') {
1167: 
1168:                 $item['error'] = NULL;
1169:                 $valid_item = TRUE;
1170:             }
1171: 
1172:             if ($valid_item === FALSE) {
1173:                 $valid = FALSE;
1174:             }
1175:         }
1176: 
1177:         $this->is_valid = $valid;
1178: 
1179:         return $valid;
1180:     }
1181: 
1182: 
1183:     /**
1184:      * Metóda na overenie hodnoty položky pomocou vlastnej funkcie
1185:      *
1186:      * @param  array        metóda na overenie
1187:      * @param  mixed        hodnota na overenie
1188:      * @param  mixed        doplnkové argumenty pre overovaciu funkciu
1189:      * @return string|FALSE hodnota alebo FALSE ak overovanie neprejde
1190:      */
1191:     public function validate_callback() {
1192:         $arguments = func_get_args();
1193:         $func = array_splice($arguments, 1, 1);
1194: 
1195:         return call_user_func_array($func[0], $arguments);
1196:     }
1197: 
1198: 
1199:     /**
1200:      * Metóda na overenie či hodnota je totožná s hodnotou inej položky
1201:      *
1202:      * @param  string hodnota
1203:      * @param  string meno položky s ktorej hodnotou sa má hodnota aktuálnej položky porovnať
1204:      * @return bool
1205:      */
1206:     public function validate_equal_to($value, $item) {
1207:         return ($value === $this->app->request->get_current_method_data($item));
1208:     }
1209: 
1210: 
1211:     /**
1212:      * Metóda na overenie či hodnota je totožná s hodnotou inej položky
1213:      *
1214:      * @param  string hodnota
1215:      * @param  string meno položky s ktorej hodnotou sa má hodnota aktuálnej položky porovnať
1216:      * @return bool
1217:      */
1218:     public function validate_required($value) {
1219:         return (Validate::is_empty($value) === FALSE);
1220:     }
1221: 
1222: 
1223:     /**
1224:      * Metóda na overenie či hodnota je súbor v požadovanom formáte
1225:      *
1226:      * @param  object SuperArray
1227:      * @param  array|string pole prípon, alebo prípona
1228:      * @return bool
1229:      */
1230:     public function validate_file_type($value, $filetypes) {
1231:         if (isset($value[0]) === FALSE) {
1232:             return TRUE;
1233:         }
1234: 
1235:         $filetypes = (array) $filetypes;
1236:         return (in_array($value[0]['extension'], $filetypes));
1237:     }
1238: 
1239: 
1240:     /**
1241:      * Nastavenie #id a kotvy
1242:      *
1243:      * @param  string názov #id
1244:      * @param  bool   povolenie nastavenia kotvy
1245:      * @return object Form pre fluent interface
1246:      */
1247:     public function css_id($css_id, $set_anchor = FALSE)
1248:     {
1249:         $this->css_id = $css_id;
1250: 
1251:         if ($set_anchor === TRUE) {
1252:             $this->anchor = $css_id;
1253:         }
1254:         return $this;
1255:     }
1256: 
1257: 
1258:     /**
1259:      * Nastavenie css triedy
1260:      *
1261:      * @param  string názov triedy
1262:      * @return object Form pre fluent interface
1263:      */
1264:     public function css_class($css_class)
1265:     {
1266:         $this->css_class = $css_class;
1267:         return $this;
1268:     }
1269: 
1270: 
1271:     /**
1272:      * Nastavenie kotvy ktorá sa má pridať k adrese cieľa formulára
1273:      *
1274:      * @param  string názov kotvy
1275:      * @return object Form pre fluent interface
1276:      */
1277:     public function anchor($anchor)
1278:     {
1279:         $this->anchor = $anchor;
1280:         return $this;
1281:     }
1282: 
1283: 
1284:     /**
1285:      * Rewinds the iterator to the first element.
1286:      * @return void
1287:      */
1288:     public function rewind()
1289:     {
1290:         return reset($this->items);
1291:     }
1292: 
1293: 
1294:     /**
1295:      * Returns the key of the current element.
1296:      * @return mixed
1297:      */
1298:     public function key()
1299:     {
1300:         return key($this->items);
1301:     }
1302: 
1303: 
1304:     /**
1305:      * Returns the current element.
1306:      * @return mixed
1307:      */
1308:     public function current()
1309:     {
1310:         $item = current($this->items);
1311: 
1312:         return $this->render_item($item, FALSE);
1313:     }
1314: 
1315: 
1316: 
1317:     /**
1318:      * Moves forward to next element.
1319:      * @return void
1320:      */
1321:     public function next()
1322:     {
1323:         $item = next($this->items);
1324: 
1325:         if ($item === FALSE) {
1326:             return FALSE;
1327:         }
1328: 
1329:         return $this->render_item($item, FALSE);
1330:     }
1331: 
1332: 
1333: 
1334:     /**
1335:      * Checks if there is a current element after calls to rewind() or next().
1336:      * @return bool
1337:      */
1338:     public function valid()
1339:     {
1340:         return key($this->items) !== null;
1341:     }
1342: 
1343: 
1344: 
1345:     /**
1346:      * Required by the Countable interface.
1347:      * @return int
1348:      */
1349:     public function count()
1350:     {
1351:         return count($this->items);
1352:     }
1353: 
1354: 
1355:     public function offsetSet($pointer, $value)
1356:     {
1357:     }
1358: 
1359: 
1360:     public function offsetExists($pointer)
1361:     {
1362:         return isset($this->items[$pointer]);
1363:     }
1364: 
1365: 
1366:     public function offsetUnset($pointer)
1367:     {
1368:     }
1369: 
1370: 
1371:     public function offsetGet($pointer)
1372:     {
1373:         $item = $this->items[$pointer];
1374: 
1375:         return $this->render_item($item, FALSE);
1376:     }
1377: }
1378: 
Onion API documentation generated by ApiGen.
Generated using the TokenReflection library.