PageRenderTime 44ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/xajax_core/xajaxControl.inc.php

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