root/dev/mods/xajax/xajax_core/xajaxControl.inc.php @ 259

Revision 259, 17.0 KB (checked in by exi, 13 years ago)

Including the xajax mod into svn

Line 
1<?php
2/*
3        File: xajaxControl.inc.php
4
5        Contains the base class for all controls.
6
7        Title: xajaxControl class
8
9        Please see <copyright.inc.php> for a detailed description, copyright
10        and license information.
11*/
12
13/*
14        @package xajax
15        @version $Id: xajaxControl.inc.php 362 2007-05-29 15:32:24Z calltoconstruct $
16        @copyright Copyright (c) 2005-2006 by Jared White & J. Max Wilson
17        @license http://www.xajaxproject.org/bsd_license.txt BSD License
18*/
19
20/*
21        Constant: XAJAX_HTML_CONTROL_DOCTYPE_FORMAT
22       
23        Defines the doctype of the current document; this will effect how the HTML is formatted
24        when the html control library is used to construct html documents and fragments.  This can
25        be one of the following values:
26       
27        'XHTML' - (default)  Typical effects are that certain elements are closed with '/>'
28        'HTML' - Typical differences are that closing tags for certain elements cannot be '/>'
29*/
30if (false == defined('XAJAX_HTML_CONTROL_DOCTYPE_FORMAT')) define('XAJAX_HTML_CONTROL_DOCTYPE_FORMAT', 'XHTML');
31
32/*
33        Constant: XAJAX_HTML_CONTROL_DOCTYPE_VERSION
34*/
35if (false == defined('XAJAX_HTML_CONTROL_DOCTYPE_VERSION')) define('XAJAX_HTML_CONTROL_DOCTYPE_VERSION', '1.0');
36
37/*
38        Constant: XAJAX_HTML_CONTROL_DOCTYPE_VALIDATION
39*/
40if (false == defined('XAJAX_HTML_CONTROL_DOCTYPE_VALIDATION')) define('XAJAX_HTML_CONTROL_DOCTYPE_VALIDATION', 'TRANSITIONAL');
41
42/*
43        Class: xajaxControl
44
45        The base class for all xajax enabled controls.  Derived classes will generate the
46        HTML and javascript code that will be sent to the browser via <xajaxControl->printHTML>
47        or sent to the browser in a <xajaxResponse> via <xajaxControl->getHTML>.
48*/
49class xajaxControl
50{
51        /*
52                String: sTag
53        */
54        var $sTag;
55       
56        /*
57                Boolean: sEndTag
58               
59                'required' - (default) Indicates the control must have a full end tag
60                'optional' - The control may have an abbr. begin tag or a full end tag
61                'forbidden' - The control must have an abbr. begin tag and no end tag
62        */
63        var $sEndTag;
64       
65        /*
66                Array: aAttributes
67               
68                An associative array of attributes that will be used in the generation
69                of the HMTL code for this control.
70        */
71        var $aAttributes;
72       
73        /*
74                Array: aEvents
75               
76                An associative array of events that will be assigned to this control.  Each
77                event declaration will include a reference to a <xajaxRequest> object; it's
78                script will be extracted using <xajaxRequest->printScript> or
79                <xajaxRequest->getScript>.
80        */
81        var $aEvents;
82       
83        /*
84                String: sClass
85               
86                Contains a declaration of the class of this control.  %inline controls do not
87                need to be indented, %block controls should be indented.
88        */
89        var $sClass;
90
91        /*
92                Function: xajaxControl
93               
94                $aConfiguration - (array):  An associative array that contains a variety
95                        of configuration options for this <xajaxControl> object.
96                       
97                This array may contain the following entries:
98               
99                'attributes' - (array):  An associative array containing attributes
100                        that will be passed to the <xajaxControl->setAttribute> function.
101               
102                'children' - (array):  An array of <xajaxControl> derived objects that
103                        will be the children of this control.
104        */
105        function xajaxControl($sTag, $aConfiguration=array())
106        {
107                $this->sTag = $sTag;
108
109                $this->clearAttributes();
110                               
111                if (isset($aConfiguration['attributes']))
112                        if (is_array($aConfiguration['attributes']))
113                                foreach ($aConfiguration['attributes'] as $sKey => $sValue)
114                                        $this->setAttribute($sKey, $sValue);
115
116                $this->clearEvents();
117               
118                if (isset($aConfiguration['event']))
119                        call_user_func_array(array(&$this, 'setEvent'), $aConfiguration['event']);
120               
121                else if (isset($aConfiguration['events']))
122                        if (is_array($aConfiguration['events']))
123                                foreach ($aConfiguration['events'] as $aEvent)
124                                        call_user_func_array(array(&$this, 'setEvent'), $aEvent);
125               
126                $this->sClass = '%block';
127                $this->sEndTag = 'forbidden';
128        }
129       
130        /*
131                Function: getClass
132               
133                Returns the *adjusted* class of the element
134        */
135        function getClass()
136        {
137                return $this->sClass;
138        }
139
140        /*
141                Function: clearAttributes
142               
143                Removes all attributes assigned to this control.
144        */
145        function clearAttributes()
146        {
147                $this->aAttributes = array();
148        }
149
150        /*
151                Function: setAttribute
152               
153                Call to set various control specific attributes to be included in the HTML
154                script that is returned when <xajaxControl->printHTML> or <xajaxControl->getHTML>
155                is called.
156        */
157        function setAttribute($sName, $sValue)
158        {
159//SkipDebug
160                if (class_exists('clsValidator'))
161                {
162                        $objValidator =& clsValidator::getInstance();
163                        if (false == $objValidator->attributeValid($this->sTag, $sName)) {
164                                $objLanguageManager =& xajaxLanguageManager::getInstance();
165                                trigger_error(
166                                        $objLanguageManager->getText('XJXCTL:IAERR:01') 
167                                        . $sName 
168                                        . $objLanguageManager->getText('XJXCTL:IAERR:02') 
169                                        . $this->sTag 
170                                        . $objLanguageManager->getText('XJXCTL:IAERR:03')
171                                        , E_USER_ERROR
172                                        );
173                        }
174                }
175//EndSkipDebug
176
177                $this->aAttributes[$sName] = $sValue;
178        }
179       
180        /*
181                Function: getAttribute
182               
183                Call to obtain the value currently associated with the specified attribute
184                if set.
185               
186                sName - (string): The name of the attribute to be returned.
187               
188                Returns:
189               
190                mixed - The value associated with the attribute, or null.
191        */
192        function getAttribute($sName)
193        {
194                if (false == isset($this->aAttributes[$sName]))
195                        return null;
196               
197                return $this->aAttributes[$sName];
198        }
199       
200        /*
201                Function: clearEvents
202               
203                Clear the events that have been associated with this object.
204        */
205        function clearEvents()
206        {
207                $this->aEvents = array();
208        }
209
210        /*
211                Function: setEvent
212               
213                Call this function to assign a <xajaxRequest> object as the handler for
214                the specific DOM event.  The <xajaxRequest->printScript> function will
215                be called to generate the javascript for this request.
216               
217                sEvent - (string):  A string containing the name of the event to be assigned.
218                objRequest - (xajaxRequest object):  The <xajaxRequest> object to be associated
219                        with the specified event.
220                aParameters - (array, optional):  An array containing parameter declarations
221                        that will be passed to this <xajaxRequest> object just before the javascript
222                        is generated.
223                sBeforeRequest - (string, optional):  a string containing a snippet of javascript code
224                        to execute prior to calling the xajaxRequest function
225                sAfterRequest - (string, optional):  a string containing a snippet of javascript code
226                        to execute after calling the xajaxRequest function
227        */
228        function setEvent($sEvent, &$objRequest, $aParameters=array(), $sBeforeRequest='', $sAfterRequest='; return false;')
229        {
230//SkipDebug
231                if (false == is_a($objRequest, 'xajaxRequest')) {
232                        $objLanguageManager =& xajaxLanguageManager::getInstance();
233                        trigger_error(
234                                $objLanguageManager->getText('XJXCTL:IRERR:01')
235                                . $this->backtrace()
236                                , E_USER_ERROR
237                                );
238                }
239
240                if (class_exists('clsValidator')) {
241                        $objValidator =& clsValidator::getInstance();
242                        if (false == $objValidator->attributeValid($this->sTag, $sEvent)) {
243                                $objLanguageManager =& xajaxLanguageManager::getInstance();
244                                trigger_error(
245                                        $objLanguageManager->getText('XJXCTL:IEERR:01') 
246                                        . $sEvent 
247                                        . $objLanguageManager->getText('XJXCTL:IEERR:02') 
248                                        . $this->sTag 
249                                        . $objLanguageManager->getText('XJXCTL:IEERR:03')
250                                        , E_USER_ERROR
251                                        );
252                        }
253                }
254//EndSkipDebug
255
256                $this->aEvents[$sEvent] = array(
257                        &$objRequest, 
258                        $aParameters, 
259                        $sBeforeRequest, 
260                        $sAfterRequest
261                        );
262        }
263
264        /*
265                Function: getHTML
266               
267                Generates and returns the HTML representation of this control and
268                it's children.
269               
270                Returns:
271               
272                string - The HTML representation of this control.
273        */
274        function getHTML($bFormat=false)
275        {
276                ob_start();
277                if ($bFormat)
278                        $this->printHTML();
279                else
280                        $this->printHTML(false);
281                return ob_get_clean();
282        }
283       
284        /*
285                Function: printHTML
286               
287                Generates and prints the HTML representation of this control and
288                it's children.
289               
290                Returns:
291               
292                string - The HTML representation of this control.
293        */
294        function printHTML($sIndent='')
295        {
296//SkipDebug
297                if (class_exists('clsValidator'))
298                {
299                        $objValidator =& clsValidator::getInstance();
300                        $sMissing = '';
301                        if (false == $objValidator->checkRequiredAttributes($this->sTag, $this->aAttributes, $sMissing)) {
302                                $objLanguageManager =& xajaxLanguageManager::getInstance();
303                                trigger_error(
304                                        $objLanguageManager->getText('XJXCTL:MAERR:01') 
305                                        . $sMissing
306                                        . $objLanguageManager->getText('XJXCTL:MAERR:02') 
307                                        . $this->sTag 
308                                        . $objLanguageManager->getText('XJXCTL:MAERR:03')
309                                        , E_USER_ERROR
310                                        );
311                        }
312                }
313//EndSkipDebug
314
315                $sClass = $this->getClass();
316               
317                if ('%inline' != $sClass)
318                        // this odd syntax is necessary to detect request for no formatting
319                        if (false === (false === $sIndent))
320                                echo $sIndent;
321                       
322                echo '<';
323                echo $this->sTag;
324                echo ' ';
325                $this->_printAttributes();
326                $this->_printEvents();
327               
328                if ('forbidden' == $this->sEndTag)
329                {
330                        if ('HTML' == XAJAX_HTML_CONTROL_DOCTYPE_FORMAT)
331                                echo '>';
332                        else if ('XHTML' == XAJAX_HTML_CONTROL_DOCTYPE_FORMAT)
333                                echo '/>';
334                       
335                        if ('%inline' != $sClass)
336                                // this odd syntax is necessary to detect request for no formatting
337                                if (false === (false === $sIndent))
338                                        echo "\n";
339                               
340                        return;
341                }
342                else if ('optional' == $this->sEndTag)
343                {
344                        echo '/>';
345                       
346                        if ('%inline' == $sClass)
347                                // this odd syntax is necessary to detect request for no formatting
348                                if (false === (false === $sIndent))
349                                        echo "\n";
350                               
351                        return;
352                }
353//SkipDebug
354                else
355                {
356                        $objLanguageManager =& xajaxLanguageManager::getInstance();
357                        trigger_error(
358                                $objLanguageManager->getText('XJXCTL:IETERR:01')
359                                . $this->backtrace()
360                                , E_USER_ERROR
361                                );
362                }
363//EndSkipDebug
364        }
365
366        function _printAttributes()
367        {
368                // NOTE: Special case here: disabled='false' does not work in HTML; does work in javascript
369                foreach ($this->aAttributes as $sKey => $sValue)
370                        if ('disabled' != $sKey || 'false' != $sValue)
371                                echo "{$sKey}='{$sValue}' ";
372        }
373
374        function _printEvents()
375        {
376                foreach (array_keys($this->aEvents) as $sKey)
377                {
378                        $aEvent =& $this->aEvents[$sKey];
379                        $objRequest =& $aEvent[0];
380                        $aParameters = $aEvent[1];
381                        $sBeforeRequest = $aEvent[2];
382                        $sAfterRequest = $aEvent[3];
383
384                        foreach ($aParameters as $aParameter)
385                        {
386                                $nParameter = $aParameter[0];
387                                $sType = $aParameter[1];
388                                $sValue = $aParameter[2];
389                                $objRequest->setParameter($nParameter, $sType, $sValue);
390                        }
391
392                        $objRequest->useDoubleQuote();
393
394                        echo "{$sKey}='{$sBeforeRequest}";
395
396                        $objRequest->printScript();
397
398                        echo "{$sAfterRequest}' ";
399                }
400        }
401
402        function backtrace()
403        {
404                // debug_backtrace was added to php in version 4.3.0
405                // version_compare was added to php in version 4.0.7
406                if (0 <= version_compare(PHP_VERSION, '4.3.0'))
407                        return '<div><div>Backtrace:</div><pre>' 
408                                . print_r(debug_backtrace(), true) 
409                                . '</pre></div>';
410                return '';
411        }
412}
413
414/*
415        Class: xajaxControlContainer
416       
417        This class is used as the base class for controls that will contain
418        other child controls.
419*/
420class xajaxControlContainer extends xajaxControl
421{
422        /*
423                Array: aChildren
424               
425                An array of child controls.
426        */
427        var $aChildren;
428
429        /*
430                Boolean: sChildClass
431               
432                Will contain '%inline' if all children are class = '%inline', '%block' if all children are '%block' or
433                '%flow' if both '%inline' and '%block' elements are detected.
434        */
435        var $sChildClass;
436
437        /*
438                Function: xajaxControlContainer
439               
440                Called to construct and configure this control.
441               
442                aConfiguration - (array):  See <xajaxControl->xajaxControl> for more
443                        information.
444        */
445        function xajaxControlContainer($sTag, $aConfiguration=array())
446        {
447                xajaxControl::xajaxControl($sTag, $aConfiguration);
448
449                $this->clearChildren();
450               
451                if (isset($aConfiguration['child']))
452                        $this->addChild($aConfiguration['child']);
453
454                else if (isset($aConfiguration['children']))
455                        $this->addChildren($aConfiguration['children']);
456               
457                $this->sEndTag = 'required';
458        }
459       
460        /*
461                Function: getClass
462               
463                Returns the *adjusted* class of the element
464        */
465        function getClass()
466        {
467                $sClass = xajaxControl::getClass();
468               
469                if (0 < count($this->aChildren) && '%flow' == $sClass)
470                        return $this->getContentClass();
471                else if (0 == count($this->aChildren) || '%inline' == $sClass || '%block' == $sClass)
472                        return $sClass;
473               
474                $objLanguageManager =& xajaxLanguageManager::getInstance();
475                trigger_error(
476                        $objLanguageManager->getText('XJXCTL:ICERR:01')
477                        . $this->backtrace()
478                        , E_USER_ERROR
479                        );
480        }
481       
482        /*
483                Function: getContentClass
484               
485                Returns the *adjusted* class of the content (children) of this element
486        */
487        function getContentClass()
488        {
489                $sClass = '';
490               
491                foreach (array_keys($this->aChildren) as $sKey)
492                {
493                        if ('' == $sClass)
494                                $sClass = $this->aChildren[$sKey]->getClass();
495                        else if ($sClass != $this->aChildren[$sKey]->getClass())
496                                return '%flow';
497                }
498               
499                if ('' == $sClass)
500                        return '%inline';
501                       
502                return $sClass;
503        }
504       
505        /*
506                Function: clearChildren
507               
508                Clears the list of child controls associated with this control.
509        */
510        function clearChildren()
511        {
512                $this->sChildClass = '%inline';
513                $this->aChildren = array();
514        }
515
516        /*
517                Function: addChild
518               
519                Adds a control to the array of child controls.  Child controls
520                must be derived from <xajaxControl>.
521        */
522        function addChild(&$objControl)
523        {
524//SkipDebug
525                if (false == is_a($objControl, 'xajaxControl')) {
526                        $objLanguageManager =& xajaxLanguageManager::getInstance();
527                        trigger_error(
528                                $objLanguageManager->getText('XJXCTL:ICLERR:01')
529                                . $this->backtrace()
530                                , E_USER_ERROR
531                                );
532                }
533
534                if (class_exists('clsValidator'))
535                {
536                        $objValidator =& clsValidator::getInstance();
537                        if (false == $objValidator->childValid($this->sTag, $objControl->sTag)) {
538                                $objLanguageManager =& xajaxLanguageManager::getInstance();
539                                trigger_error(
540                                        $objLanguageManager->getText('XJXCTL:ICLERR:02') 
541                                        . $objControl->sTag
542                                        . $objLanguageManager->getText('XJXCTL:ICLERR:03') 
543                                        . $this->sTag 
544                                        . $objLanguageManager->getText('XJXCTL:ICLERR:04')
545                                        . $this->backtrace()
546                                        , E_USER_ERROR
547                                        );
548                        }
549                }
550//EndSkipDebug
551
552                $this->aChildren[] =& $objControl;
553        }
554       
555        function addChildren(&$aChildren)
556        {
557//SkipDebug
558                if (false == is_array($aChildren)) {
559                        $objLanguageManager =& xajaxLanguageManager::getInstance();
560                        trigger_error(
561                                $objLanguageManager->getText('XJXCTL:ICHERR:01')
562                                . $this->backtrace()
563                                , E_USER_ERROR
564                                );
565                }
566//EndSkipDebug
567                               
568                foreach (array_keys($aChildren) as $sKey)
569                        $this->addChild($aChildren[$sKey]);
570        }
571
572        function printHTML($sIndent='')
573        {
574//SkipDebug
575                if (class_exists('clsValidator'))
576                {
577                        $objValidator =& clsValidator::getInstance();
578                        $sMissing = '';
579                        if (false == $objValidator->checkRequiredAttributes($this->sTag, $this->aAttributes, $sMissing)) {
580                                $objLanguageManager =& xajaxLanguageManager::getInstance();
581                                trigger_error(
582                                        $objLanguageManager->getText('XJXCTL:MRAERR:01') 
583                                        . $sMissing
584                                        . $objLanguageManager->getText('XJXCTL:MRAERR:02') 
585                                        . $this->sTag 
586                                        . $objLanguageManager->getText('XJXCTL:MRAERR:03')
587                                        , E_USER_ERROR
588                                        );
589                        }
590                }
591//EndSkipDebug
592
593                $sClass = $this->getClass();
594               
595                if ('%inline' != $sClass)
596                        // this odd syntax is necessary to detect request for no formatting
597                        if (false === (false === $sIndent))
598                                echo $sIndent;
599                       
600                echo '<';
601                echo $this->sTag;
602                echo ' ';
603                $this->_printAttributes();
604                $this->_printEvents();
605               
606                if (0 == count($this->aChildren))
607                {
608                        if ('optional' == $this->sEndTag)
609                        {
610                                echo '/>';
611                               
612                                if ('%inline' != $sClass)
613                                        // this odd syntax is necessary to detect request for no formatting
614                                        if (false === (false === $sIndent))
615                                                echo "\n";
616                                       
617                                return;
618                        }
619//SkipDebug
620                        else if ('required' != $this->sEndTag)
621                                trigger_error("Invalid end tag designation; should be optional or required.\n"
622                                        . $this->backtrace(),
623                                        E_USER_ERROR
624                                        );
625//EndSkipDebug
626                }
627               
628                echo '>';
629               
630                $sContentClass = $this->getContentClass();
631               
632                if ('%inline' != $sContentClass)
633                        // this odd syntax is necessary to detect request for no formatting
634                        if (false === (false === $sIndent))
635                                echo "\n";
636
637                $this->_printChildren($sIndent);
638               
639                if ('%inline' != $sContentClass)
640                        // this odd syntax is necessary to detect request for no formatting
641                        if (false === (false === $sIndent))
642                                echo $sIndent;
643               
644                echo '<' . '/';
645                echo $this->sTag;
646                echo '>';
647               
648                if ('%inline' != $sClass)
649                        // this odd syntax is necessary to detect request for no formatting
650                        if (false === (false === $sIndent))
651                                echo "\n";
652        }
653
654        function _printChildren($sIndent='')
655        {
656                if (false == is_a($this, 'clsDocument'))
657                        // this odd syntax is necessary to detect request for no formatting
658                        if (false === (false === $sIndent))
659                                $sIndent .= "\t";
660
661                // children
662                foreach (array_keys($this->aChildren) as $sKey)
663                {
664                        $objChild =& $this->aChildren[$sKey];
665                        $objChild->printHTML($sIndent);
666                }
667        }
668}
Note: See TracBrowser for help on using the browser.