1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
12:
13: 14: 15: 16: 17: 18: 19:
20:
21: require_once('xajaxRequest.inc.php');
22:
23: 24: 25: 26: 27: 28: 29: 30: 31: 32:
33: if (false == defined('XAJAX_HTML_CONTROL_DOCTYPE_FORMAT')) define('XAJAX_HTML_CONTROL_DOCTYPE_FORMAT', 'XHTML');
34:
35: 36: 37:
38: if (false == defined('XAJAX_HTML_CONTROL_DOCTYPE_VERSION')) define('XAJAX_HTML_CONTROL_DOCTYPE_VERSION', '1.0');
39:
40: 41: 42:
43: if (false == defined('XAJAX_HTML_CONTROL_DOCTYPE_VALIDATION')) define('XAJAX_HTML_CONTROL_DOCTYPE_VALIDATION', 'TRANSITIONAL');
44:
45:
46: define('XAJAX_DOMRESPONSE_APPENDCHILD', 100);
47: define('XAJAX_DOMRESPONSE_INSERTBEFORE', 101);
48: define('XAJAX_DOMRESPONSE_INSERTAFTER', 102);
49: 50: 51: 52: 53: 54: 55:
56: class xajaxControl
57: {
58: 59: 60:
61: protected $sTag;
62:
63: 64: 65: 66: 67: 68: 69:
70: protected $sEndTag;
71:
72: 73: 74: 75: 76: 77:
78: protected $aAttributes;
79:
80: 81: 82: 83: 84: 85: 86: 87:
88: protected $aEvents;
89:
90: 91: 92: 93: 94: 95:
96: protected $sClass;
97:
98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114:
115: protected function __construct($sTag, $aConfiguration=array())
116: {
117: $this->sTag = $sTag;
118:
119: $this->clearAttributes();
120:
121: if (isset($aConfiguration['attributes']))
122: if (is_array($aConfiguration['attributes']))
123: foreach ($aConfiguration['attributes'] as $sKey => $sValue)
124: $this->setAttribute($sKey, $sValue);
125:
126: $this->clearEvents();
127:
128: if (isset($aConfiguration['event']))
129: call_user_func_array(
130: array($this, 'setEvent'),
131: $aConfiguration['event']
132: );
133:
134: else if (isset($aConfiguration['events']))
135: if (is_array($aConfiguration['events']))
136: foreach ($aConfiguration['events'] as $aEvent)
137: call_user_func_array(
138: array($this, 'setEvent'),
139: $aEvent
140: );
141:
142: $this->sClass = '%block';
143: $this->sEndTag = 'forbidden';
144: }
145:
146: 147: 148: 149: 150:
151: public function getClass()
152: {
153: return $this->sClass;
154: }
155:
156: 157: 158: 159: 160:
161: public function clearAttributes()
162: {
163: $this->aAttributes = array();
164: }
165:
166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176:
177: public function setAttribute($sName, $sValue)
178: {
179:
180: if (class_exists('clsValidator'))
181: {
182: $objValidator = clsValidator::getInstance();
183: if (false == $objValidator->attributeValid($this->sTag, $sName)) {
184: $objLanguageManager = xajaxLanguageManager::getInstance();
185: trigger_error(
186: $objLanguageManager->getText('XJXCTL:IAERR:01')
187: . $sName
188: . $objLanguageManager->getText('XJXCTL:IAERR:02')
189: . $this->sTag
190: . $objLanguageManager->getText('XJXCTL:IAERR:03')
191: , E_USER_ERROR
192: );
193: }
194: }
195:
196:
197: $this->aAttributes[$sName] = $sValue;
198: }
199:
200: 201: 202: 203: 204: 205: 206: 207: 208: 209: 210: 211: 212: 213:
214: public function getAttribute($sName)
215: {
216: if (false == isset($this->aAttributes[$sName]))
217: return null;
218:
219: return $this->aAttributes[$sName];
220: }
221:
222: 223: 224: 225: 226:
227: public function clearEvents()
228: {
229: $this->aEvents = array();
230: }
231:
232: 233: 234: 235: 236: 237: 238: 239: 240: 241: 242: 243: 244: 245: 246: 247: 248: 249: 250: 251:
252: public function setEvent($sEvent, $objRequest, $aParameters=array(), $sBeforeRequest='', $sAfterRequest='; return false;')
253: {
254:
255: if (false == ($objRequest instanceof xajaxRequest)) {
256: $objLanguageManager = xajaxLanguageManager::getInstance();
257: trigger_error(
258: $objLanguageManager->getText('XJXCTL:IRERR:01')
259: . $this->backtrace()
260: , E_USER_ERROR
261: );
262: }
263:
264: if (class_exists('clsValidator')) {
265: $objValidator = clsValidator::getInstance();
266: if (false == $objValidator->attributeValid($this->sTag, $sEvent)) {
267: $objLanguageManager = xajaxLanguageManager::getInstance();
268: trigger_error(
269: $objLanguageManager->getText('XJXCTL:IEERR:01')
270: . $sEvent
271: . $objLanguageManager->getText('XJXCTL:IEERR:02')
272: . $this->sTag
273: . $objLanguageManager->getText('XJXCTL:IEERR:03')
274: , E_USER_ERROR
275: );
276: }
277: }
278:
279:
280: $objRequest = clone($objRequest);
281:
282: $this->aEvents[$sEvent] = array(
283: $objRequest,
284: $aParameters,
285: $sBeforeRequest,
286: $sAfterRequest
287: );
288: }
289:
290: 291: 292: 293: 294: 295: 296: 297: 298: 299:
300: public function getHTML($bFormat=false)
301: {
302: ob_start();
303: if ($bFormat)
304: $this->printHTML();
305: else
306: $this->printHTML(false);
307: return ob_get_clean();
308: }
309:
310: 311: 312: 313: 314: 315: 316: 317: 318: 319:
320: public function printHTML($sIndent='')
321: {
322:
323: if (class_exists('clsValidator'))
324: {
325: $objValidator = clsValidator::getInstance();
326: $sMissing = '';
327: if (false == $objValidator->checkRequiredAttributes($this->sTag, $this->aAttributes, $sMissing)) {
328: $objLanguageManager = xajaxLanguageManager::getInstance();
329: trigger_error(
330: $objLanguageManager->getText('XJXCTL:MAERR:01')
331: . $sMissing
332: . $objLanguageManager->getText('XJXCTL:MAERR:02')
333: . $this->sTag
334: . $objLanguageManager->getText('XJXCTL:MAERR:03')
335: , E_USER_ERROR
336: );
337: }
338: }
339:
340:
341: $sClass = $this->getClass();
342:
343: if ('%inline' != $sClass)
344:
345: if (false === (false === $sIndent))
346: echo $sIndent;
347:
348: echo '<';
349: echo $this->sTag;
350: echo ' ';
351: $this->_printAttributes();
352: $this->_printEvents();
353:
354: if ('forbidden' == $this->sEndTag)
355: {
356: if ('HTML' == XAJAX_HTML_CONTROL_DOCTYPE_FORMAT)
357: echo '>';
358: else if ('XHTML' == XAJAX_HTML_CONTROL_DOCTYPE_FORMAT)
359: echo '/>';
360:
361: if ('%inline' != $sClass)
362:
363: if (false === (false === $sIndent))
364: echo "\n";
365:
366: return;
367: }
368: else if ('optional' == $this->sEndTag)
369: {
370: echo '/>';
371:
372: if ('%inline' == $sClass)
373:
374: if (false === (false === $sIndent))
375: echo "\n";
376:
377: return;
378: }
379:
380: else
381: {
382: $objLanguageManager = xajaxLanguageManager::getInstance();
383: trigger_error(
384: $objLanguageManager->getText('XJXCTL:IETERR:01')
385: . $this->backtrace()
386: , E_USER_ERROR
387: );
388: }
389:
390: }
391:
392: public function getResponse($count, $parent, $flag=XAJAX_DOMRESPONSE_APPENDCHILD)
393: {
394: $variable = "xjxElm[{$count}]";
395:
396: $response = $this->beginGetResponse($variable, $count);
397: $this->getResponseAttributes($response, $variable);
398: $this->getResponseEvents($response, $variable);
399: $this->endGetResponse($response, $variable, $count, $parent, $flag);
400:
401: return $response;
402: }
403:
404: protected function beginGetResponse($variable, $count)
405: {
406: $response = new xajaxResponse();
407:
408: if ($count == 0)
409: $response->domStartResponse();
410:
411: $response->domCreateElement($variable, $this->sTag);
412:
413: return $response;
414: }
415:
416: protected function getResponseAttributes($response, $variable)
417: {
418: foreach ($this->aAttributes as $sKey => $sValue)
419: if ('disabled' != $sKey || 'false' != $sValue)
420: $response->domSetAttribute($variable, $sKey, $sValue);
421: }
422:
423: protected function endGetResponse($response, $variable, $count, $parent, $flag)
424: {
425: if ($flag == XAJAX_DOMRESPONSE_APPENDCHILD)
426: $response->domAppendChild($parent, $variable);
427: else if ($flag == XAJAX_DOMRESPONSE_INSERTBEFORE)
428: $response->domInsertBefore($parent, $variable);
429: else if ($flag == XAJAX_DOMRESPONSE_INSERTAFTER)
430: $response->domInsertAfter($parent, $variable);
431:
432: if ($count == 0)
433: $response->domEndResponse();
434: }
435:
436: protected function getResponseEvents($response, $variable)
437: {
438: foreach (array_keys($this->aEvents) as $sKey)
439: {
440: $aEvent = $this->aEvents[$sKey];
441: $objRequest = $aEvent[0];
442: $aParameters = $aEvent[1];
443: $sBeforeRequest = $aEvent[2];
444: $sAfterRequest = $aEvent[3];
445:
446: foreach ($aParameters as $aParameter)
447: {
448: $nParameter = $aParameter[0];
449: $sType = $aParameter[1];
450: $sValue = $aParameter[2];
451: $objRequest->setParameter($nParameter, $sType, $sValue);
452: }
453:
454: $objRequest->useDoubleQuote();
455:
456: $response->script(
457: "{$variable}.{$sKey} = function(evt) { " .
458: "if (!evt) var evt = window.event; " .
459: $sBeforeRequest .
460: $objRequest->getScript() .
461: $sAfterRequest .
462: " } "
463: );
464: }
465: }
466:
467: protected function _printAttributes()
468: {
469:
470: foreach ($this->aAttributes as $sKey => $sValue)
471: if ('disabled' != $sKey || 'false' != $sValue)
472: echo "{$sKey}='{$sValue}' ";
473: }
474:
475: protected function _printEvents()
476: {
477: foreach (array_keys($this->aEvents) as $sKey)
478: {
479: $aEvent = $this->aEvents[$sKey];
480: $objRequest = $aEvent[0];
481: $aParameters = $aEvent[1];
482: $sBeforeRequest = $aEvent[2];
483: $sAfterRequest = $aEvent[3];
484:
485: foreach ($aParameters as $aParameter)
486: {
487: $nParameter = $aParameter[0];
488: $sType = $aParameter[1];
489: $sValue = $aParameter[2];
490: $objRequest->setParameter($nParameter, $sType, $sValue);
491: }
492:
493: $objRequest->useDoubleQuote();
494:
495: echo "{$sKey}='{$sBeforeRequest}";
496:
497: $objRequest->printScript();
498:
499: echo "{$sAfterRequest}' ";
500: }
501: }
502:
503: public function backtrace()
504: {
505:
506:
507: if (0 <= version_compare(PHP_VERSION, '4.3.0'))
508: return '<div><div>Backtrace:</div><pre>'
509: . print_r(debug_backtrace(), true)
510: . '</pre></div>';
511: return '';
512: }
513: }
514:
515: 516: 517: 518: 519: 520:
521: class xajaxControlContainer extends xajaxControl
522: {
523: 524: 525: 526: 527:
528: protected $aChildren;
529:
530: 531: 532: 533: 534: 535:
536: protected $sChildClass;
537:
538: 539: 540: 541: 542: 543: 544: 545: 546: 547:
548: protected function __construct($sTag, $aConfiguration=array())
549: {
550: parent::__construct($sTag, $aConfiguration);
551:
552: $this->clearChildren();
553:
554: if (isset($aConfiguration['child']))
555: $this->addChild($aConfiguration['child']);
556:
557: else if (isset($aConfiguration['children']))
558: $this->addChildren($aConfiguration['children']);
559:
560: $this->sEndTag = 'required';
561: }
562:
563: 564: 565: 566: 567:
568: public function getClass()
569: {
570: $sClass = xajaxControl::getClass();
571:
572: if (0 < count($this->aChildren) && '%flow' == $sClass)
573: return $this->getContentClass();
574: else if (0 == count($this->aChildren) || '%inline' == $sClass || '%block' == $sClass)
575: return $sClass;
576:
577: $objLanguageManager = xajaxLanguageManager::getInstance();
578: trigger_error(
579: $objLanguageManager->getText('XJXCTL:ICERR:01')
580: . $this->backtrace()
581: , E_USER_ERROR
582: );
583: }
584:
585: 586: 587: 588: 589:
590: public function getContentClass()
591: {
592: $sClass = '';
593:
594: foreach (array_keys($this->aChildren) as $sKey)
595: {
596: if ('' == $sClass)
597: $sClass = $this->aChildren[$sKey]->getClass();
598: else if ($sClass != $this->aChildren[$sKey]->getClass())
599: return '%flow';
600: }
601:
602: if ('' == $sClass)
603: return '%inline';
604:
605: return $sClass;
606: }
607:
608: 609: 610: 611: 612:
613: public function clearChildren()
614: {
615: $this->sChildClass = '%inline';
616: $this->aChildren = array();
617: }
618:
619: 620: 621: 622: 623: 624:
625: public function addChild($objControl)
626: {
627:
628: if (false == ($objControl instanceof xajaxControl )) {
629: $objLanguageManager = xajaxLanguageManager::getInstance();
630: trigger_error(
631: $objLanguageManager->getText('XJXCTL:ICLERR:01')
632: . $this->backtrace()
633: , E_USER_ERROR
634: );
635: }
636:
637: if (class_exists('clsValidator'))
638: {
639: $objValidator = clsValidator::getInstance();
640: if (false == $objValidator->childValid($this->sTag, $objControl->sTag)) {
641: $objLanguageManager = xajaxLanguageManager::getInstance();
642: trigger_error(
643: $objLanguageManager->getText('XJXCTL:ICLERR:02')
644: . $objControl->sTag
645: . $objLanguageManager->getText('XJXCTL:ICLERR:03')
646: . $this->sTag
647: . $objLanguageManager->getText('XJXCTL:ICLERR:04')
648: . $this->backtrace()
649: , E_USER_ERROR
650: );
651: }
652: }
653:
654:
655: $this->aChildren[] = $objControl;
656: }
657:
658: public function addChildren($aChildren)
659: {
660:
661: if (false == is_array($aChildren)) {
662: $objLanguageManager = xajaxLanguageManager::getInstance();
663: trigger_error(
664: $objLanguageManager->getText('XJXCTL:ICHERR:01')
665: . $this->backtrace()
666: , E_USER_ERROR
667: );
668: }
669:
670:
671: foreach (array_keys($aChildren) as $sKey)
672: $this->addChild($aChildren[$sKey]);
673: }
674:
675: public function printHTML($sIndent='')
676: {
677:
678: if (class_exists('clsValidator'))
679: {
680: $objValidator = clsValidator::getInstance();
681: $sMissing = '';
682: if (false == $objValidator->checkRequiredAttributes($this->sTag, $this->aAttributes, $sMissing)) {
683: $objLanguageManager = xajaxLanguageManager::getInstance();
684: trigger_error(
685: $objLanguageManager->getText('XJXCTL:MRAERR:01')
686: . $sMissing
687: . $objLanguageManager->getText('XJXCTL:MRAERR:02')
688: . $this->sTag
689: . $objLanguageManager->getText('XJXCTL:MRAERR:03')
690: , E_USER_ERROR
691: );
692: }
693: }
694:
695:
696: $sClass = $this->getClass();
697:
698: if ('%inline' != $sClass)
699:
700: if (false === (false === $sIndent))
701: echo $sIndent;
702:
703: echo '<';
704: echo $this->sTag;
705: echo ' ';
706: $this->_printAttributes();
707: $this->_printEvents();
708:
709: if (0 == count($this->aChildren))
710: {
711: if ('optional' == $this->sEndTag)
712: {
713: echo '/>';
714:
715: if ('%inline' != $sClass)
716:
717: if (false === (false === $sIndent))
718: echo "\n";
719:
720: return;
721: }
722:
723: else if ('required' != $this->sEndTag)
724: trigger_error("Invalid end tag designation; should be optional or required.\n"
725: . $this->backtrace(),
726: E_USER_ERROR
727: );
728:
729: }
730:
731: echo '>';
732:
733: $sContentClass = $this->getContentClass();
734:
735: if ('%inline' != $sContentClass)
736:
737: if (false === (false === $sIndent))
738: echo "\n";
739:
740: $this->_printChildren($sIndent);
741:
742: if ('%inline' != $sContentClass)
743:
744: if (false === (false === $sIndent))
745: echo $sIndent;
746:
747: echo '<' . '/';
748: echo $this->sTag;
749: echo '>';
750:
751: if ('%inline' != $sClass)
752:
753: if (false === (false === $sIndent))
754: echo "\n";
755: }
756:
757: protected function _printChildren($sIndent='')
758: {
759: if (false == ($this instanceof clsDocument ))
760:
761: if (false === (false === $sIndent))
762: $sIndent .= "\t";
763:
764:
765: foreach (array_keys($this->aChildren) as $sKey)
766: {
767: $objChild = $this->aChildren[$sKey];
768: $objChild->printHTML($sIndent);
769: }
770: }
771:
772: public function getResponse($count, $parent, $flag=XAJAX_DOMRESPONSE_APPENDCHILD)
773: {
774: $variable = "xjxElm[{$count}]";
775:
776: $response = $this->beginGetResponse($variable, $count);
777: $this->getResponseAttributes($response, $variable);
778: $this->getResponseEvents($response, $variable);
779: $this->getResponseChildren($response, $variable, $count);
780: $this->endGetResponse($response, $variable, $count, $parent, $flag);
781:
782: return $response;
783: }
784:
785: protected function getResponseChildren($response, $variable, $count)
786: {
787: foreach (array_keys($this->aChildren) as $sKey)
788: {
789: $objChild = $this->aChildren[$sKey];
790: $response->appendResponse(
791: $objChild->getResponse($count+1, $variable)
792: );
793: }
794: }
795: }
796: