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");
  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; $lastcnt = -1;
  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 $content Content to poke into the cell
  2396. * @param string $css Cell css setting, or omit to not set it.
  2397. * @param boolean $heading Whether it is a 'heading' cell or not
  2398. */
  2399. function td($content="", $css="", $heading=false) {
  2400. // Automatically insert row if no groups yet, and this
  2401. // will create the 'tbody' group as well..
  2402. if (count($this->groups) == 0) {
  2403. $this->tr();
  2404. }
  2405. // Deal with auto-justification if required..
  2406. $content = trim($content);
  2407.  
  2408. // Create new cell in this group..
  2409. $group = array_pop($this->groups);
  2410. $group->td($content, $css, $heading);
  2411. array_push($this->groups, $group);
  2412. }
  2413. // ....................................................................
  2414. /**
  2415. * Define a new heading cell for the current row.
  2416. * @param string $content Content to poke into the cell
  2417. * @param string $css Cell css setting, or omit to not set it.
  2418. */
  2419. function th($content="", $css="") {
  2420. // Create new cell in this group..
  2421. $group = array_pop($this->groups);
  2422. $group->td($content, $css, true);
  2423. array_push($this->groups, $group);
  2424. }
  2425. // ....................................................................
  2426. /**
  2427. * Set the working cell css properties. Use this method AFTER you have
  2428. * defined the cell with the td() method. This defines the style or
  2429. * classname to use for the cell. Note this is for the cell, rather
  2430. * than the content inside the cell.
  2431. * @param string $css Style or classname to use for the cell.
  2432. */
  2433. function td_css($css="") {
  2434. $group = array_pop($this->groups);
  2435. $group->td_css($css);
  2436. array_push($this->groups, $group);
  2437. }
  2438. // ....................................................................
  2439. /**
  2440. * Set the working cell content css properties in one hit. Use this
  2441. * method AFTER you have defined the cell with the td() method. This
  2442. * defines the style or classname to use for the cell content. This
  2443. * will be implemented using span tags.
  2444. * @param string $css Style or classname to use for the cell content.
  2445. */
  2446. function td_contentcss($css="") {
  2447. $group = array_pop($this->groups);
  2448. $group->td_contentcss($css);
  2449. array_push($this->groups, $group);
  2450. }
  2451. // ....................................................................
  2452. /**
  2453. * Append content to the working cell. Use this method AFTER you have
  2454. * defined the cell with the td() method.
  2455. * @param string $content Content to append to the current cell.
  2456. * @param string $css Style or classname to use for the cell content.
  2457. */
  2458. function td_content($content="", $css="") {
  2459. $group = array_pop($this->groups);
  2460. $group->td_content($content);
  2461. array_push($this->groups, $group);
  2462. }
  2463. // ....................................................................
  2464. /**
  2465. * Set the working cell alignment properties in one hit. Use
  2466. * this method AFTER you have defined the cell with the td() method.
  2467. * @param string $align Horizontal alignment: 'left', 'center', 'right'.
  2468. * @param string $valign Vertical alignment: 'top', 'middle', 'bottom'.
  2469. */
  2470. function td_alignment($align="", $valign="") {
  2471. $group = array_pop($this->groups);
  2472. $group->td_alignment($align, $valign);
  2473. array_push($this->groups, $group);
  2474. }
  2475. // ....................................................................
  2476. /**
  2477. * Set the working cell width and height properties in one hit. Use
  2478. * this method AFTER you have defined the cell with the td() method.
  2479. * @param string $width Number of pixels or % width of this cell.
  2480. * @param string $height Number of pixels or % height of this cell.
  2481. */
  2482. function td_metrics($width="", $height="") {
  2483. $group = array_pop($this->groups);
  2484. $group->td_metrics($width, $height);
  2485. array_push($this->groups, $group);
  2486. }
  2487. // ....................................................................
  2488. /**
  2489. * Set the working cell width property. Use this method AFTER you
  2490. * have defined the cell with the td() method.
  2491. * @param string $width Number of pixels or % width of this cell.
  2492. */
  2493. function td_width($width="") {
  2494. $group = array_pop($this->groups);
  2495. $group->td_width($width);
  2496. array_push($this->groups, $group);
  2497. }
  2498. // ....................................................................
  2499. /**
  2500. * Set the working cell height property. Use this method AFTER you
  2501. * have defined the cell with the td() method.
  2502. * @param string $height Number of pixels or % height of this cell.
  2503. */
  2504. function td_height($height="") {
  2505. $group = array_pop($this->groups);
  2506. $group->td_height($height);
  2507. array_push($this->groups, $group);
  2508. }
  2509. // ....................................................................
  2510. /**
  2511. * Set the working cell colspan property. Use this method AFTER you
  2512. * have defined the cell with the td() method.
  2513. * @param integer $span Number of columns this cell will span.
  2514. */
  2515. function td_colspan($span=1) {
  2516. $group = array_pop($this->groups);
  2517. $group->td_colspan($span);
  2518. array_push($this->groups, $group);
  2519. }
  2520. // ....................................................................
  2521. /**
  2522. * Set the working cell rowspan property. Use this method AFTER you
  2523. * have defined the cell with the td() method.
  2524. * @param integer $span Number of rows this cell will span.
  2525. */
  2526. function td_rowspan($span=1) {
  2527. $group = array_pop($this->groups);
  2528. $group->td_rowspan($span);
  2529. array_push($this->groups, $group);
  2530. }
  2531. // ....................................................................
  2532. /** Alias for td_css() */
  2533.  
  2534. function th_css($css="") { $this->td_css($css); }
  2535. /** Alias for td_contentcss() */
  2536.  
  2537. function th_contentcss($css="") { $this->td_contentcss($css); }
  2538. /** Alias for td_content() */
  2539.  
  2540. function th_content($text="", $css="") { $this->td_content($text, $css); }
  2541. /** Alias for td_alignment() */
  2542.  
  2543. function th_alignment($align="", $valign="") { $this->td_alignment($align, $valign); }
  2544. /** Alias for td_metrics() */
  2545.  
  2546. function th_metrics($width="", $height="") { $this->td_metrics($width, $height); }
  2547. /** Alias for td_width() */
  2548.  
  2549. function th_width($width="") { $this->td_width($width); }
  2550. /** Alias for td_height() */
  2551.  
  2552. function th_height($height="") { $this->td_height($height); }
  2553. /** Alias for td_colspan() */
  2554.  
  2555. function th_colspan($span="") { $this->td_colspan($span); }
  2556. /** Alias for td_rowspan() */
  2557.  
  2558. function th_rowspan($span="") { $this->td_rowspan($span); }
  2559. // ....................................................................
  2560. /**
  2561. * Return the index of the given group type.
  2562. * @param string $tag The tagname of the group to return the index of
  2563. * @return integer The index of the group type
  2564. * @access private
  2565. */
  2566. function get_group_index($tag) {
  2567. for ($gix=0; $gix < count($this->groups); $gix++) {
  2568. $gp = $this->groups[$gix];
  2569. if ($gp->tag == $tag) {
  2570. return $gix;
  2571. break;
  2572. }
  2573. }
  2574. return -1;
  2575. }
  2576. // ....................................................................
  2577. /**
  2578. * Poke some content into the given row,col cell..
  2579. * @param integer $row The row that the cell is in (0 = first row)
  2580. * @param integer $col The column that the cell is in
  2581. * @param string $content The content to put in the cell
  2582. * @param string $css Cell css setting, or omit to not set it.
  2583. * @param string $contentcss Cell content css setting, or omit to not set it.
  2584. * @param string $group The group to find the rows
  2585. * @return bool True if cell exists and was poked with the content
  2586. */
  2587. function poke_cell($row, $col, $content, $css="", $contentcss="", $group="tbody") {
  2588. $rc = false;
  2589. $gpix = $this->get_group_index($group);
  2590. if ($gpix != -1) {
  2591. $gp = $this->groups[$gpix];
  2592. $rc = $gp->poke_cell($row, $col, $content, $css, $contentcss);
  2593. $this->groups[$gpix] = $gp;
  2594. }
  2595. return $rc;
  2596. }
  2597. // ....................................................................
  2598. /**
  2599. * Poke a css class/style onto the given row,col cell..
  2600. * @param integer $row The row that the cell is in (0 = first row)
  2601. * @param integer $col The column that the cell is in
  2602. * @param string $css The class or style to put on the cell
  2603. * @param string $contentcss Cell content css setting, or omit to not set it.
  2604. * @param string $group The group to find the rows
  2605. * @return bool True if cell exists and was poked with the css
  2606. */
  2607. function poke_cellcss($row, $col, $css, $contentcss="", $group="tbody") {
  2608. $rc = false;
  2609. $gpix = $this->get_group_index($group);
  2610. if ($gpix != -1) {
  2611. $gp = $this->groups[$gpix];
  2612. $rc = $gp->poke_cellcss($row, $col, $css, $contentcss);
  2613. $this->groups[$gpix] = $gp;
  2614. }
  2615. return $rc;
  2616. }
  2617. // ....................................................................
  2618. /**
  2619. * Peek content from the given row,col cell..
  2620. * @param integer $row The row that the cell is in (0 = first row)
  2621. * @param integer $col The column that the cell is in
  2622. * @param string $group The group to find the rows
  2623. * @return string The cell contents, or nullstring if none/not valid
  2624. */
  2625. function peek_cell($row, $col, $group="tbody") {
  2626. $rc = "";
  2627. $gpix = $this->get_group_index($group);
  2628. if ($gpix != -1) {
  2629. $gp = $this->groups[$gpix];
  2630. $rc = $gp->peek_cell($row, $col);
  2631. }
  2632. return $rc;
  2633. }
  2634. // ....................................................................
  2635. /**
  2636. * Return the given cell from this group
  2637. * @param integer $row The row that the cell is in (0 = first row)
  2638. * @param integer $col The column that the cell is in (0 = first cell)
  2639. * @param string $group The group to find the rows
  2640. * @return string The table cell object, or false if none/not valid
  2641. */
  2642. function get_cell($row, $col, $group="tbody") {
  2643. $cell = false;
  2644. $gpix = $this->get_group_index($group);
  2645. if ($gpix != -1) {
  2646. $gp = $this->groups[$gpix];
  2647. $cell = $gp->get_cell($row, $col);
  2648. }
  2649. return $cell;
  2650. }
  2651. // ....................................................................
  2652. /**
  2653. * Replace the given cell with new table cell. Returns true if ok.
  2654. * @param integer $row The row that the cell is in (0 = first row)
  2655. * @param integer $col The column that the cell is in
  2656. * @param object $cell The new replacement table cell object
  2657. * @param string $group The group to find the rows
  2658. */
  2659. function set_cell($row, $col, $cell, $group="tbody") {
  2660. $rc = false;
  2661. $gpix = $this->get_group_index($group);
  2662. if ($gpix != -1) {
  2663. $gp = $this->groups[$gpix];
  2664. $rc = $gp->set_cell($row, $col, $cell);
  2665. $this->groups[$gpix] = $gp;
  2666. }
  2667. return $rc;
  2668. }
  2669. // ....................................................................
  2670. /**
  2671. * Check if given cell exists, return True is it does.
  2672. * @param integer $row The row that the cell is in (0 = first row)
  2673. * @param integer $col The column that the cell is in
  2674. * @param string $group The group to find the rows
  2675. * @return bool True if given cell exists, else false.
  2676. */
  2677. function cell_exists($row, $col, $group="tbody") {
  2678. $rc = false;
  2679. $gpix = $this->get_group_index($group);
  2680. if ($gpix != -1) {
  2681. $gp = $this->groups[$gpix];
  2682. if (isset($gp->rows[$row])) {
  2683. $r = $gp->rows[$row];
  2684. $rc = isset($r->cells[$col]);
  2685. }
  2686. }
  2687. return $rc;
  2688. }
  2689. // ....................................................................
  2690. /**
  2691. * Set permission on given table cell. Optionally specify the group
  2692. * which is being targetted (default table body). The specified cell
  2693. * will have its access permission set to the given perm.
  2694. * @param integer $row The row that the cell is in (0 = first row)
  2695. * @param integer $col The column that the cell is in
  2696. * @param mixed $agentids List or Array of unique IDs of agents to assign the permission for
  2697. * @param integer $perm The permission of combination of perms to assign
  2698. * @param string $group The group the cell is found in (defaults to table body)
  2699. */
  2700. function permit_cell($row, $col, $agentids, $perm, $group="tbody") {
  2701. if ($this->cell_exists($row, $col)) {
  2702. $cell = $this->get_cell($row, $col, $group);
  2703. $cell->permit($agentids, $perm);
  2704. $cell->cellid = "_tcell|$row|$col|$group";
  2705. $this->set_cell($row, $col, $cell, $group);
  2706. }
  2707. }
  2708. // ....................................................................
  2709. /**
  2710. * Unset permission on given table cell. Optionally specify the group
  2711. * which is being targetted (default table body). The specified cell
  2712. * will have its access permission unset from the given perms.
  2713. * @param integer $row The row that the cell is in (0 = first row)
  2714. * @param integer $col The column that the cell is in
  2715. * @param mixed $agentids List or Array of unique IDs of agents to unassign the permission for
  2716. * @param integer $perm The permission of combination of perms to unassign
  2717. * @param string $group The group the cell is found in (defaults to table body)
  2718. */
  2719. function unpermit_cell($row, $col, $agentids, $perm, $group="tbody") {
  2720. if ($this->cell_exists($row, $col)) {
  2721. $cell = $this->get_cell($row, $col, $group);
  2722. $cell->unpermit($agentids, $perm);
  2723. $cell->cellid = "_tcell|$row|$col|$group";
  2724. $this->set_cell($row, $col, $cell, $group);
  2725. }
  2726. }
  2727. // ....................................................................
  2728. /**
  2729. * Merge rows at a given cell column.
  2730. * @param integer $row The anchor row for the row merge to begin
  2731. * @param integer $col The column for the row merge
  2732. * @param integer $span The number of rows to merge
  2733. * @param string $group The group to merge rows in
  2734. */
  2735. function merge_rows($row, $col, $span, $group="tbody") {
  2736. $gpix = $this->get_group_index($group);
  2737. if ($gpix != -1) {
  2738. $gp = $this->groups[$gpix];
  2739. $gp->merge_rows($row, $col, $span);
  2740. $this->groups[$gpix] = $gp;
  2741. }
  2742. }
  2743. // ....................................................................
  2744. /**
  2745. * Split rows at a given cell column.
  2746. * @param integer $row The anchor row for the row split to begin
  2747. * @param integer $col The column for the row split
  2748. * @param string $group The group to split rows in
  2749. */
  2750. function split_rows($row, $col, $group="tbody") {
  2751. $gpix = $this->get_group_index($group);
  2752. if ($gpix != -1) {
  2753. $gp = $this->groups[$gpix];
  2754. $gp->split_rows($row, $col);
  2755. $this->groups[$gpix] = $gp;
  2756. }
  2757. }
  2758. // ....................................................................
  2759. /**
  2760. * Apply a colspan in an existing table. The row and column of the
  2761. * cell which has the colspan is given. As a result the relevant
  2762. * spanned cells will be merged in the table. If the span goes
  2763. * beyond the row end, it is truncated. NB: If the spanning cell
  2764. * is already spanning cells, then the span will extend this by the
  2765. * number given.
  2766. * @param integer $row The anchor row for the cell merge to begin
  2767. * @param integer $col The anchor column for the cell merge
  2768. * @param integer $span The number of cells to merge
  2769. * @param string $group The group to merge cells in
  2770. */
  2771. function merge_cols($row, $col, $span, $group="tbody") {
  2772. $gpix = $this->get_group_index($group);
  2773. if ($gpix != -1) {
  2774. $gp = $this->groups[$gpix];
  2775. $gp->merge_cols($row, $col, $span);
  2776. $this->groups[$gpix] = $gp;
  2777. }
  2778. }
  2779. // ....................................................................
  2780. /**
  2781. * Remove a colspan from an existing table. The row and column of the
  2782. * cell which has the colspan is given. As a result the relevant
  2783. * spanned cells will be removed from the table.
  2784. * @param integer $row The anchor row for the cell split to begin
  2785. * @param integer $col The anchor column for the cell split
  2786. * @param string $group The group to split cells in
  2787. */
  2788. function split_cols($row, $col, $group="tbody") {
  2789. $gpix = $this->get_group_index($group);
  2790. if ($gpix != -1) {
  2791. $gp = $this->groups[$gpix];
  2792. $gp->split_cols($row, $col);
  2793. $this->groups[$gpix] = $gp;
  2794. }
  2795. }
  2796. // ....................................................................
  2797. /**
  2798. * Insert a column into all rows in the table. If the template cell is
  2799. * not provided, then a 'vanilla' cell is used instead.
  2800. * @param integer $col Column position to insert at, in the table
  2801. * @param object $celltoinsert Template cell to use for inserting
  2802. */
  2803. function insert_cols($col, $celltoinsert=false) {
  2804. foreach ($this->groups as $gp) {
  2805. $gpix = $this->get_group_index($gp->tag);
  2806. $gp->insert_cols($col, $celltoinsert);
  2807. $this->groups[$gpix] = $gp;
  2808. }
  2809. }
  2810. // ....................................................................
  2811. /**
  2812. * Append columns onto all rows in the table.
  2813. * @param integer $repeat Number of columns to append to table
  2814. * @param object $celltoappend Template cell to use for appending
  2815. */
  2816. function append_cols($repeat=1, $celltoappend=false) {
  2817. foreach ($this->groups as $gp) {
  2818. $gpix = $this->get_group_index($gp->tag);
  2819. $gp->append_cols($repeat, $celltoappend);
  2820. $this->groups[$gpix] = $gp;
  2821. }
  2822. }
  2823. // ....................................................................
  2824. /**
  2825. * Remove a column from all rows in the table
  2826. * @param integer $col Column position to remove from the table
  2827. */
  2828. function delete_cols($col) {
  2829. foreach ($this->groups as $gp) {
  2830. $gpix = $this->get_group_index($gp->tag);
  2831. $gp->delete_cols($col);
  2832. $this->groups[$gpix] = $gp;
  2833. }
  2834. }
  2835. // ....................................................................
  2836. /**
  2837. * Remove a row from the table. If the template cell is not provided
  2838. * then a 'vanilla' cell is used.
  2839. * @param integer $row Row position to remove from the table
  2840. * @param string $group The group to remove row from
  2841. */
  2842. function delete_row($row, $group="tbody") {
  2843. $gpix = $this->get_group_index($group);
  2844. if ($gpix != -1) {
  2845. $gp = $this->groups[$gpix];
  2846. $gp->delete_row($row);
  2847. $this->groups[$gpix] = $gp;
  2848. }
  2849. }
  2850. // ....................................................................
  2851. /**
  2852. * Return a given row from the table.
  2853. * @param integer $row Row position to remove from the table
  2854. * @return object The row reqested, or false if non-existent.
  2855. */
  2856. function get_row($row, $group="tbody") {
  2857. $therow = false;
  2858. $gpix = $this->get_group_index($group);
  2859. if ($gpix != -1) {
  2860. $gp = $this->groups[$gpix];
  2861. $therow = $gp->get_row($row);
  2862. }
  2863. return $therow;
  2864. }
  2865. // ....................................................................
  2866. /**
  2867. * Insert a row into the table. If the template cell is not provided,
  2868. * then a 'vanilla' cell is used instead. We insert the new row just
  2869. * before the given row.
  2870. * @param integer $row Row position to insert before, in the table
  2871. * @param object $celltoinsert Template cell to use for all row cells
  2872. */
  2873. function insert_row($row, $celltoinsert=false) {
  2874. foreach ($this->groups as $gp) {
  2875. $gpix = $this->get_group_index($gp->tag);
  2876. $gp->insert_row($row, $celltoinsert);
  2877. $this->groups[$gpix] = $gp;
  2878. }
  2879. }
  2880. // ....................................................................
  2881. /**
  2882. * Append a row onto the table.
  2883. * @param object $celltoappend Template cell to use for appending the row
  2884. * @param string $group The group (default tbody) to append the row to
  2885. */
  2886. function append_row($celltoappend=false, $group="tbody") {
  2887. $gpix = $this->get_group_index($group);
  2888. if ($gpix != -1) {
  2889. $gp = $this->groups[$gpix];
  2890. $gp->append_row($celltoappend);
  2891. $this->groups[$gpix] = $gp;
  2892. }
  2893. }
  2894. // ....................................................................
  2895. /**
  2896. * Set a width profile across the row of cells. The profile is passed
  2897. * as either a string or an array. If a string, the widths should be
  2898. * separated by commas. The widths can be absolute pixel values or %'s,
  2899. * and applies these widths to the first row of the given group.
  2900. * An example string might for instance be '20%,15%,65%'.
  2901. * @param mixed $prof The width profile, array or comma-delimeted string
  2902. * @param string $group The group (default tbody) to append the row to
  2903. */
  2904. function set_width_profile($prof, $group="tbody") {
  2905. // Close any open group..
  2906. $this->close_group();
  2907. $wprofile = array();
  2908. if (is_array($prof)) {
  2909. $wprofile = $prof;
  2910. }
  2911. elseif (is_string($prof)) {
  2912. $wprofile = explode(",", $prof);
  2913. }
  2914. $gpix = $this->get_group_index($group);
  2915. if ($gpix != -1) {
  2916. $gp = $this->groups[$gpix];
  2917. $gp->set_width_profile($wprofile);
  2918. $this->groups[$gpix] = $gp;
  2919. }
  2920. }
  2921. // ....................................................................
  2922. /**
  2923. * Get the width profile from the table.
  2924. * @param string $group The group (default tbody) to append the row to
  2925. * @return array Width profile as an array of widths
  2926. */
  2927. function get_width_profile($group="tbody") {
  2928. $wprofile = array();
  2929. $gpix = $this->get_group_index($group);
  2930. if ($gpix != -1) {
  2931. $gp = $this->groups[$gpix];
  2932. $wprofile = $gp->get_width_profile();
  2933. $this->groups[$gpix] = $gp;
  2934. }
  2935. return $wprofile;
  2936. }
  2937. // ....................................................................
  2938. /** Render as WML.
  2939. * @return string The table as WML. */
  2940. function wml() {
  2941. return $this->html();
  2942. }
  2943. // ....................................................................
  2944. /**
  2945. * Render the whole table as HTML
  2946. * If dedbugging mode is enabled and the DBG_TABLES flag is set, then
  2947. * we run a simple validation check, and report findings, as well as
  2948. * making sure the table borders are visible.
  2949. * @return string The HTML for this table.
  2950. */
  2951. function html() {
  2952. // Close any open group..
  2953. $this->close_group();
  2954.  
  2955. // If we are debugging tables, make sure the border is displayed..
  2956. if (debugging() && (debug_class() & DBG_TABLES)) {
  2957. $this->setborder(1);
  2958. }
  2959. $s = "";
  2960. if (count($this->groups) > 0) {
  2961. $cols = $this->colcount();
  2962. $rows = $this->rowcount();
  2963. $s .= "\n<!--TBL[$this->tablename]$rows" . "x" . "$cols-->\n";
  2964. $s .= "<table";
  2965. $s .= " cellpadding=\"$this->cellpadding\"";
  2966. $s .= " cellspacing=\"$this->cellspacing\"";
  2967. $s .= $this->attributes();
  2968. $s .= ">\n";
  2969.  
  2970. // Auto-justify heading cells of thead group. This can only
  2971. // be done here, when we have tbody content available to us
  2972. // since we justify heading cells from first body row cells..
  2973. if ($this->autojustify) {
  2974. $gpix = $this->get_group_index("tbody");
  2975. if ($gpix != -1) {
  2976. $gp = $this->groups[$gpix];
  2977. $gp->autojustify();
  2978. $this->groups[$gpix] = $gp;
  2979. }
  2980. // Now deal with any heading row..
  2981. for ($gix=0; $gix < count($this->groups); $gix++) {
  2982. $gp = $this->groups[$gix];
  2983. switch ($gp->tag) {
  2984. case "thead": $gp_head = $gp; $gp_headix = $gix; break;
  2985. case "tbody": $gp_body = $gp; $gp_bodyix = $gix; break;
  2986. }
  2987. }
  2988. if (isset($gp_head) && isset($gp_body)) {
  2989. $headrow = $gp_head->rows[0]; $bodyrow = $gp_body->rows[0];
  2990. for ($col=0; $col < count($headrow->cells); $col++) {
  2991. if (isset($bodyrow->cells[$col])) {
  2992. $cell = $bodyrow->cells[$col];
  2993. if (is_numeric($cell->content->content)) $css = "text-align:right;";
  2994. else $css = "text-align:left;";
  2995. $cell = $headrow->cells[$col];
  2996. $cell->setcss($css);
  2997. $headrow->cells[$col] = $cell;
  2998. }
  2999. }
  3000. $gp_head->rows[0] = $headrow;
  3001. $this->groups[$gp_headix] = $gp_head;
  3002. }
  3003. }
  3004.  
  3005. // Apply rowstriping to tbody if defined..
  3006. if (count($this->rowstripes) > 0) {
  3007. $gpix = $this->get_group_index("tbody");
  3008. if ($gpix != -1) {
  3009. $gp = $this->groups[$gpix];
  3010. $gp->apply_rowstripes($this->rowstripes);
  3011. $this->groups[$gpix] = $gp;
  3012. }
  3013. }
  3014.  
  3015. // Now do each group tag in the order it should be. Note
  3016. // that these may have been added in a different order
  3017. // so we force it to be thead -> tbody -> tfoot here..
  3018. $thead = ""; $tbody = ""; $tfoot = "";
  3019. for ($g = 0; $g < count($this->groups); $g++) {
  3020. $group = $this->groups[$g];
  3021. switch ($group->tag) {
  3022. case "thead":
  3023. $thead .= $group->html();
  3024. break;
  3025. case "tbody":
  3026. $tbody .= $group->html();
  3027. break;
  3028. case "tfoot":
  3029. $tfoot .= $group->html();
  3030. break;
  3031. } // switch
  3032. // Group may have altered itself in the
  3033. // act of being rendered..
  3034. $this->groups[$g] = $group;
  3035. } // for
  3036.  
  3037. // Glue them together in correct order..
  3038. $s .= $thead . $tbody . $tfoot;
  3039.  
  3040. $s .= "</table>\n";
  3041. $s .= "<!--END[$this->tablename]-->";
  3042. }
  3043. // If we are debugging tables, display validation now..
  3044. if (debugging() && (debug_class() & DBG_TABLES)) {
  3045. $this->validate();
  3046. }
  3047. // Return the HTML
  3048. return $s;
  3049. }
  3050. // ....................................................................
  3051. /**
  3052. * Render the table as a CSV formatted stream. This is designed
  3053. * to facilitate the exporting of complex tables of data as CSV format
  3054. * for importing into spreadsheets, or databases etc.
  3055. * @return string The table content in CSV format.
  3056. */
  3057. function csv() {
  3058. $s = "";
  3059. // Close any open group..
  3060. $this->close_group();
  3061. if (count($this->groups) > 0) {
  3062. $thead = ""; $tbody = ""; $tfoot = "";
  3063. for ($g = 0; $g < count($this->groups); $g++) {
  3064. $group = $this->groups[$g];
  3065. switch ($group->tag) {
  3066. case "thead":
  3067. $thead .= $group->csv();
  3068. break;
  3069. case "tbody":
  3070. $tbody .= $group->csv();
  3071. break;
  3072. case "tfoot":
  3073. $tfoot .= $group->csv();
  3074. break;
  3075. } // switch
  3076. } // for
  3077. // Glue them together in correct order..
  3078. $s .= $thead . $tbody . $tfoot;
  3079. }
  3080. // Return the csv stream..
  3081. return $s;
  3082. } // csv
  3083.  
  3084. } // table class
  3085. // ----------------------------------------------------------------------
  3086.  
  3087. /**
  3088. * A matrix is a table with no colspans or rowspans. It is an N x M
  3089. * rectangle of table cells, and created to the given size from the
  3090. * outset. This is just a simple way in which you can obtain s vanilla
  3091. * table of given dimensions, with a single statement. All the table
  3092. * methods are then available.
  3093. * @package html
  3094. */
  3095. class matrix extends table {
  3096. /** Rows in table
  3097. @access private */
  3098. var $rows = 1;
  3099. /** Columns in table
  3100. @access private */
  3101. var $cols = 1;
  3102. /**
  3103. * Construct a new matrix.
  3104. * @param integer $rows Number of table rows in the matrix
  3105. * @param integer $cols Number of table columns in the matrix
  3106. * @param string $content Optional content for every cell of the table
  3107. */
  3108. function matrix($rows, $cols, $content="") {
  3109. $this->table();
  3110. for ($r = 0; $r < $rows; $r++) {
  3111. $this->tr();
  3112. for ($c = 0; $c < $cols; $c++) {
  3113. $this->td($content);
  3114. }
  3115. }
  3116. // Close any open group..
  3117. $this->close_group();
  3118. } // matrix
  3119.  
  3120. } // matrix class
  3121. // ----------------------------------------------------------------------
  3122.  
  3123. /**
  3124. * [A] - The anchor tag, otheriwse know as a clickable link.
  3125. * @package html
  3126. */
  3127. class anchor extends HTMLObject {
  3128. // Public
  3129. // Private
  3130. /** URL that clicking the link goes to
  3131. @access private */
  3132. var $href = "";
  3133. /** Link label text
  3134. @access private */
  3135. var $label = "";
  3136. /** Stylesheet class name for highlighted link
  3137. @access private */
  3138. var $highlightclass = false;
  3139. // ....................................................................
  3140. /** Constructor
  3141. * @param string $css The style or classname to apply to the object.
  3142. */
  3143. function anchor($href="", $label="", $css="") {
  3144. $this->HTMLObject($css);
  3145. $this->href = $href;
  3146. $this->label = $label;
  3147. } // anchor
  3148. // ....................................................................
  3149. /**
  3150. * Defines special highlight class name
  3151. * Defines the name of a class in your stylesheet to use for the
  3152. * purpose of highlighting. This property is initialised to be
  3153. * 'false', but if defined, then the link is spanned by a <span>
  3154. * tag with the given class name to highlight it accordingly.
  3155. */
  3156. function highlight($highlightclass) {
  3157. $this->highlightclass = $highlightclass;
  3158. } // highlight
  3159. // ....................................................................
  3160. /** Render the object as HTML */
  3161.  
  3162. function html() {
  3163. if ($this->href != "") {
  3164. $s = "<a href=\"$this->href\"";
  3165. $s .= $this->attributes();
  3166. $s .= ">";
  3167. if ($this->highlightclass != "") {
  3168. $s .= "<span class=\"$this->highlightclass\">".$this->label."</span>";
  3169. } else {
  3170. $s .= $this->label;
  3171. }
  3172. $s .= "</a>";
  3173. }
  3174. else {
  3175. if ($this->highlightclass != "") {
  3176. $s .= "<span class=\"$this->highlightclass\">".$this->label."</span>";
  3177. } else {
  3178. $s .= $this->label;
  3179. }
  3180. }
  3181. // Return the HTML..
  3182. return $s;
  3183. } // html
  3184.  
  3185. } // anchor class
  3186. // ----------------------------------------------------------------------
  3187.  
  3188. /**
  3189. * [HR] - Horizontal Rule
  3190. * @package html
  3191. */
  3192. class hr extends HTMLObject {
  3193. // Public
  3194. // Private
  3195. /** Whether HR is shaded or not
  3196. @access private */
  3197. var $shade = false;
  3198. /** Colour of the element
  3199. @access private */
  3200. var $colour = "";
  3201. // ....................................................................
  3202. /** Constructor
  3203. * @param string $width The width of the rule eg: '100%', '550' etc.
  3204. * @param integer $size The standard thickness of the rule (px)
  3205. * @param string $colour The colour code of the rule
  3206. * @param string $css The style or classname to apply to the object.
  3207. */
  3208. function hr($width="100%", $size=1, $colour="", $css="") {
  3209. $this->HTMLObject($css);
  3210. $this->setwidth($width);
  3211. $this->setsize($size);
  3212. $this->colour = $colour;
  3213. } // hr
  3214. // ....................................................................
  3215. /** Cause HR to be shaded */
  3216.  
  3217. function shade() {
  3218. $this->shade = true;
  3219. } // ade
  3220. // ....................................................................
  3221. /** Cause HR to be unshaded */
  3222.  
  3223. function noshade() {
  3224. $this->shade = false;
  3225. } // noshade
  3226. // ....................................................................
  3227. /** Render the object as HTML
  3228. * @return string The HTML of this object
  3229. */
  3230. function html() {
  3231. global $RESPONSE;
  3232. $s = "<hr";
  3233. if (!$this->shade) {
  3234. $s .= " noshade";
  3235. }
  3236. if ($this->size > 0) {
  3237. $this->setcss("height:$this->size" . "px;");
  3238. }
  3239. // The different browsers are pretty confused about HR colour..
  3240. if ($this->colour != "") {
  3241. if (isset($RESPONSE) && $RESPONSE->browser == BROWSER_IE) {
  3242. $this->setcss("color:$this->colour;");
  3243. }
  3244. else {
  3245. $this->setcss("background-color:$this->colour;");
  3246. }
  3247. }
  3248. $s .= $this->attributes();
  3249. $s .= ">\n";
  3250. // Return the HTML..
  3251. return $s;
  3252. } // html
  3253.  
  3254. } // hr class
  3255. // ----------------------------------------------------------------------
  3256.  
  3257. /**
  3258. * Item list
  3259. * Internal list class used to generate list HTML content
  3260. * @package html
  3261. * @access private
  3262. */
  3263. class itemlist extends HTMLobject {
  3264. // Public
  3265. // Private
  3266. /** Array of items (strings) to display
  3267. @access private */
  3268. var $list = array();
  3269. /** Type of list: 'list', 'ordered', or 'bullets'
  3270. @access private */
  3271. var $type = "bullets";
  3272. // ....................................................................
  3273. /** Constructor
  3274. * @param string $type The type of list to create
  3275. * @param string $css The style or classname to apply to the object.
  3276. */
  3277. function itemlist($type, $css="") {
  3278. $this->type = $type;
  3279. $this->HTMLobject($css);
  3280. } // itemlist
  3281. // ....................................................................
  3282. /**
  3283. * Add an item to the list.
  3284. * @param string $item The item to add
  3285. */
  3286. function additem($item="") {
  3287. $this->list[] = $item;
  3288. } // additem
  3289. // ....................................................................
  3290. /**
  3291. * Render the HTML
  3292. * @return string The HTML for this list.
  3293. */
  3294. function html() {
  3295. $s = "";
  3296. if (count($this->items) > 0) {
  3297. $tag = (($this->type == "bullets") ? "ul" : "ol");
  3298. $s = "<$tag" . $this->attributes() . ">";
  3299. foreach ($this->items as $item) {
  3300. if ($item != "") {
  3301. $s .= "<li" . $this->attributes() . ">$item";
  3302. }
  3303. }
  3304. $s .= "</$tag>";
  3305. }
  3306. // Return the HTML..
  3307. return $s;
  3308. } // html
  3309.  
  3310. } // itemlist class
  3311.  
  3312. /**
  3313. * [OL] - Ordered list
  3314. * @package html
  3315. */
  3316. class ol extends itemlist {
  3317. /** Constructor
  3318. * @param string $css The style or classname to apply to the object.
  3319. */
  3320. function ol($css="") {
  3321. $this->itemlist("ordered", $css);
  3322. }
  3323. } // ol
  3324. /**
  3325. * [UL] - Unordered list
  3326. * @package html
  3327. */
  3328. class ul extends itemlist {
  3329. /** Constructor
  3330. * @param string $css The style or classname to apply to the object.
  3331. */
  3332. function ul($css="") {
  3333. $this->itemlist("bullets", $css);
  3334. }
  3335. } // ul
  3336. /**
  3337. * [VL] - Vanilla list (suppressed markers)
  3338. * @package html
  3339. */
  3340. class vl extends itemlist {
  3341. /** Constructor
  3342. * @param string $css The style or classname to apply to the object.
  3343. */
  3344. function vl($css="") {
  3345. $this->itemlist("bullets", $css);
  3346. $this->setcss("list-style:none;");
  3347. }
  3348. } // vl
  3349. // ----------------------------------------------------------------------
  3350.  
  3351. /**
  3352. * [IMG] - The img class. This is an object which renders the img tag.
  3353. * @package html
  3354. */
  3355. class img extends HTMLObject {
  3356. /** Name of an image map */
  3357.  
  3358. var $map;
  3359. /** URL associated with the image */
  3360.  
  3361. var $url;
  3362. /** Target frame for URL */
  3363.  
  3364. var $target;
  3365. /** Image which acts as a clickable icon */
  3366.  
  3367. var $icon;
  3368. /** The image type: "GIF", "JPG", "PNG", "TIFF", "BMP".. */
  3369.  
  3370. var $image_type = "";
  3371. //.....................................................................
  3372. /**
  3373. * Constructor
  3374. * The src field is mandatory. The name is optional but if given it will
  3375. * also be used for the ALT tag. If a tooltip is not given then the name
  3376. * will also be used for that attribute.
  3377. * NB: If the width and/or height are not given and GD is installed it
  3378. * will be used to find the image dimensions, otherwise these attributes
  3379. * will be supressed and the browser left to work it out.
  3380. * @param string $src The path/URL of the image file
  3381. * @param string $name Name of the image object - also used as ALT tag
  3382. * @param string $tooltip The tooltip appears on mouseover for most browsers
  3383. * @param integer $width The width of the image in pixels
  3384. * @param integer $height The height of the image in pixels
  3385. */
  3386. function img($src, $name="", $tooltip="", $width=false, $height=false) {
  3387. $this->HTMLObject();
  3388. $this->set_image($src, $width, $height);
  3389. $this->setborder(0);
  3390. // Set name to image file if not given..
  3391. if ($name == "") {
  3392. $fbits = explode(".", basename($src));
  3393. $name = $fbits[0];
  3394. }
  3395. $this->setname($name);
  3396. $this->setalt($name);
  3397. $this->settitle($tooltip);
  3398. if ($this->title == "") {
  3399. $this->settitle($name);
  3400. }
  3401. } // img
  3402. //.....................................................................
  3403. /**
  3404. * Set the image src and details for this image object.
  3405. * @param string $src The path/URL of the image file
  3406. * @param integer $width The width of the image in pixels
  3407. * @param integer $height The height of the image in pixels
  3408. */
  3409. function set_image($src, $width=false, $height=false) {
  3410. global $RESPONSE;
  3411. $this->setsrc($src);
  3412. // Get image sizing if not specified. Try to ascertain the
  3413. // physical file path. We skip this for remote images..
  3414. $imgpath = $src;
  3415. if ($imgpath != "" && !protocol_prefixed($imgpath)) {
  3416. if (substr($imgpath, 0, 1) == "/") {
  3417. $imgpath = substr($imgpath, 1);
  3418. }
  3419. if (isset($RESPONSE)) {
  3420. $imgpath = "$RESPONSE->site_docroot/$imgpath";
  3421. }
  3422. if (is_readable($imgpath)) {
  3423. $imginfo = getimagesize($imgpath);
  3424. switch ($imginfo[2]) {
  3425. case 1: $this->image_type = "GIF"; break;
  3426. case 2: $this->image_type = "JPG"; break;
  3427. case 3: $this->image_type = "PNG"; break;
  3428. case 4: $this->image_type = "SWF"; break;
  3429. case 5: $this->image_type = "PSD"; break;
  3430. case 6: $this->image_type = "BMP"; break;
  3431. case 7: $this->image_type = "TIFF"; break;
  3432. case 15: $this->image_type = "WBMP"; break;
  3433. default: "??";
  3434. } // switch
  3435. if ($width === false) $width = $imginfo[0];
  3436. if ($height === false) $height = $imginfo[1];
  3437. }
  3438. }
  3439. if ($width !== false) $this->setwidth($width);
  3440. if ($height !== false) $this->setheight($height);
  3441. } // set_image
  3442. //.....................................................................
  3443. /** Set URL. When the image is clicked, the browser will target the
  3444. * URL. Note that this will not work if you have defined the onclick
  3445. * event handler.
  3446. * @param string $url The URL to go to when image is clicked.
  3447. * @param string $target The optional target frame, eg: '_blank' etc.
  3448. */
  3449. function seturl($url, $target="") {
  3450. $this->url = $url;
  3451. $this->target = $target;
  3452. } // seturl
  3453. //.....................................................................
  3454. /** Set image map
  3455. * Defines the image map to use with this image.
  3456. * @param string $map The name of the image map to associate with this image.
  3457. */
  3458. function use_map($map) {
  3459. $this->map = $map;
  3460. } // use_map
  3461. // ....................................................................
  3462. /** Render image as javascript object
  3463. * @return string Javascript code rendering of this image
  3464. */
  3465. function javascript() {
  3466. $js = "var $this->name=new Image($this->width,$this->height);\n";
  3467. $js .= "var $this->name src=\"$this->src\";\n";
  3468. return $js;
  3469. } // javascript
  3470. // ....................................................................
  3471. /** Render as WML.
  3472. * @return string The image as WML. */
  3473. function wml() {
  3474. return $this->html();
  3475. } // wml
  3476. // ....................................................................
  3477. /**
  3478. * Render the image object as an image 'icon' which can be clicked to
  3479. * display the object in a popup window.
  3480. * @param string $tooltip Optional browser mouseover tooltip text
  3481. * @param object $iconimage A custom image object
  3482. */
  3483. function AsIcon($tooltip="", $iconimage=false) {
  3484. global $RESPONSE, $LIBDIR;
  3485. if ($iconimage) {
  3486. $this->icon = $iconimage;
  3487. }
  3488. else {
  3489. $this->icon = new img("$LIBDIR/img/_image.gif", "Image");
  3490. }
  3491. if ($tooltip != "") {
  3492. $this->icon->title = $tooltip;
  3493. }
  3494. // Display the icon with onclickability..
  3495. if (isset($RESPONSE)) {
  3496. $RESPONSE->body->add_popup_script(
  3497. "vwimg_$this->name",
  3498. $this->width,
  3499. $this->height,
  3500. false,
  3501. false,
  3502. "toolbar=no,status=no,scrollbars=no,resizable=yes"
  3503. );
  3504. $this->icon->set_onclick("vwimg_$this->name" . "('$this->src')");
  3505. //$s = $this->icon->render();
  3506. }
  3507. else {
  3508. // Use vanilla new browser window approach..
  3509. $this->url = $this->src;
  3510. $this->set_image("$LIBDIR/img/_image.gif");
  3511. $this->target = "_new";
  3512. //$s = $this->html();
  3513. }
  3514. //return $s;
  3515. } // AsIcon
  3516. // ....................................................................
  3517. /** Render as HTML
  3518. * @return string The image as HTML. */
  3519. function html() {
  3520. global $RESPONSE;
  3521.  
  3522. if ( isset($this->icon) ) {
  3523. $s = $this->icon->render();
  3524. } else {
  3525. $s = "";
  3526. if (isset($this->url) && $this->url != "") {
  3527. $s .= "<a href=\"$this->url\"";
  3528. if ($this->target != "") {
  3529. $s .= " target=\"$this->target\"";
  3530. }
  3531. $s .= ">";
  3532. }
  3533. $s .= "<img";
  3534. if (isset($this->map) && $this->map != "") {
  3535. $s .= " usemap=\"$this->map\"";
  3536. }
  3537. $s .= $this->attributes();
  3538. $s .= ">";
  3539. if (isset($this->url) && $this->url != "") {
  3540. $s .= "</a>";
  3541. }
  3542. }
  3543. return $s;
  3544. } // html
  3545.  
  3546. } // img class
  3547. // ----------------------------------------------------------------------
  3548.  
  3549. /**
  3550. * Deprecated embed Object (HTML3.2)
  3551. * This object supports the older embed tag used to embed objects
  3552. * into HTML pages. for backward compatibility. In reality there is
  3553. * still a lot of mileage left in this tag.
  3554. * @package html
  3555. */
  3556. class embed extends HTMLObject {
  3557. // Public
  3558. /** Name of Java file, if java applet */
  3559.  
  3560. var $code;
  3561. /** Base URL for plug-in or potenial java applet (IE) */
  3562.  
  3563. var $codebase;
  3564. /** URL of page to acquire the relevant object plugin */
  3565.  
  3566. var $pluginspage;
  3567. /** The MIME type of the object */
  3568.  
  3569. var $mimetype;
  3570. /** If true the object is hidden */
  3571.  
  3572. var $hidden = false;
  3573.  
  3574. // Private
  3575. /** Array of non-std attributes as name/value pairs
  3576. @access private */
  3577. var $other_attributes = array();
  3578. // ....................................................................
  3579. /** Constructor
  3580. * @param string $src The URL of the source data for this object
  3581. * @param string $mimetype The MIMETYPE of this object, eg: 'application/x-sockwave-flash' etc.
  3582. * @param string $pluginspage The URL for downloading the relevant plugin
  3583. * @param string $width Width of object in pixels
  3584. * @param string $height Height of object in pixels
  3585. * @param string $alt ALT text to display if object does not execute
  3586. */
  3587. function embed($src="", $mimetype="", $pluginspage="", $width="", $height="", $alt="", $hidden=false) {
  3588. $this->HTMLObject();
  3589. if ($src != "") $this->setsrc($src);
  3590. if ($mimetype != "") $this->mimetype = $mimetype;
  3591. if ($pluginspage != "") $this->pluginspage = $pluginspage;
  3592. if ($width != "") $this->setwidth($width);
  3593. if ($height != "") $this->setheight($height);
  3594. if ($alt != "") $this->setalt($alt);
  3595. $this->hidden = $hidden;
  3596. } // embed
  3597. // ....................................................................
  3598. /**
  3599. * Specify the parameters required for a Java applet, the name
  3600. * of the file containing the applet code, and the URL to find
  3601. * the file at.
  3602. * @param string $code The name of the file contaiing the applet
  3603. * @param string $codebase The URL to locate the code file at
  3604. */
  3605. function java_applet($code, $codebase="") {
  3606. $this->code = $code;
  3607. if ($codebase != "") $this->codebase = $codebase;
  3608. } // java_applet
  3609. // ....................................................................
  3610. /**
  3611. * Add non-standard attribute to be rendered.
  3612. * @param string $name Name of the new attribute
  3613. * @param string $value Value of the new attribute
  3614. */
  3615. function add_attribute($name, $value) {
  3616. $this->other_attributes[$name] = $value;
  3617. } // add_attribute
  3618. // ....................................................................
  3619. function html() {
  3620. $s = "";
  3621. $s .= "<embed";
  3622. if (isset($this->pluginspage)) $s .= " pluginspage=\"$this->pluginspage\"";
  3623. if (isset($this->mimetype)) $s .= " type=\"$this->mimetype\"";
  3624. if (isset($this->code)) $s .= " code=\"$this->code\"";
  3625. if (isset($this->codebase)) $s .= " codebase=\"$this->codebase\"";
  3626. if (isset($this->quality)) $s .= " quality=\"$this->quality\"";
  3627. $s .= " hidden=" . ($this->hidden ? "\"true\"" : "\"false\"");
  3628. $s .= $this->attributes();
  3629. while ( list($name, $value) = each($this->other_attributes)) {
  3630. $s .= " $name=\"$value\"";
  3631. }
  3632. $s .= ">";
  3633. // Return the HTML..
  3634. return $s;
  3635. } // html
  3636.  
  3637. } // embed class
  3638. // ----------------------------------------------------------------------
  3639.  
  3640. /**
  3641. * Object
  3642. * This HTML4 entity is the preferred method for embedding objects into a
  3643. * webpage using the object tag. The only drawback is that a lot of browsers
  3644. * don't support it fully, hence the older embed tag is also available for
  3645. * use as a fallback mechanism via the add_embed() method.
  3646. * @see function add_embed
  3647. * @package html
  3648. */
  3649. class EmbeddedObject extends HTMLObject {
  3650. // Public
  3651. /** MIME type of data required by the object */
  3652.  
  3653. var $mimetype = "";
  3654. /** URL for the object's implementation */
  3655.  
  3656. var $classid;
  3657. /** URL for relative base for accessing object
  3658. specified by the classid */
  3659. var $codebase;
  3660. /** URL of data object might require */
  3661.  
  3662. var $data;
  3663. /** Object MIME type */
  3664.  
  3665. var $codetype;
  3666. /** Standby message text */
  3667.  
  3668. var $standby;
  3669. /** URL of page to acquire the relevant embed plugin */
  3670.  
  3671. var $pluginspage = "";
  3672. /** MIMETYPE of file by using its extension */
  3673.  
  3674. var $extn_mimetype = "";
  3675. /** Mimetype category, eg: 'movie', 'audio' etc. */
  3676.  
  3677. var $category = "";
  3678. /** Image which acts as a play icon */
  3679.  
  3680. var $icon;
  3681.  
  3682. // Private
  3683. /** Array of parameter key-values
  3684. @access private */
  3685. var $params = array();
  3686. /** If set, contains a EmbeddedObject_Compat object to
  3687. be rendered in this object for compatibility
  3688. @access private */
  3689. var $embed_obj;
  3690. /** Internal name sans spaces
  3691. @access private */
  3692. var $internal_name = "obj";
  3693. /** If not empty, render as a link using $aslink as the text
  3694. @access private */
  3695. var $aslink = "";
  3696. /** Target frame for the $aslink
  3697. @access private */
  3698. var $aslink_target = "";
  3699. // ....................................................................
  3700. /** Constructor
  3701. * @param string $src URL of the source datafor the object, if any
  3702. * @param string $mimetype Mimetypeof the embedded object
  3703. * @param string $classid The classid (CLSID) unique ID of this object
  3704. * @param integer $width Width of object
  3705. * @param integer $height Height of object
  3706. * @param string $codebase URL of code location for this object
  3707. * @param string $standby Standby message whilst loading
  3708. */
  3709. function EmbeddedObject(
  3710. $src="",
  3711. $mimetype="",
  3712. $classid="",
  3713. $width=0,
  3714. $height=0,
  3715. $codebase="",
  3716. $standby="Loading..")
  3717. {
  3718. $this->HTMLobject();
  3719. // Deal with source file, mimetype and category..
  3720. if($src != "") {
  3721. $this->data = $src;
  3722. $file = basename($src);
  3723. $fnbits = explode(".", $file);
  3724. $this->setname($fnbits[0]);
  3725. $this->internal_name = md5(preg_replace("/[ \-,.;:_{}()<>\"\'\`\+\=]/", "", $this->name));
  3726. $mime = mimetype_from_filename($src);
  3727. if ($mime) {
  3728. $this->extn_mimetype = $mime;
  3729. }
  3730. else {
  3731. $this->extn_mimetype = "";
  3732. }
  3733. $this->category = mimetype_category($this->extn_mimetype);
  3734. }
  3735. if ($mimetype != "") {
  3736. $this->mimetype = $mimetype;
  3737. }
  3738. else {
  3739. $this->mimetype = $this->extn_mimetype;
  3740. }
  3741. if ($classid != "") $this->classid = $classid;
  3742. $this->setwidth($width);
  3743. $this->setheight($height);
  3744. if ($codebase != "") $this->codebase = $codebase;
  3745. if ($standby != "") $this->standby = $standby;
  3746. } // EmbeddedObject
  3747. // ....................................................................
  3748. /**
  3749. * Set up a new object parameter name/value pair. This will be rendered
  3750. * as a param name="foo" value="bar" tag.
  3751. * @param string $name Name of the new param entity
  3752. * @param string $value Value of the new param entity
  3753. */
  3754. function setparam($name, $value) {
  3755. if (trim($name) != "") {
  3756. $this->params[trim($name)] = trim($value);
  3757. }
  3758. } // setparam
  3759. // ....................................................................
  3760. /**
  3761. * Add an embed object to provide fallback for browsers which do not
  3762. * support the object tag properly.
  3763. * @param string $src The URL of the source data for this object
  3764. * @param string $pluginspage The URL for downloading the relevant plugin
  3765. */
  3766. function add_embed($src="", $pluginspage="") {
  3767. $this->embed_obj =
  3768. new embed(
  3769. $src,
  3770. $this->mimetype,
  3771. $pluginspage
  3772. );
  3773. } // add_embed
  3774. // ....................................................................
  3775. /**
  3776. * Render the object as a simple link. The parameter passed will be
  3777. * the text of the link, and the URL is determined by the location
  3778. * of the object as specified in the constructor.
  3779. * @param string $linktext Text to use for the link
  3780. */
  3781. function AsLink($linktext="", $target="") {
  3782. $this->aslink = $linktext;
  3783. $this->aslink_target = $target;
  3784. } // AsLink
  3785. // ....................................................................
  3786. /** Render the HTML
  3787. * @return string HTML for this object
  3788. */
  3789. function html() {
  3790. $s = "";
  3791. if($this->aslink != "") {
  3792. $s .= "<a href=\"$this->data\"";
  3793. if ($this->aslink_target != "") {
  3794. $s .= " target=\"_blank\"";
  3795. }
  3796. $s .= ">";
  3797. $s .= $this->aslink;
  3798. $s .= "</a>";
  3799. }
  3800. else {
  3801. $s .= "<object";
  3802. $s .= $this->attributes();
  3803. if (isset($this->classid)) $s .= " classid=\"$this->classid\"";
  3804. if (isset($this->codebase)) $s .= " codebase=\"$this->codebase\"";
  3805. if (isset($this->data)) $s .= " data=\"$this->data\"";
  3806. if (isset($this->codetype)) $s .= " codetype=\"$this->codetype\"";
  3807. if ($this->mimetype != "") $s .= " type=\"$this->mimetype\"";
  3808. if (isset($this->standby)) $s .= " standby=\"$this->standby\"";
  3809. $s .= ">";
  3810.  
  3811. // Add param items..
  3812. while ( list($name, $value) = each($this->params)) {
  3813. $s .= "<param name=\"$name\" value=\"$value\">";
  3814. }
  3815. // Add fallback <embed> object..
  3816. if (isset($this->embed_obj)) {
  3817. $this->embed_obj->width = $this->width;
  3818. $this->embed_obj->height = $this->height;
  3819. $this->embed_obj->mimetype = $this->mimetype;
  3820. if (isset($this->standby)) {
  3821. $this->embed_obj->alt = $this->standby;
  3822. }
  3823. $s .= $this->embed_obj->html();
  3824. }
  3825. $s .= "</object>";
  3826. }
  3827. // Return the html..
  3828. return $s;
  3829. } // html
  3830.  
  3831. } // EmbeddedObject class
  3832. // ----------------------------------------------------------------------
  3833.  
  3834. /** Macromedia Flash Windows CLASS ID */
  3835. ("FLASH_CLSID", "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000");
  3836. /** Macromedia Flash Codebase - where to download the player */
  3837. ("FLASH_CODEBASE", "http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=5,0,0,0");
  3838. /** Macromedia Flash Plugins plage - support for other platforms */
  3839. ("FLASH_PLUGINSPAGE", "http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash");
  3840. /** Macromedia Flash MimeType */
  3841. ("FLASH_MIMETYPE", "application/x-shockwave-flash");
  3842. /**
  3843. * Macromedia Shockwave/Flash Object
  3844. * @package html
  3845. */
  3846. class FlashObject extends EmbeddedObject {
  3847. /* URL of Flash movie */
  3848. var $movie = "";
  3849. /** Quality setting for the movie */
  3850.  
  3851. var $quality = "high";
  3852. // ....................................................................
  3853. /** Constructor
  3854. * @param string $movie URL of the flash movie file
  3855. * @param integer $width Width in pixels of the movie
  3856. * @param integer $height Height in pixels of the movie
  3857. * @param string $quality Quality spec of the movie
  3858. * @param string $standby Optional message to display while loading
  3859. */
  3860. function FlashObject($movie, $width="", $height="", $quality="high", $standby="") {
  3861. $this->movie = $movie;
  3862. // These attributes are defined by Macromedia for Flash content..
  3863. $classid = FLASH_CLSID;
  3864. $codebase = FLASH_CODEBASE;
  3865. $this->pluginspage = FLASH_PLUGINSPAGE;
  3866. $this->EmbeddedObject($movie, FLASH_MIMETYPE, $classid, $width, $height, $codebase, $standby);
  3867. $this->quality = $quality;
  3868. } // FlashObject
  3869. // ....................................................................
  3870. /**
  3871. * Render the flash object as an image 'icon' which can be clicked to play
  3872. * the movie. If image is specified, it must be a valid 'image' object,
  3873. * otherwise a generic library symbol will be used.
  3874. * @param string $tooltip Optional browser mouseover tooltip text
  3875. * @param object $iconimage A custom image object
  3876. * @see img
  3877. */
  3878. function AsIcon($tooltip="", $iconimage=false) {
  3879. global $RESPONSE, $LIBDIR;
  3880. if ($iconimage) {
  3881. $this->icon = $iconimage;
  3882. }
  3883. else {
  3884. $this->icon = new img("$LIBDIR/img/_flash.gif", "Play");
  3885. }
  3886. if ($tooltip != "") {
  3887. $this->icon->title = $tooltip;
  3888. }
  3889. } // AsIcon
  3890. // ....................................................................
  3891. /** Render the HTML
  3892. * @return string HTML for this object
  3893. */
  3894. function html() {
  3895. global $RESPONSE;
  3896. $s = "";
  3897. if ($RESPONSE->browser != BROWSER_IE) {
  3898. // Need one of these for compatibility..
  3899. $this->embed_obj =
  3900. new embed(
  3901. $this->movie,
  3902. FLASH_MIMETYPE,
  3903. $this->pluginspage,
  3904. $this->width,
  3905. $this->height,
  3906. $this->standby
  3907. );
  3908. $this->embed_obj->add_attribute("quality", $this->quality);
  3909. }
  3910. $this->setparam("movie", $this->movie);
  3911. $this->setparam("quality", $this->quality);
  3912.  
  3913. // If we are doing a clickable image, we need the aid of
  3914. // some handy javascript to make it work..
  3915. if (isset($this->icon)) {
  3916. $this->icon->set_onclick("play_$this->internal_name('$this->name')");
  3917. $embeddedMedia = EmbeddedObject::html();
  3918. $RESPONSE->body->add_popup_script("popup_$this->internal_name", $this->width, $this->height, 100, 40);
  3919. $RESPONSE->body->add_script(
  3920. "var playing=false;\n"
  3921. . "function play_$this->internal_name(pname) {\n"
  3922. . " popup_$this->internal_name('');\n"
  3923. . " with (popup_" . $this->internal_name . "Win.document) {\n"
  3924. . " open();\n"
  3925. . " write('');\n"
  3926. . " write('<body bgcolor=\"#333333\" leftmargin=\"0\" rightmargin=\"0\" topmargin=\"0\" marginwidth=\"0\" marginheight=\"0\">');\n"
  3927. . " write('<center><font face=arial,helvetica size=2>');\n"
  3928. . " write('$embeddedMedia');\n"
  3929. . " title='$this->name';\n"
  3930. . " close();\n"
  3931. . " }\n"
  3932. . "}\n"
  3933. );
  3934. $s .= $this->icon->render();
  3935. }
  3936. else {
  3937. $s .= EmbeddedObject::html();
  3938. }
  3939. // Return html..
  3940. return $s;
  3941. } // html
  3942.  
  3943. } // FlashObject class
  3944. // ----------------------------------------------------------------------
  3945.  
  3946. /** Windows Media Player CLASS ID */
  3947. ("WM_CLSID", "CLSID:22D6f312-B0F6-11D0-94AB-0080C74C7E95");
  3948. /** Windows Media Player Codebase - where to download the player */
  3949. ("WM_CODEBASE", "http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=6,4,7,1112");
  3950. /** Windows Media Player - General plugins page for other platforms */
  3951. ("WM_PLUGINSPAGE", "http://www.microsoft.com/Windows/MediaPlayer/");
  3952. /** Windows Media Player - MimeType */
  3953. ("WM_MIMETYPE", "application/x-mplayer2");
  3954. /** Used to indicate sound should start playing on load */
  3955. ("AUTOSTART", true);
  3956. /** Used to indicate sound should loop indefinitely */
  3957. ("LOOP", true);
  3958. /** Used to hide the object control */
  3959. ("HIDDEN", true);
  3960. /**
  3961. * Generic Multimedia Object
  3962. * @package html
  3963. */
  3964. class MediaObject extends EmbeddedObject {
  3965. /* URL of media file */
  3966. var $media = "";
  3967. /** If true the media start immediately it is loaded */
  3968.  
  3969. var $autostart = false;
  3970. /** If true the media replays endlessly */
  3971.  
  3972. var $loop = false;
  3973. /** If true the media object is hidden */
  3974.  
  3975. var $hidden = false;
  3976. /** If true the mediaplayer controls are shown */
  3977.  
  3978. var $showcontrols = true;
  3979. // ....................................................................
  3980. /** Constructor
  3981. * @param string $media URL of the media file
  3982. * @param integer $width Width in pixels of the media object
  3983. * @param integer $height Height in pixels of the media object
  3984. * @param boolean $autostart True if you want the media to auto-start on load
  3985. * @param boolean $loop True if you want the media to repeat endlessly
  3986. * @param boolean $hidden True if you want the media to be hidden from view
  3987. * @param string $standby Standby message whilst loading
  3988. */
  3989. function MediaObject($media, $width="", $height="", $autostart=false, $loop=false, $showcontrols=true, $hidden=false, $standby="Loading..") {
  3990. global $RESPONSE, $LIBDIR;
  3991. $this->media = $media;
  3992. $this->autostart = $autostart;
  3993. $this->loop = $loop;
  3994. $this->showcontrols = $showcontrols;
  3995. $this->hidden = $hidden;
  3996. // Set up parameters according to browser..
  3997. if ($RESPONSE->browser == BROWSER_IE) {
  3998. $classid = WM_CLSID;
  3999. $codebase = WM_CODEBASE;
  4000. $this->pluginspage = WM_PLUGINSPAGE;
  4001. $mimetype = WM_MIMETYPE;
  4002. }
  4003. else {
  4004. $mimetype = $this->extn_mimetype;
  4005. }
  4006. $this->EmbeddedObject($media, $mimetype, $classid, $width, $height, $codebase, $standby);
  4007. } // MediaObject
  4008. // ....................................................................
  4009. /**
  4010. * Render the media object as an image 'icon' which can be clicked to play
  4011. * the media. If image is specified, it must be a valid 'image' object,
  4012. * otherwise a generic library symbol will be used.
  4013. * @param string $tooltip Optional browser mouseover tooltip text
  4014. * @param object $iconimage A custom image object
  4015. * @see img
  4016. */
  4017. function AsIcon($tooltip="", $iconimage=false) {
  4018. global $RESPONSE, $LIBDIR;
  4019. // Make sounds invisible..
  4020. switch ($this->category) {
  4021. case "audio":
  4022. $this->hidden = true;
  4023. $this->setwidth(0);
  4024. $this->setheight(0);
  4025. break;
  4026. default:
  4027. $this->hidden = false;
  4028. break;
  4029. }
  4030. if ($iconimage) {
  4031. $this->icon = $iconimage;
  4032. }
  4033. else {
  4034. switch ($this->category) {
  4035. case "audio":
  4036. $this->icon = new img("$LIBDIR/img/_sound.gif", "Play");
  4037. break;
  4038. default:
  4039. $this->icon = new img("$LIBDIR/img/_movie.gif", "Play");
  4040. break;
  4041. } // switch
  4042. }
  4043. if ($tooltip != "") {
  4044. $this->icon->title = $tooltip;
  4045. }
  4046. } // AsIcon
  4047. // ....................................................................
  4048. /** Render the HTML
  4049. * @return string HTML for this object
  4050. */
  4051. function html() {
  4052. global $RESPONSE, $LIBDIR;
  4053. $s = "";
  4054. // Render the object itself..
  4055. $this->embed_obj =
  4056. new embed(
  4057. $this->media,
  4058. $this->extn_mimetype,
  4059. $this->pluginspage,
  4060. $this->width,
  4061. $this->height,
  4062. $this->standby
  4063. );
  4064. $this->embed_obj->hidden = $this->hidden;
  4065. $this->embed_obj->add_attribute("autostart", ($this->autostart ? "true" : "false"));
  4066. $this->embed_obj->add_attribute("loop", ($this->loop ? "true" : "false"));
  4067.  
  4068. // Do Windows Media Player params for Internet Explorer..
  4069. if ($RESPONSE->browser == BROWSER_IE) {
  4070. $this->setparam("FileName", $this->media);
  4071. $this->setparam("PlayCount", ($this->loop ? "0" : "1"));
  4072. $this->setparam("Volume", "4");
  4073. $this->setparam("ShowControls", ($this->showcontrols ? "true" : "false"));
  4074. $this->setparam("TransparentAtStart", ($this->hidden ? "true" : "false"));
  4075. $this->setparam("AutoStart", ($this->autostart ? "true" : "false"));
  4076. $this->setparam("ShowStatusBar", "false");
  4077. }
  4078.  
  4079. // If we are doing a clickable image, we need the aid of
  4080. // some handy javascript to make it work..
  4081. if (isset($this->icon)) {
  4082. switch ($RESPONSE->browser){
  4083. // For IE we can do the full nine yards and open a special
  4084. // window where we put the embedded object..
  4085. case BROWSER_IE:
  4086. // Play all media in separate window..
  4087. $this->icon->set_onclick("play_$this->internal_name('$this->name')");
  4088. switch ($this->category) {
  4089. // Play movies in a separate window..
  4090. case "movie":
  4091. $embeddedMedia = EmbeddedObject::html();
  4092. $RESPONSE->body->add_popup_script("popup_$this->internal_name", $this->width, $this->height, 100, 40);
  4093. $RESPONSE->body->add_script(
  4094. "var playing=false;\n"
  4095. . "function play_$this->internal_name(pname) {\n"
  4096. . " popup_$this->internal_name('');\n"
  4097. . " with (popup_" . $this->internal_name . "Win.document) {\n"
  4098. . " open();\n"
  4099. . " write('');\n"
  4100. . " write('<body bgcolor=\"#333333\" leftmargin=\"0\" rightmargin=\"0\" topmargin=\"0\" marginwidth=\"0\" marginheight=\"0\">');\n"
  4101. . " write('<center><font face=arial,helvetica size=2>');\n"
  4102. . " write('$embeddedMedia');\n"
  4103. . " title='$this->name';\n"
  4104. . " close();\n"
  4105. . " }\n"
  4106. . "}\n"
  4107. );
  4108. break;
  4109. // Play sounds in current window..
  4110. case "audio":
  4111. $RESPONSE->body->add_script(
  4112. "var playing=false;\n"
  4113. . "function play_$this->internal_name(pname) {\n"
  4114. . " player=eval('document.' + pname);\n"
  4115. . " if (player != null) {\n"
  4116. . " if (playing) {player.Stop();playing=false;}\n"
  4117. . " else {player.Play();playing=true;}\n"
  4118. . " }\n"
  4119. . "}\n"
  4120. );
  4121. // Embed the object in this page..
  4122. $s .= EmbeddedObject::html();
  4123. break;
  4124. } //switch category
  4125. $s .= $this->icon->render();
  4126. break;
  4127.  
  4128. // For other browsers we take a slightly more vanilla approach.
  4129. // The click opens a window, with URL set to the media itself.
  4130. // This should get the browser to utilize plugin/helper et al..
  4131. default:
  4132. // Play all media in separate window..
  4133. $RESPONSE->body->add_popup_script("popup_$this->internal_name", $this->width, $this->height, 100, 40);
  4134. $this->icon->set_onclick("popup_$this->internal_name('$this->media')");
  4135. $s .= $this->icon->render();
  4136. break;
  4137.  
  4138. } // switch on browser
  4139. }
  4140. else {
  4141. // No icon, just an embedded object. In this case we will
  4142. // expect problems for browsers other than IE, but c'est la vie..
  4143. $s .= EmbeddedObject::html();
  4144. }
  4145. // Return the HTML..
  4146. return $s;
  4147. } // html
  4148.  
  4149. } // MediaObject class
  4150. // ----------------------------------------------------------------------
  4151.  
  4152. /**
  4153. * Document Object
  4154. * In actual fact, we don't view Documents as Embedded objects, and instead
  4155. * we provide a link to either open a new window, or target a new browser
  4156. * window. We point the URL'sto the document, and let the system do
  4157. * what it thinks best after that.
  4158. * @package html
  4159. */
  4160. class DocumentObject extends EmbeddedObject {
  4161. /* URL of document file */
  4162. var $docurl = "";
  4163. // ....................................................................
  4164. /** Constructor
  4165. * @param string $docurl URL of the document file
  4166. * @param integer Width of window showing spreaddocurl
  4167. * @param integer Height of window showing spreaddocurl
  4168. */
  4169. function DocumentObject($docurl, $width="", $height="") {
  4170. global $RESPONSE, $LIBDIR;
  4171. $this->docurl = $docurl;
  4172. $classid = "";
  4173. $this->pluginspage = "";
  4174. $mimetype = "";
  4175. $codebase = "";
  4176. $this->EmbeddedObject($docurl, $mimetype, $classid, $width, $height);
  4177. } // DocumentObject
  4178. // ....................................................................
  4179. /**
  4180. * Render the document object as an image 'icon' which can be clicked to play
  4181. * the media. If image is specified, it must be a valid 'image' object,
  4182. * otherwise a generic library symbol will be used.
  4183. * @param string $tooltip Optional browser mouseover tooltip text
  4184. * @param object $iconimage A custom image object
  4185. * @see img, @see clickable_image
  4186. */
  4187. function AsIcon($tooltip="", $iconimage=false) {
  4188. global $RESPONSE, $LIBDIR;
  4189. if ($iconimage) {
  4190. $this->icon = $iconimage;
  4191. }
  4192. else {
  4193. debugbr("image mime type: ".$this->extn_mimetype);
  4194. switch ($this->extn_mimetype) {
  4195. case CONTENT_MSEXCEL:
  4196. $this->icon = new img("$LIBDIR/img/_excel.gif", "Excel Spreadsheet");
  4197. break;
  4198. case CONTENT_MSWORD:
  4199. $this->icon = new img("$LIBDIR/img/_msword.gif", "Word Document");
  4200. break;
  4201. case CONTENT_PDF:
  4202. $this->icon = new img("$LIBDIR/img/_pdf.gif", "PDF Document");
  4203. break;
  4204. default:
  4205. $this->icon = new img("$LIBDIR/img/_document.gif", "Document");
  4206. } // switch
  4207. }
  4208. if ($tooltip != "") {
  4209. $this->icon->title = $tooltip;
  4210. }
  4211. } // AsIcon
  4212. // ....................................................................
  4213. /** Render the HTML
  4214. * @return string HTML for this object
  4215. */
  4216. function html() {
  4217. global $RESPONSE, $LIBDIR;
  4218. $s = "";
  4219. // If we are doing a clickable image, we need the aid of
  4220. // some handy javascript to make it work..
  4221. if (isset($this->icon)) {
  4222. // Spreaddocurl in separate window..
  4223. $RESPONSE->body->add_popup_script(
  4224. "popup_$this->internal_name",
  4225. $this->width,
  4226. $this->height,
  4227. 100,
  4228. 40,
  4229. "toolbar=yes,status=yes,scrollbars=yes,resizable=yes"
  4230. );
  4231. $this->icon->set_onclick("popup_$this->internal_name('$this->docurl')");
  4232. $s .= $this->icon->render();
  4233. }
  4234. else {
  4235. // No icon, so we render the object. Note: embedding documents is
  4236. // bound to end in tears, so always render AsLink in your app..
  4237. $s .= EmbeddedObject::html();
  4238. }
  4239. // Return the HTML..
  4240. return $s;
  4241. } // html
  4242.  
  4243. } // DocumentObject class
  4244. // ----------------------------------------------------------------------
  4245.  
  4246. ?>

Documentation generated by phpDocumentor 1.3.0RC3