Source for file webpage-defs.php

Documentation is available at webpage-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: webpage-defs.php */
  22. /* Author: Paul Waite */
  23. /* Description: Definitions for managing web-pages. */
  24. /* */
  25. /* ******************************************************************** */
  26. /** @package core */
  27. include_once("plugin-defs.php");
  28. /** Date-time functions */
  29. ("datetime-defs.php");
  30.  
  31. // ----------------------------------------------------------------------
  32. // Flag determining whether webpage is cached or not..
  33.  
  34. /** The webpage is cached */
  35. ("CACHED", true);
  36. /** The webpage is not cached */
  37. ("NOT_CACHED", false);
  38.  
  39. // ----------------------------------------------------------------------
  40. // Option to determine the buffering mode.
  41.  
  42. /** The webpage is buffered using Php buffering */
  43. ("BUFFERED", true);
  44. /** The webpage is not buffered */
  45. ("UNBUFFERED", false);
  46.  
  47. // ----------------------------------------------------------------------
  48. /**
  49. * The webstream class
  50. * A class to manage buffering, cacheing, processing and output of the
  51. * content to the user agent. This is the entity which manages the Php
  52. * buffering mechanism, starting and stopping buffering and sending the
  53. * buffer to the client's browser. It also manages any cacheing of the webpage.
  54. * This class extends the session, since the whole point of the session is
  55. * to output content back to the user agent.
  56. * @package core
  57. */
  58. class webstream extends session {
  59. /** Whether to use Php buffering */
  60.  
  61. var $buffered = true;
  62. /** The content to send to browser */
  63.  
  64. var $content = "";
  65. /** Replacements to make in template */
  66.  
  67. var $replacement;
  68. /** Page is cached or dynamic */
  69.  
  70. var $cached = NOT_CACHED;
  71. /** Seconds expiry for cached webpages */
  72.  
  73. var $cache_expiry = 0;
  74. /** Path to use to save cached version of webpage */
  75.  
  76. var $cache_path = "";
  77. /** If true, force regeneration of cached webpage */
  78.  
  79. var $cache_regen = false;
  80. // .....................................................................
  81. /**
  82. * Constructor
  83. * Create a new webstream object. When this object is created it
  84. * always starts buffering with the ob_start() call. The Phplib
  85. * system always uses the Php buffering mechanism. This allows us
  86. * to process the output content and do 'clever things' right up
  87. * to the point of sending it all to the user.
  88. * @param string $initcontent Some intial content for the page
  89. */
  90. function webstream($initcontent="", $buffered=true) {
  91. // Create the session
  92. $this->session();
  93.  
  94. // Set buffering mode..
  95. $this->buffered = $buffered;
  96.  
  97. // Open for business..
  98. $this->open_webstream();
  99.  
  100. // Kick off with any initial content..
  101. $this->add_content($initcontent);
  102. } // webstream constructor
  103. // .....................................................................
  104. /** Start webstream output channel.. */
  105.  
  106. function open_webstream() {
  107. if ($this->buffered) {
  108. if ($this->multilang && $this->mbstring_avail) {
  109. ob_start("mb_output_handler");
  110. debugbr("webstream: mb_output_handler (multilang)", DBG_DEBUG);
  111. }
  112. else {
  113. ob_start();
  114. debugbr("webstream: standard buffering", DBG_DEBUG);
  115. }
  116. }
  117. else {
  118. debugbr("webstream: no buffering", DBG_DEBUG);
  119. }
  120. } // open_webstream
  121. // .....................................................................
  122. /**
  123. * Close the webstream. Return any current webpage content. Clear the
  124. * current content. This method clears content, but leaves any replacement
  125. * definitions untouched for further processing. It is designed to be
  126. * called as part of the final webpage rendering process.
  127. * @return string The current content, as it stands.
  128. */
  129. function close_webstream() {
  130. if ($this->buffered) {
  131. $content = ob_get_contents();
  132. ob_end_clean();
  133. }
  134. else {
  135. $content = $this->content;
  136. }
  137.  
  138. // Clear content..
  139. $this->content = "";
  140.  
  141. // Return what there was..
  142. return $content;
  143. } // close_webstream
  144. // .....................................................................
  145. /** Reset the webstream. This method clears any current content, and
  146. * also clears any stored replacement definitions. This resets the
  147. * stream to the point at which it was created - a virgin webstream.
  148. */
  149. function reset_webstream() {
  150. $this->content = "";
  151. unset($this->replacement);
  152. } // reset_webstream
  153. // .....................................................................
  154. /** Add new content to the webstream.. */
  155.  
  156. function add_content($content) {
  157. if ($content != "") {
  158. if ($this->buffered) {
  159. echo $content;
  160. }
  161. else {
  162. $this->content .= $content;
  163. }
  164. }
  165. } // add_content
  166. // .....................................................................
  167. /**
  168. * Cache this webpage
  169. * Causes the current webpage to be regarded as a cached page.
  170. * This means we look for a file of the same name but with extension
  171. * 'cached' in the $CACHEDIR directory, and check the modification
  172. * time. If it isn't expired then we set the page content to that file,
  173. * and send it. Otherwise we behave as if it is a normal dynamic Php page.
  174. * @param $expirysecs integer Seconds before page cacheing expires
  175. */
  176. function cache($expirysecs=0) {
  177. global $CACHEDIR;
  178. $this->cache_path = "$this->site_docroot/$CACHEDIR/" . $this->theme . "_" . basename($this->requested) . ".cached";
  179. $this->cache_expiry = $expirysecs;
  180. $this->cached = CACHED;
  181.  
  182. // Obey any cache control directives..
  183. if (isset($this->cachecontrol)) {
  184. // Possible forced refresh..
  185. if ($this->cachecontrol == "refresh" || $this->cachecontrol == "dynamic") {
  186. $this->cache_expiry = 0;
  187. debugbr("cachecontrol: forced cache refresh", DBG_DEBUG);
  188. }
  189. // Possible forced expirytime..
  190. else {
  191. $this->cache_expiry = (int)($this->cachecontrol);
  192. debugbr("cachecontrol: cache expiry set to $this->cachecontrol", DBG_DEBUG);
  193. }
  194. }
  195. if (file_exists($this->cache_path)) {
  196. $tsnow = time();
  197. $tsfile = filemtime($this->cache_path);
  198. if ($tsnow > $tsfile + $this->cache_expiry) {
  199. // We are about to drop through and allow this cached
  200. // file to be regenerated, but we touch it here to decrease
  201. // the chance of multiple rebuilds in the meantime..
  202. $this->cache_regen = true;
  203. touch($this->cache_path);
  204. debugbr("cachecontrol: re-generating expired page '$this->cache_path'", DBG_DEBUG);
  205. }
  206. else {
  207. // This cached file has a current version out on
  208. // disk, so we just return this file to the client..
  209. $this->discard();
  210. $cachefile = new inputfile($this->cache_path);
  211. if ($cachefile->opened) {
  212. $cachefile->readall();
  213. $this->content = $cachefile->content;
  214. $cachefile->closefile();
  215. $this->send_to_browser();
  216. exit;
  217. }
  218. else {
  219. log_sys("cachecontrol: failed to read cached page '$this->cache_path'");
  220. }
  221. }
  222. }
  223. else {
  224. // Non-existant cache file. Make sure it gets built..
  225. $this->cache_regen = true;
  226. touch($this->cache_path);
  227. debugbr("cachecontrol: generating cache for '$this->cache_path'", DBG_DEBUG);
  228. }
  229. } // cache
  230. // .....................................................................
  231. /**
  232. * Length of output buffer
  233. * Returns the length of our output buffer. Be careful when this is
  234. * called, since the buffer might not be filled by make_content() yet!
  235. * @param $expirysecs integer Seconds before page cacheing expires
  236. */
  237. function length() {
  238. if ($this->buffered) {
  239. return ob_get_length();
  240. }
  241. else {
  242. return strlen($this->content);
  243. }
  244. } // length
  245. // .....................................................................
  246. /**
  247. * Replace pattern in webpage content
  248. * Replaces multiple occurrences of the given tag (pattern) in the
  249. * body content with the specified new stuff. NB: when you call this
  250. * method the replacement isn't actually done there and then. It is
  251. * simply flagged as something to be done just before all of the
  252. * content is delivered to the user browser.
  253. * @param string $tag Pattern to replace in content
  254. * @param string $newstuff Stuff to replace the tag with
  255. */
  256. function replace($tag, $newstuff) {
  257. $this->replacement[$tag] = $newstuff;
  258. return $this;
  259. } // replace
  260. // .....................................................................
  261. /**
  262. * Replace all webpage content
  263. * For replacing the total contents of the buffer so far
  264. * with a new content. Throw buffer away and start anew with
  265. * immediate effect.
  266. * @param string $newcontent Replacement webpage content
  267. */
  268. function replace_content($newcontent) {
  269. $this->close_webstream();
  270. $this->reset_webstream();
  271. $this->open_webstream($newcontent);
  272. } // replace_content
  273. // .....................................................................
  274. /**
  275. * Discard all webpage content
  276. * For discarding the content so far with immediate effect.
  277. */
  278. function discard() {
  279. $this->close_webstream();
  280. $this->reset_webstream();
  281. } // discard
  282. // .....................................................................
  283. /**
  284. * Make content
  285. * This function takes our buffered content so far, stops buffering,
  286. * makes any replacements, and puts the resulting content into
  287. * the staging ($this->content) variable. This is mainly an internal
  288. * method which is called prior to sending the output to the user's
  289. * browser.
  290. * @access private
  291. */
  292. function make_content() {
  293. global $BLOCK_DEFS;
  294. $content = $this->close_webstream();
  295. if (isset($this->replacement)) {
  296. foreach ($this->replacement as $tag => $newstuff) {
  297. $tmp = str_replace($tag, $newstuff, $content);
  298. $content = $tmp;
  299. }
  300. }
  301. // Now insert our debugging output, if any..
  302. if (isset($this->debugger) && $this->debugger->debug_hascontent()) {
  303. switch($this->browser_type) {
  304. case BROWSER_TYPE_XHTML:
  305. case BROWSER_TYPE_HTML:
  306. // Tuck debugging info in after <body> tag..
  307. $pos = strpos($content, "<body");
  308. if (!($pos === false)) {
  309. $pos = strpos($content, ">", $pos);
  310. if (!($pos === false)) {
  311. $pos++;
  312. $content1 = substr($content, 0, $pos);
  313. $content2 = substr($content, $pos);
  314. $content = $content1 . $this->debugger->render() . $content2;
  315. }
  316. }
  317. break;
  318. case BROWSER_TYPE_XHTMLMP:
  319. case BROWSER_TYPE_WML:
  320. case BROWSER_TYPE_WMLUP:
  321. // For WML debug output we replace the content with a
  322. // dedicated card containing the debugging info..
  323. $bits = explode("<wml>", $content);
  324. $head = $bits[0];
  325. $dbgcard = new WMLcard("debug", "Debug");
  326. $dbgcard->insert_para($this->debugger->render());
  327. $dbgdeck = new WMLdeck($dbgcard);
  328. $content = $head . "<wml>" . $dbgdeck->render() . "</wml>";
  329. break;
  330. } // switch
  331. }
  332. $this->content = $content;
  333. return $this;
  334. } // make_content
  335. // .....................................................................
  336. /**
  337. * Send content to user browser
  338. * Deliver the content to the browser. First check if the page is cached
  339. * and if so whether we are going to update the cache. Next we get the
  340. * current buffer and aply any compression required. Then we send the
  341. * output on its way using the simple echo() function.
  342. * NOTE: If the page is not cached then we always send headers which
  343. * will make the user browser avoid cacheing it locally. This makes
  344. * sure that our dynamic pages will always be requested by it.
  345. */
  346. function send_to_browser() {
  347. global $HTTP_ACCEPT_ENCODING;
  348. global $compression_minsize;
  349. global $compression_type;
  350.  
  351. // Check if the webpage is cached or not..
  352. if ($this->cached) {
  353. if ($this->cache_regen) {
  354. $cachefile = new outputfile($this->cache_path);
  355. if ($cachefile->opened) {
  356. $cachefile->write($this->content);
  357. $cachefile->closefile();
  358. }
  359. else {
  360. log_sys("Failed to write cache file '$this->cache_path'");
  361. }
  362. }
  363. }
  364. // Deal with compression options..
  365. switch ($compression_type) {
  366. case BUILTIN_COMPRESSION:
  367. ob_start("ob_gzhandler");
  368. echo $this->content;
  369. ob_end_flush();
  370. break;
  371. case CUSTOM_COMPRESSION:
  372. $size = strlen($this->content);
  373. if ($size >= $compression_minsize) {
  374. if (isset($HTTP_ACCEPT_ENCODING) && stristr($HTTP_ACCEPT_ENCODING, "gzip")) {
  375. $crc = crc32($this->content);
  376. $this->content = gzcompress($this->content, 9);
  377. $gzlen = strlen($this->content);
  378. $this->content = substr($this->content, 0, $gzlen - 4);
  379. $this->content .= AsFourChars($crc);
  380. $this->content .= AsFourChars($size);
  381. header("Content-Encoding: gzip");
  382. echo "\x1f\x8b\x08\x00\x00\x00\x00\x00";
  383. }
  384. }
  385. echo $this->content;
  386. break;
  387. default:
  388. echo $this->content;
  389. } // switch
  390. } // send_to_browser
  391. // .....................................................................
  392. /**
  393. * Send content to file
  394. * Deliver the content to a given file.
  395. * Make our buffer content, and then deliver it to a file.
  396. * @see make_content()
  397. * @see output_to_file()
  398. * @param string $name The name of the file
  399. * @param string $dir The directory the file is in
  400. * @return boolean True if file was opened, else false
  401. */
  402. function send_to_file($name, $dir="") {
  403. $this->make_content();
  404. return $this->output_to_file($name, $dir);
  405. } // send_to_file
  406. // .....................................................................
  407. /**
  408. * Output content to file
  409. * Raw function to output content to file..
  410. * @param string $name The name of the file
  411. * @param string $dir The directory the file is in
  412. * @return boolean True if file was opened, else false
  413. * @access private
  414. */
  415. function output_to_file($name, $dir="") {
  416. $res = false;
  417. $f = new outputfile($name, $dir);
  418. if ($f->opened) {
  419. $f->write($this->content);
  420. $f->closefile();
  421. }
  422. return $res;
  423. } // output_to_file
  424. // .....................................................................
  425. /**
  426. * Return webpage content
  427. * Builds all of the webpage content and returns it to the caller.
  428. * @return string All of the webpage content as it would be sent to the user browser
  429. */
  430. function webpage_content() {
  431. $this->make_content();
  432. return $this->content;
  433. } // webpage_content
  434. // .....................................................................
  435. /**
  436. * Send error and die
  437. * Generic function to abort and send an error notification to the user
  438. * instead. This function is a one-way trip to oblivion.
  439. * @param string $heading The error heading or subject
  440. * @param string $msg The detailed error message
  441. */
  442. function send_error_and_die($heading, $msg="") {
  443. // Discard current buffered output..
  444. $this->discard();
  445.  
  446. // Return error message in error page..
  447. $errorpg = new error_page($heading, $msg);
  448. $this->content = $errorpg->render();
  449. $this->send_to_browser();
  450. exit;
  451. } // send_error_and_die
  452. // .....................................................................
  453. /**
  454. * Send HTTP error code and die
  455. * Generic function to abort and send an error code notification to the
  456. * user. These are lookalike errors for generic ones like 404: Page not found
  457. * etc. This function will not return.
  458. * @param integer $code The HTTP error code to generate
  459. */
  460. function send_errorcode_and_die($code) {
  461. $this->send_error_and_die( HTTPError($code) );
  462. } // send_errorcode_and_die
  463.  
  464. } // webstream class
  465. // ----------------------------------------------------------------------
  466.  
  467. /**
  468. * The webpage page class.
  469. * This is the main focus of the Axyl framework for generating webpage
  470. * content of any kind and for any device. We envisage the standard page
  471. * structure with a head, body and foot section. Depending on the device
  472. * this might not be exactly right, but it doesn't really matter, since
  473. * you have complete control over the content.
  474. * @package core
  475. */
  476. class webpage extends webstream {
  477. // Public
  478. /** Webpage head object */
  479.  
  480. var $head;
  481. /** Webpage body object */
  482.  
  483. var $body;
  484. /** Webpage foot object */
  485.  
  486. var $foot;
  487. /** The name of the template which was applied, if any */
  488.  
  489. var $template = "";
  490. /** The file the template content is to be found in */
  491.  
  492. var $templatefile = "";
  493. /**
  494. * Theme to apply to the page. This should be a single-word ID, and
  495. * there should be a sub-directory of the same name in the 'templates'
  496. * directory, with templates and stylesheet(s) in it which comprise
  497. * the theme. This is how we provide different template sets and
  498. * stylesheets for branding purposes.
  499. */
  500. var $theme = "";
  501.  
  502. // Private
  503. /** True if page has been generated
  504. @access private */
  505. var $generated = false;
  506. /** Set of plugins with content
  507. @access private */
  508. var $pluginset;
  509. // .....................................................................
  510. /**
  511. * Constructor
  512. * Create a new webpage object. When this object is created it
  513. * implicitly starts buffering with the ob_start() call by creating
  514. * a webstream.
  515. * NOTES: If you name your stylesheets after the APP_PREFIX (see your
  516. * application.php setup file), eg: 'haka.css' and 'haka_ie.css', then
  517. * the system will find them for you. The same applies if you call them
  518. * 'sitestyle.css' and 'sitestyle_ie.css'.
  519. * @param string $title Webpage title string
  520. * @param string $template Template for this webpage
  521. * @param string $theme Theme to apply. This is for branding purposes
  522. * @param string $stylesheet Name of stylesheet. Defaults to {APP_PREFIX}.css
  523. */
  524. function webpage($title="", $template="", $sitetheme="", $stylesheet="") {
  525. // Create webstream, start buffering..
  526. $this->webstream();
  527.  
  528. // Define the theme, if any. We override the static
  529. // defined theme with one which might be coming in
  530. // on a URL or via a form submission..
  531. global $theme;
  532. if (isset($theme) && $theme != "") {
  533. $this->set_theme($theme);
  534. }
  535. else {
  536. $this->set_theme($sitetheme);
  537. }
  538.  
  539. // HEAD - Set up the head page section..
  540. $this->head = new head($title);
  541.  
  542. // BODY - Set up body OR deck page section..
  543. if ($this->browser == BROWSER_PHONE) {
  544. $this->body = new deck();
  545. if ($this->browser_type == BROWSER_TYPE_WMLUP) {
  546. $s = "<meta forua=\"true\" http-equiv=\"Cache-Control\" content=\"max-age=0\"/>";
  547. $s .= "<meta forua=\"true\" http-equiv=\"Cache-Control\" content=\"must revalidate\"/>";
  548. $this->head->add($s);
  549. }
  550. }
  551. else {
  552. $this->body = new body();
  553. }
  554.  
  555. // FOOT - Define foot page section
  556. $this->foot = new foot();
  557.  
  558. // Set up the template..
  559. $this->set_template($template);
  560.  
  561. // Set up the stylesheet(s)..
  562. $this->set_stylesheet($stylesheet);
  563.  
  564. // Set up the DTDs..
  565. $this->assign_DTD();
  566.  
  567. // Initialise a plugin set..
  568. $this->pluginset = new pluginset();
  569.  
  570. } // webpage constructor
  571. // .....................................................................
  572. /**
  573. * Add to the body content
  574. * @param string $morestuff Content to append to the body of the webpage
  575. */
  576. function add($morestuff) {
  577. $this->body->add($morestuff);
  578. return $this;
  579. } // add
  580. // .....................................................................
  581. /**
  582. * Add named script
  583. * This adds a specific lump of script to the body under a unique name.
  584. * It allows you to collect multiple additions of script content under
  585. * a single grouping, and so cause the final rendering to group it all
  586. * together.
  587. * @param string $script Script content (omit <script> tags)
  588. * @param string $name Script content grouping identity
  589. * @param string $language The language the script is in
  590. */
  591. function add_named_script($script, $name, $language="javascript") {
  592. $this->body->add_named_script($script, $name, $language);
  593. } // add_named_script
  594. // .....................................................................
  595. /**
  596. * Add named script to the body
  597. * @param string $script Script to insert into the body of the webpage
  598. * @param string $language Language of this script (default javascript)
  599. */
  600. function add_script($script, $language="javascript") {
  601. $this->body->add_script($script, $language);
  602. } // add_script
  603. // .....................................................................
  604. /**
  605. * Add script URL to the body
  606. * @param string $src URL reference to script to insert into the body
  607. * @param string $language Language of this script (default javascript)
  608. */
  609. function add_scriptsrc($src, $language="javascript") {
  610. $this->body->add_scriptsrc($src, $language);
  611. } // add_scriptsrc
  612. // .....................................................................
  613. /**
  614. * Add content to a plugin
  615. * Plugins are regions of a webpage which you want to plug content into.
  616. * This is the method to call to add content to a named region or plugin.
  617. * The plugin ID (name) is related to a COMMENT TAG which appears in the
  618. * template of the page. If the plugin doesn't exist then one is created
  619. * otherwise the content is simply appended to that already defined.
  620. * The 'content' can be any one of the following types:
  621. * String - A literal string of content to put in the plugin
  622. * Path - Path to a file containing content (can be relative)
  623. * Function - A function definition, eg: "foo('xyx')" to return content
  624. * Object - An object. Must be a descendant of RenderableObject.
  625. * NB: This method can be called multiple times for the given plugin ID,
  626. * and content will be accumulated each time.
  627. * NB: When you nominate an object or a function to provide content, the
  628. * system assumes you want these generated "late" - ie. at the time
  629. * the webpage is being sent back to the user agent. If you want
  630. * content to be inserted early, then use literal strings.
  631. * @param string $pluginid ID of this plugin. Used to find plugin location
  632. * @param mixed $content The plugin content (literal, function, object...)
  633. */
  634. function plugin($pluginid, $content) {
  635. $this->pluginset->addto($pluginid, $content);
  636. } // plugin
  637. // .....................................................................
  638. /**
  639. * Define or redefine a plugin. This acts similarly to the above plugin()
  640. * method, except that here we replace the existing content, if any is
  641. * present, with this content.
  642. * @param string $pluginid ID of this plugin. Used to find plugin location
  643. * @param mixed $content The plugin content (literal, function, object...)
  644. */
  645. function plugin_replace($pluginid, $content) {
  646. $this->pluginset->add_plugin($pluginid, $content);
  647. } // plugin_replace
  648. // .....................................................................
  649. /**
  650. * Start/stop inline plugin content definition
  651. * This method allows plugin content to be taken from inline content
  652. * in the script page itself. At the start of the content call this
  653. * method with the name of the plugin (pluginid) you want to put the
  654. * content into. At the end of the content, call this method with
  655. * no parameter.
  656. */
  657. function plugin_inline($pluginid="") {
  658. static $the_plugin_id = "";
  659. if ($the_plugin_id == "") {
  660. if ($pluginid != "") {
  661. $the_plugin_id = $pluginid;
  662. $this->inline_start();
  663. }
  664. }
  665. else {
  666. $content = $this->inline_end();
  667. $this->plugin($the_plugin_id, $content);
  668. $the_plugin_id = "";
  669. }
  670. } // plugin_inline
  671. // .....................................................................
  672. /**
  673. * Begin inline buffering
  674. * If you want to include some 'naked' HTML in-line with your webpage
  675. * content, then call this method, then close the Php script with the
  676. * usual "?>" tag. Follow this with your HTML, then restart Php script
  677. * and grab the resulting HTML with... <?php $s = $page->inline_end();
  678. * Then $s will contain all the HTML between inline_start/inline_end.
  679. * @see inline_end()
  680. */
  681. function inline_start() {
  682. ob_start();
  683. } // inline_start
  684. // .....................................................................
  685. /**
  686. * End inline buffering
  687. * Usually used as in: <?php $s = $page->inline_end();
  688. * Then $s will contain all the HTML between inline_start/inline_end.
  689. * @see inline_start()
  690. * @return string Contents of the buffer gathered since inline_start()
  691. */
  692. function inline_end() {
  693. $content = ob_get_contents();
  694. ob_end_clean();
  695. return $content;
  696. } // inline_end
  697. // .....................................................................
  698. /**
  699. * Define the theme
  700. * Set the theme to apply to the page. This should be a single-word ID,
  701. * and there should be a sub-directory of the same name in the 'templates'
  702. * directory, with templates and stylesheet(s) in it which comprise
  703. * the theme. This is how we provide different template sets and stylesheets
  704. * for branding purposes.
  705. * @param string $theme Theme name for this webpage
  706. */
  707. function set_theme($theme) {
  708. global $IMAGESDIR, $TEMPLATESDIR;
  709. // Store new theme name..
  710. $this->theme = $theme;
  711. if ($theme != "") {
  712. // Point at theme images directory..
  713. $bits = explode("/", $IMAGESDIR);
  714. $n = count($bits) - 1;
  715. if ($n >= 0) {
  716. $imgdirname = $bits[$n];
  717. $IMAGESDIR = "$TEMPLATESDIR/$this->theme/$imgdirname";
  718. debugbr("theme '$this->theme': setting images directory to '$IMAGESDIR'", DBG_DEBUG);
  719. }
  720. }
  721. } // set_theme
  722. // .....................................................................
  723. /**
  724. * Set the filenames for the main stylesheet and (optionally) the
  725. * stylesheet for Internet Explorer compatible browsers.
  726. * @param string $ss Name of normal stylesheet (others are derived)
  727. */
  728. function set_stylesheet($ss="") {
  729. $sheets = $this->get_stylesheets($ss);
  730. $this->head->set_stylesheet(
  731. $sheets["ss"],
  732. $sheets["ss_ie"],
  733. $sheets["ss_ns"]
  734. );
  735. } // set_stylesheet
  736. // .....................................................................
  737. /**
  738. * Get the filenames for the main stylesheet and (optionally) the
  739. * stylesheet for Internet Explorer compatible browsers. Note: this
  740. * should only be a filename, not a path. If a theme has been defined
  741. * then the stylesheet will be expected to be in the subdirectory of
  742. * the same name as the theme, under the 'templates' directory. If not
  743. * then the stylesheet is expected to be in the website root dir.
  744. * Defaults are in effect as follows:
  745. * If the stylesheet is nullstring, then we look for a stylesheet in
  746. * the appropriate directory with a name of APP_PREFIX.css. If that
  747. * isn't found we try looking for 'sitestyle.css'. Same applies for
  748. * the IE stylesheet, but with "_ie" appended to the filename part.
  749. * We return the results in an associative array, with elements:
  750. * returned_array["css"] = standard stylsheet
  751. * returned_array["css_ie"] = IE stylsheet
  752. * returned_array["css_ns"] = Netscape 4.xx stylsheet
  753. * @param string $ss Name of normal stylesheet (others are derived).
  754. * @param string $theme The theme to retreive the stylesheets for.
  755. * @return array Associative array of stylesheets as located.
  756. */
  757. function get_stylesheets($ss="", $theme="?") {
  758. global $TEMPLATESDIR;
  759.  
  760. // Initialise return var..
  761. $stylesheets = array();
  762. $stylesheets["ss"] = "";
  763. $stylesheets["ss_ie"] = "";
  764. $stylesheets["ss_ns"] = "";
  765.  
  766. // Use current theme unless overriden..
  767. if ($theme == "?") {
  768. $theme = $this->theme;
  769. }
  770.  
  771. // Set the path prefixes..
  772. if ($theme != "") {
  773. $prefix = $this->site_docroot . "$TEMPLATESDIR/$theme/";
  774. $wwwprefix = "$TEMPLATESDIR/$theme/";
  775. }
  776. else {
  777. $prefix = $this->site_docroot . "/";
  778. $wwwprefix = "/";
  779. }
  780.  
  781. // See if we can find defaults if null. We first try files
  782. // with the standard 'sitestyle.css' naming scheme. If that
  783. // fails we try a stem of APP_PREFIX.
  784. if ($ss == "") {
  785. $try = "sitestyle";
  786. if (file_exists($prefix.$try.".css")) {
  787. $ss = $try.".css";
  788. }
  789. else {
  790. $try = APP_PREFIX;
  791. if (file_exists($prefix.$try.".css")) {
  792. $ss = $try.".css";
  793. }
  794. }
  795. }
  796. // Check for IE & Netscape stylesheets. The rule is that if this
  797. // exists it will be the same name as the standard stylesheet but
  798. // with "_ie" & "_ns" suffixes respectively..
  799. $ss_ie = ""; $ss_ns = "";
  800. if ($ss != "") {
  801. $ssbits = explode(".", $ss);
  802. $try = $ssbits[0] . "_ie";
  803. if (file_exists($prefix.$try.".css")) {
  804. $ss_ie = $try.".css";
  805. }
  806. $try = $ssbits[0] . "_ns";
  807. if (file_exists($prefix.$try.".css")) {
  808. $ss_ns = $try.".css";
  809. }
  810. }
  811.  
  812. // Define any stylesheets found..
  813. if ($ss != "") $stylesheets["ss"] = $wwwprefix.$ss;
  814. if ($ss_ie != "") $stylesheets["ss_ie"] = $wwwprefix.$ss_ie;
  815. if ($ss_ns != "") $stylesheets["ss_ns"] = $wwwprefix.$ss_ns;
  816.  
  817. // Return the results..
  818. return $stylesheets;
  819.  
  820. } // get_stylesheets
  821. // .....................................................................
  822. /**
  823. * Define the script to execute after page has loaded
  824. * @param string $onload Script to execute when page loads
  825. */
  826. function set_onload($onload) {
  827. $this->body->set_onload($onload);
  828. return $this;
  829. } // set_onload
  830. // .....................................................................
  831. /**
  832. * Define the webpage title
  833. * @param string $title Title to give the webpage
  834. */
  835. function set_title($title) {
  836. $this->head->set_title($title);
  837. return $this;
  838. } // set_title
  839. // .....................................................................
  840. /**
  841. * Define the style settings for the webpage. Usually the stylesheet
  842. * will be all you require, however occasionally it is necessary to
  843. * have specific styles for a page. Set these here, but make sure to
  844. * provide the FULL style complete with <style></style> tags.
  845. * @param string $style Style to insert into the webpage
  846. */
  847. function set_style($style) {
  848. $this->head->set_style($style);
  849. return $this;
  850. } // set_style
  851. // .....................................................................
  852. /**
  853. * Define the template for the webpage.
  854. * The $templatename can be the special "plain" which is a pseudo template
  855. * of vanilla content, a fll path to a file, or a name. If it is a simple
  856. * name, then the system knows where to find it and constructs a full
  857. * path to the file from it.
  858. * @param string $templatename The name of, or full path to the template file
  859. */
  860. function set_template($templatename) {
  861. global $TEMPLATESDIR;
  862. if ($templatename != "") {
  863. $this->templatefile = "";
  864. if ($templatename != "plain") {
  865. if (strtolower(substr($templatename, 5)) == ".html" ||
  866. strtolower(substr($templatename, 4)) == ".wml") {
  867. // Absolute path to template as it stands..
  868. $templatefile = $templatename;
  869. $this->template = get_file_stem(basename($templatefile));
  870. }
  871. else {
  872. // Try to find the template file - fallback to "main"..
  873. $templatenames_to_try = array($templatename);
  874. if ($templatename != "main") {
  875. $templatenames_to_try[] = "main";
  876. }
  877. foreach ($templatenames_to_try as $templatename) {
  878. $this->template = $templatename;
  879. $extn = "html";
  880. if ($this->browser == BROWSER_PHONE) {
  881. $extn = "wml";
  882. }
  883. // Build assumed path to correct template file..
  884. $templatefile = "template_" . $templatename . "." . $extn;
  885. if ($this->theme != "") {
  886. // Use a template from a theme sub-directory..
  887. $templatefile = "$TEMPLATESDIR/$this->theme/$templatefile";
  888. }
  889. else {
  890. // Use standard template..
  891. $templatefile = "$TEMPLATESDIR/$templatefile";
  892. }
  893. // Check it exists..
  894. $this->templatefile = $this->site_docroot . $templatefile;
  895. if (is_readable($this->templatefile)) {
  896. break;
  897. }
  898. } // foreach
  899. }
  900. } // not plain
  901. else {
  902. $this->template = "plain";
  903. }
  904. // Now we have the template content, use it..
  905. debugbr("template name: $this->template", DBG_DEBUG);
  906. debugbr("template file: $this->templatefile", DBG_DEBUG);
  907. $this->head->load_template($this->templatefile);
  908. $this->body->load_template($this->templatefile);
  909. }
  910. } // set_template
  911. // .....................................................................
  912. /**
  913. * Assign the DTD for the resident head page section. We have two ways
  914. * to do this: directly via passed parameter $DTD, or indirectly by
  915. * using the content (browser) type, and looking up the DTD from the
  916. * array of DTD specifiers created in the response object.
  917. * @param string $DTD Optional override DTD specifier string
  918. */
  919. function assign_DTD($DTD="") {
  920. if (isset($this->head)) {
  921. if ($DTD == "" && isset($this->DTD)) {
  922. switch ($this->browser_type) {
  923. case BROWSER_TYPE_XHTML:
  924. case BROWSER_TYPE_HTML:
  925. if (isset($this->DTD[BROWSER_TYPE_HTML])) {
  926. $DTD = $this->DTD[BROWSER_TYPE_HTML];
  927. }
  928. break;
  929. case BROWSER_TYPE_XHTMLMP:
  930. case BROWSER_TYPE_WML:
  931. case BROWSER_TYPE_WMLUP:
  932. if (isset($this->DTD[BROWSER_TYPE_WML])) {
  933. $DTD = $this->DTD[BROWSER_TYPE_WML];
  934. }
  935. break;
  936. }
  937. }
  938. $this->head->set_dtd($DTD);
  939. }
  940. } // assign_DTD
  941. // .....................................................................
  942. /**
  943. * Insert a ready-made meta tag object into the webpage head section.
  944. * @param string $id Meta tag unique ID
  945. * @param object $metatag Meta tag object to insert
  946. */
  947. function insert_metatag($id, $metatag) {
  948. $this->head->insert_metatag($id, $metatag);
  949. } // insert_metatag
  950. // .....................................................................
  951. /**
  952. * Add a meta tag to the webpage head section.
  953. * @param string $name Meta tag name
  954. * @param string $content Meta tag content
  955. * @param string $language Optional language specifier for content
  956. * @param string $scheme Optional scheme specifier for content
  957. */
  958. function set_metatag($name, $content, $language, $scheme) {
  959. $this->head->set_metatag($name, $content, $language, $scheme);
  960. } // set_metatag
  961. // .....................................................................
  962. /**
  963. * Generate the webpage content
  964. * This routine is usually called after all the set-up calls for the
  965. * head, body etc. have been made. This echoes each page section to the
  966. * buffer, in preparation for delivery to the browser.
  967. */
  968. function generate() {
  969. global $HTMLAREA;
  970. if (!$this->generated) {
  971. if ($this->pluginset->hascontent) {
  972. foreach ($this->pluginset->plugins as $id => $plugin) {
  973. if (is_object($plugin)) {
  974. $newstuff = $plugin->render();
  975. $tag = "<!--" . strtoupper($id) . "-->";
  976. $this->replace($tag, $newstuff);
  977. }
  978. }
  979. }
  980. // Set up the javascript environment for any
  981. // htmlarea widgest which have been used..
  982. if (isset($HTMLAREA) && $HTMLAREA->activated) {
  983. $HTMLAREA->render();
  984. }
  985. // Produce the content..
  986. if ($this->buffered) {
  987. // Acquire content via the Php buffer..
  988. echo $this->head->render();
  989. echo $this->body->render();
  990. echo $this->foot->render();
  991. }
  992. else {
  993. // Content goes directly in..
  994. $this->content .= $this->head->render();
  995. $this->content .= $this->body->render();
  996. $this->content .= $this->foot->render();
  997. }
  998. $this->generated = true;
  999. $this->make_content();
  1000. }
  1001. } // generate
  1002. // .....................................................................
  1003. /**
  1004. * Generate the content and then send it to the user browser.
  1005. */
  1006. function send() {
  1007. $this->generate();
  1008. $this->send_to_browser();
  1009. } // send
  1010. // .....................................................................
  1011. /**
  1012. * Generate the content into the buffer, then return the content.
  1013. * @return string The webpage content complete, as a string
  1014. */
  1015. function render() {
  1016. $this->generate();
  1017. return $this->webpage_content();
  1018. } // render
  1019.  
  1020. } // webpage class
  1021. // ----------------------------------------------------------------------
  1022.  
  1023. /**
  1024. * The head class.
  1025. * The class is a special kind of page section. It contains all of the meta
  1026. * tags, style tags, title and other such things for the webpage. Note that
  1027. * this section is not just the head content, but really comprises everything
  1028. * which is prior to the /head tag. This might include the DTD specifier
  1029. * for instance.
  1030. * @package core
  1031. */
  1032. class head extends page_section {
  1033. /** Title of the webpage */
  1034.  
  1035. var $title = "";
  1036. /** Style settings for the webpage */
  1037.  
  1038. var $style = "";
  1039. /** The Document Type Definition for this head section */
  1040.  
  1041. var $DTD = "";
  1042. /** Meta tags array */
  1043.  
  1044. var $meta;
  1045. /** Name of the stylesheet associated with the webpage */
  1046.  
  1047. var $stylesheet = "";
  1048. /** Name of the IE stylesheet */
  1049.  
  1050. var $stylesheet_ie = "";
  1051. /** Name of the Netscape stylesheet */
  1052.  
  1053. var $stylesheet_ns = "";
  1054. /** Languages used in content of the page */
  1055.  
  1056. var $languages = array();
  1057. /** Charset for content of the page */
  1058.  
  1059. var $charset = "ISO-8859-1";
  1060. // .....................................................................
  1061. /**
  1062. * Constructor
  1063. * Create a new head object.
  1064. * @param string $title Title of the webpage
  1065. * @param string $style Specific style settings for the webpage
  1066. */
  1067. function head($title="", $style="") {
  1068. $this->page_section();
  1069. $this->set_title($title);
  1070. $this->set_style($style);
  1071. } //head constructor
  1072. // .....................................................................
  1073. /**
  1074. * Define the title
  1075. * @param string $title Title of the webpage
  1076. */
  1077. function set_title($title) {
  1078. $this->title = $title;
  1079. } // set_title
  1080. // .....................................................................
  1081. /**
  1082. * Define the style
  1083. * NB: The way this is currently done, you are expected to supply
  1084. * your style WITHOUT style tags here.
  1085. * @param string $style Specific style settings for the webpage
  1086. */
  1087. function set_style($style) {
  1088. $this->style = $style;
  1089. } // set_style
  1090. // .....................................................................
  1091. /**
  1092. * Add the given content to the current style. Appends style statements
  1093. * to the style string, which is rendered when the page gets rendered.
  1094. * @param string $style Style settings to add to existing ones.
  1095. */
  1096. function add_style($style) {
  1097. $this->style .= $style;
  1098. } // add_style
  1099. // .....................................................................
  1100. /**
  1101. * Set the stylesheet to use. This should be a valid pathname to an
  1102. * existing file. The second parm is for special styles for Internet
  1103. * Explorer-compatible browsers.
  1104. * @param string $ss Path to normal stylesheet
  1105. * @param string $ss_ie Path to stylesheet for Internet Explorer
  1106. */
  1107. function set_stylesheet($ss, $ss_ie="", $ss_ns="") {
  1108. $this->stylesheet = $ss;
  1109. $this->stylesheet_ie = $ss_ie;
  1110. $this->stylesheet_ns = $ss_ns;
  1111. } // set_stylesheet
  1112. // .....................................................................
  1113. /**
  1114. * Insert a ready-made meta tag object into the metatags array.
  1115. * @param string $id Meta tag unique ID
  1116. * @param object $metatag Meta tag object to insert
  1117. */
  1118. function insert_metatag($id, $metatag) {
  1119. $this->meta[$id] = $metatag;
  1120. } // insert_metatag
  1121. // .....................................................................
  1122. /**
  1123. * Add meta tag to the section
  1124. * @param string $name Meta tag name
  1125. * @param string $content Meta tag content
  1126. * @param string $language Optional language specifier for content
  1127. * @param string $scheme Optional scheme specifier for content
  1128. */
  1129. function set_metatag($name, $content, $language="", $scheme="") {
  1130. if ($name != "" && $content != "") {
  1131. $newtag = new HTMLtag("meta");
  1132. $newtag->add_attribute("name", $name);
  1133. $newtag->add_attribute("content", $content);
  1134. if ($language != "") {
  1135. $newtag->add_attribute("lang", $language);
  1136. }
  1137. if ($scheme != "") {
  1138. $newtag->add_attribute("scheme", $scheme);
  1139. }
  1140. $this->insert_metatag($name, $newtag);
  1141. }
  1142. } //set_metatag
  1143. // .....................................................................
  1144. /**
  1145. * Set the DTD specifier string for this head section.
  1146. * @param string $DTD The Document Type Definition string for this head
  1147. */
  1148. function set_dtd($DTD) {
  1149. $this->DTD = $DTD;
  1150. } // set_dtd
  1151. // ...................................................................
  1152. /**
  1153. * Adds another language for the current head. Webpages might
  1154. * contain content in multiple languages, hence the need for a list.
  1155. * @param integer $langid The new language ID to add for the webpage
  1156. */
  1157. function add_language($langid) {
  1158. if (!in_array($langid, $this->languages)) {
  1159. $this->languages[] = $langid;
  1160. }
  1161. } // add_language
  1162. // .....................................................................
  1163. /**
  1164. * Set the charset for this head section
  1165. * @param string $charset The charset code for content of this head section
  1166. */
  1167. function set_charset($charset) {
  1168. $this->charset = $charset;
  1169. } // set_charset
  1170. // ....................................................................
  1171. /**
  1172. * Load given template content.
  1173. * We scrape everything between the appropriate tags and use it as
  1174. * the template for our content.
  1175. * @param string $templatefile The full path to the template file
  1176. */
  1177. function load_template($templatefile="") {
  1178. $template = $this->get_template($templatefile);
  1179. if ($template != "") {
  1180. $bits = explode("<head>", $template);
  1181. if (isset($bits[0]) && $bits[0] != "") {
  1182. // Always use DTD from template if found..
  1183. if (preg_match("/<!DOCTYPE (.+)>/i", $bits[0], $matches)) {
  1184. $this->set_dtd($matches[0]);
  1185. }
  1186. if (isset($bits[1]) && $bits[1] != "") {
  1187. $bits = explode("</head>", $bits[1]);
  1188. if (isset($bits[0]) && $bits[0] != "") {
  1189. $head = $bits[0];
  1190. // Strip items which Axyl generates for itself..
  1191. $patts = array(
  1192. "<title>.*?<\/title>", // Title tag
  1193. "<meta http-equiv=\"content-type.*?>", // Content type meta tag
  1194. "<link rel=(.*?)stylesheet.*?>" // All stylesheet links
  1195. );
  1196. foreach ($patts as $patt) {
  1197. $head = preg_replace("/$patt\n|$patt/i", "", $head);
  1198. }
  1199. $this->content = $head;
  1200. }
  1201. }
  1202. }
  1203. }
  1204. return $this;
  1205. } // load_template
  1206. // ....................................................................
  1207. /**
  1208. * This renders the head as HTML. After the title and the meta tags
  1209. * are rendered, the stylesheets are next. For the stylesheets we first
  1210. * render the standard links, and then overlay this with the Internet Explorer
  1211. * stylesheet if it is defined. Finally any literal styles are rendered
  1212. * so they will take precedence. The scripts are rendered after the styles,
  1213. * and the head content comes last.
  1214. * @see render()
  1215. * @return string The head section as HTML.
  1216. */
  1217. function html() {
  1218. global $RESPONSE;
  1219. // Content type meta tag - always has to be first..
  1220. $meta = new HTMLtag("meta");
  1221. $meta->add_attribute("http-equiv", "content-type");
  1222. $meta->add_attribute("content", "text/html; charset=$this->charset");
  1223. $this->meta[] = $meta;
  1224.  
  1225. // Language(s) meta tag..
  1226. $languages = array();
  1227. if (count($this->languages) > 0) {
  1228. $q = "SELECT * FROM ax_language";
  1229. $q .= " WHERE lang_id IN (" . implode(",", $this->languages) . ")";
  1230. $q .= " AND lang_id <> 0";
  1231. $q .= " ORDER BY display_order";
  1232. $langs = dbrecordset($q);
  1233. if ($langs->hasdata) {
  1234. do {
  1235. $languages[] = $langs->field("char_encoding");
  1236. } while ($langs->get_next());
  1237. // Create the meta tag..
  1238. if (count($languages) > 0) {
  1239. $meta = new HTMLtag("meta");
  1240. $meta->add_attribute("http-equiv", "content-language");
  1241. $meta->add_attribute("content", implode(",", $languages));
  1242. $this->meta[] = $meta;
  1243. }
  1244. }
  1245. }
  1246.  
  1247. // Generator meta tag..
  1248. $meta = new HTMLtag("meta");
  1249. $meta->add_attribute("name", "generator");
  1250. $meta->add_attribute("content", "Catalyst IT Axyl");
  1251. $this->meta[] = $meta;
  1252.  
  1253. // Assemble head section..
  1254. $s = "";
  1255. if ($this->DTD != "") $s .= "$this->DTD\n";
  1256. $s .= "<html";
  1257. if (count($languages) > 0) {
  1258. $s .= " lang=\"" . implode(",", $languages) . "\"";
  1259. }
  1260. $s .= ">\n";
  1261. $s .= "<head>\n";
  1262. $s .= "<title>$this->title</title>\n";
  1263.  
  1264. // Now insert all defined meta tags..
  1265. foreach ($this->meta as $metatag) {
  1266. $s .= $metatag->render();
  1267. }
  1268.  
  1269. // Literal head content..
  1270. $s .= $this->get_trimcontent();
  1271.  
  1272. // The General Stylesheet..
  1273. if (isset($this->stylesheet) && $this->stylesheet != "") {
  1274. $s .= "<link rel=\"stylesheet\" href=\"$this->stylesheet\" type=\"text/css\">\n";
  1275. }
  1276.  
  1277. // Specific IE or Netscape Stylesheet..
  1278. switch ($RESPONSE->browser) {
  1279. case BROWSER_IE:
  1280. if (isset($this->stylesheet_ie) && $this->stylesheet_ie != "") {
  1281. $s .= "<link rel=\"stylesheet\" href=\"$this->stylesheet_ie\" type=\"text/css\">\n";
  1282. }
  1283. break;
  1284. case BROWSER_NETSCAPE:
  1285. if (isset($this->stylesheet_ns) && $this->stylesheet_ns != "") {
  1286. $s .= "<link rel=\"stylesheet\" href=\"$this->stylesheet_ns\" type=\"text/css\">\n";
  1287. }
  1288. break;
  1289. } // switch
  1290.  
  1291. // Static styles..
  1292. if (isset($this->style) && $this->style != "") {
  1293. $s .= "<style type=\"text/css\">\n";
  1294. $s .= "$this->style\n";
  1295. $s .= "</style>\n";
  1296. }
  1297.  
  1298. // Scripts..
  1299. $s .= $this->script();
  1300.  
  1301. $s .= "</head>\n";
  1302. return $s;
  1303. } // html
  1304. // ....................................................................
  1305. /**
  1306. * Use render() to render this element in your page.
  1307. * This renders the field as WML.
  1308. * @see render()
  1309. * @return string The field as WML.
  1310. */
  1311. function wml() {
  1312. $s = "";
  1313. $s .= "<?xml version=\"1.0\" encoding=\"$this->charset\"?>\n";
  1314. if ($this->DTD != "") $s .= "$this->DTD\n";
  1315. $s .= "<wml>";
  1316. if ($this->content != "" || isset($this->meta)) {
  1317. $s .= "<head>";
  1318. if (isset($this->meta)) {
  1319. while (list($name, $content) = each($this->meta)) {
  1320. $s .= "<meta name=\"$name\" content=\"$content\">\n";
  1321. }
  1322. }
  1323. $s .= $this->content;
  1324. $s .= "</head>";
  1325. }
  1326. return $s;
  1327. } // wml
  1328.  
  1329. } // head class
  1330. // ----------------------------------------------------------------------
  1331.  
  1332. /**
  1333. * The body class
  1334. * The class is a special kind of page section. It contains all of the
  1335. * main page content.
  1336. * @package core
  1337. */
  1338. class body extends page_section {
  1339. /** The script to execute when the page has loaded */
  1340.  
  1341. var $onload = "";
  1342. /** Miscellaneous content for the body tag */
  1343.  
  1344. var $parms = "";
  1345. // .....................................................................
  1346. /**
  1347. * Constructor
  1348. * Create a new body object.
  1349. * @param string $templatefile Template file to load content from
  1350. * @param string $onload Script to execute when page loads
  1351. * @param string $parms Misc other content for the body tag
  1352. */
  1353. function body($templatefile="", $onload="", $parms="") {
  1354. $this->page_section();
  1355. $this->load_template($templatefile);
  1356. $this->set_onload($onload);
  1357. $this->set_parms($parms);
  1358. } // body constructor
  1359. // .....................................................................
  1360. /**
  1361. * Define the script to execute after page has loaded
  1362. * @param string $onload Script to execute when page loads
  1363. */
  1364. function set_onload($onload) {
  1365. $this->onload .= $onload;
  1366. } // set_onload
  1367. // .....................................................................
  1368. /**
  1369. * Define other miscellaneous content to be put into the body tag.
  1370. * This method can be called multiple times. Each time the content
  1371. * is added (appended) to.
  1372. * @param string $parms Misc other content for the body tag
  1373. */
  1374. function set_parms($parms) {
  1375. if ($parms != "") {
  1376. if ($this->parms != "") {
  1377. $this->parms .= " ";
  1378. }
  1379. $this->parms .= $parms;
  1380. }
  1381. } // set_parms
  1382. // .....................................................................
  1383. /**
  1384. * Load given template content.
  1385. * We scrape everything between the appropriate tags and use it as
  1386. * the template for our content.
  1387. * @param string $templatefile The full path to template file
  1388. * @access private
  1389. */
  1390. function load_template($templatefile="") {
  1391. if ($templatefile == "") {
  1392. $this->content = "<!--MAIN_CONTENT-->";
  1393. }
  1394. else {
  1395. $template = $this->get_template($templatefile);
  1396. if ($template != "" && strstr($template, "<body")) {
  1397. $bits = explode("<body", $template);
  1398. if (isset($bits[1]) && $bits[1] != "") {
  1399. $i = strpos($bits[1], ">");
  1400. if ($i > 1) {
  1401. // Scrape body tag parameters and keep these..
  1402. $parms = trim( substr($bits[1], 0, $i) );
  1403. if ($parms != "") {
  1404. $this->set_parms($parms);
  1405. }
  1406. }
  1407. // Scrape body content..
  1408. $content = substr($bits[1], $i + 1);
  1409. $bits = explode("</body>", $content);
  1410. if (isset($bits[0])) {
  1411. $this->content = $bits[0];
  1412. $this->fix_imagerefs();
  1413. }
  1414. }
  1415. }
  1416. else {
  1417. $this->content = "<!--MAIN_CONTENT-->";
  1418. }
  1419. }
  1420. } // load_template
  1421. // ....................................................................
  1422. /**
  1423. * Fixes up all the media src= references taking into account theme etc.
  1424. * Operates on the current $content variable, and fixes it directly.
  1425. * Fix up all src= references (etc) to point to the correct images
  1426. * directory, appropriate to any active theme, but ignores absolute
  1427. * http;// refs..
  1428. * @access private
  1429. */
  1430. function fix_imagerefs() {
  1431. global $IMAGESDIR;
  1432. // Fix up main body content..
  1433. $this->content = preg_replace(
  1434. "/(src=[\'\"])((?!http)(.+?))([\'\"])/ie",
  1435. "'src=\"' . '$IMAGESDIR/' . basename('\\2') . '\"'",
  1436. $this->content
  1437. );
  1438. $this->content = preg_replace(
  1439. "/(background=[\'\"])((?!http)(.+?))([\'\"])/ie",
  1440. "'background=\"' . '$IMAGESDIR/' . basename('\\2') . '\"'",
  1441. $this->content
  1442. );
  1443. $this->content = preg_replace(
  1444. "/(param name=movie value=[\'\"])((?!http)(.+?))([\'\"])/ie",
  1445. "'param name=movie value=\"' . '$IMAGESDIR/' . basename('\\2') . '\"'",
  1446. $this->content
  1447. );
  1448. // Fix up background refs in <body> tag..
  1449. $this->parms = preg_replace(
  1450. "/(background=[\'\"])((?!http)(.+?))([\'\"])/ie",
  1451. "'background=\"' . '$IMAGESDIR/' . basename('\\2') . '\"'",
  1452. $this->parms
  1453. );
  1454. } // fix_imagerefs
  1455. // ....................................................................
  1456. /**
  1457. * This renders the body as HTML.
  1458. * @return string The body section as HTML.
  1459. */
  1460. function html() {
  1461. $s = "<body";
  1462. if (!empty($this->onload)) $s .= " onload=\"" . $this->onload . "\"";
  1463. if (!empty($this->parms)) $s .= " " . $this->parms;
  1464. $s .= ">\n";
  1465. $s .= $this->script();
  1466. $s .= $this->get_trimcontent();
  1467. $s .= "\n</body>\n";
  1468.  
  1469. return $s;
  1470. } //html
  1471. // ....................................................................
  1472. /**
  1473. * This renders the body as WML.
  1474. * @return string The body section as WML.
  1475. */
  1476. function wml() {
  1477. return $this->content;
  1478. } // wml
  1479.  
  1480. } // body class
  1481. // ----------------------------------------------------------------------
  1482.  
  1483. /**
  1484. * The deck class
  1485. * The class is a special kind of body section. It contains all of the
  1486. * main page content for a WAP phone (wml).
  1487. * @package core
  1488. */
  1489. class deck extends body {
  1490. /** Template object for WML deck */
  1491.  
  1492. var $WMLtemplate;
  1493. // .....................................................................
  1494. /**
  1495. * Constructor
  1496. * Create a new deck object.
  1497. * @param string $templatefile Template file to load content from
  1498. * @param string $onload Script to execute when page loads
  1499. * @param string $parms Misc other parameters
  1500. */
  1501. function deck($templatefile="", $onload="", $parms="") {
  1502. $this->body($templatefile, $onload, $parms);
  1503. } // deck constructor
  1504. // ....................................................................
  1505. /**
  1506. * Defines the template section for the deck.
  1507. * @param object $wmltemplate The template object for the WML deck
  1508. */
  1509. function wml_template($wmltemplate) {
  1510. $this->WMLtemplate = $wmltemplate;
  1511. } // wml_template
  1512. // .....................................................................
  1513. /**
  1514. * Load the template content.
  1515. * We scrape everything between the appropriate tags and use it as the
  1516. * template for our body content.
  1517. * @param string $templatefile The full path to template file
  1518. * @access private
  1519. */
  1520. function load_template($templatefile="") {
  1521. if ($templatefile == "") {
  1522. $this->content = "<!--MAIN_CONTENT-->";
  1523. }
  1524. else {
  1525. $template = $this->get_template($templatefile);
  1526. if ($template != "" && strstr($template, "<wml>")) {
  1527. $bits = explode("<wml>", $template);
  1528. if (isset($bits[1]) && $bits[1] != "") {
  1529. $bits = explode("</wml>", $bits[1]);
  1530. if (isset($bits[0]) && $bits[0] != "") {
  1531. $this->content = $bits[0];
  1532. $this->fix_imagerefs();
  1533. }
  1534. }
  1535. }
  1536. else {
  1537. $this->content = "<!--MAIN_CONTENT-->";
  1538. }
  1539. }
  1540. } // load_template
  1541. // ....................................................................
  1542. /**
  1543. * This renders the body as HTML.
  1544. * @return string The body section as HTML.
  1545. */
  1546. function html() {
  1547. $s = "<body>";
  1548. $s .= $this->get_trimcontent();
  1549. $s .= "\n</body>\n";
  1550. return $s;
  1551. } // html
  1552. // ....................................................................
  1553. /**
  1554. * This renders the deck content.
  1555. * @return string The body section as WML.
  1556. */
  1557. function wml() {
  1558. $s = "";
  1559. if (isset($this->WMLtemplate)) {
  1560. $s .= $this->WMLtemplate->wml();
  1561. }
  1562. $s .= $this->get_trimcontent();
  1563. return $s;
  1564. } // wml
  1565.  
  1566.  
  1567.  
  1568. } // deck class
  1569. // ----------------------------------------------------------------------
  1570.  
  1571. /**
  1572. * The foot class
  1573. * The class is a special kind of page section. It contains all of the
  1574. * page content for the footer region. Actually the footer is the
  1575. * simplest of the page sections in a webpage. All it really has is
  1576. * the main content, some optional script content and that's about it.
  1577. * @package core
  1578. */
  1579. class foot extends page_section {
  1580. /**
  1581. * Constructor
  1582. * Create a new foot object.
  1583. */
  1584. function foot() {
  1585. $this->page_section();
  1586. } // foot constructor
  1587. // ....................................................................
  1588. /**
  1589. * This renders the foot as HTML.
  1590. * @return string The foot section as HTML.
  1591. */
  1592. function html() {
  1593. $s = "";
  1594. $s .= $this->content;
  1595. $s .= $this->script();
  1596. $s .= "</html>\n";
  1597. return $s;
  1598. } // html
  1599. // ....................................................................
  1600. /**
  1601. * This renders the foot as WML.
  1602. * @return string The foot section as WML.
  1603. */
  1604. function wml() {
  1605. return $this->content . "</wml>";
  1606. } // wml
  1607.  
  1608. }
  1609.  
  1610. // ----------------------------------------------------------------------
  1611. /**
  1612. * The error page class
  1613. * Allows us to render errors as either HTML or WML.
  1614. * @package core
  1615. */
  1616. class error_page extends page_section {
  1617. /** Heading or subject of the error */
  1618.  
  1619. var $heading;
  1620. /** Actual error message in detail */
  1621.  
  1622. var $msg;
  1623. // .....................................................................
  1624. /**
  1625. * Constructor
  1626. * Create a new error page object.
  1627. * @param string $heading The error heading or subject
  1628. * @param string $msg The detailed error message
  1629. */
  1630. function error_page($heading, $msg="") {
  1631. $this->heading = $heading;
  1632. $this->msg = $msg;
  1633. } // error_page
  1634. // ....................................................................
  1635. /**
  1636. * This renders the error page section as HTML. We do this simply
  1637. * as a heading at level 3 (h3), and the message content.
  1638. * @return string The error page section as HTML.
  1639. */
  1640. function html() {
  1641. return "<h3>$this->heading</h3>" . $this->msg;
  1642. } // html
  1643. // ....................................................................
  1644. /**
  1645. * This renders the error page section as WML. We do this simply
  1646. * as a single card with the appropriate title, and the content
  1647. * on the card in paragraph tags.
  1648. * @return string The error page section as WML.
  1649. */
  1650. function wml() {
  1651. $card = new WMLcard("error", "Error");
  1652. $card->insert(
  1653. "<p><b>" . $this->heading . "</b><br/>" . $this->msg . "</p>"
  1654. );
  1655. // Create the card deck and output it..
  1656. $deck = new WMLdeck($card);
  1657. return $deck->wml();
  1658. } // wml
  1659.  
  1660. }
  1661.  
  1662. // ----------------------------------------------------------------------
  1663. /**
  1664. * The templated webpage page class
  1665. * This is a special case of webpage, but is largely deprecated since
  1666. * the better way of using templates is via the kind of mechanism
  1667. * seen in the "site-webpage.php" example file which comes with
  1668. * the Phplib. This method is rather a DIY approach.
  1669. * @package core
  1670. */
  1671. class templated_webpage extends webstream {
  1672. /**
  1673. * Constructor
  1674. * Create a new templated webpage object.
  1675. * @param string $path Path to the template for the webpage
  1676. */
  1677. function templated_webpage($path="") {
  1678. $this->webstream();
  1679. if ($path != "") {
  1680. $this->set_template($path);
  1681. }
  1682. } // templated_webpage
  1683. // .....................................................................
  1684. /**
  1685. * Set the template file
  1686. * Base webpage content on a template. We echo this to the buffer.
  1687. * The expected usage is that further programming will then repeatedly
  1688. * call the 'replace' function, to make the customised webpage. After
  1689. * that calling 'send' will deliver it to the end browser.
  1690. * @param string $path Path to the template for the webpage
  1691. */
  1692. function set_template($path) {
  1693. $fp = fopen($path, "r");
  1694. if ($fp) {
  1695. $content = fread($fp, filesize($path));
  1696. fclose ($fp);
  1697. echo $content;
  1698. }
  1699. return $this;
  1700. } // set_template
  1701. // .....................................................................
  1702. /**
  1703. * Send content to user browser
  1704. */
  1705. function send() {
  1706. $this->make_content();
  1707. $this->send_to_browser();
  1708. } // send
  1709. // .....................................................................
  1710. /**
  1711. * Return content to caller
  1712. * @return string Webpage content
  1713. */
  1714. function render() {
  1715. return $this->webpage_content();
  1716. } // render
  1717.  
  1718. } // templated_webpage class
  1719. // ----------------------------------------------------------------------
  1720.  
  1721. /**
  1722. * gzip utility. Returns Value as a four-char string.
  1723. * @param integer $value Character value to return as four-char string
  1724. * @return string Four char string equivalent of the given value
  1725. * @access private
  1726. */
  1727. function AsFourChars($value) {
  1728. $s = "";
  1729. for ($i = 0; $i < 4; $i++) {
  1730. $s .= chr($value % 256);
  1731. $value = floor($value / 256);
  1732. }
  1733. return $s;
  1734. } // AsFourChars
  1735. // ----------------------------------------------------------------------
  1736.  
  1737. ?>

Documentation generated by phpDocumentor 1.3.0RC3