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

Documentation generated by phpDocumentor 1.3.0RC3