Source for file html-defs.php

Documentation is available at html-defs.php

  1. <?php
  2. /* ******************************************************************** */
  3. /* CATALYST PHP Source Code */
  4. /* -------------------------------------------------------------------- */
  5. /* This program is free software; you can redistribute it and/or modify */
  6. /* it under the terms of the GNU General Public License as published by */
  7. /* the Free Software Foundation; either version 2 of the License, or */
  8. /* (at your option) any later version. */
  9. /* */
  10. /* This program is distributed in the hope that it will be useful, */
  11. /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
  12. /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
  13. /* GNU General Public License for more details. */
  14. /* */
  15. /* You should have received a copy of the GNU General Public License */
  16. /* along with this program; if not, write to: */
  17. /* The Free Software Foundation, Inc., 59 Temple Place, Suite 330, */
  18. /* Boston, MA 02111-1307 USA */
  19. /* -------------------------------------------------------------------- */
  20. /* */
  21. /* Filename: html-defs.php */
  22. /* Author: Paul Waite */
  23. /* Description: Definitions for generic HTML objects such as table, */
  24. /* etc. These are objects used to render common HTML */
  25. /* entities. */
  26. /* */
  27. /* The classes all inherit RenderableObject, and have a */
  28. /* common ancestor defined herein called StylableObject */
  29. /* which encapsulates the data and methods to do with */
  30. /* the application of styles. */
  31. /* */
  32. /* ******************************************************************** */
  33. /** @package html */
  34. define("SCRIPT_REPLACE", 0);
  35.  
  36. /** Mode of adding scripts - append to existing */
  37. ("APPEND_SCRIPT", 1);
  38.  
  39. // ......................................................................
  40. /**
  41. * A renderable tag of some kind. Basically a tag is a language construct
  42. * designed to render at least an identifying name and a value. More
  43. * specific variants might add other properties, and control the way
  44. * the tag is actually rendered.
  45. * @package html
  46. */
  47. class HTMLtag extends tag {
  48. // Constructor
  49. function HTMLtag($name, $value="") {
  50. $this->tag($name, $value);
  51. }
  52. function html() {
  53. $s = "";
  54. if ($this->tag_name != "") {
  55. $s = "<$this->tag_name";
  56. if (count($this->attributes) > 0) {
  57. $s .= " ";
  58. $attrs = array();
  59. foreach ($this->attributes as $name => $value) {
  60. $attr = $name;
  61. if ($value != "") {
  62. $attr .= "=\"$value\"";
  63. }
  64. $attrs[] = $attr;
  65. }
  66. $s .= implode(" ", $attrs);
  67. }
  68. $s .= ">";
  69. if ($this->tag_value != "") {
  70. $s .= $this->tag_value;
  71. $s .= "</$this->tag_name>";
  72. }
  73. }
  74. return "$s\n";
  75. }
  76. } // HTMLtag class
  77. // ......................................................................
  78.  
  79. /**
  80. * StylableObject
  81. * This is a virtual class representing something which can have
  82. * its look changed by applying styles and/or classnames to it.
  83. * @package html
  84. */
  85. class StylableObject extends RenderableObject {
  86. /** The ID tag to apply to this object */
  87.  
  88. var $id;
  89. /** The style to apply to this object */
  90.  
  91. var $style;
  92. /** The stylesheet class to apply to this object */
  93.  
  94. var $class;
  95. // ....................................................................
  96. /**
  97. * Constructor
  98. * Create a stylableobject. Sets basic field attributes.
  99. * @param string $class_style Classname or Style setting to apply
  100. */
  101. function StylableObject($css="") {
  102. $this->setcss($css);
  103. } // StylableObject
  104. // ....................................................................
  105. /**
  106. * Set the ID tag of the object
  107. * @param string $id The ID to set against this ibject
  108. */
  109. function setid($id) {
  110. $this->id = $id;
  111. } // setid
  112. // ....................................................................
  113. /**
  114. * Set the class (from stylesheet) for the object
  115. * @param string $class Class to apply to this object
  116. */
  117. function setclass($class) {
  118. $this->class = $class;
  119. } // setclass
  120. // ....................................................................
  121. /** Clear all existing style settings. This leaves any class
  122. * settings alone. */
  123.  
  124. function clearstyle() {
  125. $this->style = "";
  126. } // clearstyle
  127. // ....................................................................
  128. /**
  129. * Append a style to ant exitsing style the object has.
  130. * @param string $style Style to append to existing.
  131. */
  132. function setstyle($style) {
  133. if (!strstr($this->style, $style)) {
  134. if ($this->style != "" && substr($this->style, -1) != ";") {
  135. $this->style .= ";";
  136. }
  137. $this->style .= $style;
  138. }
  139. } // style
  140. // ....................................................................
  141. /**
  142. * Set class or style for the object. A style is detected by
  143. * the presence of the colon (:) character in the string.
  144. * NOTE: styles will be added to the existing style value in
  145. * cumulative fashion.
  146. */
  147. function setcss($css="") {
  148. // If it contains ":" assume style, else classname..
  149. if ($css != "") {
  150. if (strstr($css, ":")) $this->setstyle($css);
  151. else $this->setclass($css);
  152. }
  153. else {
  154. // Clean 'em out..
  155. if (isset($this->style)) unset($this->style);
  156. if (isset($this->class)) unset($this->class);
  157. }
  158. } // setcss
  159. // ....................................................................
  160. /**
  161. * This method renders the stylable object attributes. Used in the
  162. * descendant classes to generate the property tags.
  163. * $return string Common attribute property tags for current object
  164. * @access private
  165. */
  166. function style_attributes() {
  167. global $RESPONSE;
  168. $s = "";
  169. // Omit the attributes unless we are not part of a reponse,
  170. // OR we are part of one and the browser is not Netscape..
  171. if (!isset($RESPONSE) || $RESPONSE->browser != BROWSER_NETSCAPE) {
  172. if (isset($this->style) && $this->style != "") $s .= " style=\"$this->style\"";
  173. if (isset($this->id) && $this->id != "") $s .= " id=\"$this->id\"";
  174. if (isset($this->class) && $this->class != "") $s .= " class=\"$this->class\"";
  175. }
  176. // Return the HTML..
  177. return $s;
  178. } // style_attributes
  179.  
  180. } // StylableObject class
  181. // ......................................................................
  182.  
  183. /**
  184. * An HTMLObject is any object which will be rendered in HTML according
  185. * to the basic syntax defined for HTML.
  186. * @package html
  187. */
  188. class HTMLObject extends StylableObject {
  189. /** Name of the object */
  190.  
  191. var $name;
  192. /** TAB index of the object */
  193.  
  194. var $tabindex;
  195. /** Access key of the object */
  196.  
  197. var $accesskey;
  198. /** Size of the object */
  199.  
  200. var $size;
  201. /** Width of the object */
  202.  
  203. var $width;
  204. /** Height of the object */
  205.  
  206. var $height;
  207. /** Alignment of the object: left, right, center */
  208.  
  209. var $align;
  210. /** Vertical alignment: top, bottom, middle */
  211.  
  212. var $valign;
  213. /** Title of the object */
  214.  
  215. var $title;
  216. /** ALT text for this object */
  217.  
  218. var $alt;
  219. /** Source URL for this object */
  220.  
  221. var $src;
  222. /** Language code for text content in this object */
  223.  
  224. var $lang;
  225. /** Direction for text - 'LTR' (left-to-right) or 'RTL' (right-to-left) */
  226.  
  227. var $langdir;
  228. /** Traget frame for this object */
  229.  
  230. var $target;
  231. /** Horizontal space around object (pixels) */
  232.  
  233. var $hspace;
  234. /** Vertical space around object (pixels) */
  235.  
  236. var $vspace;
  237. /** Border size (pixels) */
  238.  
  239. var $border;
  240. /** Foreground/text colour of the object */
  241.  
  242. var $color;
  243. /** Background colour of the object */
  244.  
  245. var $bgcolor;
  246. /** Background image url */
  247.  
  248. var $bgurl;
  249. /** Script to call when mouse clicked */
  250.  
  251. var $onclick;
  252. /** Script to call when mouse double-clicked */
  253.  
  254. var $ondblclick;
  255. /** Script to call on key down */
  256.  
  257. var $onkeydown;
  258. /** Script to call on key pressed */
  259.  
  260. var $onkeypress;
  261. /** Script to call on key up */
  262.  
  263. var $onkeyup;
  264. /** Script to call on mouse button down */
  265.  
  266. var $onmousedown;
  267. /** Script to call on mouse button down */
  268.  
  269. var $onmousemove;
  270. /** Script to call on mouse off object */
  271.  
  272. var $onmouseout;
  273. /** Script to call on mouse over object */
  274.  
  275. var $onmouseover;
  276. /** Script to call on mouse button up */
  277.  
  278. var $onmouseup;
  279. /** Script to call onblur */
  280.  
  281. var $onblur;
  282. /** Script to call onfocus */
  283.  
  284. var $onfocus;
  285. /** Script to call onload */
  286.  
  287. var $onload;
  288. /** Script to call onchange */
  289.  
  290. var $onchange;
  291. /** Script to call onselect */
  292.  
  293. var $onselect;
  294. // ....................................................................
  295. /** User-defined attributes
  296. @access private */
  297. var $user_attributes = array();
  298. // ....................................................................
  299. /** Text to display in statusbar when mouse over object
  300. @access private */
  301. var $linkover_text = "";
  302. // ....................................................................
  303. /**
  304. * Constructor
  305. * Create a HTMLObject. Sets basic field attributes.
  306. * @param string $class_style Classname or Style setting to apply
  307. */
  308. function HTMLObject($css="") {
  309. $this->StylableObject($css);
  310. }
  311. /** Set the name of the object
  312. @param string $name Name of this object */
  313. function setname($name) { $this->name = $name; }
  314. /** Set the TAB index of the object (with alias)
  315. @param integer $ix Tab index for this object */
  316. function settabindex($ix) { $this->tabindex = $ix; }
  317. /** Alias for settabindex(), deprecated, backward compat.
  318. @param integer $ix Tab index for this object */
  319. function set_tabindex($ix) { $this->settabindex($ix); }
  320. /** Set the access key of the object
  321. @param string $key Access key for this object */
  322. function setaccesskey($key) { $this->accesskey = $key; }
  323. /** Set the size specifier of the element
  324. @param integer $size Size of this object */
  325. function setsize($size) { $this->size = $size; }
  326. /** Set the width specifier of the element
  327. @param integer $width Width of this object */
  328. function setwidth($width) { $this->width = $width; }
  329. /** Set the height specifier of the element
  330. @param integer $height Height of this object */
  331. function setheight($height) { $this->height = $height; }
  332. /** Set the horizontal alignment eg: left, center, right
  333. @param string $align Horizontal alignment of this object */
  334. function setalign($align) { $this->align = $align; }
  335. /** Set the vertical-alignment eg: top, middle, bottom
  336. @param string $valign Vertical alignment of this object */
  337. function setvalign($valign) { $this->valign = $valign; }
  338. /** Set the title of this element
  339. @param string $title Title of this object */
  340. function settitle($title) { $this->title = $title; }
  341. /** Set the ALT text
  342. @param string $alt ALT text describing this object */
  343. function setalt($alt) { $this->alt = $alt; }
  344. /** Set the src URL/relative path
  345. @param string $src SRC path of this object */
  346. function setsrc($src) { $this->src = $src; }
  347. /** Set the language for text content
  348. @param string $lang Language code for this object */
  349. function setlang($lang) { $this->lang = $lang; }
  350. /** Set the text direction for text content: 'rtl' or 'ltr'
  351. @param string $langdir Language direction for this object. */
  352. function setlangdir($langdir) {
  353. if (strtolower($langdir) === "rtl") $this->langdir = "RTL";
  354. else $this->langdir = "LTR";
  355. }
  356. /** Set the frame target.
  357. @param string $target The frame target for this object */
  358. function settarget($target) { $this->target = $target; }
  359. /** Horizontal spacing (pixels)
  360. @param integer $px Horizontal spacing in pixels */
  361. function sethspace($px) { $this->hspace = $px; }
  362. /** Vertical spacing (pixels)
  363. @param integer $px Vertical spacing in pixels */
  364. function setvspace($px) { $this->vspace = $px; }
  365. /** Border thickness (pixels)
  366. @param integer $px Border thickness in pixels */
  367. function setborder($px) { $this->border = $px; }
  368. /** Set the foreground colour
  369. @param string $color Foreground colour code */
  370. function setcolor($color) { $this->color = $color; }
  371. /** Set the background colour
  372. @param string $bgcolor Background colour code */
  373. function setbgcolor($bgcolor) { $this->bgcolor = $bgcolor; }
  374. /** Set the background image (url)
  375. @param string $bgurl Background image URL */
  376. function setbackground($bgurl) { $this->bgurl = $bgurl; }
  377. /** Set the on click script
  378. @param string $script Name of script to execute */
  379. function set_onclick($script, $mode=SCRIPT_REPLACE) {
  380. $this->onclick = inline_script($script, $this->onclick, $mode);
  381. }
  382. /** Set the on doubleclick script
  383. @param string $script Name of script to execute
  384. @param integer $mode Mode: SCRIPT_REPLACE, SCRIPT_APPEND or SCRIPT_PREFIX */
  385. function set_ondblclick($script, $mode=SCRIPT_REPLACE) {
  386. $this->ondblclick = inline_script($script, $this->ondblclick, $mode);
  387. }
  388. /** Set the on keydown script
  389. @param string $script Name of script to execute
  390. @param integer $mode Mode: SCRIPT_REPLACE, SCRIPT_APPEND or SCRIPT_PREFIX */
  391. function set_onkeydown($script, $mode=SCRIPT_REPLACE) {
  392. $this->onkeydown = inline_script($script, $this->onkeydown, $mode);
  393. }
  394. /** Set the on keypress script
  395. @param string $script Name of script to execute
  396. @param integer $mode Mode: SCRIPT_REPLACE, SCRIPT_APPEND or SCRIPT_PREFIX */
  397. function set_onkeypress($script, $mode=SCRIPT_REPLACE) {
  398. $this->onkeypress = inline_script($script, $this->onkeypress, $mode);
  399. }
  400. /** Set the on keyup script
  401. @param string $script Name of script to execute
  402. @param integer $mode Mode: SCRIPT_REPLACE, SCRIPT_APPEND or SCRIPT_PREFIX */
  403. function set_onkeyup($script, $mode=SCRIPT_REPLACE) {
  404. $this->onkeyup = inline_script($script, $this->onkeyup, $mode);
  405. }
  406. /** Set the on mousedown script
  407. @param string $script Name of script to execute
  408. @param integer $mode Mode: SCRIPT_REPLACE, SCRIPT_APPEND or SCRIPT_PREFIX */
  409. function set_onmousedown($script, $mode=SCRIPT_REPLACE) {
  410. $this->onmousedown = inline_script($script, $this->onmousedown, $mode);
  411. }
  412. /** Set the on mousemove script
  413. @param string $script Name of script to execute
  414. @param integer $mode Mode: SCRIPT_REPLACE, SCRIPT_APPEND or SCRIPT_PREFIX */
  415. function set_onmousemove($script, $mode=SCRIPT_REPLACE) {
  416. $this->onmousemove = inline_script($script, $this->onmousemove, $mode);
  417. }
  418. /** Set the on mouseout script
  419. @param string $script Name of script to execute
  420. @param integer $mode Mode: SCRIPT_REPLACE, SCRIPT_APPEND or SCRIPT_PREFIX */
  421. function set_onmouseout($script, $mode=SCRIPT_REPLACE) {
  422. $this->onmouseout = inline_script($script, $this->onmouseout, $mode);
  423. }
  424. /** Set the on mouseover script
  425. @param string $script Name of script to execute
  426. @param integer $mode Mode: SCRIPT_REPLACE, SCRIPT_APPEND or SCRIPT_PREFIX */
  427. function set_onmouseover($script, $mode=SCRIPT_REPLACE) {
  428. $this->onmouseover = inline_script($script, $this->onmouseover, $mode);
  429. }
  430. /** Set the on mouseup script
  431. @param string $script Name of script to execute
  432. @param integer $mode Mode: SCRIPT_REPLACE, SCRIPT_APPEND or SCRIPT_PREFIX */
  433. function set_onmouseup($script, $mode=SCRIPT_REPLACE) {
  434. $this->onmouseup = inline_script($script, $this->onmouseup, $mode);
  435. }
  436. /** Set the onblur script
  437. @param string $script Name of script to execute
  438. @param integer $mode Mode: SCRIPT_REPLACE, SCRIPT_APPEND or SCRIPT_PREFIX */
  439. function set_onblur($script, $mode=SCRIPT_REPLACE) {
  440. $this->onblur = inline_script($script, $this->onblur, $mode);
  441. }
  442. /** Set the onfocus script
  443. @param string $script Name of script to execute
  444. @param integer $mode Mode: SCRIPT_REPLACE, SCRIPT_APPEND or SCRIPT_PREFIX */
  445. function set_onfocus($script, $mode=SCRIPT_REPLACE) {
  446. $this->onfocus = inline_script($script, $this->onfocus, $mode);
  447. }
  448. /** Set the onload script
  449. @param string $script Name of script to execute
  450. @param integer $mode Mode: SCRIPT_REPLACE, SCRIPT_APPEND or SCRIPT_PREFIX */
  451. function set_onload($script, $mode=SCRIPT_REPLACE) {
  452. $this->onload = inline_script($script, $this->onload, $mode);
  453. }
  454. /** Set the onchange script
  455. @param string $script Name of script to execute
  456. @param integer $mode Mode: SCRIPT_REPLACE, SCRIPT_APPEND or SCRIPT_PREFIX */
  457. function set_onchange($script, $mode=SCRIPT_REPLACE) {
  458. $this->onchange = inline_script($script, $this->onchange, $mode);
  459. }
  460. /** Set the onselect script
  461. @param string $script Name of script to execute
  462. @param integer $mode Mode: SCRIPT_REPLACE, SCRIPT_APPEND or SCRIPT_PREFIX */
  463. function set_onselect($script, $mode=SCRIPT_REPLACE) {
  464. $this->onselect = inline_script($script, $this->onselect, $mode);
  465. }
  466. //.....................................................................
  467. /**
  468. * This defines a key=value pair which will be rendered in the form
  469. * of '$attrname="$attrvalue"' inside the HTML object tag when rendered.
  470. * It is provided to cater for attributes not defined explicitly.
  471. * NOTES: If you omit the attribute value, the attribute will be
  472. * rendered as just '$attrname', without any value clause.
  473. * @param string $attrname Name or idenitifier of attribute
  474. * @param string $attrvalue Value of the attribute (not rendered if omitted)
  475. */
  476. function set_attribute($attrname, $attrvalue="???") {
  477. $this->user_attributes[$attrname] = $attrvalue;
  478. } // set_attribute
  479. //.....................................................................
  480. /**
  481. * This sets our attributes from another object which is a descendant of
  482. * HTMLObject. The attributes are specially selected to be only those
  483. * which are associated with the basic appearance of the object.
  484. * @param object $obj HTMLObject object instance to inherit attributes from
  485. */
  486. function inherit_attributes($obj) {
  487. if (is_subclass_of($obj, "HTMLObject")) {
  488. if (isset($obj->style)) $this->setstyle($obj->style);
  489. if (isset($obj->class)) $this->class = $obj->class;
  490. if (isset($obj->width)) $this->width = $obj->width;
  491. if (isset($obj->height)) $this->height = $obj->height;
  492. if (isset($obj->align)) $this->align = $obj->align;
  493. if (isset($obj->valign)) $this->valign = $obj->valign;
  494. if (isset($obj->hspace)) $this->hspace = $obj->hspace;
  495. if (isset($obj->vspace)) $this->vspace = $obj->vspace;
  496. if (isset($obj->border)) $this->border = $obj->border;
  497. if (isset($obj->color)) $this->color = $obj->color;
  498. if (isset($obj->bgcolor)) $this->bgcolor = $obj->bgcolor;
  499. if (isset($obj->bgurl)) $this->bgurl = $obj->bgurl;
  500. if (isset($obj->lang)) $this->lang = $obj->lang;
  501. if (isset($obj->langdir)) $this->langdir = $obj->langdir;
  502. }
  503. } // inherit_attributes
  504. //.....................................................................
  505. /**
  506. * Defines the text to show when the mouse moves over the object.
  507. * @param string $txt Text to show in status area when mouse-over.
  508. */
  509. function set_linkover_text($txt="") {
  510. // Encode so we can allow quotes in this string..
  511. $this->linkover_text = rawurlencode($txt);
  512. } // set_linkover_text
  513. // ....................................................................
  514. /**
  515. * Render the full tag. This method renders the given tag including
  516. * all the attributes, as HTML.
  517. */
  518. function taghtml($tag) {
  519. return "<$tag" . $this->attributes() . ">";
  520. } // taghtml
  521. // ....................................................................
  522. /**
  523. * Render common field properties
  524. * This method renders the common object attributes. Used in the
  525. * descendant classes to generate the property tags.
  526. * $return string Common attribute property tags for current object
  527. * @access private
  528. */
  529. function attributes() {
  530. global $RESPONSE;
  531. $s = $this->style_attributes();
  532. // Optional linkover statusbar message..
  533. if ($this->linkover_text != "" && !isset($this->onmouseover)) {
  534. $this->onmouseover = "status=unescape('$this->linkover_text');return true;";
  535. $this->onmouseout = "status='';return true;";
  536. }
  537. // Properties
  538. if (isset($this->name) && $this->name != "") $s .= " name=\"$this->name\"";
  539. if (isset($this->tabindex)) $s .= " tabindex=\"$this->tabindex\"";
  540. if (isset($this->accesskey)) $s .= " accesskey=\"$this->accesskey\"";
  541. if (isset($this->size)) $s .= " size=\"$this->size\"";
  542. if (isset($this->width)) $s .= " width=\"$this->width\"";
  543. if (isset($this->height)) $s .= " height=\"$this->height\"";
  544. if (isset($this->align) && $this->align != "") $s .= " align=\"$this->align\"";
  545. if (isset($this->valign) && $this->valign != "") $s .= " valign=\"$this->valign\"";
  546. if (isset($this->title) && $this->title != "") $s .= " title=\"$this->title\"";
  547. if (isset($this->alt) && $this->alt != "") $s .= " alt=\"$this->alt\"";
  548. if (isset($this->src) && $this->src != "") $s .= " src=\"$this->src\"";
  549. if (isset($this->lang) && $this->lang != "") $s .= " lang=\"$this->lang\"";
  550. if (isset($this->langdir) && $this->langdir != "") $s .= " dir=\"$this->langdir\"";
  551. if (isset($this->target) && $this->target != "") $s .= " target=\"$this->target\"";
  552. if (isset($this->hspace)) $s .= " hspace=\"$this->hspace\"";
  553. if (isset($this->vspace)) $s .= " vspace=\"$this->vspace\"";
  554. if (isset($this->border)) $s .= " border=\"$this->border\"";
  555. if (isset($this->bgcolor) && $this->bgcolor != "") $s .= " bgcolor=\"$this->bgcolor\"";
  556. if (isset($this->bgurl) && $this->bgurl != "") $s .= " background=\"$this->bgurl\"";
  557. if (isset($this->color) && $this->color != "") $s .= " color=\"$this->color\"";
  558. // Events
  559. if (isset($this->onclick)) $s .= " onclick=\"$this->onclick\"";
  560. if (isset($this->ondblclick)) $s .= " ondblclick=\"$this->ondblclick\"";
  561. if (isset($this->onkeydown)) $s .= " onkeydown=\"$this->onkeydown\"";
  562. if (isset($this->onkeypress)) $s .= " onkeypress=\"$this->onkeypress\"";
  563. if (isset($this->onkeyup)) $s .= " onkeyup=\"$this->onkeyup\"";
  564. if (isset($this->onmousedown)) $s .= " onmousedown=\"$this->onmousedown\"";
  565. if (isset($this->onmousemove)) $s .= " onmousemove=\"$this->onmousemove\"";
  566. if (isset($this->onmouseout)) $s .= " onmouseout=\"$this->onmouseout\"";
  567. if (isset($this->onmouseover)) $s .= " onmouseover=\"$this->onmouseover\"";
  568. if (isset($this->onmouseup)) $s .= " onmouseup=\"$this->onmouseup\"";
  569. if (isset($this->onblur)) $s .= " onblur=\"$this->onblur\"";
  570. if (isset($this->onfocus)) $s .= " onfocus=\"$this->onfocus\"";
  571. if (isset($this->onload)) $s .= " onload=\"$this->onload\"";
  572. if (isset($this->onchange)) $s .= " onchange=\"$this->onchange\"";
  573. if (isset($this->onselect)) $s .= " onselect=\"$this->onselect\"";
  574. // Any user-defined attributes..
  575. foreach ($this->user_attributes as $attrname => $attrvalue) {
  576. $s .= " $attrname";
  577. if ($attrvalue != "???") {
  578. $s .= "=\"$attrvalue\"";
  579. }
  580. }
  581. // Return the HTML..
  582. return $s;
  583. } // attributes
  584.  
  585. } // HTMLObject class
  586. // ......................................................................
  587.  
  588. /**
  589. * This represents text which is the content of a layout object
  590. * such as a paragraph, a table cell etc. As such is may have an
  591. * associated style and/or classname which is applied with a
  592. * span tag.
  593. * @package html
  594. * @access private
  595. */
  596. class textcontent extends StylableObject {
  597. /** Content contained by the object */
  598.  
  599. var $content = "";
  600. // ....................................................................
  601. /**
  602. * Set the text content and the style/class for it
  603. * @param string $content The content to assign to the object
  604. * @param string $css The style or class to assign to the object
  605. */
  606. function textcontent($content="", $css="") {
  607. $this->StylableObject($css);
  608. $this->content = $content;
  609. }
  610. // ....................................................................
  611. /** Set the content for the object
  612. * @param string $content The content to assign to the object
  613. */
  614. function setcontent($content) {
  615. $this->content = $content;
  616. }
  617. // ....................................................................
  618. /** Add to the content for the object
  619. * @param string $content The content to assign to the object
  620. */
  621. function addcontent($content) {
  622. $this->content .= $content;
  623. }
  624. // ....................................................................
  625. /** Return the HTML for this text content
  626. * @return string The HTML of this object
  627. */
  628. function html() {
  629. $s = "";
  630. if (isset($this->style) || isset($this->class) || isset($this->id)) {
  631. $s .= "<span";
  632. $s .= $this->style_attributes();
  633. $s .= ">$this->content</span>";
  634. }
  635. else {
  636. $s .= $this->content;
  637. }
  638. // Return the html..
  639. return $s;
  640. }
  641. } // textcontent class
  642. // ......................................................................
  643.  
  644. /**
  645. * tablecell
  646. * This class encapsulates a single cell of a table. As such is is a
  647. * receptacle of content which can be styled. The cell can also optionally
  648. * have permissions defined for it. If defined the rendering as HTML will
  649. * check the logged-in user groups form permission to update content. If
  650. * permission exists, then the content is rendered as a form text field
  651. * instead. The cell variable "cellid" should have been set before this,
  652. * so that the form field is named.
  653. *
  654. * @package html
  655. */
  656. class tablecell extends HTMLObject {
  657. /** Optional unique ID for this cell. Used for form field naming. */
  658.  
  659. var $cellid = "";
  660. /** Column span that this cell is anchor of */
  661.  
  662. var $colspan = 1;
  663. /** Row span that this cell is anchor of */
  664.  
  665. var $rowspan = 1;
  666. /** Whether this is a heading cell */
  667.  
  668. var $heading = false;
  669. /** The cell content object */
  670.  
  671. var $content;
  672. /** Whether this cell is colspanned (invisible) */
  673.  
  674. var $colspanned = false;
  675. /** Whether this cell is rowspanned (invisible) */
  676.  
  677. var $rowspanned = false;
  678. /** Force blank content to be non-blank space */
  679.  
  680. var $nbsp = false;
  681. /** Optional access permissions for cell. */
  682.  
  683. var $access;
  684. // ....................................................................
  685. /** Constructor. Create this new table cell object. */
  686.  
  687. function tablecell($content="", $css="") {
  688. $this->HTMLObject($css);
  689. $this->content = new textcontent($content);
  690. } // tablecell
  691. // ....................................................................
  692. /**
  693. * Set permission for this cell for given agent
  694. * @param integer $agentids List of unique IDs of agents to assign the permission for
  695. * @param integer $perm The permission or combination of perms to assign
  696. * @param string $cellid Identity of the cell, used for rendering cell as textfield in a form
  697. */
  698. function permit($agentids, $perm, $cellid="???") {
  699. if (!isset($this->access)) {
  700. $this->access = new permissions();
  701. }
  702. $this->access->permit($agentids, $perm);
  703. if ($cellid != "???") {
  704. $this->setcellid($cellid);
  705. }
  706. }
  707. // ....................................................................
  708. /**
  709. * Unset permission for this cell for given agent
  710. * @param integer $agentids List of unique IDs of agents to unassign the permission from
  711. * @param integer $perm The permission or combination of perms to unassign
  712. */
  713. function unpermit($agentids, $perm) {
  714. if (isset($this->access)) {
  715. $this->access->unpermit($agentids, $perm);
  716. }
  717. }
  718. // ....................................................................
  719. /** Set the cell ID */
  720.  
  721. function setcellid($cellid) {
  722. $this->cellid = $cellid;
  723. }
  724. // ....................................................................
  725. /** Set the number of columns this cell spans */
  726.  
  727. function setcolspan($span) {
  728. if ($this->rowspanned) {
  729. if ($span > 1) {
  730. $this->colspan = $span - 1;
  731. }
  732. $this->rowspanned = false;
  733. }
  734. else {
  735. $this->colspan = $span;
  736. }
  737. }
  738. // ....................................................................
  739. /** Set the number of rows this cell spans */
  740.  
  741. function setrowspan($span) {
  742. if ($this->colspanned) {
  743. $this->colspanned = false;
  744. }
  745. $this->rowspan = $span;
  746. }
  747. // ....................................................................
  748. /** Flag this cell as being spanned */
  749.  
  750. function span($type) {
  751. if ($type == "column") {
  752. $this->colspan = 1;
  753. $this->colspanned = true;
  754. }
  755. elseif ($type == "row") {
  756. if ($this->colspan > 1) {
  757. $this->colspan -= 1;
  758. }
  759. else {
  760. $this->rowspan = 1;
  761. $this->rowspanned = true;
  762. }
  763. }
  764. }
  765. // ....................................................................
  766. /** Flag this cell as being unspanned */
  767.  
  768. function unspan($type) {
  769. if ($type == "column") {
  770. $this->colspanned = false;
  771. }
  772. elseif ($type == "row") {
  773. $this->rowspanned = false;
  774. }
  775. }
  776. // ....................................................................
  777. /** Set the style or class for the content of this cell */
  778.  
  779. function setcontentcss($css="") {
  780. $this->content->setcss($css);
  781. }
  782. // ....................................................................
  783. /** Set the content for this cell */
  784.  
  785. function setcontent($text="") {
  786. $this->content->setcontent($text);
  787. }
  788. // ....................................................................
  789. /** Add to the content for this cell */
  790.  
  791. function addcontent($text="") {
  792. $this->content->addcontent($text);
  793. }
  794. // ....................................................................
  795. /** Clear the content from this cell. */
  796.  
  797. function clearcontent() {
  798. $this->content->setcontent("");
  799. }
  800. // ....................................................................
  801. /** Automatically set the alignment of this cell according to content. */
  802.  
  803. function autojustify() {
  804. $content = $this->content->content;
  805. if ($content != "") {
  806. $style = $this->style;
  807. $content_style = $this->content->style;
  808. if (!stristr($style, "text-align") && !stristr($content_style, "text-align")) {
  809. //if (is_numeric($content)) {
  810. $pat = "/^[0-9|\.\$|,]+$/";
  811. if (preg_match($pat, $content)) {
  812. $just = "text-align:right;";
  813. $this->setstyle($just);
  814. }
  815. }
  816. }
  817. }
  818. // ....................................................................
  819. /** Set the alignment of this cell */
  820.  
  821. function setalignment($align="", $valign="") {
  822. if ($align != "") $this->setalign($align);
  823. if ($valign != "") $this->setvalign($valign);
  824. }
  825. // ....................................................................
  826. /** Set the width and height of this cell */
  827.  
  828. function setmetrics($width="", $height="") {
  829. $this->setwidth($width);
  830. $this->setheight($height);
  831. }
  832. // ....................................................................
  833. /**
  834. * Return the HTML for this cell. Cell content can be displayed as either
  835. * standard text, or as a form-field. The latter case is only possible if
  836. * the cell has had permissions defined, and the logged-in user is found
  837. * to be permitted UPDATE access to the cell.
  838. */
  839. function html() {
  840. global $RESPONSE;
  841. $s = "";
  842. // We are only visible if not spanned..
  843. if (!$this->colspanned && !$this->rowspanned) {
  844. if ($this->heading) $tag = "th";
  845. else $tag = "td";
  846. $s .= "<$tag";
  847. $s .= $this->attributes();
  848. if ($this->colspan > 1) {
  849. $s .= " colspan=\"$this->colspan\"";
  850. }
  851. if ($this->rowspan > 1) {
  852. $s .= " rowspan=\"$this->rowspan\"";
  853. }
  854. $s .= ">";
  855. $sc = $this->content->html();
  856. if ($sc == "" && $this->nbsp) {
  857. $sc = "&nbsp;";
  858. }
  859. $s .= $sc;
  860. // Close cell tag..
  861. $s .= "</$tag>";
  862. }
  863. // Return the HTML
  864. return $s;
  865. }
  866. // ....................................................................
  867. /**
  868. * Return the CSV content for this cell.
  869. */
  870. function csv() {
  871. $s = "";
  872. // We are only visible if not spanned..
  873. if (!$this->colspanned && !$this->rowspanned) {
  874. $s = strip_tags($this->content->content);
  875. $s = trim(str_replace("&nbsp;", " ", $s));
  876. if (strpos($s, "\"") !== false || strpos($s, ",") !== false) {
  877. $s = str_replace("\"", "\"\"", $s);
  878. $s = "\"$s\"";
  879. }
  880. }
  881. return $s;
  882. }
  883. } // tablecell class
  884. // ......................................................................
  885.  
  886. /**
  887. * headingcell
  888. * @package html
  889. * @access private
  890. */
  891. class headingcell extends tablecell {
  892. function headingcell($content="", $css="") {
  893. $this->tablecell($content, $css);
  894. $this->heading = true;
  895. }
  896. } // headingcell class
  897. // ......................................................................
  898.  
  899. /**
  900. * tablerow
  901. * A container of table cells.
  902. * @package html
  903. * @access private
  904. */
  905. class tablerow extends HTMLObject {
  906. /** An array containing the cells of this row */
  907.  
  908. var $cells = array();
  909. // ....................................................................
  910. /** Constructor. Create a new row object. */
  911.  
  912. function tablerow($css="") {
  913. $this->HTMLObject($css);
  914. }
  915. // ....................................................................
  916. /** Set cell permissions across entire row. If the row number os specified
  917. * then we assign the cell ID string, which is used when rendering the cell
  918. * as an editable field, to give the field a name used in form submission.
  919. * @param integer $agentids List of unique IDs of agents to assign the permission for
  920. * @param integer $perm The permission or combination of perms to assign
  921. * @param integer $row The row number, for cell ID purposes
  922. * @param string $group The group tag (eg. 'tbody'), for cell ID purposes
  923. */
  924. function permit($agentids, $perm, $row="", $group="") {
  925. for ($c = 0; $c < $this->cellcount(); $c++) {
  926. // Determine cell ID..
  927. $cellid = "";
  928. if ($row != "") {
  929. $cellid = "_tcell|$row|$c";
  930. if ($group != "") $cellid .= "|$group";
  931. }
  932. // Set cell access permission..
  933. $cell = $this->cells[$c];
  934. $cell->permit($agentids, $perm, $cellid);
  935. $this->cells[$c] = $cell;
  936. }
  937. }
  938. // ....................................................................
  939. /** Autojustify all cells in this row based on current content */
  940.  
  941. function autojustify() {
  942. for ($c = 0; $c < $this->cellcount(); $c++) {
  943. $cell = $this->cells[$c];
  944. $cell->autojustify();
  945. $this->cells[$c] = $cell;
  946. }
  947. }
  948. // ....................................................................
  949. /** Return the number of cells in this row
  950. * @return integer Number of physical cells in the row
  951. */
  952. function cellcount() {
  953. return count($this->cells);
  954. }
  955. // ....................................................................
  956. /**
  957. * Return the number of columns in this row. This counts spanned
  958. * cells as well, so a cell with colspan=2 would count as 2 columns.
  959. * cells whch are col-spanned are omitted, but those which are
  960. * row-spanned are counted, as they should be.
  961. * @return integer Number of actual table columns in row
  962. */
  963. function colcount() {
  964. $tot = 0;
  965. foreach ($this->cells as $cell) {
  966. if (!$cell->colspanned) {
  967. $tot += $cell->colspan;
  968. }
  969. }
  970. return $tot;
  971. }
  972. // ....................................................................
  973. /**
  974. * Return the number of visible cells in this row. This takes account
  975. * of colspans, and only counts cells that are seen in the row when
  976. * it is rendered.
  977. * @return integer Number of visible cells in the row
  978. */
  979. function visible_cellsinrow() {
  980. $tot = 0;
  981. foreach ($this->cells as $cell) {
  982. if (!$cell->colspanned) {
  983. $tot += 1;
  984. }
  985. }
  986. return $tot;
  987. }
  988. // ....................................................................
  989. /** Clear the content from all cells in row. */
  990.  
  991. function clearcontent() {
  992. for ($c = 0; $c < $this->cellcount(); $c++) {
  993. $cell = $this->cells[$c];
  994. $cell->clearcontent();
  995. $this->cells[$c] = $cell;
  996. }
  997. }
  998. // ....................................................................
  999. /** Set nbsp setting for cells in this row
  1000. * @param boolean mode If true, then all cells will return "&nbsp;" if blank.
  1001. */
  1002. function setnbsp($mode=true) {
  1003. for ($c = 0; $c < $this->cellcount(); $c++) {
  1004. $cell = $this->cells[$c];
  1005. $cell->nbsp = $mode;
  1006. $this->cells[$c] = $cell;
  1007. }
  1008. }
  1009. // ....................................................................
  1010. /** Flag a given column as being spanned.
  1011. * @param string $type Type of span 'column' or 'row'
  1012. * $param integer $col Column (zero-referenced) to span
  1013. */
  1014. function span($type, $col) {
  1015. if (isset($this->cells[$col])) {
  1016. $cell = $this->cells[$col];
  1017. $cell->span($type);
  1018. $this->cells[$col] = $cell;
  1019. }
  1020. }
  1021. // ....................................................................
  1022. /** Flag a given column as being unspanned.
  1023. * @param string $type Type of span 'column' or 'row'
  1024. * @param integer $col Column (zero-referenced) to unspan
  1025. */
  1026. function unspan($type, $col) {
  1027. if (isset($this->cells[$col])) {
  1028. $cell = $this->cells[$col];
  1029. $cell->unspan($type);
  1030. $this->cells[$col] = $cell;
  1031. }
  1032. }
  1033. // ....................................................................
  1034. /** Add a ready-made cell to this row
  1035. * @param object $cell Cell object to add to the row
  1036. */
  1037. function add_cell($cell) {
  1038. $this->cells[] = $cell;
  1039. }
  1040. // ....................................................................
  1041. /**
  1042. * Insert a new cell at the given column position. The new cell
  1043. * takes the place of any cell currently at that position, and
  1044. * the previous cell then occupies the next highest column slot.
  1045. * @param integer $col Column/cell to insert at
  1046. * @param mixed $celltoinsert Optional cell object to use when inserting
  1047. */
  1048. function insert_cell($col, $celltoinsert=false) {
  1049. // Inserting off the end of the row..
  1050. if ($col == $this->cellcount() || $this->cellcount() == 0) {
  1051. $this->append_cells(1, $celltoinsert);
  1052. }
  1053. else {
  1054. if (!$celltoinsert) $celltoinsert = new tablecell();
  1055. $newcells = array();
  1056. $c = 0;
  1057. foreach ($this->cells as $cell) {
  1058. if ($c == $col) {
  1059. if ($cell->colspanned) {
  1060. for ($cc = $c; $cc >= 0; $cc--) {
  1061. if (isset($newcells[$cc])) {
  1062. $prevcell = $newcells[$cc];
  1063. if (!$prevcell->colspanned) {
  1064. $prevcell->colspan += 1;
  1065. $newcells[$cc] = $prevcell;
  1066. break;
  1067. }
  1068. }
  1069. }
  1070. $spannedcell = $celltoinsert;
  1071. $spannedcell->colspanned = true;
  1072. $newcells[] = $spannedcell;
  1073. }
  1074. else {
  1075. $newcells[] = $celltoinsert;
  1076. }
  1077. }
  1078. // Always add original cell afterwards..
  1079. $newcells[] = $cell;
  1080. $c += 1;
  1081. } // foreach
  1082.  
  1083. // Replace row cells with new set..
  1084. $this->cells = $newcells;
  1085. }
  1086. }
  1087. // ....................................................................
  1088. /** Append cells onto the end of this row
  1089. * @param integer $repeat Number of cells to append
  1090. * @param mixed $celltoappend Optional cell object to use when appending
  1091. */
  1092. function append_cells($repeat=1, $celltoappend=false) {
  1093. if (!$celltoappend) $celltoappend = new tablecell();
  1094. for ($i = 0; $i < $repeat; $i++) {
  1095. $this->add_cell( $celltoappend );
  1096. }
  1097. }
  1098. // ....................................................................
  1099. /** Delete a cell from the given column position.
  1100. * @param integer $col Column/cell to delete
  1101. */
  1102. function delete_cell($col) {
  1103. $newcells = array();
  1104. $ctot = $this->cellcount();
  1105. for ($c=0; $c < $ctot; $c++) {
  1106. $cell = $this->cells[$c];
  1107. if ($c == $col) {
  1108. if ($cell->colspanned) {
  1109. for ($cc = $c; $cc >= 0; $cc--) {
  1110. if (isset($newcells[$cc])) {
  1111. $prevcell = $newcells[$cc];
  1112. if (!$prevcell->colspanned) {
  1113. $prevcell->colspan -= 1;
  1114. $newcells[$cc] = $prevcell;
  1115. break;
  1116. }
  1117. }
  1118. }
  1119. }
  1120. elseif ($cell->colspan > 1) {
  1121. if (isset($this->cells[$c + 1])) {
  1122. $nextcell = $this->cells[$c + 1];
  1123. $nextcell->colspanned = false;
  1124. $nextcell->colspan = $cell->colspan - 1;
  1125. $this->cells[$c + 1] = $nextcell;
  1126. }
  1127. }
  1128. }
  1129. else {
  1130. $newcells[] = $cell;
  1131. }
  1132. }
  1133. $this->cells = $newcells;
  1134. }
  1135. // ....................................................................
  1136. /** Poke content into the given cell in this row. The first column
  1137. * in a row being zero (0).
  1138. * @param integer $col Column/cell in row to apply css to
  1139. * @param string $content Cell content to poke into the cell
  1140. * @param string $css Cell css setting, or omit to not set it.
  1141. * @param string $contentcss Cell content css setting, or omit to not set it.
  1142. */
  1143. function poke_cell($col, $content, $css="", $contentcss="") {
  1144. $rc = false;
  1145. if (isset($this->cells[$col])) {
  1146. $cell = $this->cells[$col];
  1147. $cell->setcontent($content);
  1148. if ($css != "") $cell->setcontentcss($css);
  1149. $this->cells[$col] = $cell;
  1150. $rc = true;
  1151. }
  1152. return $rc;
  1153. }
  1154. // ....................................................................
  1155. /** Poke css onto the given cell in this row. The first column
  1156. * in a row being zero (0).
  1157. * @param integer $col Column/cell in row to apply css to
  1158. * @param string $css Cell css setting, or nullstring to leave as is.
  1159. * @param string $contentcss Optional cell content css setting, or omit to not set it.
  1160. */
  1161. function poke_cellcss($col, $css="", $contentcss="") {
  1162. $rc = false;
  1163. if (isset($this->cells[$col])) {
  1164. $cell = $this->cells[$col];
  1165. if ($css != "") $cell->setcss($css);
  1166. if ($contentcss != "") $cell->setcontentcss($css);
  1167. $this->cells[$col] = $cell;
  1168. $rc = true;
  1169. }
  1170. return $rc;
  1171. }
  1172. // ....................................................................
  1173. /** Peek cell content. Returns the content of the given cell.
  1174. * @param integer $col Column/cell in row to retreive content from
  1175. * @return string Cell content of the given column
  1176. */
  1177. function peek_cell($col) {
  1178. $rc = "";
  1179. if (isset($this->cells[$col])) {
  1180. $cell = $this->cells[$col];
  1181. $rc = $cell->content->content;
  1182. }
  1183. return $rc;
  1184. }
  1185. // ....................................................................
  1186. /** Return the given cell in this row. The first column
  1187. * in a row being zero (0). Returns false if no cell present.
  1188. * @param integer $col Column/cell in row to retreive cell object of
  1189. * @return object Cell object of the given column
  1190. */
  1191. function get_cell($col) {
  1192. $cell = false;
  1193. if (isset($this->cells[$col])) {
  1194. $cell = $this->cells[$col];
  1195. }
  1196. return $cell;
  1197. }
  1198. // ....................................................................
  1199. /** Replace the given cell with new table cell. Returns true if ok.
  1200. * @param integer $col Column/cell in row to set cell object of
  1201. * @return object Cell object to insert at the given column
  1202. */
  1203. function set_cell($col, $cell) {
  1204. $rc = false;
  1205. if (isset($this->cells[$col])) {
  1206. $this->cells[$col] = $cell;
  1207. $rc = true;
  1208. }
  1209. return $rc;
  1210. }
  1211. // ....................................................................
  1212. /**
  1213. * Apply a colspan. The column of the cell which has the colspan is
  1214. * given. As a result the relevant spanned cells will be flagged as spanned.
  1215. * If the span goes beyond the row end, it is truncated. NB: If the
  1216. * anchor cell is already spanning, then the new span is added to
  1217. * the original one, up to the limit of the table columns.
  1218. * @param integer $col Number of column to anchor the span (first=0)
  1219. * @param integer $span Number of columns to span across
  1220. */
  1221. function merge_cols($col, $span) {
  1222. if (isset($this->cells[$col])) {
  1223. $cell = $this->cells[$col];
  1224. if (!$cell->colspanned) {
  1225. $oldspan = $cell->colspan;
  1226. $newspan = $oldspan + $span - 1;
  1227. $spancount = $newspan - 1;
  1228. $adj = 0;
  1229. $nxtcol = $col + 1;
  1230. for ($c = $nxtcol; $c < $nxtcol + $spancount; $c++) {
  1231. if (isset($this->cells[$c])) {
  1232. $lacell = $this->cells[$c];
  1233. if ($lacell->colspan > 1) {
  1234. $adj = $adj + $lacell->colspan - 1;
  1235. }
  1236. }
  1237. }
  1238. $spancount += $adj;
  1239. $newspan += $adj;
  1240. $this->span_cols($nxtcol, $spancount);
  1241. $cell->setcolspan($newspan);
  1242. $this->cells[$col] = $cell;
  1243. }
  1244. }
  1245. }
  1246. // ....................................................................
  1247. /**
  1248. * Apply spanning to multiple cells in the row.
  1249. * @param integer $col Number of column to start spanning
  1250. * @param integer $spancount Number of columns to set as spanned
  1251. */
  1252. function span_cols($col, $spancount) {
  1253. for ($c = $col; $c < $spancount + $col; $c++) {
  1254. $this->span("column", $c);
  1255. }
  1256. }
  1257. // ....................................................................
  1258. /**
  1259. * Remove spanning from a colspanned set of cells. This will effectively
  1260. * set the colspan of the orgin cell to 1, and insert new cells after
  1261. * it to make up the difference and maintain the original colcount.
  1262. * @param integer $col Number of column to split at
  1263. */
  1264. function split_cols($col) {
  1265. if (isset($this->cells[$col])) {
  1266. $cell = $this->cells[$col];
  1267. if ($cell->colspan > 1) {
  1268. $unspancount = $cell->colspan - 1;
  1269. $cell->setcolspan(1);
  1270. $this->cells[$col] = $cell;
  1271. for ($i = 1; $i <= $unspancount; $i++) {
  1272. $this->unspan("column", $col + $i);
  1273. }
  1274. }
  1275. }
  1276. }
  1277. // ....................................................................
  1278. /** Set a width profile across the row of cells
  1279. * @param string $prof The width profile eg '33%,67%'
  1280. */
  1281. function set_width_profile($prof) {
  1282. if (!$this->has_colspans()) {
  1283. $ix = 0;
  1284. foreach ($prof as $width) {
  1285. if (isset($this->cells[$ix])) {
  1286. $cell = $this->cells[$ix];
  1287. $cell->setwidth($width);
  1288. $this->cells[$ix] = $cell;
  1289. $ix += 1;
  1290. }
  1291. }
  1292. }
  1293. }
  1294. // ....................................................................
  1295. /** Returns true if this row has colspanned cells
  1296. * @return boolean True if the row has colspanned cells in it
  1297. */
  1298. function has_colspans() {
  1299. $rc = false;
  1300. foreach ($this->cells as $chk) {
  1301. if ($chk->colspanned || $chk->colspan > 1) {
  1302. $rc = true;
  1303. break;
  1304. }
  1305. }
  1306. return $rc;
  1307. }
  1308. // ....................................................................
  1309. /** Set a width profile across the row of cells
  1310. * @return string The current width profile setting for the row
  1311. */
  1312. function get_width_profile() {
  1313. $prof = array();
  1314. if (!$this->has_colspans()) {
  1315. foreach ($this->cells as $cell) {
  1316. $prof[] = (isset($cell->width) ? $cell->width : "");
  1317. }
  1318. }
  1319. return $prof;
  1320. }
  1321. // ....................................................................
  1322. /** Return the HTML for this row and all its cells
  1323. * @return string The HTML for the row
  1324. */
  1325. function html() {
  1326. $s = " <tr" . $this->attributes() . ">\n";
  1327. foreach ($this->cells as $cell) {
  1328. $s .= $cell->html();
  1329. }
  1330. $s .= " </tr>\n";
  1331. // Return the HTML
  1332. return $s;
  1333. }
  1334. // ....................................................................
  1335. /** Return the CSV for this row and all its cells
  1336. * @return string The CSV rendering of the row
  1337. */
  1338. function csv() {
  1339. $s = "";
  1340. foreach ($this->cells as $cell) {
  1341. $s .= $cell->csv() . ",";
  1342. }
  1343. if ($s != "") {
  1344. $s = substr($s, 0, -1);
  1345. }
  1346. return $s;
  1347. }
  1348. } // tablerow class
  1349. // ......................................................................
  1350.  
  1351. /**
  1352. * tablegroup
  1353. * This is a virtual class which contains a group of table rows. An
  1354. * examples of this would be the <tbody></tbody> or <thead></thead>. It
  1355. * is basically an entity which contains and manages a group of rows.
  1356. *
  1357. * @package html
  1358. * @access private
  1359. */
  1360. class tablegroup extends StylableObject {
  1361. /** Table group tag, eg: 'tbody' */
  1362.  
  1363. var $tag;
  1364. /** Array containing table rows */
  1365.  
  1366. var $rows = array();
  1367. /** The most recently added cell object */
  1368.  
  1369. var $working_cell;
  1370. /** Column rowspans in effect */
  1371.  
  1372. var $colrowspans = array();
  1373. // ....................................................................
  1374. /** Tablegroup constructor
  1375. * Create a new tablegroup object.
  1376. * @param string $tag The group tag: 'tbody', 'thead' etc.
  1377. * @param string $css The style or class of the group
  1378. */
  1379. function tablegroup($tag, $css="") {
  1380. $this->tag = $tag;
  1381. $this->StylableObject($css);
  1382. }
  1383. // ....................................................................
  1384. /** Set cell permissions across entire group. An optional table name can
  1385. * be passed, which is used with identifying the cell when rendering the cells
  1386. * in th row as an editable field, to give the fields a name used in form
  1387. * submission.
  1388. * @param integer $agentids List of unique IDs of agents to assign the permission for
  1389. * @param integer $perm The permission or combination of perms to assign
  1390. */
  1391. function permit($agentids, $perm) {
  1392. for ($r = 0; $r < $this->rowcount(); $r++) {
  1393. $row = $this->rows[$r];
  1394. $row->permit($agentids, $perm, $r, $this->tag);
  1395. $this->rows[$r] = $row;
  1396. }
  1397. }
  1398. // ....................................................................
  1399. /** Set cell nbsp setting across entire group.
  1400. * @param boolean mode If true, then all cells will return "&nbsp;" if blank.
  1401. */
  1402. function setnbsp($mode=true) {
  1403. for ($r = 0; $r < $this->rowcount(); $r++) {
  1404. $row = $this->rows[$r];
  1405. $row->setnbsp($mode);
  1406. $this->rows[$r] = $row;
  1407. }
  1408. }
  1409. // ....................................................................
  1410. /**
  1411. * Return the number of rows in this group.
  1412. * @return integer The number of rows in this group
  1413. */
  1414. function rowcount() {
  1415. return count($this->rows);
  1416. }
  1417. // ....................................................................
  1418. /**
  1419. * Return the visible cellcount for a given column in the group. This
  1420. * takes account of any rowspans in effect.
  1421. * @param integer $col Number of the column to count cells in
  1422. * @return integer The visible cell count for the column
  1423. */
  1424. function visible_cellsincol($col) {
  1425. $rc = 0;
  1426. if (isset($this->rows[$col])) {
  1427. foreach ($this->rows as $row) {
  1428. if (isset($row->cells[$col])) {
  1429. $cell = $row->cells[$col];
  1430. if (!$cell->rowspanned) $rc += 1;
  1431. }
  1432. }
  1433. }
  1434. return $rc;
  1435. }
  1436. // ....................................................................
  1437. /** Create a new row
  1438. * @param string $css The style or class of the group
  1439. */
  1440. function tr($css="") {
  1441. // Take care of any pending cell first..
  1442. $this->build();
  1443. $this->insert_rowspanned_cells();
  1444. $this->rows[] = new tablerow($css);
  1445. }
  1446. // ....................................................................
  1447. /** Check the current row and add in any cells which are rowspanned
  1448. * @private
  1449. */
  1450. function insert_rowspanned_cells() {
  1451. if (count($this->colrowspans) > 0 && count($this->rows) > 0) {
  1452. $row = array_pop($this->rows);
  1453.  
  1454. $colrowspans = $this->colrowspans;
  1455. while (list($col, $span) = each($colrowspans)) {
  1456. if ($span > 0) {
  1457. $chk = $row->get_cell($col);
  1458. if (!$chk || $chk->rowspan == 1) {
  1459. $cell = new tablecell();
  1460. $cell->rowspanned = true;
  1461. $row->insert_cell($col, $cell);
  1462. $this->colrowspans[$col] -= 1;
  1463. }
  1464. }
  1465. }
  1466. array_push($this->rows, $row);
  1467. }
  1468. }
  1469. // ....................................................................
  1470. /** Build the current working cell into the row
  1471. * @access private
  1472. */
  1473. function build() {
  1474. if (isset($this->working_cell)) {
  1475. if (count($this->rows) > 0) {
  1476. $row = array_pop($this->rows);
  1477.  
  1478. // Add the working cell first..
  1479. $row->add_cell($this->working_cell);
  1480.  
  1481. // Now record any rowspan being applied..
  1482. if ($this->working_cell->rowspan > 1) {
  1483. $thecol = $row->cellcount() - 1;
  1484. $this->colrowspans[$thecol] = $this->working_cell->rowspan - 1;
  1485. }
  1486.  
  1487. // Finally, add invisible colspanned cells, if any..
  1488. if ($this->working_cell->colspan > 1) {
  1489. $cell = new tablecell();
  1490. $cell->colspanned = true;
  1491. $row->append_cells($this->working_cell->colspan - 1, $cell);
  1492. }
  1493. array_push($this->rows, $row);
  1494. }
  1495. unset($this->working_cell);
  1496. }
  1497. }
  1498. // ....................................................................
  1499. /** Create a new standard cell for the row
  1500. * @param string $content Content to poke into the cell
  1501. * @param string $css Cell css setting, or omit to not set it.
  1502. * @param boolean $heading Whether it is a 'heading' cell or not
  1503. */
  1504. function td($content="", $css="", $heading=false) {
  1505. // Take care of any pending cell..
  1506. $this->build();
  1507. if ($heading) {
  1508. $this->working_cell = new headingcell($content, $css);
  1509. }
  1510. else {
  1511. $this->working_cell = new tablecell($content, $css);
  1512. }
  1513. }
  1514. // ....................................................................
  1515. /** Create a new heading cell for the row
  1516. * @param string $content Content to poke into the cell
  1517. * @param string $css Cell css setting, or omit to not set it.
  1518. */
  1519. function th($content="", $css="") {
  1520. $this->td($content, $css, true);
  1521. }
  1522. // ....................................................................
  1523. /** Clear the content from all rows in the group. */
  1524.  
  1525. function clearcontent() {
  1526. for ($r = 0; $r < $this->rowcount(); $r++) {
  1527. $row = $this->rows[$r];
  1528. $row->clearcontent();
  1529. $this->rows[$r] = $row;
  1530. }
  1531. }
  1532. // ....................................................................
  1533. /** Set the working cell style/class properties
  1534. * @param string $css Cell css setting, or omit to not set it.
  1535. */
  1536. function td_css($css="") {
  1537. $this->working_cell->setcss($css);
  1538. }
  1539. // ....................................................................
  1540. /** Set the working cell content style or class.
  1541. * @param string $css Content css setting, or omit to not set it.
  1542. */
  1543. function td_contentcss($css="") {
  1544. $this->working_cell->content->setcss($css);
  1545. }
  1546. // ....................................................................
  1547. /** Append to the working cell content
  1548. * @param string $text Cell text content
  1549. * @param string $css Cell css setting, or omit to not set it.
  1550. */
  1551. function td_content($text="", $css="") {
  1552. $this->working_cell->addcontent($text);
  1553. $this->working_cell->setcss($css);
  1554. }
  1555. // ....................................................................
  1556. /** Set the working cell alignment properties */
  1557.  
  1558. function td_alignment($align="", $valign="") {
  1559. $this->working_cell->setalignment($align, $valign);
  1560. }
  1561. // ....................................................................
  1562. /** Set the working cell size properties */
  1563.  
  1564. function td_metrics($width="", $height="") {
  1565. $this->working_cell->setmetrics($width, $height);
  1566. }
  1567. // ....................................................................
  1568. /** Set the working cell width property */
  1569.  
  1570. function td_width($width="") {
  1571. $this->working_cell->setwidth($width);
  1572. }
  1573. // ....................................................................
  1574. /** Set the working cell height property */
  1575.  
  1576. function td_height($height="") {
  1577. $this->working_cell->setheight($height);
  1578. }
  1579. // ....................................................................
  1580. /** Set the working cell colspan property */
  1581.  
  1582. function td_colspan($span=1) {
  1583. $this->working_cell->setcolspan($span);
  1584. }
  1585. // ....................................................................
  1586. /** Set the working cell rowspan property */
  1587.  
  1588. function td_rowspan($span=1) {
  1589. $this->working_cell->setrowspan($span);
  1590. }
  1591. // ....................................................................
  1592. /** Poke content into the given cell in this group
  1593. * @param integer $row Row that the column is in
  1594. * @param integer $col Column/cell in row to poke content into
  1595. * @param string $content Cell content to poke into the cell
  1596. * @param string $css Cell css setting, or omit to not set it.
  1597. * @param string $contentcss Cell content css setting, or omit to not set it.
  1598. */
  1599. function poke_cell($row, $col, $content, $css="", $contentcss="") {
  1600. $rc = false;
  1601. if (isset($this->rows[$row])) {
  1602. $r = $this->rows[$row];
  1603. $rc = $r->poke_cell($col, $content, $css, $contentcss);
  1604. $this->rows[$row] = $r;
  1605. }
  1606. return $rc;
  1607. }
  1608. // ....................................................................
  1609. /** Autojustify all rows in this group */
  1610.  
  1611. function autojustify() {
  1612. for ($r = 0; $r < $this->rowcount(); $r++) {
  1613. $row = $this->rows[$r];
  1614. $row->autojustify();
  1615. $this->rows[$r] = $row;
  1616. }
  1617. }
  1618. // ....................................................................
  1619. /** Poke css onto the given cell in this group
  1620. * @param integer $row Row that the column is in
  1621. * @param integer $col Column/cell in row to apply css to
  1622. * @param string $css Cell css setting.
  1623. * @param string $contentcss Cell content css setting, or omit to not set it.
  1624. */
  1625. function poke_cellcss($row, $col, $css, $contentcss="") {
  1626. $rc = false;
  1627. if (isset($this->rows[$row])) {
  1628. $r = $this->rows[$row];
  1629. $rc = $r->poke_cellcss($col, $css, $contentcss);
  1630. $this->rows[$row] = $r;
  1631. }
  1632. return $rc;
  1633. }
  1634. // ....................................................................
  1635. /** Peek content from the given cell in this group */
  1636.  
  1637. function peek_cell($row, $col) {
  1638. $rc = "";
  1639. if (isset($this->rows[$row])) {
  1640. $r = $this->rows[$row];
  1641. $rc = $r->peek_cell($col);
  1642. }
  1643. return $rc;
  1644. }
  1645. // ....................................................................
  1646. /** Return the given cell from this group */
  1647.  
  1648. function get_cell($row, $col) {
  1649. $cell = false;
  1650. if (isset($this->rows[$row])) {
  1651. $r = $this->rows[$row];
  1652. $cell = $r->get_cell($col);
  1653. }
  1654. return $cell;
  1655. }
  1656. // ....................................................................
  1657. /** Replace the given cell with new table cell. Returns true if ok. */
  1658.  
  1659. function set_cell($row, $col, $cell) {
  1660. $rc = false;
  1661. if (isset($this->rows[$row])) {
  1662. $r = $this->rows[$row];
  1663. $rc = $r->set_cell($col, $cell);
  1664. $this->rows[$row] = $r;
  1665. }
  1666. return $rc;
  1667. }
  1668. // ....................................................................
  1669. /** Apply a rowspan. The anchor row,col are given, and the rowspan. */
  1670.  
  1671. function merge_rows($row, $col, $span) {
  1672. $therow = $this->rows[$row];
  1673. $cell = $therow->cells[$col];
  1674. $oldspan = $cell->rowspan;
  1675. $newspan = $oldspan + $span - 1;
  1676. $spancount = $newspan - $oldspan;
  1677. $colspan = $cell->colspan;
  1678. $cell->setrowspan($newspan);
  1679. $therow->cells[$col] = $cell;
  1680. $this->rows[$row] = $therow;
  1681. for ($c = $col; $c < $col + $colspan; $c++) {
  1682. for ($i = 0; $i < $spancount; $i++) {
  1683. $r = $row + $i + $oldspan;
  1684. if (isset($this->rows[$r])) {
  1685. $therow = $this->rows[$r];
  1686. $therow->span("row", $c);
  1687. $this->rows[$r] = $therow;
  1688. }
  1689. }
  1690. }
  1691. }
  1692. // ....................................................................
  1693. /** Apply row-spanning to a number of rows. */
  1694.  
  1695. function span_rows($row, $col, $spancount) {
  1696. for ($r = $row; $r < $spancount + $row; $r++) {
  1697. if (isset($this->rows[$r])) {
  1698. $therow = $this->rows[$r];
  1699. if (isset($therow->cells[$col])) {
  1700. $cell = $therow->cells[$col];
  1701. $cell->span("row", $c);
  1702. $therow->cells[$col] = $cell;
  1703. }
  1704. $this->rows[$r] = $therow;
  1705. }
  1706. }
  1707. }
  1708. // ....................................................................
  1709. /** Remove a rowspan. The anchor row,col are given of the existing span. */
  1710.  
  1711. function split_rows($row, $col) {
  1712. $newrows = $this->rows;
  1713. if (isset($newrows[$row])) {
  1714. $therow = $newrows[$row];
  1715. if (isset($therow->cells[$col])) {
  1716. $cell = $therow->cells[$col];
  1717. $span = $cell->rowspan;
  1718. $colspan = $cell->colspan;
  1719. if ($span > 1) {
  1720. $cell->setrowspan(1);
  1721. $therow->cells[$col] = $cell;
  1722. $newrows[$row] = $therow;
  1723. for ($c = $col; $c < $col + $colspan; $c++) {
  1724. for ($r = $row + 1; $r < $row + $span; $r++) {
  1725. if (isset($newrows[$r])) {
  1726. $therow = $newrows[$r];
  1727. $therow->unspan("row", $c);
  1728. $newrows[$r] = $therow;
  1729. }
  1730. }
  1731. }
  1732. $this->rows = $newrows;
  1733. }
  1734. }
  1735. }
  1736. }
  1737. // ....................................................................
  1738. /**
  1739. * Apply a colspan. The row and column of the cell which has the
  1740. * colspan is given. As a result the relevant spanned cells will be
  1741. * removed from the table. If the span goes beyond the row end,
  1742. * it is truncated.
  1743. */
  1744. function merge_cols($row, $col, $span) {
  1745. if (isset($this->rows[$row])) {
  1746. $r = $this->rows[$row];
  1747. $thecell = $r->cells[$col];
  1748. $rowspan = $thecell->rowspan;
  1749. $r->merge_cols($col, $span);
  1750. $this->rows[$row] = $r;
  1751. if ($rowspan > 1) {
  1752. for ($r = $row + 1; $r < $rowspan + $row; $r++) {
  1753. if (isset($this->rows[$r])) {
  1754. $therow = $this->rows[$r];
  1755. $therow->span_cols($col + 1, $span - 1);
  1756. $this->rows[$r] = $therow;
  1757. }
  1758. }
  1759. }
  1760. }
  1761. }
  1762. // ....................................................................
  1763. /**
  1764. * Remove spanning from a colspanned set of cells. This will effectively
  1765. * set the colspan of the orgin cell to 1, and insert new cells after
  1766. * it to make up the difference and maintain the original colcount.
  1767. */
  1768. function split_cols($row, $col) {
  1769. if (isset($this->rows[$row])) {
  1770. $r = $this->rows[$row];
  1771. $r->split_cols($col);
  1772. $this->rows[$row] = $r;
  1773. }
  1774. }
  1775. // ....................................................................
  1776. /** Insert a column into all rows in the group. */
  1777.  
  1778. function insert_cols($col, $celltoinsert=false) {
  1779. for ($r = 0; $r < $this->rowcount(); $r++) {
  1780. $row = $this->rows[$r];
  1781. $row->insert_cell($col, $celltoinsert);
  1782. $this->rows[$r] = $row;
  1783. }
  1784. }
  1785. // ....................................................................
  1786. /** Append columns onto all rows in the group. */
  1787.  
  1788. function append_cols($repeat=1, $celltoappend=false) {
  1789. for ($r = 0; $r < $this->rowcount(); $r++) {
  1790. $row = $this->rows[$r];
  1791. $row->append_cells($repeat, $celltoappend);
  1792. $this->rows[$r] = $row;
  1793. }
  1794. }
  1795. // ....................................................................
  1796. /** Remove a column from all rows in the group. */
  1797.  
  1798. function delete_cols($col) {
  1799. for ($r = 0; $r < $this->rowcount(); $r++) {
  1800. $row = $this->rows[$r];
  1801. $row->delete_cell($col);
  1802. $this->rows[$r] = $row;
  1803. }
  1804. }
  1805. // ....................................................................
  1806. /** Return a given row from the group. */
  1807.  
  1808. function get_row($row) {
  1809. $therow = false;
  1810. if (isset($this->rows[$row])) {
  1811. $therow = $this->rows[$row];
  1812. }
  1813. return $therow;
  1814. }
  1815. // ....................................................................
  1816. /** Delete a row from the group. */
  1817.  
  1818. function delete_row($row) {
  1819. if (isset($this->rows[$row]) && $this->rowcount() > 0) {
  1820. $newrows = array();
  1821. $r = 0;
  1822. foreach ($this->rows as $therow) {
  1823. if ($r == $row) {
  1824. // Scan this row for rowspans
  1825. $c = 0;
  1826. foreach ($therow->cells as $cell) {
  1827. if ($cell->rowspanned) {
  1828. for ($i = $r - 1; $i >= 0; $i--) {
  1829. $prevrow = $newrows[$i];
  1830. $prevcell = $prevrow->get_cell($c);
  1831. if (!$prevcell->rowspanned) {
  1832. $prevcell->rowspan -= 1;
  1833. $prevrow->set_cell($c, $prevcell);
  1834. $newrows[$i] = $prevrow;
  1835. break;
  1836. }
  1837. }
  1838. }
  1839. elseif ($cell->rowspan > 1) {
  1840. if (isset($this->rows[$r + 1])) {
  1841. $nextrow = $this->rows[$r + 1];
  1842. $nextcell = $nextrow->get_cell($c);
  1843. $nextcell->rowspanned = false;
  1844. $nextcell->rowspan = $cell->rowspan - 1;
  1845. $nextrow->set_cell($c, $nextcell);
  1846. $this->rows[$r + 1] = $nextrow;
  1847. }
  1848. }
  1849. $c += 1;
  1850. } // foreach
  1851. }
  1852. else {
  1853. $newrows[] = $therow;
  1854. }
  1855. $r += 1;
  1856. } // foreach
  1857. // Establish the new set of rows..
  1858. $this->rows = $newrows;
  1859. }
  1860. }
  1861. // ....................................................................
  1862. /**
  1863. * Insert a row into the table. If the template cell is not provided,
  1864. * then a 'vanilla' cell is used instead. We insert the new row just
  1865. * before the given row.
  1866. * @param integer $row Row position to insert before, in the table
  1867. * @param object $celltoinsert Template cell to use for all row cells
  1868. */
  1869. function insert_row($row, $celltoinsert=false) {
  1870. if ($this->rowcount() == 0) {
  1871. $this->append_row($celltoinsert);
  1872. }
  1873. else {
  1874. $newrow = new tablerow();
  1875. $arow = $this->rows[0];
  1876. $cnt = $arow->cellcount();
  1877. $newrow->append_cells($cnt, $celltoinsert);
  1878. $newrows = array();
  1879. $r = 0;
  1880. foreach ($this->rows as $therow) {
  1881. if ($r == $row) {
  1882. // Scan this row for rowspans
  1883. $c = 0;
  1884. foreach ($therow->cells as $cell) {
  1885. if ($cell->rowspanned) {
  1886. $newcell = $newrow->get_cell($c);
  1887. $newcell->rowspanned = true;
  1888. $newrow->set_cell($c, $newcell);
  1889. for ($i = $r - 1; $i >= 0; $i--) {
  1890. $prevrow = $newrows[$i];
  1891. if (is_object($prevrow)) {
  1892. $prevcell = $prevrow->get_cell($c);
  1893. if (!$prevcell->rowspanned) {
  1894. $prevcell->rowspan += 1;
  1895. $prevrow->set_cell($c, $prevcell);
  1896. $newrows[$i] = $prevrow;
  1897. break;
  1898. }
  1899. }
  1900. }
  1901. }
  1902. $c += 1;
  1903. } // foreach
  1904. // Insert new row..
  1905. $newrows[] = $newrow;
  1906. }
  1907. // Insert existing row..
  1908. $newrows[] = $therow;
  1909. $r += 1;
  1910. } // foreach
  1911. // Establish the new set of rows..
  1912. $this->rows = $newrows;
  1913. }
  1914. }
  1915. // ....................................................................
  1916. /** Append a row onto the group. */
  1917.  
  1918. function append_row($celltoappend=false) {
  1919. if ($this->rowcount() > 0) {
  1920. $lastrow = $this->rows[$this->rowcount() - 1];
  1921. $cnt = $lastrow->colcount();
  1922. }
  1923. else {
  1924. $cnt = 1;
  1925. }
  1926. $newrow = new tablerow();
  1927. $newrow->append_cells($cnt, $celltoappend);
  1928. $this->rows[] = $newrow;
  1929. }
  1930. // ....................................................................
  1931. /** Set a width profile across the row of cells
  1932. * @param array $prof Array of widths defining the profile
  1933. */
  1934. function set_width_profile($prof) {
  1935. for ($r = 0; $r < $this->rowcount(); $r++) {
  1936. $row = $this->rows[$r];
  1937. $row->set_width_profile($prof);
  1938. $this->rows[$r] = $row;
  1939. }
  1940. }
  1941. // ....................................................................
  1942. /** Return the width profile for this group.
  1943. * @return array Returned array of profile widths
  1944. */
  1945. function get_width_profile() {
  1946. $prof = array();
  1947. if (isset($this->rows)) {
  1948. foreach ($this->rows as $row) {
  1949. $prof = $row->get_width_profile();
  1950. if (count($prof) > 0) {
  1951. break;
  1952. }
  1953. }
  1954. }
  1955. return $prof;
  1956. }
  1957. // ....................................................................
  1958. /**
  1959. * Apply row-stripes to the rows in this group. The parameter
  1960. * passed in is a delimited string list OR array of classes or
  1961. * styles to apply to the rows.
  1962. *
  1963. * @param mixed $csslist Array OR delimited list of styles or classnames
  1964. * @param string $delim Optional delimiter char, defaults to a comma
  1965. */
  1966. function apply_rowstripes($csslist, $delim=",") {
  1967. if (!is_array($csslist)) {
  1968. $csslist = explode($delim, $csslist);
  1969. }
  1970. $totrows = $this->rowcount();
  1971. $totcss = count($csslist);
  1972. if ($totcss > 0 && $totrows > 0) {
  1973. $cssix = 0;
  1974. for ($r = 0; $r < $totrows; $r++) {
  1975. $css = $csslist[$cssix];
  1976. $row = $this->rows[$r];
  1977. $s = (isset($row->class)) ? $row->class : "";
  1978. $s .= (isset($row->style)) ? $row->style : "";
  1979. if ($css != "" && !strstr($s, $css)) {
  1980. $row->setcss($css);
  1981. $this->rows[$r] = $row;
  1982. }
  1983. $cssix += 1;
  1984. if ($cssix >= $totcss) $cssix = 0;
  1985. }
  1986. }
  1987. }
  1988. // ....................................................................
  1989. /**
  1990. * Return the HTML for this group.
  1991. * @return string HTML rendering for this group of rows.
  1992. */
  1993. function html() {
  1994. // Take care of any pending stuff..
  1995. $this->build();
  1996. $this->insert_rowspanned_cells();
  1997. // $row = array_pop($this->rows);
  1998. // array_push($this->rows, $row);
  1999.  
  2000. // Render all rows inside tag..
  2001. $s = "";
  2002. $s .= " <$this->tag";
  2003. $s .= $this->style_attributes();
  2004. $s .= ">\n";
  2005. foreach ($this->rows as $row) {
  2006. if (is_object($row)) {
  2007. $s .= $row->html();
  2008. }
  2009. }
  2010. $s .= " </$this->tag>\n";
  2011. // Return the HTML..
  2012. return $s;
  2013. }
  2014.  
  2015. // ....................................................................
  2016. /**
  2017. * Return the CSV for this group.
  2018. * @return string CSV rendering for this group of rows.
  2019. */
  2020. function csv() {
  2021. // Take care of any pending stuff..
  2022. $this->build();
  2023. $this->insert_rowspanned_cells();
  2024. $s = "";
  2025. foreach ($this->rows as $row) {
  2026. if (is_object($row)) {
  2027. $s .= $row->csv() . "\n";
  2028. }
  2029. }
  2030. // Return the CSV..
  2031. return $s;
  2032. }
  2033. } // tablegroup class
  2034. // ......................................................................
  2035.  
  2036. /**
  2037. * Table.
  2038. * A table is a container of tablegroups. Tablegroups are in turn
  2039. * containers of table rows, and table rows contain table cells.
  2040. *
  2041. * This class is predicated on the idea that tables will be built bit
  2042. * by bit, in a sequential manner by Php code. That is to say, you will
  2043. * be looping through adding to the table structure and content, row
  2044. * by row, and within each row, cell by cell.
  2045. *
  2046. * Here's an example of usage. Copy and paste into a test page in order
  2047. * to view the result and see how it works.
  2048. *
  2049. * $mytable = new table("test");
  2050. * $mytable->autojustify();
  2051. * $mytable->rowstripes("background-color:#dddddd;,background-color:#efefef;");
  2052. * $mytable->setalign("center");
  2053. * $mytable->setwidth("70%");
  2054. * $mytable->setborder(1);
  2055. * $mytable->thead();
  2056. * $mytable->tr();
  2057. * $mytable->th("Heading 1");
  2058. * $mytable->th("Heading 2", "text-align:right");
  2059. * $mytable->th("Heading 3");
  2060. * $mytable->tbody();
  2061. * $mytable->tr();
  2062. * $mytable->td("Rowspan Text");
  2063. * $mytable->td_rowspan(2);
  2064. * $mytable->td("1234");
  2065. * $mytable->td("Text");
  2066. * $mytable->tr();
  2067. * $mytable->td("Text");
  2068. * $mytable->td("1234");
  2069. * $mytable->tr();
  2070. * $mytable->td("Text");
  2071. * $mytable->td("Text");
  2072. * $mytable->td("Text");
  2073. * $mytable->tr();
  2074. * $mytable->td("Colspan Text");
  2075. * $mytable->td_colspan(3);
  2076. * @package html
  2077. */
  2078. class table extends HTMLObject {
  2079. // Public
  2080. /** Tablename. Required. An internal name for use in debugging etc. */
  2081.  
  2082. var $tablename = "";
  2083. /** Padding of cells in pixels */
  2084.  
  2085. var $cellpadding = 0;
  2086. /** Spacing between cells in pixels */
  2087.  
  2088. var $cellspacing = 0;
  2089. /** Auto-justify numerics to the right, text to the left */
  2090.  
  2091. var $autojustify = false;
  2092.  
  2093. // Private
  2094. /** Array containing table groups
  2095. @access private */
  2096. var $groups = array();
  2097. /**
  2098. * Array containing css definitions for row striping. Rows
  2099. * will have the css applied repeatedly. Any number of css
  2100. * definitions can be added to the array. These can be either
  2101. * classnames or styles, or a mixture of both.
  2102. * @access private
  2103. */
  2104. var $rowstripes = array();
  2105. // ....................................................................
  2106. /** Table constructor
  2107. * Create a new table object.
  2108. * @param string $tablename A required name string to identify this table.
  2109. * @param string $css The style or classname to apply to the object.
  2110. */
  2111. function table($tablename="", $css="") {
  2112. $this->HTMLObject($css);
  2113. $this->setwidth("100%");
  2114. $this->setborder(0);
  2115. $this->tablename = $tablename;
  2116. }
  2117. // ....................................................................
  2118. /** Set cell permissions across entire table
  2119. * @param integer $agentids List of unique IDs of agents to assign the permission for
  2120. * @param integer $perm The permission or combination of perms to assign
  2121. */
  2122. function permit($agentids, $perm) {
  2123. foreach ($this->groups as $gp) {
  2124. $gpix = $this->get_group_index($gp->tag);
  2125. $gp->permit($agentids, $perm);
  2126. $this->groups[$gpix] = $gp;
  2127. }
  2128. }
  2129. // ....................................................................
  2130. /** Set nbsp setting for cells in this table
  2131. * @param boolean mode If true, then all cells will return "&nbsp;" if blank.
  2132. */
  2133. function setnbsp($mode=true) {
  2134. foreach ($this->groups as $gp) {
  2135. $gpix = $this->get_group_index($gp->tag);
  2136. $gp->setnbsp($mode);
  2137. $this->groups[$gpix] = $gp;
  2138. }
  2139. }
  2140. // ....................................................................
  2141. /**
  2142. * Return the number of rows in this table.
  2143. * @return integer The number of rows in the table.
  2144. */
  2145. function rowcount() {
  2146. $tot = 0;
  2147. foreach ($this->groups as $group) {
  2148. $tot += $group->rowcount();
  2149. }
  2150. return $tot;
  2151. }
  2152. // ....................................................................
  2153. /**
  2154. * Return the number of cols in this table.
  2155. * This is the number of columns, rather than physical cells, any of
  2156. * which may be spanning multiple columns. In the case of a table which
  2157. * is not properly formatted, this function will return the maximum
  2158. * columns it finds by looking across all of the table rows.
  2159. * @return integer The number of columns in the table.
  2160. */
  2161. function colcount() {
  2162. $tot = 0;
  2163. if (isset($this->groups[0])) {
  2164. $g = $this->groups[0];
  2165. if (isset($g->rows[0])) {
  2166. $r = $g->rows[0];
  2167. $tot = $r->cellcount();
  2168. }
  2169. }
  2170. return $tot;
  2171. }
  2172. // ....................................................................
  2173. /**
  2174. * Return the number of cells in a specific row.
  2175. * This is the number of physical cells, rather than the number of logical
  2176. * number of columns. It should be the same as the colcount() method if
  2177. * the table is properly formatted.
  2178. * @param integer $row The row that the cell is in (0 = first row)
  2179. * @param string $group The group to find the rows
  2180. * @return integer The number of cells in the row.
  2181. */
  2182. function cellcount($row=0, $group="tbody") {
  2183. $rc = 0;
  2184. $gpix = $this->get_group_index($group);
  2185. if ($gpix != -1) {
  2186. $gp = $this->groups[$gpix];
  2187. if (isset($gp->rows[$row])) {
  2188. $r = $gp->rows[$row];
  2189. $rc = $r->cellcount();
  2190. }
  2191. }
  2192. return $rc;
  2193. }
  2194. // ....................................................................
  2195. /**
  2196. * Return the number of visible cells in a specific row.
  2197. * This is the number of viewed cells, rather than the number of physical
  2198. * columns. Ie. if there is a colspan of 2, then only 1 cell will be
  2199. * counted for it, since only one cell appears in the rendered table.
  2200. * @param integer $row The row that the cell is in (0 = first row)
  2201. * @param string $group The group to find the rows
  2202. * @return integer The number of visible cells in the row.
  2203. */
  2204. function visible_cellsinrow($row, $group="tbody") {
  2205. $rc = 0;
  2206. $gpix = $this->get_group_index($group);
  2207. if ($gpix != -1) {
  2208. $gp = $this->groups[$gpix];
  2209. if (isset($gp->rows[$row])) {
  2210. $r = $gp->rows[$row];
  2211. $rc = $r->visible_cellsinrow();
  2212. }
  2213. }
  2214. return $rc;
  2215. }
  2216. // ....................................................................
  2217. /**
  2218. * Return the number of visible cells in a specific column.
  2219. * This is the number of viewed cells, rather than the number of physical
  2220. * cells. Ie. if there is a rowspan of 2, then only 1 cell will be
  2221. * counted for it, since only one cell appears in the rendered table.
  2222. * @return integer The number of visible cells in the given column.
  2223. */
  2224. function visible_cellsincol($col, $group="tbody") {
  2225. $rc = 0;
  2226. $gpix = $this->get_group_index($group);
  2227. if ($gpix != -1) {
  2228. $gp = $this->groups[$gpix];
  2229. $rc = $gp->visible_cellsincol($col);
  2230. }
  2231. return $rc;
  2232. }
  2233. // ....................................................................
  2234. /**
  2235. * Clear the content from all rows in table. This sets the content of
  2236. * every cell in every row in every group to nullstring.
  2237. */
  2238. function clearcontent() {
  2239. foreach ($this->groups as $gp) {
  2240. $gpix = $this->get_group_index($gp->tag);
  2241. $gp->clearcontent();
  2242. $this->groups[$gpix] = $gp;
  2243. }
  2244. }
  2245. // ....................................................................
  2246. /**
  2247. * Set the table padding and spacing amounts. This sets the table
  2248. * 'cellpadding' and 'cellspacing' attributes, in that order.
  2249. * @param integer $pad Amount of cellpadding in pixels
  2250. * @param integer $space Amount of cellspacing in pixels
  2251. */
  2252. function setpadding($pad=0, $space=0) {
  2253. $this->cellpadding = $pad;
  2254. $this->cellspacing = $space;
  2255. }
  2256. // ....................................................................
  2257. /**
  2258. * Close the current group if need be. This just makes sure that the
  2259. * current group stores the working cell in its $rows array.
  2260. * @access private
  2261. */
  2262. function close_group() {
  2263. if (count($this->groups) > 0) {
  2264. $group = array_pop($this->groups);
  2265. $group->build();
  2266. array_push($this->groups, $group);
  2267. }
  2268. }
  2269. // ....................................................................
  2270. /**
  2271. * Define a new table group. A group is simply a container of table
  2272. * rows. We recognize three different kinds of group: 'thead', 'tbody',
  2273. * and 'tfoot'.
  2274. * @param string $tag Type of group: 'thead', 'tbody' or 'tfoot'.
  2275. * @param string $css Style or classname to use for the group.
  2276. * @access private
  2277. */
  2278. function new_group($tag, $css="") {
  2279. $this->close_group();
  2280. $this->groups[] = new tablegroup($tag, $css);
  2281. }
  2282. // ....................................................................
  2283. /**
  2284. * Define a new thead table group.
  2285. * @param string $css Style or classname to use for the group.
  2286. */
  2287. function thead($css="") {
  2288. $this->new_group("thead", $css);
  2289. }
  2290. // ....................................................................
  2291. /**
  2292. * Define a new tbody table group.
  2293. * @param string $css Style or classname to use for the group.
  2294. */
  2295. function tbody($css="") {
  2296. $this->new_group("tbody", $css);
  2297. }
  2298. // ....................................................................
  2299. /**
  2300. * Define a new tfoot table group.
  2301. * @param string $css Style or classname to use for the group.
  2302. */
  2303. function tfoot($css="") {
  2304. $this->new_group("tfoot", $css);
  2305. }
  2306. // ....................................................................
  2307. /**
  2308. * Check if first group is defined and if not then define tbody.
  2309. * @access private
  2310. */
  2311. function check_group() {
  2312. if (count($this->groups) == 0) {
  2313. $this->tbody();
  2314. }
  2315. }
  2316. // ....................................................................
  2317. /**
  2318. * Set table auto-justify mode on or off.
  2319. * If set to on, then when we render the table, cells will have a
  2320. * style automatically applied to justify numeric content to the right
  2321. * and non-numeric content to the left. Handy with simple data tables.
  2322. * @param bool $mode True if we should auto justify all table cells
  2323. */
  2324. function autojustify($mode=true) {
  2325. $this->autojustify = $mode;
  2326. }
  2327. // ....................................................................
  2328. /**
  2329. * Define css for row striping with comma-delimted list of css. Any
  2330. * number of these can be added to style rows in a repeating cycle.
  2331. * @param mixed $csslist Array OR delimited list of styles or classnames
  2332. * @param string $delim Optional delimiter char, defaults to a comma
  2333. */
  2334. function rowstripes($csslist, $delim=",") {
  2335. if (!is_array($csslist)) {
  2336. $csslist = explode($delim, $csslist);
  2337. }
  2338. $this->rowstripes = $csslist;
  2339. }
  2340. // ....................................................................
  2341. /**
  2342. * Check the table cell balance. Ie. make sure we have the
  2343. * same number of cells in each row, taking account of rowspan
  2344. * and of course colspan. NB: Complex mixtures of col and row
  2345. * spanning will not be coped with - this is currently a very
  2346. * simplistic algorithm, intended for fairly basic structures.
  2347. * @return boolean True if the table checks out ok, else false
  2348. */
  2349. function validate() {
  2350. $this->close_group();
  2351. $rowstats = array();
  2352. $totrows = 0;
  2353. $totcols = 0;
  2354. foreach ($this->groups as $group) {
  2355. foreach ($group->rows as $row) {
  2356. $totrows += 1;
  2357. if (is_object($row)) {
  2358. $cols = $row->colcount();
  2359. }
  2360. else $cols = 0;
  2361. if ($cols > $totcols) $totcols = $cols;
  2362. $rowstats[] = $cols;
  2363. }
  2364. }
  2365. if (debugging() && (debug_class() & DBG_TABLES)) {
  2366. if ($this->tablename != "") $name = "'$this->tablename'";
  2367. else $name = "(unnamed)";
  2368. debug("table $name validation: ($totrows rows x $totcols cols) cols by row: ", DBG_TABLES);
  2369. debug(implode(",", $rowstats), DBG_TABLES);
  2370. $first = true; $valid = true;
  2371. foreach($rowstats as $cnt) {
  2372. if ($first) {
  2373. $lastcnt = $cnt;
  2374. $first = false;
  2375. }
  2376. else {
  2377. if ($cnt != $lastcnt) $valid = false;
  2378. $lastcnt = $cnt;
  2379. }
  2380. }
  2381. if ($valid) debugbr(" valid.", DBG_TABLES);
  2382. else debugbr(" <span style='color:red'>error!</span>", DBG_TABLES);
  2383. // Return code
  2384. return $valid;
  2385. }
  2386. } // validate
  2387. // ....................................................................
  2388. /**
  2389. * Define a new row for the current group.
  2390. * @param string $css Style or classname to use for the row.
  2391. */
  2392. function tr($css="") {
  2393. static $stripe_ix = 0;
  2394. $this->check_group();
  2395. $group = array_pop($this->groups);
  2396. $group->tr($css);
  2397. array_push($this->groups, $group);
  2398. }
  2399. // ....................................................................
  2400. /**
  2401. * Define a new standard cell for the current row.
  2402. * @param string $text Content to put in the new cell.
  2403. * @param string $css Style or classname to use for the cell.
  2404. */
  2405. function td($content="", $css="", $heading=false) {
  2406. // Automatically insert row if no groups yet, and this
  2407. // will create the 'tbody' group as well..
  2408. if (count($this->groups) == 0) {
  2409. $this->tr();
  2410. }
  2411. // Deal with auto-justification if required..
  2412. $content = trim($content);
  2413.  
  2414. // Create new cell in this group..
  2415. $group = array_pop($this->groups);
  2416. $group->td($content, $css, $heading);
  2417. array_push($this->groups, $group);
  2418. }
  2419. // ....................................................................
  2420. /**
  2421. * Define a new heading cell for the current row.
  2422. * @param string $text Content to put in the new heading cell.
  2423. * @param string $css Style or classname to use for the cell.
  2424. */
  2425. function th($content="", $css="") {
  2426. // Create new cell in this group..
  2427. $group = array_pop($this->groups);
  2428. $group->td($content, $css, true);
  2429. array_push($this->groups, $group);
  2430. }
  2431. // ....................................................................
  2432. /**
  2433. * Set the working cell css properties. Use this method AFTER you have
  2434. * defined the cell with the td() method. This defines the style or
  2435. * classname to use for the cell. Note this is for the cell, rather
  2436. * than the content inside the cell.
  2437. * @param string $css Style or classname to use for the cell.
  2438. */
  2439. function td_css($css="") {
  2440. $group = array_pop($this->groups);
  2441. $group->td_css($css);
  2442. array_push($this->groups, $group);
  2443. }
  2444. // ....................................................................
  2445. /**
  2446. * Set the working cell content css properties in one hit. Use this
  2447. * method AFTER you have defined the cell with the td() method. This
  2448. * defines the style or classname to use for the cell content. This
  2449. * will be implemented using span tags.
  2450. * @param string $css Style or classname to use for the cell content.
  2451. */
  2452. function td_contentcss($css="") {
  2453. $group = array_pop($this->groups);
  2454. $group->td_contentcss($css);
  2455. array_push($this->groups, $group);
  2456. }
  2457. // ....................................................................
  2458. /**
  2459. * Append content to the working cell. Use this method AFTER you have
  2460. * defined the cell with the td() method.
  2461. * @param string $text Content to append to the current cell.
  2462. * @param string $css Style or classname to use for the cell content.
  2463. */
  2464. function td_content($text="", $css="") {
  2465. $group = array_pop($this->groups);
  2466. $group->td_content($text);
  2467. array_push($this->groups, $group);
  2468. }
  2469. // ....................................................................
  2470. /**
  2471. * Set the working cell alignment properties in one hit. Use
  2472. * this method AFTER you have defined the cell with the td() method.
  2473. * @param string $align Horizontal alignment: 'left', 'center', 'right'.
  2474. * @param string $valign Vertical alignment: 'top', 'middle', 'bottom'.
  2475. */
  2476. function td_alignment($align="", $valign="") {
  2477. $group = array_pop($this->groups);
  2478. $group->td_alignment($align, $valign);
  2479. array_push($this->groups, $group);
  2480. }
  2481. // ....................................................................
  2482. /**
  2483. * Set the working cell width and height properties in one hit. Use
  2484. * this method AFTER you have defined the cell with the td() method.
  2485. * @param string $width Number of pixels or % width of this cell.
  2486. * @param string $height Number of pixels or % height of this cell.
  2487. */
  2488. function td_metrics($width="", $height="") {
  2489. $group = array_pop($this->groups);
  2490. $group->td_metrics($width, $height);
  2491. array_push($this->groups, $group);
  2492. }
  2493. // ....................................................................
  2494. /**
  2495. * Set the working cell width property. Use this method AFTER you
  2496. * have defined the cell with the td() method.
  2497. * @param string $width Number of pixels or % width of this cell.
  2498. */
  2499. function td_width($width="") {
  2500. $group = array_pop($this->groups);
  2501. $group->td_width($width);
  2502. array_push($this->groups, $group);
  2503. }
  2504. // ....................................................................
  2505. /**
  2506. * Set the working cell height property. Use this method AFTER you
  2507. * have defined the cell with the td() method.
  2508. * @param string $height Number of pixels or % height of this cell.
  2509. */
  2510. function td_height($height="") {
  2511. $group = array_pop($this->groups);
  2512. $group->td_height($height);
  2513. array_push($this->groups, $group);
  2514. }
  2515. // ....................................................................
  2516. /**
  2517. * Set the working cell colspan property. Use this method AFTER you
  2518. * have defined the cell with the td() method.
  2519. * @param integer $span Number of columns this cell will span.
  2520. */
  2521. function td_colspan($span=1) {
  2522. $group = array_pop($this->groups);
  2523. $group->td_colspan($span);
  2524. array_push($this->groups, $group);
  2525. }
  2526. // ....................................................................
  2527. /**
  2528. * Set the working cell rowspan property. Use this method AFTER you
  2529. * have defined the cell with the td() method.
  2530. * @param integer $span Number of rows this cell will span.
  2531. */
  2532. function td_rowspan($span=1) {
  2533. $group = array_pop($this->groups);
  2534. $group->td_rowspan($span);
  2535. array_push($this->groups, $group);
  2536. }
  2537. // ....................................................................
  2538. /** Alias for td_css() */
  2539.  
  2540. function th_css($css="") { $this->td_css($css); }
  2541. /** Alias for td_contentcss() */
  2542.  
  2543. function th_contentcss($css="") { $this->td_contentcss($css); }
  2544. /** Alias for td_content() */
  2545.  
  2546. function th_content($text="", $css="") { $this->td_content($text, $css); }
  2547. /** Alias for td_alignment() */
  2548.  
  2549. function th_alignment($align="", $valign="") { $this->td_alignment($align, $valign); }
  2550. /** Alias for td_metrics() */
  2551.  
  2552. function th_metrics($width="", $height="") { $this->td_metrics($width, $height); }
  2553. /** Alias for td_width() */
  2554.  
  2555. function th_width($width="") { $this->td_width($width); }
  2556. /** Alias for td_height() */
  2557.  
  2558. function th_height($height="") { $this->td_height($height); }
  2559. /** Alias for td_colspan() */
  2560.  
  2561. function th_colspan($span="") { $this->td_colspan($span); }
  2562. /** Alias for td_rowspan() */
  2563.  
  2564. function th_rowspan($span="") { $this->td_rowspan($span); }
  2565. // ....................................................................
  2566. /**
  2567. * Return the index of the given group type.
  2568. * @param string $tag The tagname of the group to return the index of
  2569. * @return integer The index of the group type
  2570. * @access private
  2571. */
  2572. function get_group_index($tag) {
  2573. for ($gix=0; $gix < count($this->groups); $gix++) {
  2574. $gp = $this->groups[$gix];
  2575. if ($gp->tag == $tag) {
  2576. return $gix;
  2577. break;
  2578. }
  2579. }
  2580. return -1;
  2581. }
  2582. // ....................................................................
  2583. /**
  2584. * Poke some content into the given row,col cell..
  2585. * @param integer $row The row that the cell is in (0 = first row)
  2586. * @param integer $col The column that the cell is in
  2587. * @param string $content The content to put in the cell
  2588. * @param string $css Cell css setting, or omit to not set it.
  2589. * @param string $contentcss Cell content css setting, or omit to not set it.
  2590. * @param string $group The group to find the rows
  2591. * @return bool True if cell exists and was poked with the content
  2592. */
  2593. function poke_cell($row, $col, $content, $css="", $contentcss="", $group="tbody") {
  2594. $rc = false;
  2595. $gpix = $this->get_group_index($group);
  2596. if ($gpix != -1) {
  2597. $gp = $this->groups[$gpix];
  2598. $rc = $gp->poke_cell($row, $col, $content, $css, $contentcss);
  2599. $this->groups[$gpix] = $gp;
  2600. }
  2601. return $rc;
  2602. }
  2603. // ....................................................................
  2604. /**
  2605. * Poke a css class/style onto the given row,col cell..
  2606. * @param integer $row The row that the cell is in (0 = first row)
  2607. * @param integer $col The column that the cell is in
  2608. * @param string $css The class or style to put on the cell
  2609. * @param string $contentcss Cell content css setting, or omit to not set it.
  2610. * @param string $group The group to find the rows
  2611. * @return bool True if cell exists and was poked with the css
  2612. */
  2613. function poke_cellcss($row, $col, $css, $contentcss="", $group="tbody") {
  2614. $rc = false;
  2615. $gpix = $this->get_group_index($group);
  2616. if ($gpix != -1) {
  2617. $gp = $this->groups[$gpix];
  2618. $rc = $gp->poke_cellcss($row, $col, $css, $contentcss);
  2619. $this->groups[$gpix] = $gp;
  2620. }
  2621. return $rc;
  2622. }
  2623. // ....................................................................
  2624. /**
  2625. * Peek content from the given row,col cell..
  2626. * @param integer $row The row that the cell is in (0 = first row)
  2627. * @param integer $col The column that the cell is in
  2628. * @param string $group The group to find the rows
  2629. * @return string The cell contents, or nullstring if none/not valid
  2630. */
  2631. function peek_cell($row, $col, $group="tbody") {
  2632. $rc = "";
  2633. $gpix = $this->get_group_index($group);
  2634. if ($gpix != -1) {
  2635. $gp = $this->groups[$gpix];
  2636. $rc = $gp->peek_cell($row, $col);
  2637. }
  2638. return $rc;
  2639. }
  2640. // ....................................................................
  2641. /**
  2642. * Return the given cell from this group
  2643. * @param integer $row The row that the cell is in (0 = first row)
  2644. * @param integer $col The column that the cell is in (0 = first cell)
  2645. * @param string $group The group to find the rows
  2646. * @return string The table cell object, or false if none/not valid
  2647. */
  2648. function get_cell($row, $col, $group="tbody") {
  2649. $cell = false;
  2650. $gpix = $this->get_group_index($group);
  2651. if ($gpix != -1) {
  2652. $gp = $this->groups[$gpix];
  2653. $cell = $gp->get_cell($row, $col);
  2654. }
  2655. return $cell;
  2656. }
  2657. // ....................................................................
  2658. /**
  2659. * Replace the given cell with new table cell. Returns true if ok.
  2660. * @param integer $row The row that the cell is in (0 = first row)
  2661. * @param integer $col The column that the cell is in
  2662. * @param object $cell The new replacement table cell object
  2663. * @param string $group The group to find the rows
  2664. */
  2665. function set_cell($row, $col, $cell, $group="tbody") {
  2666. $rc = false;
  2667. $gpix = $this->get_group_index($group);
  2668. if ($gpix != -1) {
  2669. $gp = $this->groups[$gpix];
  2670. $rc = $gp->set_cell($row, $col, $cell);
  2671. $this->groups[$gpix] = $gp;
  2672. }
  2673. return $rc;
  2674. }
  2675. // ....................................................................
  2676. /**
  2677. * Check if given cell exists, return True is it does.
  2678. * @param integer $row The row that the cell is in (0 = first row)
  2679. * @param integer $col The column that the cell is in
  2680. * @param string $group The group to find the rows
  2681. * @return bool True if given cell exists, else false.
  2682. */
  2683. function cell_exists($row, $col, $group="tbody") {
  2684. $rc = false;
  2685. $gpix = $this->get_group_index($group);
  2686. if ($gpix != -1) {
  2687. $gp = $this->groups[$gpix];
  2688. if (isset($gp->rows[$row])) {
  2689. $r = $gp->rows[$row];
  2690. $rc = isset($r->cells[$col]);
  2691. }
  2692. }
  2693. return $rc;
  2694. }
  2695. // ....................................................................
  2696. /**
  2697. * Set permission on given table cell. Optionally specify the group
  2698. * which is being targetted (default table body). The specified cell
  2699. * will have its access permission set to the given perm.
  2700. * @param integer $row The row that the cell is in (0 = first row)
  2701. * @param integer $col The column that the cell is in
  2702. * @param integer $agentids List of unique IDs of agents to assign the permission for
  2703. * @param integer $perm The permission of combination of perms to assign
  2704. * @param string $group The group the cell is found in (defaults to table body)
  2705. */
  2706. function permit_cell($row, $col, $agentids, $perm, $group="tbody") {
  2707. if ($this->cell_exists($row, $col)) {
  2708. $cell = $this->get_cell($row, $col, $group);
  2709. $cell->permit($agentids, $perm);
  2710. $cell->cellid = "_tcell|$row|$col|$group";
  2711. $this->set_cell($row, $col, $cell, $group);
  2712. }
  2713. }
  2714. // ....................................................................
  2715. /**
  2716. * Unset permission on given table cell. Optionally specify the group
  2717. * which is being targetted (default table body). The specified cell
  2718. * will have its access permission unset from the given perms.
  2719. * @param integer $row The row that the cell is in (0 = first row)
  2720. * @param integer $col The column that the cell is in
  2721. * @param integer $agentids List of unique IDs of agents to unassign the permission for
  2722. * @param integer $perm The permission of combination of perms to unassign
  2723. * @param string $group The group the cell is found in (defaults to table body)
  2724. */
  2725. function unpermit_cell($row, $col, $agentids, $perm, $group="tbody") {
  2726. if ($this->cell_exists($row, $col)) {
  2727. $cell = $this->get_cell($row, $col, $group);
  2728. $cell->unpermit($agentids, $perm);
  2729. $cell->cellid = "_tcell|$row|$col|$group";
  2730. $this->set_cell($row, $col, $cell, $group);
  2731. }
  2732. }
  2733. // ....................................................................
  2734. /**
  2735. * Merge rows at a given cell column.
  2736. * @param integer $row The anchor row for the row merge to begin
  2737. * @param integer $col The column for the row merge
  2738. * @param integer $span The number of rows to merge
  2739. * @param string $group The group to merge rows in
  2740. */
  2741. function merge_rows($row, $col, $span, $group="tbody") {
  2742. $gpix = $this->get_group_index($group);
  2743. if ($gpix != -1) {
  2744. $gp = $this->groups[$gpix];
  2745. $gp->merge_rows($row, $col, $span);
  2746. $this->groups[$gpix] = $gp;
  2747. }
  2748. }
  2749. // ....................................................................
  2750. /**
  2751. * Split rows at a given cell column.
  2752. * @param integer $row The anchor row for the row split to begin
  2753. * @param integer $col The column for the row split
  2754. * @param string $group The group to split rows in
  2755. */
  2756. function split_rows($row, $col, $group="tbody") {
  2757. $gpix = $this->get_group_index($group);
  2758. if ($gpix != -1) {
  2759. $gp = $this->groups[$gpix];
  2760. $gp->split_rows($row, $col);
  2761. $this->groups[$gpix] = $gp;
  2762. }
  2763. }
  2764. // ....................................................................
  2765. /**
  2766. * Apply a colspan in an existing table. The row and column of the
  2767. * cell which has the colspan is given. As a result the relevant
  2768. * spanned cells will be merged in the table. If the span goes
  2769. * beyond the row end, it is truncated. NB: If the spanning cell
  2770. * is already spanning cells, then the span will extend this by the
  2771. * number given.
  2772. * @param integer $row The anchor row for the cell merge to begin
  2773. * @param integer $col The anchor column for the cell merge
  2774. * @param integer $span The number of cells to merge
  2775. * @param string $group The group to merge cells in
  2776. */
  2777. function merge_cols($row, $col, $span, $group="tbody") {
  2778. $gpix = $this->get_group_index($group);
  2779. if ($gpix != -1) {
  2780. $gp = $this->groups[$gpix];
  2781. $gp->merge_cols($row, $col, $span);
  2782. $this->groups[$gpix] = $gp;
  2783. }
  2784. }
  2785. // ....................................................................
  2786. /**
  2787. * Remove a colspan from an existing table. The row and column of the
  2788. * cell which has the colspan is given. As a result the relevant
  2789. * spanned cells will be removed from the table.
  2790. * @param integer $row The anchor row for the cell split to begin
  2791. * @param integer $col The anchor column for the cell split
  2792. * @param string $group The group to split cells in
  2793. */
  2794. function split_cols($row, $col, $group="tbody") {
  2795. $gpix = $this->get_group_index($group);
  2796. if ($gpix != -1) {
  2797. $gp = $this->groups[$gpix];
  2798. $gp->split_cols($row, $col);
  2799. $this->groups[$gpix] = $gp;
  2800. }
  2801. }
  2802. // ....................................................................
  2803. /**
  2804. * Insert a column into all rows in the table. If the template cell is
  2805. * not provided, then a 'vanilla' cell is used instead.
  2806. * @param integer $col Column position to insert at, in the table
  2807. * @param object $celltoinsert Template cell to use for inserting
  2808. */
  2809. function insert_cols($col, $celltoinsert=false) {
  2810. foreach ($this->groups as $gp) {
  2811. $gpix = $this->get_group_index($gp->tag);
  2812. $gp->insert_cols($col, $celltoinsert);
  2813. $this->groups[$gpix] = $gp;
  2814. }
  2815. }
  2816. // ....................................................................
  2817. /**
  2818. * Append columns onto all rows in the table.
  2819. * @param integer $repeat Number of columns to append to table
  2820. * @param object $celltoappend Template cell to use for appending
  2821. */
  2822. function append_cols($repeat=1, $celltoappend=false) {
  2823. foreach ($this->groups as $gp) {
  2824. $gpix = $this->get_group_index($gp->tag);
  2825. $gp->append_cols($repeat, $celltoappend);
  2826. $this->groups[$gpix] = $gp;
  2827. }
  2828. }
  2829. // ....................................................................
  2830. /**
  2831. * Remove a column from all rows in the table
  2832. * @param integer $col Column position to remove from the table
  2833. */
  2834. function delete_cols($col) {
  2835. foreach ($this->groups as $gp) {
  2836. $gpix = $this->get_group_index($gp->tag);
  2837. $gp->delete_cols($col);
  2838. $this->groups[$gpix] = $gp;
  2839. }
  2840. }
  2841. // ....................................................................
  2842. /**
  2843. * Remove a row from the table. If the template cell is not provided
  2844. * then a 'vanilla' cell is used.
  2845. * @param integer $row Row position to remove from the table
  2846. * @param string $group The group to remove row from
  2847. */
  2848. function delete_row($row, $group="tbody") {
  2849. $gpix = $this->get_group_index($group);
  2850. if ($gpix != -1) {
  2851. $gp = $this->groups[$gpix];
  2852. $gp->delete_row($row);
  2853. $this->groups[$gpix] = $gp;
  2854. }
  2855. }
  2856. // ....................................................................
  2857. /**
  2858. * Return a given row from the table.
  2859. * @param integer $row Row position to remove from the table
  2860. * @return object The row reqested, or false if non-existent.
  2861. */
  2862. function get_row($row, $group="tbody") {
  2863. $therow = false;
  2864. $gpix = $this->get_group_index($group);
  2865. if ($gpix != -1) {
  2866. $gp = $this->groups[$gpix];
  2867. $therow = $gp->get_row($row);
  2868. }
  2869. return $therow;
  2870. }
  2871. // ....................................................................
  2872. /**
  2873. * Insert a row into the table. If the template cell is not provided,
  2874. * then a 'vanilla' cell is used instead. We insert the new row just
  2875. * before the given row.
  2876. * @param integer $row Row position to insert before, in the table
  2877. * @param object $celltoinsert Template cell to use for all row cells
  2878. */
  2879. function insert_row($row, $celltoinsert=false) {
  2880. foreach ($this->groups as $gp) {
  2881. $gpix = $this->get_group_index($gp->tag);
  2882. $gp->insert_row($row, $celltoinsert);
  2883. $this->groups[$gpix] = $gp;
  2884. }
  2885. }
  2886. // ....................................................................
  2887. /**
  2888. * Append a row onto the table.
  2889. * @param object $celltoappend Template cell to use for appending the row
  2890. * @param string $group The group (default tbody) to append the row to
  2891. */
  2892. function append_row($celltoappend=false, $group="tbody") {
  2893. $gpix = $this->get_group_index($group);
  2894. if ($gpix != -1) {
  2895. $gp = $this->groups[$gpix];
  2896. $gp->append_row($celltoappend);
  2897. $this->groups[$gpix] = $gp;
  2898. }
  2899. }
  2900. // ....................................................................
  2901. /**
  2902. * Set a width profile across the row of cells. The profile is passed
  2903. * as either a string or an array. If a string, the widths should be
  2904. * separated by commas. The widths can be absolute pixel values or %'s,
  2905. * and applies these widths to the first row of the given group.
  2906. * An example string might for instance be '20%,15%,65%'.
  2907. * @param mixed $prof The width profile, array or comma-delimeted string
  2908. * @param string $group The group (default tbody) to append the row to
  2909. */
  2910. function set_width_profile($prof, $group="tbody") {
  2911. // Close any open group..
  2912. $this->close_group();
  2913.  
  2914. $wprofile = array();
  2915. if (is_array($prof)) {
  2916. $wprofile = $prof;
  2917. }
  2918. elseif (is_string($prof)) {
  2919. $wprofile = explode(",", $prof);
  2920. }
  2921. $gpix = $this->get_group_index($group);
  2922. if ($gpix != -1) {
  2923. $gp = $this->groups[$gpix];
  2924. $gp->set_width_profile($wprofile);
  2925. $this->groups[$gpix] = $gp;
  2926. }
  2927. }
  2928. // ....................................................................
  2929. /**
  2930. * Get the width profile from the table.
  2931. * @param string $group The group (default tbody) to append the row to
  2932. * @return array Width profile as an array of widths
  2933. */
  2934. function get_width_profile($group="tbody") {
  2935. $wprofile = array();
  2936. $gpix = $this->get_group_index($group);
  2937. if ($gpix != -1) {
  2938. $gp = $this->groups[$gpix];
  2939. $wprofile = $gp->get_width_profile();
  2940. $this->groups[$gpix] = $gp;
  2941. }
  2942. return $wprofile;
  2943. }
  2944. // ....................................................................
  2945. /** Render as WML.
  2946. * @return string The table as WML. */
  2947. function wml() {
  2948. return $this->html();
  2949. }
  2950. // ....................................................................
  2951. /**
  2952. * Render the whole table as HTML
  2953. * If dedbugging mode is enabled and the DBG_TABLES flag is set, then
  2954. * we run a simple validation check, and report findings, as well as
  2955. * making sure the table borders are visible.
  2956. * @return string The HTML for this table.
  2957. */
  2958. function html() {
  2959. // Close any open group..
  2960. $this->close_group();
  2961.  
  2962. // If we are debugging tables, make sure the border is displayed..
  2963. if (debugging() && (debug_class() & DBG_TABLES)) {
  2964. $this->setborder(1);
  2965. }
  2966. $s = "";
  2967. if (count($this->groups) > 0) {
  2968. $cols = $this->colcount();
  2969. $rows = $this->rowcount();
  2970. $s .= "\n<!--TBL[$this->tablename]$rows" . "x" . "$cols-->\n";
  2971. $s .= "<table";
  2972. $s .= " cellpadding=\"$this->cellpadding\"";
  2973. $s .= " cellspacing=\"$this->cellspacing\"";
  2974. $s .= $this->attributes();
  2975. $s .= ">\n";
  2976.  
  2977. // Auto-justify heading cells of thead group. This can only
  2978. // be done here, when we have tbody content available to us
  2979. // since we justify heading cells from first body row cells..
  2980. if ($this->autojustify) {
  2981. $gpix = $this->get_group_index("tbody");
  2982. if ($gpix != -1) {
  2983. $gp = $this->groups[$gpix];
  2984. $gp->autojustify();
  2985. $this->groups[$gpix] = $gp;
  2986. }
  2987. // Now deal with any heading row..
  2988. for ($gix=0; $gix < count($this->groups); $gix++) {
  2989. $gp = $this->groups[$gix];
  2990. switch ($gp->tag) {
  2991. case "thead": $gp_head = $gp; $gp_headix = $gix; break;
  2992. case "tbody": $gp_body = $gp; $gp_bodyix = $gix; break;
  2993. }
  2994. }
  2995. if (isset($gp_head) && isset($gp_body)) {
  2996. $headrow = $gp_head->rows[0]; $bodyrow = $gp_body->rows[0];
  2997. for ($col=0; $col < count($headrow->cells); $col++) {
  2998. if (isset($bodyrow->cells[$col])) {
  2999. $cell = $bodyrow->cells[$col];
  3000. if (is_numeric($cell->content->content)) $css = "text-align:right;";
  3001. else $css = "text-align:left;";
  3002. $cell = $headrow->cells[$col];
  3003. $cell->setcss($css);
  3004. $headrow->cells[$col] = $cell;
  3005. }
  3006. }
  3007. $gp_head->rows[0] = $headrow;
  3008. $this->groups[$gp_headix] = $gp_head;
  3009. }
  3010. }
  3011.  
  3012. // Apply rowstriping to tbody if defined..
  3013. if (count($this->rowstripes) > 0) {
  3014. $gpix = $this->get_group_index("tbody");
  3015. if ($gpix != -1) {
  3016. $gp = $this->groups[$gpix];
  3017. $gp->apply_rowstripes($this->rowstripes);
  3018. $this->groups[$gpix] = $gp;
  3019. }
  3020. }
  3021.  
  3022. // Now do each group tag in the order it should be. Note
  3023. // that these may have been added in a different order
  3024. // so we force it to be thead -> tbody -> tfoot here..
  3025. $thead = ""; $tbody = ""; $tfoot = "";
  3026. for ($g = 0; $g < count($this->groups); $g++) {
  3027. $group = $this->groups[$g];
  3028. switch ($group->tag) {
  3029. case "thead":
  3030. $thead .= $group->html();
  3031. break;
  3032. case "tbody":
  3033. $tbody .= $group->html();
  3034. break;
  3035. case "tfoot":
  3036. $tfoot .= $group->html();
  3037. break;
  3038. } // switch
  3039. // Group may have altered itself in the
  3040. // act of being rendered..
  3041. $this->groups[$g] = $group;
  3042. } // for
  3043.  
  3044. // Glue them together in correct order..
  3045. $s .= $thead . $tbody . $tfoot;
  3046.  
  3047. $s .= "</table>\n";
  3048. $s .= "<!--END[$this->tablename]-->";
  3049. }
  3050. // If we are debugging tables, display validation now..
  3051. if (debugging() && (debug_class() & DBG_TABLES)) {
  3052. $this->validate();
  3053. }
  3054. // Return the HTML
  3055. return $s;
  3056. }
  3057. // ....................................................................
  3058. /**
  3059. * Render the table as a CSV formatted stream. This is designed
  3060. * to facilitate the exporting of complex tables of data as CSV format
  3061. * for importing into spreadsheets, or databases etc.
  3062. * @return string The table content in CSV format.
  3063. */
  3064. function csv() {
  3065. $s = "";
  3066. // Close any open group..
  3067. $this->close_group();
  3068. if (count($this->groups) > 0) {
  3069. $thead = ""; $tbody = ""; $tfoot = "";
  3070. for ($g = 0; $g < count($this->groups); $g++) {
  3071. $group = $this->groups[$g];
  3072. switch ($group->tag) {
  3073. case "thead":
  3074. $thead .= $group->csv();
  3075. break;
  3076. case "tbody":
  3077. $tbody .= $group->csv();
  3078. break;
  3079. case "tfoot":
  3080. $tfoot .= $group->csv();
  3081. break;
  3082. } // switch
  3083. } // for
  3084. // Glue them together in correct order..
  3085. $s .= $thead . $tbody . $tfoot;
  3086. }
  3087. // Return the csv stream..
  3088. return $s;
  3089. } // csv
  3090.  
  3091. } // table class
  3092. // ----------------------------------------------------------------------
  3093.  
  3094. /**
  3095. * A matrix is a table with no colspans or rowspans. It is an N x M
  3096. * rectangle of table cells, and created to the given size from the
  3097. * outset. This is just a simple way in which you can obtain s vanilla
  3098. * table of given dimensions, with a single statement. All the table
  3099. * methods are then available.
  3100. * @package html
  3101. */
  3102. class matrix extends table {
  3103. /** Rows in table
  3104. @access private */
  3105. var $rows = 1;
  3106. /** Columns in table
  3107. @access private */
  3108. var $cols = 1;
  3109. /**
  3110. * Construct a new matrix.
  3111. * @param integer $rows Number of table rows in the matrix
  3112. * @param integer $cols Number of table columns in the matrix
  3113. * @param string $content Optional content for every cell of the table
  3114. */
  3115. function matrix($rows, $cols, $content="") {
  3116. $this->table();
  3117. for ($r = 0; $r < $rows; $r++) {
  3118. $this->tr();
  3119. for ($c = 0; $c < $cols; $c++) {
  3120. $this->td($content);
  3121. }
  3122. }
  3123. // Close any open group..
  3124. $this->close_group();
  3125. } // matrix
  3126.  
  3127. } // matrix class
  3128. // ----------------------------------------------------------------------
  3129.  
  3130. /**
  3131. * [A] - The anchor tag, otheriwse know as a clickable link.
  3132. * @package html
  3133. */
  3134. class anchor extends HTMLObject {
  3135. // Public
  3136. // Private
  3137. /** URL that clicking the link goes to
  3138. @access private */
  3139. var $href = "";
  3140. /** Link label text
  3141. @access private */
  3142. var $label = "";
  3143. /** Stylesheet class name for highlighted link
  3144. @access private */
  3145. var $highlightclass = false;
  3146. // ....................................................................
  3147. /** Constructor
  3148. * @param string $css The style or classname to apply to the object.
  3149. */
  3150. function anchor($href="", $label="", $css="") {
  3151. $this->HTMLObject($css);
  3152. $this->href = $href;
  3153. $this->label = $label;
  3154. } // anchor
  3155. // ....................................................................
  3156. /**
  3157. * Defines special highlight class name
  3158. * Defines the name of a class in your stylesheet to use for the
  3159. * purpose of highlighting. This property is initialised to be
  3160. * 'false', but if defined, then the link is spanned by a <span>
  3161. * tag with the given class name to highlight it accordingly.
  3162. */
  3163. function highlight($highlightclass) {
  3164. $this->highlightclass = $highlightclass;
  3165. } // highlight
  3166. // ....................................................................
  3167. /** Render the object as HTML */
  3168.  
  3169. function html() {
  3170. if ($this->highlightclass != "") {
  3171. $html .= "<span class=$this->highlightclass>";
  3172. }
  3173. if ($this->href != "") {
  3174. $s = "<a href=\"$this->href\"";
  3175. $s .= $this->attributes();
  3176. $s .= ">";
  3177. $s .= $this->label;
  3178. $s .= "</a>";
  3179. }
  3180. else {
  3181. $s .= $this->label;
  3182. }
  3183. if ($this->highlightclass != "") {
  3184. $s .= "/span>";
  3185. }
  3186. // Return the HTML..
  3187. return $s;
  3188. } // html
  3189.  
  3190. } // anchor class
  3191. // ----------------------------------------------------------------------
  3192.  
  3193. /**
  3194. * [HR] - Horizontal Rule
  3195. * @package html
  3196. */
  3197. class hr extends HTMLObject {
  3198. // Public
  3199. // Private
  3200. /** Whether HR is shaded or not
  3201. @access private */
  3202. var $shade = false;
  3203. /** Colour of the element
  3204. @access private */
  3205. var $colour = "";
  3206. // ....................................................................
  3207. /** Constructor
  3208. * @param string $width The width of the rule eg: '100%', '550' etc.
  3209. * @param integer $size The standard thickness of the rule (px)
  3210. * @param string $colour The colour code of the rule
  3211. * @param string $css The style or classname to apply to the object.
  3212. */
  3213. function hr($width="100%", $size=1, $colour="", $css="") {
  3214. $this->HTMLObject($css);
  3215. $this->setwidth($width);
  3216. $this->setsize($size);
  3217. $this->colour = $colour;
  3218. } // hr
  3219. // ....................................................................
  3220. /** Cause HR to be shaded */
  3221.  
  3222. function shade() {
  3223. $this->shade = true;
  3224. } // ade
  3225. // ....................................................................
  3226. /** Cause HR to be unshaded */
  3227.  
  3228. function noshade() {
  3229. $this->shade = false;
  3230. } // noshade
  3231. // ....................................................................
  3232. /** Render the object as HTML
  3233. * @return string The HTML of this object
  3234. */
  3235. function html() {
  3236. global $RESPONSE;
  3237. $s = "<hr";
  3238. if (!$this->shade) {
  3239. $s .= " noshade";
  3240. }
  3241. if ($this->size > 0) {
  3242. $this->setcss("height:$this->size" . "px;");
  3243. }
  3244. // The different browsers are pretty confused about HR colour..
  3245. if ($this->colour != "") {
  3246. if (isset($RESPONSE) && $RESPONSE->browser == BROWSER_IE) {
  3247. $this->setcss("color:$this->colour;");
  3248. }
  3249. else {
  3250. $this->setcss("background-color:$this->colour;");
  3251. }
  3252. }
  3253. $s .= $this->attributes();
  3254. $s .= ">\n";
  3255. // Return the HTML..
  3256. return $s;
  3257. } // html
  3258.  
  3259. } // hr class
  3260. // ----------------------------------------------------------------------
  3261.  
  3262. /**
  3263. * Item list
  3264. * Internal list class used to generate list HTML content
  3265. * @package html
  3266. * @access private
  3267. */
  3268. class itemlist extends HTMLobject {
  3269. // Public
  3270. // Private
  3271. /** Array of items (strings) to display
  3272. @access private */
  3273. var $list = array();
  3274. /** Type of list: 'list', 'ordered', or 'bullets'
  3275. @access private */
  3276. var $type = "bullets";
  3277. // ....................................................................
  3278. /** Constructor
  3279. * @param string $type The type of list to create
  3280. * @param string $css The style or classname to apply to the object.
  3281. */
  3282. function itemlist($type, $css="") {
  3283. $this->type = $type;
  3284. $this->HTMLobject($css);
  3285. } // itemlist
  3286. // ....................................................................
  3287. /**
  3288. * Add an item to the list.
  3289. * @param string $item The item to add
  3290. */
  3291. function additem($item="") {
  3292. $this->list[] = $item;
  3293. } // additem
  3294. // ....................................................................
  3295. /**
  3296. * Render the HTML
  3297. * @return string The HTML for this list.
  3298. */
  3299. function html() {
  3300. $s = "";
  3301. if (count($this->items) > 0) {
  3302. $tag = (($this->type == "bullets") ? "ul" : "ol");
  3303. $s = "<$tag" . $this->attributes() . ">";
  3304. foreach ($this->items as $item) {
  3305. if ($item != "") {
  3306. $s .= "<li" . $this->attributes() . ">$item";
  3307. }
  3308. }
  3309. $s .= "</$tag>";
  3310. }
  3311. // Return the HTML..
  3312. return $s;
  3313. } // html
  3314.  
  3315. } // itemlist class
  3316.  
  3317. /**
  3318. * [OL] - Ordered list
  3319. * @package html
  3320. */
  3321. class ol extends itemlist {
  3322. /** Constructor
  3323. * @param string $css The style or classname to apply to the object.
  3324. */
  3325. function ol($css="") {
  3326. $this->itemlist("ordered", $css);
  3327. }
  3328. } // ol
  3329. /**
  3330. * [UL] - Unordered list
  3331. * @package html
  3332. */
  3333. class ul extends itemlist {
  3334. /** Constructor
  3335. * @param string $css The style or classname to apply to the object.
  3336. */
  3337. function ul($css="") {
  3338. $this->itemlist("bullets", $css);
  3339. }
  3340. } // ul
  3341. /**
  3342. * [VL] - Vanilla list (suppressed markers)
  3343. * @package html
  3344. */
  3345. class vl extends itemlist {
  3346. /** Constructor
  3347. * @param string $css The style or classname to apply to the object.
  3348. */
  3349. function vl($css="") {
  3350. $this->itemlist("bullets", $css);
  3351. $this->setcss("list-style:none;");
  3352. }
  3353. } // vl
  3354. // ----------------------------------------------------------------------
  3355.  
  3356. /**
  3357. * [IMG] - The img class. This is an object which renders the img tag.
  3358. * @package html
  3359. */
  3360. class img extends HTMLObject {
  3361. /** Name of an image map */
  3362.  
  3363. var $map;
  3364. /** URL associated with the image */
  3365.  
  3366. var $url;
  3367. /** Target frame for URL */
  3368.  
  3369. var $target;
  3370. /** Image which acts as a clickable icon */
  3371.  
  3372. var $icon;
  3373. //.....................................................................
  3374. /**
  3375. * Constructor
  3376. * The src field is mandatory. The name is optional but if given it will
  3377. * also be used for the ALT tag. If a tooltip is not given then the name
  3378. * will also be used for that attribute.
  3379. * NB: If the width and/or height are not given and GD is installed it
  3380. * will be used to find the image dimensions, otherwise these attributes
  3381. * will be supressed and the browser left to work it out.
  3382. * @param string $src The path/URL of the image file
  3383. * @param string $name Name of the image object - also used as ALT tag
  3384. * @param string $tooltip The tooltip appears on mouseover for most browsers
  3385. * @param integer $width The width of the image in pixels
  3386. * @param integer $height The height of the image in pixels
  3387. */
  3388. function img($src, $name="", $tooltip="", $width=false, $height=false) {
  3389. $this->HTMLObject();
  3390. $this->set_image($src, $width, $height);
  3391. $this->setborder(0);
  3392. // Set name to image file if not given..
  3393. if ($name == "") {
  3394. $fbits = explode(".", basename($src));
  3395. $name = $fbits[0];
  3396. }
  3397. $this->setname($name);
  3398. $this->setalt($name);
  3399. $this->settitle($tooltip);
  3400. if ($this->title == "") $this->settitle($name);
  3401. } // img
  3402. //.....................................................................
  3403. /**
  3404. * Set the image src and details for this image object.
  3405. * @param string $src The path/URL of the image file
  3406. * @param integer $width The width of the image in pixels
  3407. * @param integer $height The height of the image in pixels
  3408. */
  3409. function set_image($src, $width=false, $height=false) {
  3410. global $RESPONSE;
  3411. $this->setsrc($src);
  3412. // Get image sizing if not specified. To do this we need
  3413. // to determine the physical file path first..
  3414. if (($width === false || $height === false) && extension_loaded("gd")) {
  3415. $imgpath = $src;
  3416. if (substr($imgpath, 0, 1) == "/") {
  3417. $imgpath = substr($imgpath, 1);
  3418. }
  3419. if (isset($RESPONSE)) {
  3420. $imgpath = "$RESPONSE->site_docroot/$imgpath";
  3421. }
  3422. if (is_readable($imgpath)) {
  3423. $szinfo = getimagesize($imgpath);
  3424. if ($width === false) $width = $szinfo[0];
  3425. if ($height === false) $height = $szinfo[1];
  3426. }
  3427. }
  3428. if ($width) $this->setwidth($width);
  3429. if ($height) $this->setheight($height);
  3430. } // set_image
  3431. //.....................................................................
  3432. /** Set URL. When the image is clicked, the browser will target the
  3433. * URL. Note that this will not work if you have defined the onclick
  3434. * event handler.
  3435. * @param string $url The URL to go to when image is clicked.
  3436. * @param string $target The optional target frame, eg: '_blank' etc.
  3437. */
  3438. function seturl($url, $target="") {
  3439. $this->url = $url;
  3440. $this->target = $target;
  3441. } // seturl
  3442. //.....................................................................
  3443. /** Set image map
  3444. * Defines the image map to use with this image.
  3445. * @param string $map The name of the image map to associate with this image.
  3446. */
  3447. function use_map($map) {
  3448. $this->map = $map;
  3449. } // use_map
  3450. // ....................................................................
  3451. /** Render image as javascript object
  3452. * @return string Javascript code rendering of this image
  3453. */
  3454. function javascript() {
  3455. $js = "var $this->name=new Image($this->width,$this->height);\n";
  3456. $js .= "var $this->name src=\"$this->src\";\n";
  3457. return $js;
  3458. } // javascript
  3459. // ....................................................................
  3460. /** Render as WML.
  3461. * @return string The image as WML. */
  3462. function wml() {
  3463. return $this->html();
  3464. } // wml
  3465. // ....................................................................
  3466. /**
  3467. * Render the image object as an image 'icon' which can be clicked to
  3468. * display the object in a popup window.
  3469. * @param string $tooltip Optional browser mouseover tooltip text
  3470. * @param object $iconimage A custom image object
  3471. */
  3472. function AsIcon($tooltip="", $iconimage=false) {
  3473. global $RESPONSE, $LIBDIR;
  3474. if ($iconimage) {
  3475. $this->icon = $iconimage;
  3476. }
  3477. else {
  3478. $this->icon = new img("$LIBDIR/img/_image.gif", "Image");
  3479. }
  3480. if ($tooltip != "") {
  3481. $this->icon->title = $tooltip;
  3482. }
  3483. // Display the icon with onclickability..
  3484. if (isset($RESPONSE)) {
  3485. $RESPONSE->body->add_popup_script(
  3486. "vwimg_$this->name",
  3487. $this->width,
  3488. $this->height,
  3489. false,
  3490. false,
  3491. "toolbar=no,status=no,scrollbars=no,resizable=yes"
  3492. );
  3493. $this->icon->set_onclick("vwimg_$this->name" . "('$this->src')");
  3494. //$s = $this->icon->render();
  3495. }
  3496. else {
  3497. // Use vanilla new browser window approach..
  3498. $this->url = $this->src;
  3499. $this->set_image("$LIBDIR/img/_image.gif");
  3500. $this->target = "_new";
  3501. //$s = $this->html();
  3502. }
  3503. //return $s;
  3504. } // AsIcon
  3505. // ....................................................................
  3506. /** Render as HTML
  3507. * @return string The image as HTML. */
  3508. function html() {
  3509. global $RESPONSE;
  3510.  
  3511. if ( isset($this->icon) ) {
  3512. $s = $this->icon->render();
  3513. } else {
  3514. $s = "";
  3515. if (isset($this->url) && $this->url != "") {
  3516. $s .= "<a href=\"$this->url\"";
  3517. if ($this->target != "") {
  3518. $s .= " target=\"$this->target\"";
  3519. }
  3520. $s .= ">";
  3521. }
  3522. $s .= "<img";
  3523. if (isset($this->map) && $this->map != "") {
  3524. $s .= " usemap=\"$this->map\"";
  3525. }
  3526. $s .= $this->attributes();
  3527. $s .= ">";
  3528. if (isset($this->url) && $this->url != "") {
  3529. $s .= "</a>";
  3530. }
  3531. }
  3532. return $s;
  3533. } // html
  3534.  
  3535. } // img class
  3536. // ----------------------------------------------------------------------
  3537.  
  3538. /**
  3539. * Deprecated embed Object (HTML3.2)
  3540. * This object supports the older embed tag used to embed objects
  3541. * into HTML pages. for backward compatibility. In reality there is
  3542. * still a lot of mileage left in this tag.
  3543. * @package html
  3544. */
  3545. class embed extends HTMLObject {
  3546. // Public
  3547. /** Name of Java file, if java applet */
  3548.  
  3549. var $code;
  3550. /** Base URL for plug-in or potenial java applet (IE) */
  3551.  
  3552. var $codebase;
  3553. /** URL of page to acquire the relevant object plugin */
  3554.  
  3555. var $pluginspage;
  3556. /** The MIME type of the object */
  3557.  
  3558. var $mimetype;
  3559. /** If true the object is hidden */
  3560.  
  3561. var $hidden = false;
  3562.  
  3563. // Private
  3564. /** Array of non-std attributes as name/value pairs
  3565. @access private */
  3566. var $other_attributes = array();
  3567. // ....................................................................
  3568. /** Constructor
  3569. * @param string $src The URL of the source data for this object
  3570. * @param string $mimetype The MIMETYPE of this object, eg: 'application/x-sockwave-flash' etc.
  3571. * @param string $pluginspage The URL for downloading the relevant plugin
  3572. * @param string $width Width of object in pixels
  3573. * @param string $height Height of object in pixels
  3574. * @param string $alt ALT text to display if object does not execute
  3575. */
  3576. function embed($src="", $mimetype="", $pluginspage="", $width="", $height="", $alt="", $hidden=false) {
  3577. $this->HTMLObject();
  3578. if ($src != "") $this->setsrc($src);
  3579. if ($mimetype != "") $this->mimetype = $mimetype;
  3580. if ($pluginspage != "") $this->pluginspage = $pluginspage;
  3581. if ($width != "") $this->setwidth($width);
  3582. if ($height != "") $this->setheight($height);
  3583. if ($alt != "") $this->setalt($alt);
  3584. $this->hidden = $hidden;
  3585. } // embed
  3586. // ....................................................................
  3587. /**
  3588. * Specify the parameters required for a Java applet, the name
  3589. * of the file containing the applet code, and the URL to find
  3590. * the file at.
  3591. * @param string $code The name of the file contaiing the applet
  3592. * @param string $codebase The URL to locate the code file at
  3593. */
  3594. function java_applet($code, $codebase="") {
  3595. $this->code = $code;
  3596. if ($codebase != "") $this->codebase = $codebase;
  3597. } // java_applet
  3598. // ....................................................................
  3599. /**
  3600. * Add non-standard attribute to be rendered.
  3601. * @param string $name Name of the new attribute
  3602. * @param string $value Value of the new attribute
  3603. */
  3604. function add_attribute($name, $value) {
  3605. $this->other_attributes[$name] = $value;
  3606. } // add_attribute
  3607. // ....................................................................
  3608. function html() {
  3609. $s = "";
  3610. $s .= "<embed";
  3611. if (isset($this->pluginspage)) $s .= " pluginspage=\"$this->pluginspage\"";
  3612. if (isset($this->mimetype)) $s .= " type=\"$this->mimetype\"";
  3613. if (isset($this->code)) $s .= " code=\"$this->code\"";
  3614. if (isset($this->codebase)) $s .= " codebase=\"$this->codebase\"";
  3615. if (isset($this->quality)) $s .= " quality=\"$this->quality\"";
  3616. $s .= " hidden=" . ($this->hidden ? "\"true\"" : "\"false\"");
  3617. $s .= $this->attributes();
  3618. while ( list($name, $value) = each($this->other_attributes)) {
  3619. $s .= " $name=\"$value\"";
  3620. }
  3621. $s .= ">";
  3622. // Return the HTML..
  3623. return $s;
  3624. } // html
  3625.  
  3626. } // embed class
  3627. // ----------------------------------------------------------------------
  3628.  
  3629. /**
  3630. * Object
  3631. * This HTML4 entity is the preferred method for embedding objects into a
  3632. * webpage using the object tag. The only drawback is that a lot of browsers
  3633. * don't support it fully, hence the older embed tag is also available for
  3634. * use as a fallback mechanism via the add_embed() method.
  3635. * @see function add_embed
  3636. * @package html
  3637. */
  3638. class EmbeddedObject extends HTMLObject {
  3639. // Public
  3640. /** MIME type of data required by the object */
  3641.  
  3642. var $mimetype = "";
  3643. /** URL for the object's implementation */
  3644.  
  3645. var $classid;
  3646. /** URL for relative base for accessing object
  3647. specified by the classid */
  3648. var $codebase;
  3649. /** URL of data object might require */
  3650.  
  3651. var $data;
  3652. /** Object MIME type */
  3653.  
  3654. var $codetype;
  3655. /** Standby message text */
  3656.  
  3657. var $standby;
  3658. /** URL of page to acquire the relevant embed plugin */
  3659.  
  3660. var $pluginspage = "";
  3661. /** MIMETYPE of file by using its extension */
  3662.  
  3663. var $extn_mimetype = "";
  3664. /** Mimetype category, eg: 'movie', 'audio' etc. */
  3665.  
  3666. var $category = "";
  3667. /** Image which acts as a play icon */
  3668.  
  3669. var $icon;
  3670.  
  3671. // Private
  3672. /** Array of parameter key-values
  3673. @access private */
  3674. var $params = array();
  3675. /** If set, contains a EmbeddedObject_Compat object to
  3676. be rendered in this object for compatibility
  3677. @access private */
  3678. var $embed_obj;
  3679. /** Internal name sans spaces
  3680. @access private */
  3681. var $internal_name = "obj";
  3682. /** If not empty, render as a link using $aslink as the text
  3683. @access private */
  3684. var $aslink = "";
  3685. /** Target frame for the $aslink
  3686. @access private */
  3687. var $aslink_target = "";
  3688. // ....................................................................
  3689. /** Constructor
  3690. * @param string $src URL of the source datafor the object, if any
  3691. * @param string $mimetype Mimetypeof the embedded object
  3692. * @param string $classid The classid (CLSID) unique ID of this object
  3693. * @param integer $width Width of object
  3694. * @param integer $height Height of object
  3695. * @param string $codebase URL of code location for this object
  3696. * @param string $standby Standby message whilst loading
  3697. */
  3698. function EmbeddedObject(
  3699. $src="",
  3700. $mimetype="",
  3701. $classid="",
  3702. $width=0,
  3703. $height=0,
  3704. $codebase="",
  3705. $standby="Loading..")
  3706. {
  3707. $this->HTMLobject();
  3708. // Deal with source file, mimetype and category..
  3709. if($src != "") {
  3710. $this->data = $src;
  3711. $file = basename($src);
  3712. $fnbits = explode(".", $file);
  3713. $this->setname($fnbits[0]);
  3714. $this->internal_name = md5(preg_replace("/[ \-,.;:_{}()<>\"\'\`\+\=]/", "", $this->name));
  3715. $mime = mimetype_from_filename($src);
  3716. if ($mime) $this->extn_mimetype = $mime;
  3717. else $this->extn_mimetype = "";
  3718. $this->category = mimetype_category($this->extn_mimetype);
  3719. }
  3720. if ($mimetype != "") {
  3721. $this->mimetype = $mimetype;
  3722. }
  3723. else {
  3724. $this->mimetype = $extn_mimetype;
  3725. }
  3726. if ($classid != "") $this->classid = $classid;
  3727. $this->setwidth($width);
  3728. $this->setheight($height);
  3729. if ($codebase != "") $this->codebase = $codebase;
  3730. if ($standby != "") $this->standby = $standby;
  3731. } // EmbeddedObject
  3732. // ....................................................................
  3733. /**
  3734. * Set up a new object parameter name/value pair. This will be rendered
  3735. * as a param name="foo" value="bar" tag.
  3736. * @param string $name Name of the new param entity
  3737. * @param string $value Value of the new param entity
  3738. */
  3739. function setparam($name, $value) {
  3740. if (trim($name) != "") {
  3741. $this->params[trim($name)] = trim($value);
  3742. }
  3743. } // setparam
  3744. // ....................................................................
  3745. /**
  3746. * Add an embed object to provide fallback for browsers which do not
  3747. * support the object tag properly.
  3748. * @param string $src The URL of the source data for this object
  3749. * @param string $pluginspage The URL for downloading the relevant plugin
  3750. */
  3751. function add_embed($src="", $pluginspage="") {
  3752. $this->embed_obj =
  3753. new embed(
  3754. $src,
  3755. $this->mimetype,
  3756. $pluginspage
  3757. );
  3758. } // add_embed
  3759. // ....................................................................
  3760. /**
  3761. * Render the object as a simple link. The parameter passed will be
  3762. * the text of the link, and the URL is determined by the location
  3763. * of the object as specified in the constructor.
  3764. * @param string $linktext Text to use for the link
  3765. */
  3766. function AsLink($linktext="", $target="") {
  3767. $this->aslink = $linktext;
  3768. $this->aslink_target = $target;
  3769. } // AsLink
  3770. // ....................................................................
  3771. /** Render the HTML
  3772. * @return string HTML for this object
  3773. */
  3774. function html() {
  3775. $s = "";
  3776. if($this->aslink != "") {
  3777. $s .= "<a href=\"$this->data\"";
  3778. if ($this->aslink_target != "") {
  3779. $s .= " target=\"_blank\"";
  3780. }
  3781. $s .= ">";
  3782. $s .= $this->aslink;
  3783. $s .= "</a>";
  3784. }
  3785. else {
  3786. $s .= "<object";
  3787. $s .= $this->attributes();
  3788. if (isset($this->classid)) $s .= " classid=\"$this->classid\"";
  3789. if (isset($this->codebase)) $s .= " codebase=\"$this->codebase\"";
  3790. if (isset($this->data)) $s .= " data=\"$this->data\"";
  3791. if (isset($this->codetype)) $s .= " codetype=\"$this->codetype\"";
  3792. if ($this->mimetype != "") $s .= " type=\"$this->mimetype\"";
  3793. if (isset($this->standby)) $s .= " standby=\"$this->standby\"";
  3794. $s .= ">";
  3795.  
  3796. // Add param items..
  3797. while ( list($name, $value) = each($this->params)) {
  3798. $s .= "<param name=\"$name\" value=\"$value\">";
  3799. }
  3800. // Add fallback <embed> object..
  3801. if (isset($this->embed_obj)) {
  3802. $this->embed_obj->width = $this->width;
  3803. $this->embed_obj->height = $this->height;
  3804. $this->embed_obj->mimetype = $this->mimetype;
  3805. if (isset($this->standby)) {
  3806. $this->embed_obj->alt = $this->standby;
  3807. }
  3808. $s .= $this->embed_obj->html();
  3809. }
  3810. $s .= "</object>";
  3811. }
  3812. // Return the html..
  3813. return $s;
  3814. } // html
  3815.  
  3816. } // EmbeddedObject class
  3817. // ----------------------------------------------------------------------
  3818.  
  3819. /** Macromedia Flash Windows CLASS ID */
  3820. ("FLASH_CLSID", "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000");
  3821. /** Macromedia Flash Codebase - where to download the player */
  3822. ("FLASH_CODEBASE", "http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=5,0,0,0");
  3823. /** Macromedia Flash Plugins plage - support for other platforms */
  3824. ("FLASH_PLUGINSPAGE", "http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash");
  3825. /** Macromedia Flash MimeType */
  3826. ("FLASH_MIMETYPE", "application/x-shockwave-flash");
  3827. /**
  3828. * Macromedia Shockwave/Flash Object
  3829. * @package html
  3830. */
  3831. class FlashObject extends EmbeddedObject {
  3832. /* URL of Flash movie */
  3833. var $movie = "";
  3834. /** Quality setting for the movie */
  3835.  
  3836. var $quality = "high";
  3837. // ....................................................................
  3838. /** Constructor
  3839. * @param string $movie URL of the flash movie file
  3840. * @param integer $width Width in pixels of the movie
  3841. * @param integer $height Height in pixels of the movie
  3842. * @param string $quality Quality spec of the movie
  3843. * @param string $standby Optional message to display while loading
  3844. */
  3845. function FlashObject($movie, $width="", $height="", $quality="high", $standby="") {
  3846. $this->movie = $movie;
  3847. // These attributes are defined by Macromedia for Flash content..
  3848. $classid = FLASH_CLSID;
  3849. $codebase = FLASH_CODEBASE;
  3850. $this->pluginspage = FLASH_PLUGINSPAGE;
  3851. $this->EmbeddedObject($movie, FLASH_MIMETYPE, $classid, $width, $height, $codebase, $standby);
  3852. $this->quality = $quality;
  3853. } // FlashObject
  3854. // ....................................................................
  3855. /**
  3856. * Render the flash object as an image 'icon' which can be clicked to play
  3857. * the movie. If image is specified, it must be a valid 'image' object,
  3858. * otherwise a generic library symbol will be used.
  3859. * @param string $tooltip Optional browser mouseover tooltip text
  3860. * @param object $iconimage A custom image object
  3861. * @see img
  3862. */
  3863. function AsIcon($tooltip="", $iconimage=false) {
  3864. global $RESPONSE, $LIBDIR;
  3865. if ($iconimage) {
  3866. $this->icon = $iconimage;
  3867. }
  3868. else {
  3869. $this->icon = new img("$LIBDIR/img/_flash.gif", "Play");
  3870. }
  3871. if ($tooltip != "") {
  3872. $this->icon->title = $tooltip;
  3873. }
  3874. } // AsIcon
  3875. // ....................................................................
  3876. /** Render the HTML
  3877. * @return string HTML for this object
  3878. */
  3879. function html() {
  3880. global $RESPONSE;
  3881. $s = "";
  3882. if ($RESPONSE->browser != BROWSER_IE) {
  3883. // Need one of these for compatibility..
  3884. $this->embed_obj =
  3885. new embed(
  3886. $this->movie,
  3887. FLASH_MIMETYPE,
  3888. $this->pluginspage,
  3889. $this->width,
  3890. $this->height,
  3891. $this->standby
  3892. );
  3893. $this->embed_obj->add_attribute("quality", $this->quality);
  3894. }
  3895. $this->setparam("movie", $this->movie);
  3896. $this->setparam("quality", $this->quality);
  3897.  
  3898. // If we are doing a clickable image, we need the aid of
  3899. // some handy javascript to make it work..
  3900. if (isset($this->icon)) {
  3901. $this->icon->set_onclick("play_$this->internal_name('$this->name')");
  3902. $embeddedMedia = EmbeddedObject::html();
  3903. $RESPONSE->body->add_popup_script("popup_$this->internal_name", $this->width, $this->height, 100, 40);
  3904. $RESPONSE->body->add_script(
  3905. "var playing=false;\n"
  3906. . "function play_$this->internal_name(pname) {\n"
  3907. . " popup_$this->internal_name('');\n"
  3908. . " with (popup_" . $this->internal_name . "Win.document) {\n"
  3909. . " open();\n"
  3910. . " write('');\n"
  3911. . " write('<body bgcolor=\"#333333\" leftmargin=\"0\" rightmargin=\"0\" topmargin=\"0\" marginwidth=\"0\" marginheight=\"0\">');\n"
  3912. . " write('<center><font face=arial,helvetica size=2>');\n"
  3913. . " write('$embeddedMedia');\n"
  3914. . " title='$this->name';\n"
  3915. . " close();\n"
  3916. . " }\n"
  3917. . "}\n"
  3918. );
  3919. $s .= $this->icon->render();
  3920. }
  3921. else {
  3922. $s .= EmbeddedObject::html();
  3923. }
  3924. // Return html..
  3925. return $s;
  3926. } // html
  3927.  
  3928. } // FlashObject class
  3929. // ----------------------------------------------------------------------
  3930.  
  3931. /** Windows Media Player CLASS ID */
  3932. ("WM_CLSID", "CLSID:22D6f312-B0F6-11D0-94AB-0080C74C7E95");
  3933. /** Windows Media Player Codebase - where to download the player */
  3934. ("WM_CODEBASE", "http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=6,4,7,1112");
  3935. /** Windows Media Player - General plugins page for other platforms */
  3936. ("WM_PLUGINSPAGE", "http://www.microsoft.com/Windows/MediaPlayer/");
  3937. /** Windows Media Player - MimeType */
  3938. ("WM_MIMETYPE", "application/x-mplayer2");
  3939. /** Used to indicate sound should start playing on load */
  3940. ("AUTOSTART", true);
  3941. /** Used to indicate sound should loop indefinitely */
  3942. ("LOOP", true);
  3943. /** Used to hide the object control */
  3944. ("HIDDEN", true);
  3945. /**
  3946. * Generic Multimedia Object
  3947. * @package html
  3948. */
  3949. class MediaObject extends EmbeddedObject {
  3950. /* URL of media file */
  3951. var $media = "";
  3952. /** If true the media start immediately it is loaded */
  3953.  
  3954. var $autostart = false;
  3955. /** If true the media replays endlessly */
  3956.  
  3957. var $loop = false;
  3958. /** If true the media object is hidden */
  3959.  
  3960. var $hidden = false;
  3961. /** If true the mediaplayer controls are shown */
  3962.  
  3963. var $showcontrols = true;
  3964. // ....................................................................
  3965. /** Constructor
  3966. * @param string $media URL of the media file
  3967. * @param integer $width Width in pixels of the media object
  3968. * @param integer $height Height in pixels of the media object
  3969. * @param boolean $autostart True if you want the media to auto-start on load
  3970. * @param boolean $loop True if you want the media to repeat endlessly
  3971. * @param boolean $hidden True if you want the media to be hidden from view
  3972. * @param string $standby Standby message whilst loading
  3973. */
  3974. function MediaObject($media, $width="", $height="", $autostart=false, $loop=false, $showcontrols=true, $hidden=false, $standby="Loading..") {
  3975. global $RESPONSE, $LIBDIR;
  3976. $this->media = $media;
  3977. $this->autostart = $autostart;
  3978. $this->loop = $loop;
  3979. $this->showcontrols = $showcontrols;
  3980. $this->hidden = $hidden;
  3981. // Set up parameters according to browser..
  3982. if ($RESPONSE->browser == BROWSER_IE) {
  3983. $classid = WM_CLSID;
  3984. $codebase = WM_CODEBASE;
  3985. $this->pluginspage = WM_PLUGINSPAGE;
  3986. $mimetype = WM_MIMETYPE;
  3987. }
  3988. else {
  3989. $mimetype = $this->extn_mimetype;
  3990. }
  3991. $this->EmbeddedObject($media, $mimetype, $classid, $width, $height, $codebase, $standby);
  3992. } // MediaObject
  3993. // ....................................................................
  3994. /**
  3995. * Render the media object as an image 'icon' which can be clicked to play
  3996. * the media. If image is specified, it must be a valid 'image' object,
  3997. * otherwise a generic library symbol will be used.
  3998. * @param string $tooltip Optional browser mouseover tooltip text
  3999. * @param object $iconimage A custom image object
  4000. * @see img
  4001. */
  4002. function AsIcon($tooltip="", $iconimage=false) {
  4003. global $RESPONSE, $LIBDIR;
  4004. // Make sounds invisible..
  4005. switch ($this->category) {
  4006. case "audio":
  4007. $this->hidden = true;
  4008. $this->setwidth(0);
  4009. $this->setheight(0);
  4010. break;
  4011. default:
  4012. $this->hidden = false;
  4013. break;
  4014. }
  4015. if ($iconimage) {
  4016. $this->icon = $iconimage;
  4017. }
  4018. else {
  4019. switch ($this->category) {
  4020. case "audio":
  4021. $this->icon = new img("$LIBDIR/img/_sound.gif", "Play");
  4022. break;
  4023. default:
  4024. $this->icon = new img("$LIBDIR/img/_movie.gif", "Play");
  4025. break;
  4026. } // switch
  4027. }
  4028. if ($tooltip != "") {
  4029. $this->icon->title = $tooltip;
  4030. }
  4031. } // AsIcon
  4032. // ....................................................................
  4033. /** Render the HTML
  4034. * @return string HTML for this object
  4035. */
  4036. function html() {
  4037. global $RESPONSE, $LIBDIR;
  4038. $s = "";
  4039. // Render the object itself..
  4040. $this->embed_obj =
  4041. new embed(
  4042. $this->media,
  4043. $this->extn_mimetype,
  4044. $this->pluginspage,
  4045. $this->width,
  4046. $this->height,
  4047. $this->standby
  4048. );
  4049. $this->embed_obj->hidden = $this->hidden;
  4050. $this->embed_obj->add_attribute("autostart", ($this->autostart ? "true" : "false"));
  4051. $this->embed_obj->add_attribute("loop", ($this->loop ? "true" : "false"));
  4052.  
  4053. // Do Windows Media Player params for Internet Explorer..
  4054. if ($RESPONSE->browser == BROWSER_IE) {
  4055. $this->setparam("FileName", $this->media);
  4056. $this->setparam("PlayCount", ($this->loop ? "0" : "1"));
  4057. $this->setparam("Volume", "4");
  4058. $this->setparam("ShowControls", ($this->showcontrols ? "true" : "false"));
  4059. $this->setparam("TransparentAtStart", ($this->hidden ? "true" : "false"));
  4060. $this->setparam("AutoStart", ($this->autostart ? "true" : "false"));
  4061. $this->setparam("ShowStatusBar", "false");
  4062. }
  4063.  
  4064. // If we are doing a clickable image, we need the aid of
  4065. // some handy javascript to make it work..
  4066. if (isset($this->icon)) {
  4067. switch ($RESPONSE->browser){
  4068. // For IE we can do the full nine yards and open a special
  4069. // window where we put the embedded object..
  4070. case BROWSER_IE:
  4071. // Play all media in separate window..
  4072. $this->icon->set_onclick("play_$this->internal_name('$this->name')");
  4073. switch ($this->category) {
  4074. // Play movies in a separate window..
  4075. case "movie":
  4076. $embeddedMedia = EmbeddedObject::html();
  4077. $RESPONSE->body->add_popup_script("popup_$this->internal_name", $this->width, $this->height, 100, 40);
  4078. $RESPONSE->body->add_script(
  4079. "var playing=false;\n"
  4080. . "function play_$this->internal_name(pname) {\n"
  4081. . " popup_$this->internal_name('');\n"
  4082. . " with (popup_" . $this->internal_name . "Win.document) {\n"
  4083. . " open();\n"
  4084. . " write('');\n"
  4085. . " write('<body bgcolor=\"#333333\" leftmargin=\"0\" rightmargin=\"0\" topmargin=\"0\" marginwidth=\"0\" marginheight=\"0\">');\n"
  4086. . " write('<center><font face=arial,helvetica size=2>');\n"
  4087. . " write('$embeddedMedia');\n"
  4088. . " title='$this->name';\n"
  4089. . " close();\n"
  4090. . " }\n"
  4091. . "}\n"
  4092. );
  4093. break;
  4094. // Play sounds in current window..
  4095. case "audio":
  4096. $RESPONSE->body->add_script(
  4097. "var playing=false;\n"
  4098. . "function play_$this->internal_name(pname) {\n"
  4099. . " player=eval('document.' + pname);\n"
  4100. . " if (player != null) {\n"
  4101. . " if (playing) {player.Stop();playing=false;}\n"
  4102. . " else {player.Play();playing=true;}\n"
  4103. . " }\n"
  4104. . "}\n"
  4105. );
  4106. // Embed the object in this page..
  4107. $s .= EmbeddedObject::html();
  4108. break;
  4109. } //switch category
  4110. $s .= $this->icon->render();
  4111. break;
  4112.  
  4113. // For other browsers we take a slightly more vanilla approach.
  4114. // The click opens a window, with URL set to the media itself.
  4115. // This should get the browser to utilize plugin/helper et al..
  4116. default:
  4117. // Play all media in separate window..
  4118. $RESPONSE->body->add_popup_script("popup_$this->internal_name", $this->width, $this->height, 100, 40);
  4119. $this->icon->set_onclick("popup_$this->internal_name('$this->media')");
  4120. $s .= $this->icon->render();
  4121. break;
  4122.  
  4123. } // switch on browser
  4124. }
  4125. else {
  4126. // No icon, just an embedded object. In this case we will
  4127. // expect problems for browsers other than IE, but c'est la vie..
  4128. $s .= EmbeddedObject::html();
  4129. }
  4130. // Return the HTML..
  4131. return $s;
  4132. } // html
  4133.  
  4134. } // MediaObject class
  4135. // ----------------------------------------------------------------------
  4136.  
  4137. /**
  4138. * Document Object
  4139. * In actual fact, we don't view Documents as Embedded objects, and instead
  4140. * we provide a link to either open a new window, or target a new browser
  4141. * window. We point the URL'sto the document, and let the system do
  4142. * what it thinks best after that.
  4143. * @package html
  4144. */
  4145. class DocumentObject extends EmbeddedObject {
  4146. /* URL of document file */
  4147. var $docurl = "";
  4148. // ....................................................................
  4149. /** Constructor
  4150. * @param string $docurl URL of the document file
  4151. * @param integer Width of window showing spreaddocurl
  4152. * @param integer Height of window showing spreaddocurl
  4153. */
  4154. function DocumentObject($docurl, $width="", $height="") {
  4155. global $RESPONSE, $LIBDIR;
  4156. $this->docurl = $docurl;
  4157. $classid = "";
  4158. $this->pluginspage = "";
  4159. $mimetype = "";
  4160. $codebase = "";
  4161. $this->EmbeddedObject($docurl, $mimetype, $classid, $width, $height);
  4162. } // DocumentObject
  4163. // ....................................................................
  4164. /**
  4165. * Render the document object as an image 'icon' which can be clicked to play
  4166. * the media. If image is specified, it must be a valid 'image' object,
  4167. * otherwise a generic library symbol will be used.
  4168. * @param string $tooltip Optional browser mouseover tooltip text
  4169. * @param object $iconimage A custom image object
  4170. * @see img, @see clickable_image
  4171. */
  4172. function AsIcon($tooltip="", $iconimage=false) {
  4173. global $RESPONSE, $LIBDIR;
  4174. if ($iconimage) {
  4175. $this->icon = $iconimage;
  4176. }
  4177. else {
  4178. debugbr("image mime type: ".$this->extn_mimetype);
  4179. switch ($this->extn_mimetype) {
  4180. case CONTENT_MSEXCEL:
  4181. $this->icon = new img("$LIBDIR/img/_excel.gif", "Excel Spreadsheet");
  4182. break;
  4183. case CONTENT_MSWORD:
  4184. $this->icon = new img("$LIBDIR/img/_msword.gif", "Word Document");
  4185. break;
  4186. case CONTENT_PDF:
  4187. $this->icon = new img("$LIBDIR/img/_pdf.gif", "PDF Document");
  4188. break;
  4189. default:
  4190. $this->icon = new img("$LIBDIR/img/_document.gif", "Document");
  4191. } // switch
  4192. }
  4193. if ($tooltip != "") {
  4194. $this->icon->title = $tooltip;
  4195. }
  4196. } // AsIcon
  4197. // ....................................................................
  4198. /** Render the HTML
  4199. * @return string HTML for this object
  4200. */
  4201. function html() {
  4202. global $RESPONSE, $LIBDIR;
  4203. $s = "";
  4204. // If we are doing a clickable image, we need the aid of
  4205. // some handy javascript to make it work..
  4206. if (isset($this->icon)) {
  4207. // Spreaddocurl in separate window..
  4208. $RESPONSE->body->add_popup_script(
  4209. "popup_$this->internal_name",
  4210. $this->width,
  4211. $this->height,
  4212. 100,
  4213. 40,
  4214. "toolbar=yes,status=yes,scrollbars=yes,resizable=yes"
  4215. );
  4216. $this->icon->set_onclick("popup_$this->internal_name('$this->docurl')");
  4217. $s .= $this->icon->render();
  4218. }
  4219. else {
  4220. // No icon, so we render the object. Note: embedding documents is
  4221. // bound to end in tears, so always render AsLink in your app..
  4222. $s .= EmbeddedObject::html();
  4223. }
  4224. // Return the HTML..
  4225. return $s;
  4226. } // html
  4227.  
  4228. } // DocumentObject class
  4229. // ----------------------------------------------------------------------
  4230.  
  4231. ?>

Documentation generated by phpDocumentor 1.3.0RC3