xajaxResponse.inc.php 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587
  1. <?php
  2. /**
  3. * xajaxResponse.inc.php :: xajax XML response class
  4. *
  5. * xajax version 0.2.4
  6. * copyright (c) 2005 by Jared White & J. Max Wilson
  7. * http://www.xajaxproject.org
  8. *
  9. * xajax is an open source PHP class library for easily creating powerful
  10. * PHP-driven, web-based Ajax Applications. Using xajax, you can asynchronously
  11. * call PHP functions and update the content of your your webpage without
  12. * reloading the page.
  13. *
  14. * xajax is released under the terms of the LGPL license
  15. * http://www.gnu.org/copyleft/lesser.html#SEC3
  16. *
  17. * This library is free software; you can redistribute it and/or
  18. * modify it under the terms of the GNU Lesser General Public
  19. * License as published by the Free Software Foundation; either
  20. * version 2.1 of the License, or (at your option) any later version.
  21. *
  22. * This library is distributed in the hope that it will be useful,
  23. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  24. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  25. * Lesser General Public License for more details.
  26. *
  27. * You should have received a copy of the GNU Lesser General Public
  28. * License along with this library; if not, write to the Free Software
  29. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  30. *
  31. * @package chamilo.include.xajax
  32. * @version $Id: xajaxResponse.inc.php,v 1.1 2006/07/21 15:29:46 elixir_inter Exp $
  33. * @copyright Copyright (c) 2005-2006 by Jared White & J. Max Wilson
  34. * @license http://www.gnu.org/copyleft/lesser.html#SEC3 LGPL License
  35. */
  36. /*
  37. ----------------------------------------------------------------------------
  38. | Online documentation for this class is available on the xajax wiki at: |
  39. | http://wiki.xajaxproject.org/Documentation:xajaxResponse.inc.php |
  40. ----------------------------------------------------------------------------
  41. */
  42. /**
  43. * The xajaxResponse class is used to create responses to be sent back to your
  44. * Web page. A response contains one or more command messages for updating
  45. * your page.
  46. * Currently xajax supports 21 kinds of command messages, including some common
  47. * ones such as:
  48. * <ul>
  49. * <li>Assign - sets the specified attribute of an element in your page</li>
  50. * <li>Append - appends data to the end of the specified attribute of an
  51. * element in your page</li>
  52. * <li>Prepend - prepends data to the beginning of the specified attribute of
  53. * an element in your page</li>
  54. * <li>Replace - searches for and replaces data in the specified attribute of
  55. * an element in your page</li>
  56. * <li>Script - runs the supplied JavaScript code</li>
  57. * <li>Alert - shows an alert box with the supplied message text</li>
  58. * </ul>
  59. *
  60. * <i>Note:</i> elements are identified by their HTML id, so if you don't see
  61. * your browser HTML display changing from the request, make sure you're using
  62. * the right id names in your response.
  63. *
  64. * @package chamilo.include.xajax
  65. */
  66. class xajaxResponse
  67. {
  68. /**#@+
  69. * @access protected
  70. */
  71. /**
  72. * @var string internal XML storage
  73. */
  74. var $xml;
  75. /**
  76. * @var string the encoding type to use
  77. */
  78. var $sEncoding;
  79. /**
  80. * @var boolean if special characters in the XML should be converted to
  81. * entities
  82. */
  83. var $bOutputEntities;
  84. /**#@-*/
  85. /**
  86. * The constructor's main job is to set the character encoding for the
  87. * response.
  88. *
  89. * <i>Note:</i> to change the character encoding for all of the
  90. * responses, set the XAJAX_DEFAULT_ENCODING constant before you
  91. * instantiate xajax.
  92. *
  93. * @param string contains the character encoding string to use
  94. * @param boolean lets you set if you want special characters in the output
  95. * converted to HTML entities
  96. *
  97. */
  98. function xajaxResponse($sEncoding=XAJAX_DEFAULT_CHAR_ENCODING, $bOutputEntities=false)
  99. {
  100. $this->setCharEncoding($sEncoding);
  101. $this->bOutputEntities = $bOutputEntities;
  102. }
  103. /**
  104. * Sets the character encoding for the response based on $sEncoding, which
  105. * is a string containing the character encoding to use. You don't need to
  106. * use this method normally, since the character encoding for the response
  107. * gets set automatically based on the XAJAX_DEFAULT_CHAR_ENCODING
  108. * constant.
  109. *
  110. * @param string
  111. */
  112. function setCharEncoding($sEncoding)
  113. {
  114. $this->sEncoding = $sEncoding;
  115. }
  116. /**
  117. * Tells the response object to convert special characters to HTML entities
  118. * automatically (only works if the mb_string extension is available).
  119. */
  120. function outputEntitiesOn()
  121. {
  122. $this->bOutputEntities = true;
  123. }
  124. /**
  125. * Tells the response object to output special characters intact. (default
  126. * behavior)
  127. */
  128. function outputEntitiesOff()
  129. {
  130. $this->bOutputEntities = false;
  131. }
  132. /**
  133. * Adds a confirm commands command message to the XML response.
  134. *
  135. * <i>Usage:</i> <kbd>$objResponse->addConfirmCommands(1, "Do you want to preview the new data?");</kbd>
  136. *
  137. * @param integer the number of commands to skip if the user presses
  138. * Cancel in the browsers's confirm dialog
  139. * @param string the message to show in the browser's confirm dialog
  140. */
  141. function addConfirmCommands($iCmdNumber, $sMessage)
  142. {
  143. $this->xml .= $this->_cmdXML(array("n"=>"cc","t"=>$iCmdNumber),$sMessage);
  144. }
  145. /**
  146. * Adds an assign command message to the XML response.
  147. *
  148. * <i>Usage:</i> <kbd>$objResponse->addAssign("contentDiv", "innerHTML", "Some Text");</kbd>
  149. *
  150. * @param string contains the id of an HTML element
  151. * @param string the part of the element you wish to modify ("innerHTML",
  152. * "value", etc.)
  153. * @param string the data you want to set the attribute to
  154. */
  155. function addAssign($sTarget,$sAttribute,$sData)
  156. {
  157. $this->xml .= $this->_cmdXML(array("n"=>"as","t"=>$sTarget,"p"=>$sAttribute),$sData);
  158. }
  159. /**
  160. * Adds an append command message to the XML response.
  161. *
  162. * <i>Usage:</i> <kbd>$objResponse->addAppend("contentDiv", "innerHTML", "Some New Text");</kbd>
  163. *
  164. * @param string contains the id of an HTML element
  165. * @param string the part of the element you wish to modify ("innerHTML",
  166. * "value", etc.)
  167. * @param string the data you want to append to the end of the attribute
  168. */
  169. function addAppend($sTarget,$sAttribute,$sData)
  170. {
  171. $this->xml .= $this->_cmdXML(array("n"=>"ap","t"=>$sTarget,"p"=>$sAttribute),$sData);
  172. }
  173. /**
  174. * Adds an prepend command message to the XML response.
  175. *
  176. * <i>Usage:</i> <kbd>$objResponse->addPrepend("contentDiv", "innerHTML", "Some Starting Text");</kbd>
  177. *
  178. * @param string contains the id of an HTML element
  179. * @param string the part of the element you wish to modify ("innerHTML",
  180. * "value", etc.)
  181. * @param string the data you want to prepend to the beginning of the
  182. * attribute
  183. */
  184. function addPrepend($sTarget,$sAttribute,$sData)
  185. {
  186. $this->xml .= $this->_cmdXML(array("n"=>"pp","t"=>$sTarget,"p"=>$sAttribute),$sData);
  187. }
  188. /**
  189. * Adds a replace command message to the XML response.
  190. *
  191. * <i>Usage:</i> <kbd>$objResponse->addReplace("contentDiv", "innerHTML", "text", "<b>text</b>");</kbd>
  192. *
  193. * @param string contains the id of an HTML element
  194. * @param string the part of the element you wish to modify ("innerHTML",
  195. * "value", etc.)
  196. * @param string the string to search for
  197. * @param string the string to replace the search string when found in the
  198. * attribute
  199. */
  200. function addReplace($sTarget,$sAttribute,$sSearch,$sData)
  201. {
  202. $sDta = "<s><![CDATA[$sSearch]]></s><r><![CDATA[$sData]]></r>";
  203. $this->xml .= $this->_cmdXML(array("n"=>"rp","t"=>$sTarget,"p"=>$sAttribute),$sDta);
  204. }
  205. /**
  206. * Adds a clear command message to the XML response.
  207. *
  208. * <i>Usage:</i> <kbd>$objResponse->addClear("contentDiv", "innerHTML");</kbd>
  209. *
  210. * @param string contains the id of an HTML element
  211. * @param string the part of the element you wish to clear ("innerHTML",
  212. * "value", etc.)
  213. */
  214. function addClear($sTarget,$sAttribute)
  215. {
  216. $this->addAssign($sTarget,$sAttribute,'');
  217. }
  218. /**
  219. * Adds an alert command message to the XML response.
  220. *
  221. * <i>Usage:</i> <kbd>$objResponse->addAlert("This is important information");</kbd>
  222. *
  223. * @param string the text to be displayed in the Javascript alert box
  224. */
  225. function addAlert($sMsg)
  226. {
  227. $this->xml .= $this->_cmdXML(array("n"=>"al"),$sMsg);
  228. }
  229. /**
  230. * Uses the addScript() method to add a Javascript redirect to another URL.
  231. *
  232. * <i>Usage:</i> <kbd>$objResponse->addRedirect("http://www.xajaxproject.org");</kbd>
  233. *
  234. * @param string the URL to redirect the client browser to
  235. */
  236. function addRedirect($sURL)
  237. {
  238. //we need to parse the query part so that the values are rawurlencode()'ed
  239. //can't just use parse_url() cos we could be dealing with a relative URL which
  240. // parse_url() can't deal with.
  241. $queryStart = strpos($sURL, '?', strrpos($sURL, '/'));
  242. if ($queryStart !== FALSE)
  243. {
  244. $queryStart++;
  245. $queryEnd = strpos($sURL, '#', $queryStart);
  246. if ($queryEnd === FALSE)
  247. $queryEnd = strlen($sURL);
  248. $queryPart = substr($sURL, $queryStart, $queryEnd-$queryStart);
  249. $queryParts = array();
  250. parse_str($queryPart, $queryParts);
  251. $newQueryPart = "";
  252. foreach($queryParts as $key => $value)
  253. {
  254. $newQueryPart .= rawurlencode($key).'='.rawurlencode($value).ini_get('arg_separator.output');
  255. }
  256. $sURL = str_replace($queryPart, $newQueryPart, $sURL);
  257. }
  258. $this->addScript('window.location = "'.$sURL.'";');
  259. }
  260. /**
  261. * Adds a Javascript command message to the XML response.
  262. *
  263. * <i>Usage:</i> <kbd>$objResponse->addScript("var x = prompt('get some text');");</kbd>
  264. *
  265. * @param string contains Javascript code to be executed
  266. */
  267. function addScript($sJS)
  268. {
  269. $this->xml .= $this->_cmdXML(array("n"=>"js"),$sJS);
  270. }
  271. /**
  272. * Adds a Javascript function call command message to the XML response.
  273. *
  274. * <i>Usage:</i> <kbd>$objResponse->addScriptCall("myJSFunction", "arg 1", "arg 2", 12345);</kbd>
  275. *
  276. * @param string $sFunc the name of a Javascript function
  277. * @param mixed $args,... optional arguments to pass to the Javascript function
  278. */
  279. function addScriptCall() {
  280. $arguments = func_get_args();
  281. $sFunc = array_shift($arguments);
  282. $sData = $this->_buildObjXml($arguments);
  283. $this->xml .= $this->_cmdXML(array("n"=>"jc","t"=>$sFunc),$sData);
  284. }
  285. /**
  286. * Adds a remove element command message to the XML response.
  287. *
  288. * <i>Usage:</i> <kbd>$objResponse->addRemove("Div2");</kbd>
  289. *
  290. * @param string contains the id of an HTML element to be removed
  291. */
  292. function addRemove($sTarget)
  293. {
  294. $this->xml .= $this->_cmdXML(array("n"=>"rm","t"=>$sTarget),'');
  295. }
  296. /**
  297. * Adds a create element command message to the XML response.
  298. *
  299. * <i>Usage:</i> <kbd>$objResponse->addCreate("parentDiv", "h3", "myid");</kbd>
  300. *
  301. * @param string contains the id of an HTML element to to which the new
  302. * element will be appended.
  303. * @param string the tag to be added
  304. * @param string the id to be assigned to the new element
  305. * @param string deprecated, use the addCreateInput() method instead
  306. */
  307. function addCreate($sParent, $sTag, $sId, $sType="")
  308. {
  309. if ($sType)
  310. {
  311. trigger_error("The \$sType parameter of addCreate has been deprecated. Use the addCreateInput() method instead.", E_USER_WARNING);
  312. return;
  313. }
  314. $this->xml .= $this->_cmdXML(array("n"=>"ce","t"=>$sParent,"p"=>$sId),$sTag);
  315. }
  316. /**
  317. * Adds a insert element command message to the XML response.
  318. *
  319. * <i>Usage:</i> <kbd>$objResponse->addInsert("childDiv", "h3", "myid");</kbd>
  320. *
  321. * @param string contains the id of the child before which the new element
  322. * will be inserted
  323. * @param string the tag to be added
  324. * @param string the id to be assigned to the new element
  325. */
  326. function addInsert($sBefore, $sTag, $sId)
  327. {
  328. $this->xml .= $this->_cmdXML(array("n"=>"ie","t"=>$sBefore,"p"=>$sId),$sTag);
  329. }
  330. /**
  331. * Adds a insert element command message to the XML response.
  332. *
  333. * <i>Usage:</i> <kbd>$objResponse->addInsertAfter("childDiv", "h3", "myid");</kbd>
  334. *
  335. * @param string contains the id of the child after which the new element
  336. * will be inserted
  337. * @param string the tag to be added
  338. * @param string the id to be assigned to the new element
  339. */
  340. function addInsertAfter($sAfter, $sTag, $sId)
  341. {
  342. $this->xml .= $this->_cmdXML(array("n"=>"ia","t"=>$sAfter,"p"=>$sId),$sTag);
  343. }
  344. /**
  345. * Adds a create input command message to the XML response.
  346. *
  347. * <i>Usage:</i> <kbd>$objResponse->addCreateInput("form1", "text", "username", "input1");</kbd>
  348. *
  349. * @param string contains the id of an HTML element to which the new input
  350. * will be appended
  351. * @param string the type of input to be created (text, radio, checkbox,
  352. * etc.)
  353. * @param string the name to be assigned to the new input and the variable
  354. * name when it is submitted
  355. * @param string the id to be assigned to the new input
  356. */
  357. function addCreateInput($sParent, $sType, $sName, $sId)
  358. {
  359. $this->xml .= $this->_cmdXML(array("n"=>"ci","t"=>$sParent,"p"=>$sId,"c"=>$sType),$sName);
  360. }
  361. /**
  362. * Adds an insert input command message to the XML response.
  363. *
  364. * <i>Usage:</i> <kbd>$objResponse->addInsertInput("input5", "text", "username", "input1");</kbd>
  365. *
  366. * @param string contains the id of the child before which the new element
  367. * will be inserted
  368. * @param string the type of input to be created (text, radio, checkbox,
  369. * etc.)
  370. * @param string the name to be assigned to the new input and the variable
  371. * name when it is submitted
  372. * @param string the id to be assigned to the new input
  373. */
  374. function addInsertInput($sBefore, $sType, $sName, $sId)
  375. {
  376. $this->xml .= $this->_cmdXML(array("n"=>"ii","t"=>$sBefore,"p"=>$sId,"c"=>$sType),$sName);
  377. }
  378. /**
  379. * Adds an insert input command message to the XML response.
  380. *
  381. * <i>Usage:</i> <kbd>$objResponse->addInsertInputAfter("input7", "text", "email", "input2");</kbd>
  382. *
  383. * @param string contains the id of the child after which the new element
  384. * will be inserted
  385. * @param string the type of input to be created (text, radio, checkbox,
  386. * etc.)
  387. * @param string the name to be assigned to the new input and the variable
  388. * name when it is submitted
  389. * @param string the id to be assigned to the new input
  390. */
  391. function addInsertInputAfter($sAfter, $sType, $sName, $sId)
  392. {
  393. $this->xml .= $this->_cmdXML(array("n"=>"iia","t"=>$sAfter,"p"=>$sId,"c"=>$sType),$sName);
  394. }
  395. /**
  396. * Adds an event command message to the XML response.
  397. *
  398. * <i>Usage:</i> <kbd>$objResponse->addEvent("contentDiv", "onclick", "alert(\'Hello World\');");</kbd>
  399. *
  400. * @param string contains the id of an HTML element
  401. * @param string the event you wish to set ("onclick", "onmouseover", etc.)
  402. * @param string the Javascript string you want the event to invoke
  403. */
  404. function addEvent($sTarget,$sEvent,$sScript)
  405. {
  406. $this->xml .= $this->_cmdXML(array("n"=>"ev","t"=>$sTarget,"p"=>$sEvent),$sScript);
  407. }
  408. /**
  409. * Adds a handler command message to the XML response.
  410. *
  411. * <i>Usage:</i> <kbd>$objResponse->addHandler("contentDiv", "onclick", "content_click");</kbd>
  412. *
  413. * @param string contains the id of an HTML element
  414. * @param string the event you wish to set ("onclick", "onmouseover", etc.)
  415. * @param string the name of a Javascript function that will handle the
  416. * event. Multiple handlers can be added for the same event
  417. */
  418. function addHandler($sTarget,$sEvent,$sHandler)
  419. {
  420. $this->xml .= $this->_cmdXML(array("n"=>"ah","t"=>$sTarget,"p"=>$sEvent),$sHandler);
  421. }
  422. /**
  423. * Adds a remove handler command message to the XML response.
  424. *
  425. * <i>Usage:</i> <kbd>$objResponse->addRemoveHandler("contentDiv", "onclick", "content_click");</kbd>
  426. *
  427. * @param string contains the id of an HTML element
  428. * @param string the event you wish to remove ("onclick", "onmouseover",
  429. * etc.)
  430. * @param string the name of a Javascript handler function that you want to
  431. * remove
  432. */
  433. function addRemoveHandler($sTarget,$sEvent,$sHandler)
  434. {
  435. $this->xml .= $this->_cmdXML(array("n"=>"rh","t"=>$sTarget,"p"=>$sEvent),$sHandler);
  436. }
  437. /**
  438. * Adds an include script command message to the XML response.
  439. *
  440. * <i>Usage:</i> <kbd>$objResponse->addIncludeScript("functions.js");</kbd>
  441. *
  442. * @param string URL of the Javascript file to include
  443. */
  444. function addIncludeScript($sFileName)
  445. {
  446. $this->xml .= $this->_cmdXML(array("n"=>"in"),$sFileName);
  447. }
  448. /**
  449. * Returns the XML to be returned from your function to the xajax processor
  450. * on your page. Since xajax 0.2, you can also return an xajaxResponse
  451. * object from your function directly, and xajax will automatically request
  452. * the XML using this method call.
  453. *
  454. * <i>Usage:</i> <kbd>return $objResponse->getXML();</kbd>
  455. *
  456. * @return string response XML data
  457. */
  458. function getXML()
  459. {
  460. $sXML = "<?xml version=\"1.0\"";
  461. if ($this->sEncoding && strlen(trim($this->sEncoding)) > 0)
  462. $sXML .= " encoding=\"".$this->sEncoding."\"";
  463. $sXML .= " ?"."><xjx>" . $this->xml . "</xjx>";
  464. return $sXML;
  465. }
  466. /**
  467. * Adds the commands of the provided response XML output to this response
  468. * object
  469. *
  470. * <i>Usage:</i>
  471. * <code>$r1 = $objResponse1->getXML();
  472. * $objResponse2->loadXML($r1);
  473. * return $objResponse2->getXML();</code>
  474. *
  475. * @param string the response XML (returned from a getXML() method) to add
  476. * to the end of this response object
  477. */
  478. function loadXML($mXML)
  479. {
  480. if (is_a($mXML, "xajaxResponse")) {
  481. $mXML = $mXML->getXML();
  482. }
  483. $sNewXML = "";
  484. $iStartPos = strpos($mXML, "<xjx>") + 5;
  485. $sNewXML = substr($mXML, $iStartPos);
  486. $iEndPos = strpos($sNewXML, "</xjx>");
  487. $sNewXML = substr($sNewXML, 0, $iEndPos);
  488. $this->xml .= $sNewXML;
  489. }
  490. /**
  491. * Generates XML from command data
  492. *
  493. * @access private
  494. * @param array associative array of attributes
  495. * @param string data
  496. * @return string XML command
  497. */
  498. function _cmdXML($aAttributes, $sData)
  499. {
  500. if ($this->bOutputEntities) {
  501. // An adaptation for the Dokeos LMS, 22-AUG-2009.
  502. if (function_exists('api_convert_encoding')) {
  503. $sData = call_user_func_array('api_convert_encoding', array(&$sData, 'HTML-ENTITIES', $this->sEncoding));
  504. }
  505. //if (function_exists('mb_convert_encoding')) {
  506. elseif (function_exists('mb_convert_encoding')) {
  507. //
  508. $sData = call_user_func_array('mb_convert_encoding', array(&$sData, 'HTML-ENTITIES', $this->sEncoding));
  509. }
  510. else {
  511. trigger_error("The xajax XML response output could not be converted to HTML entities because the mb_convert_encoding function is not available", E_USER_NOTICE);
  512. }
  513. }
  514. $xml = "<cmd";
  515. foreach($aAttributes as $sAttribute => $sValue)
  516. $xml .= " $sAttribute=\"$sValue\"";
  517. if ($sData !== null && !stristr($sData,'<![CDATA['))
  518. $xml .= "><![CDATA[$sData]]></cmd>";
  519. else if ($sData !== null)
  520. $xml .= ">$sData</cmd>";
  521. else
  522. $xml .= "></cmd>";
  523. return $xml;
  524. }
  525. /**
  526. * Recursively serializes a data structure in XML so it can be sent to
  527. * the client. It could be thought of as the opposite of
  528. * {@link xajax::_parseObjXml()}.
  529. *
  530. * @access private
  531. * @param mixed data structure to serialize to XML
  532. * @return string serialized XML
  533. */
  534. function _buildObjXml($var) {
  535. if (gettype($var) == "object") $var = get_object_vars($var);
  536. if (!is_array($var)) {
  537. return "<![CDATA[$var]]>";
  538. }
  539. else {
  540. $data = "<xjxobj>";
  541. foreach ($var as $key => $value) {
  542. $data .= "<e>";
  543. $data .= "<k>" . htmlspecialchars($key) . "</k>";
  544. $data .= "<v>" . $this->_buildObjXml($value) . "</v>";
  545. $data .= "</e>";
  546. }
  547. $data .= "</xjxobj>";
  548. return $data;
  549. }
  550. }
  551. }// end class xajaxResponse
  552. ?>