1: <?php
2: 3: 4: 5: 6: 7: 8: 9:
10:
11: namespace Kotchasan;
12:
13: 14: 15: 16: 17: 18: 19:
20: class Html extends \Kotchasan\KBase
21: {
22: 23: 24: 25: 26:
27: public $attributes;
28: 29: 30: 31: 32:
33: public static $form;
34: 35: 36: 37: 38:
39: protected $javascript;
40: 41: 42: 43: 44:
45: protected $rows;
46: 47: 48: 49: 50:
51: protected $tag;
52:
53: 54: 55:
56: public function __construct($tag, $attributes = array())
57: {
58: $this->tag = strtolower($tag);
59: $this->attributes = $attributes;
60: $this->rows = array();
61: $this->javascript = array();
62: }
63:
64: 65: 66: 67: 68: 69: 70: 71:
72: public function add($tag, $attributes = array())
73: {
74: $tag = strtolower($tag);
75: if ($tag == 'groups' || $tag == 'groups-table') {
76: $obj = $this->addGroups($tag, $attributes);
77: } elseif ($tag == 'inputgroups') {
78: $obj = $this->addInputGroups($attributes);
79: } elseif ($tag == 'radiogroups' || $tag == 'checkboxgroups') {
80: $obj = $this->addRadioOrCheckbox($tag, $attributes);
81: } elseif ($tag == 'menubutton') {
82: $obj = $this->addMenuButton($attributes);
83: } elseif ($tag == 'ckeditor') {
84: $obj = $this->addCKEditor($tag, $attributes);
85: } elseif ($tag == 'row') {
86: $obj = new static('div', array(
87: 'class' => 'row',
88: ));
89: $this->rows[] = $obj;
90: } elseif ($tag == 'rowgroup') {
91: $obj = new static('div', array(
92: 'class' => 'rowgroup',
93: ));
94: $this->rows[] = $obj;
95: } else {
96: $obj = self::create($tag, $attributes);
97: $this->rows[] = $obj;
98: }
99: return $obj;
100: }
101:
102: 103: 104: 105: 106:
107: public function appendChild($html)
108: {
109: $this->rows[] = $html;
110: }
111:
112: 113: 114: 115: 116: 117: 118: 119:
120: public static function create($tag, $attributes = array())
121: {
122: if (method_exists(__CLASS__, $tag)) {
123: $obj = self::$tag($attributes);
124: } elseif (method_exists('Kotchasan\Form', $tag)) {
125: $obj = \Kotchasan\Form::$tag($attributes);
126: } else {
127: $obj = new static($tag, $attributes);
128: }
129:
130: return $obj;
131: }
132:
133: 134: 135: 136: 137: 138: 139:
140: public static function fieldset($attributes = array())
141: {
142: $prop = array();
143: $span = array();
144: foreach ($attributes as $key => $value) {
145: if ($key == 'title') {
146: $span['innerHTML'] = $value;
147: } elseif ($key == 'titleClass') {
148: $span['class'] = $value;
149: } else {
150: $prop[$key] = $value;
151: }
152: }
153: $obj = new static('fieldset', $prop);
154: if (isset($span['innerHTML'])) {
155: $legend = $obj->add('legend');
156: $legend->add('span', $span);
157: }
158:
159: return $obj;
160: }
161:
162: 163: 164: 165: 166: 167: 168:
169: public static function form($attributes = array())
170: {
171: $ajax = false;
172: $prop = array('method' => 'post');
173: $gform = true;
174: $token = false;
175: foreach ($attributes as $key => $value) {
176: if ($key === 'ajax' || $key === 'action' || $key === 'onsubmit' || $key === 'onbeforesubmit' ||
177: $key === 'elements' || $key === 'script' || $key === 'gform' || $key === 'token') {
178: $$key = $value;
179: } else {
180: $prop[$key] = $value;
181: }
182: }
183: if (isset($prop['id']) && $gform) {
184: $script = 'new GForm("'.$prop['id'].'"';
185: if (isset($action)) {
186: if ($ajax) {
187: $script .= ', "'.$action.'"';
188: if (isset($onbeforesubmit)) {
189: $script .= ',null ,false , function(){return '.$onbeforesubmit.'}';
190: }
191: } else {
192: $prop['action'] = $action;
193: }
194: }
195: $script .= ')';
196: if (isset($onsubmit)) {
197: $script .= '.onsubmit('.$onsubmit.')';
198: }
199: $script .= ';';
200: $form_inputs = Form::get2Input();
201: } else {
202: if (isset($action)) {
203: $prop['action'] = $action;
204: }
205: if (isset($onsubmit)) {
206: $prop['onsubmit'] = $onsubmit.'()';
207: }
208: if (isset($onbeforesubmit)) {
209: $prop['onbeforesubmit'] = $onbeforesubmit.'()';
210: }
211: }
212: self::$form = new static('form', $prop);
213: self::$form->ajax = $ajax;
214: self::$form->gform = $gform;
215: if (!empty($form_inputs)) {
216: self::$form->rows = $form_inputs;
217: }
218: if ($token) {
219: self::$form->rows[] = '<input type="hidden" name="token" id="token" value="'.self::$request->createToken().'">';
220: }
221: if (isset($script)) {
222: self::$form->javascript[] = $script;
223: }
224:
225: return self::$form;
226: }
227:
228: 229: 230: 231: 232: 233: 234:
235: public function innerHtml($html)
236: {
237: return '<'.$this->tag.$this->renderAttributes().'>'.$html.'</'.$this->tag.'>';
238: }
239:
240: 241: 242: 243: 244:
245: public function render()
246: {
247: $result = '<'.$this->tag.$this->renderAttributes().'>'.(isset($this->attributes['innerHTML']) ? $this->attributes['innerHTML'] : '');
248: foreach ($this->rows as $row) {
249: if (is_string($row)) {
250: $result .= $row;
251: } else {
252: $result .= $row->render();
253: if (!empty($row->javascript)) {
254: foreach ($row->javascript as $script) {
255: self::$form->javascript[] = $script;
256: }
257: }
258: }
259: }
260: $result .= '</'.$this->tag.'>';
261: if ($this->tag == 'form' && !empty(self::$form->javascript)) {
262: $result .= "\n".preg_replace('/^[\s\t]+/m', '', "<script>\n".implode("\n", self::$form->javascript)."\n</script>");
263: self::$form = null;
264: } elseif (!empty($this->javascript)) {
265: $result .= "\n".preg_replace('/^[\s\t]+/m', '', "<script>\n".implode("\n", $this->javascript)."\n</script>");
266: }
267:
268: return $result;
269: }
270:
271: 272: 273: 274: 275:
276: public function script($script)
277: {
278: if (isset(self::$form)) {
279: self::$form->javascript[] = $script;
280: } else {
281: $this->javascript[] = $script;
282: }
283: }
284:
285: 286: 287: 288: 289:
290: protected function renderAttributes()
291: {
292: $attr = array();
293: foreach ($this->attributes as $key => $value) {
294: if ($key != 'innerHTML') {
295: if (is_int($key)) {
296: $attr[] = $value;
297: } else {
298: $attr[] = $key.'="'.$value.'"';
299: }
300: }
301: }
302:
303: return count($attr) == 0 ? '' : ' '.implode(' ', $attr);
304: }
305:
306: 307: 308: 309: 310: 311:
312: private function addCKEditor($tag, $attributes)
313: {
314: if (isset($attributes[$tag])) {
315: $tag = $attributes[$tag];
316: unset($attributes[$tag]);
317: } else {
318: $tag = 'textarea';
319: }
320: if (class_exists('Kotchasan\CKEditor')) {
321: $obj = new \Kotchasan\CKEditor($tag, $attributes);
322: } else {
323: $obj = self::create($tag, $attributes);
324: }
325: $this->rows[] = $obj;
326:
327: return $obj;
328: }
329:
330: 331: 332: 333: 334: 335:
336: private function addGroups($tag, $attributes)
337: {
338: $prop = array('class' => isset($attributes['class']) ? $attributes['class'] : 'item');
339: if (isset($attributes['id'])) {
340: $prop['id'] = $attributes['id'];
341: }
342: if (isset($attributes['label'])) {
343: if (isset($attributes['for'])) {
344: $item = new static('div', $prop);
345: $item->add('label', array(
346: 'innerHTML' => $attributes['label'],
347: 'for' => $attributes['for'],
348: ));
349: } else {
350: $prop['title'] = strip_tags($attributes['label']);
351: $item = self::fieldset($prop);
352: }
353: } else {
354: $item = new static('div', $prop);
355: }
356: $this->rows[] = $item;
357: $obj = $item->add('div', array('class' => 'input-'.$tag));
358: $rows = array();
359: $comment = array();
360: if (empty($attributes['id'])) {
361: $id = '';
362: $name = '';
363: } else {
364: $id = ' id='.$attributes['id'];
365: $name = ' name='.$attributes['id'].'[]';
366: $comment['id'] = 'result_'.$attributes['id'];
367: }
368: foreach ($attributes as $key => $value) {
369: if ($key == 'checkbox' || $key == 'radio') {
370: foreach ($value as $v => $text) {
371: $chk = isset($attributes['value']) && in_array($v, $attributes['value']) ? ' checked' : '';
372: $rows[] = '<label>'.$text.' <input type='.$key.$id.$name.$chk.' value="'.$v.'"></label>';
373: $id = '';
374: }
375: }
376: }
377: if (!empty($rows)) {
378: $obj->appendChild(implode(' ', $rows));
379: }
380: if (isset($attributes['comment'])) {
381: if (isset($attributes['commentId'])) {
382: $comment['id'] = $attributes['commentId'];
383: }
384: $comment['class'] = 'comment';
385: $comment['innerHTML'] = $value;
386: $item->add('div', $comment);
387: }
388:
389: return $obj;
390: }
391:
392: 393: 394: 395: 396:
397: private function addInputGroups($attributes)
398: {
399: if (!empty($attributes['disabled'])) {
400: $attributes['disabled'] = 'disabled';
401: } else {
402: unset($attributes['disabled']);
403: }
404: if (!empty($attributes['readonly'])) {
405: $attributes['readonly'] = 'readonly';
406: } else {
407: unset($attributes['readonly']);
408: }
409: $prop = array('class' => empty($attributes['itemClass']) ? 'item' : $attributes['itemClass']);
410: if (isset($attributes['itemId'])) {
411: $prop['id'] = $attributes['itemId'];
412: }
413: $obj = new static('div', $prop);
414: $this->rows[] = $obj;
415: if (isset($attributes['id'])) {
416: $id = $attributes['id'];
417: } else {
418: $id = \Kotchasan\Password::uniqid();
419: }
420: $c = array('inputgroups');
421: if (isset($attributes['labelClass'])) {
422: $c[] = $attributes['labelClass'];
423: }
424: if (isset($attributes['label'])) {
425: $obj->add('label', array(
426: 'innerHTML' => $attributes['label'],
427: 'for' => $id,
428: ));
429: }
430: $li = '';
431: if (isset($attributes['value']) && is_array($attributes['value'])) {
432: if (isset($attributes['options'])) {
433: foreach ($attributes['value'] as $value) {
434: if (isset($attributes['options'][$value])) {
435: $li .= '<li><span>'.$attributes['options'][$value].'</span><button type="button">x</button><input type="hidden" name="'.$id.'[]" value="'.$value.'"></li>';
436: }
437: }
438: } else {
439: foreach ($attributes['value'] as $value) {
440: $li .= '<li><span>'.$value.'</span><button type="button">x</button><input type="hidden" name="'.$id.'[]" value="'.$value.'"></li>';
441: }
442: }
443: }
444: foreach ($attributes as $key => $value) {
445: if ($key == 'validator') {
446: $js = array();
447: $js[] = '"'.$id.'"';
448: $js[] = '"'.$value[0].'"';
449: $js[] = $value[1];
450: if (isset($value[2])) {
451: $js[] = '"'.$value[2].'"';
452: $js[] = empty($value[3]) || $value[3] === null ? 'null' : '"'.$value[3].'"';
453: $js[] = '"'.self::$form->attributes['id'].'"';
454: }
455: self::$form->javascript[] = 'new GValidator('.implode(', ', $js).');';
456: } elseif ($key == 'options') {
457: $options = $value;
458: $datalist = $id.'_'.\Kotchasan\Password::uniqid();
459: $prop['list'] = 'list="'.$datalist.'"';
460: } elseif ($key == 'comment') {
461: $comment = $value;
462: } elseif (!in_array($key, array('id', 'type', 'itemId', 'itemClass', 'labelClass', 'label', 'value'))) {
463: $prop[$key] = $key.'="'.$value.'"';
464: }
465: }
466: $prop['id'] = 'id="'.$id.'"';
467: $prop['type'] = 'type="text"';
468: $prop['class'] = 'class="inputgroup"';
469: $li .= '<li><input '.implode(' ', $prop).'>';
470: if (isset($options) && is_array($options)) {
471: $li .= '<datalist id="'.$datalist.'">';
472: foreach ($options as $k => $v) {
473: $li .= '<option value="'.$k.'">'.$v.'</option>';
474: }
475: $li .= '</datalist>';
476: }
477: $li .= '</li>';
478: $obj->add('ul', array(
479: 'class' => implode(' ', $c),
480: 'innerHTML' => $li,
481: ));
482: if (isset($comment)) {
483: $obj->add('div', array(
484: 'id' => 'result_'.$id,
485: 'class' => 'comment',
486: 'innerHTML' => $comment,
487: ));
488: }
489:
490: return $obj;
491: }
492:
493: 494: 495: 496: 497:
498: private function addMenuButton($attributes)
499: {
500: $prop = array('class' => empty($attributes['itemClass']) ? 'item' : $attributes['itemClass']);
501: if (isset($attributes['itemId'])) {
502: $prop['id'] = $attributes['itemId'];
503: }
504: $obj = new static('div', $prop);
505: $this->rows[] = $obj;
506: if (isset($attributes['label'])) {
507: $obj->add('label', array(
508: 'innerHTML' => $attributes['label'],
509: ));
510: }
511: $div = $obj->add('div', array(
512: 'class' => 'g-input',
513: ));
514: $li = '<ul>';
515: if (isset($attributes['submenus']) && is_array($attributes['submenus'])) {
516: foreach ($attributes['submenus'] as $item) {
517: $prop = array();
518: $text = '';
519: foreach ($item as $key => $value) {
520: if ($key == 'text') {
521: $text = $value;
522: } else {
523: $prop[$key] = $key.'="'.$value.'"';
524: }
525: }
526: $li .= '<li><a '.implode(' ', $prop).'>'.$text.'</a></li>';
527: }
528: }
529: $li .= '</ul>';
530: $prop = array(
531: 'class' => isset($attributes['class']) ? $attributes['class'].' menubutton' : 'menubutton',
532: 'tabindex' => 0,
533: );
534: if (isset($attributes['text'])) {
535: $prop['innerHTML'] = $attributes['text'].$li;
536: } else {
537: $prop['innerHTML'] = $li;
538: }
539: $div->add('div', $prop);
540: return $obj;
541: }
542:
543: 544: 545: 546: 547: 548:
549: private function addRadioOrCheckbox($tag, $attributes)
550: {
551: $prop = array('class' => empty($attributes['itemClass']) ? 'item' : $attributes['itemClass']);
552: if (!empty($attributes['itemId'])) {
553: $prop['id'] = $attributes['itemId'];
554: }
555: $obj = new static('div', $prop);
556: $this->rows[] = $obj;
557: if (isset($attributes['name'])) {
558: $name = $attributes['name'];
559: } elseif (isset($attributes['id'])) {
560: $name = $tag == 'checkboxgroups' ? $attributes['id'].'[]' : $attributes['id'];
561: } else {
562: $name = false;
563: }
564: $c = array($tag);
565: if (isset($attributes['labelClass'])) {
566: $c[] = $attributes['labelClass'];
567: }
568: if (isset($attributes['label']) && isset($attributes['id'])) {
569: $obj->add('label', array(
570: 'innerHTML' => $attributes['label'],
571: 'for' => $attributes['id'],
572: ));
573: }
574: if (isset($attributes['button']) && $attributes['button'] === true) {
575: $c[] = 'groupsbutton';
576: }
577: $prop = array(
578: 'class' => implode(' ', $c),
579: );
580: if (isset($attributes['id'])) {
581: $prop['id'] = $attributes['id'];
582: }
583: $div = $obj->add('div', $prop);
584: if (!empty($attributes['multiline'])) {
585: $c = array('multiline');
586: if (!empty($attributes['scroll'])) {
587: $c[] = 'hscroll';
588: }
589: $div = $div->add('div', array(
590: 'class' => implode(' ', $c),
591: ));
592: }
593: if (!empty($attributes['options']) && is_array($attributes['options'])) {
594: foreach ($attributes['options'] as $v => $label) {
595: $item = array(
596: 'label' => $label,
597: 'value' => $v,
598: );
599: if (isset($attributes['value'])) {
600: if (is_array($attributes['value']) && in_array($v, $attributes['value'])) {
601: $item['checked'] = $v;
602: } elseif ($v == $attributes['value']) {
603: $item['checked'] = $v;
604: }
605: }
606: if ($name) {
607: $item['name'] = $name;
608: }
609: if (isset($attributes['id'])) {
610: if (isset($attributes['button']) && $attributes['button'] === true) {
611: $item['button'] = $attributes['button'];
612: $item['class'] = (empty($attributes['class']) ? '' : $attributes['class'].' ').str_replace('groups', 'button', $tag);
613: } elseif (isset($attributes['class'])) {
614: $item['class'] = $attributes['class'];
615: }
616: }
617: if (isset($attributes['comment'])) {
618: $item['title'] = strip_tags($attributes['comment']);
619: }
620: if (!empty($attributes['disabled'])) {
621: $item['disabled'] = true;
622: }
623: $div->add($tag == 'radiogroups' ? 'radio' : 'checkbox', $item);
624: }
625: }
626: if (isset($attributes['id']) && !empty($attributes['comment'])) {
627: $obj->add('div', array(
628: 'id' => 'result_'.$attributes['id'],
629: 'class' => 'comment',
630: 'innerHTML' => $attributes['comment'],
631: ));
632: }
633: return $obj;
634: }
635: }
636: