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

Documentation generated by phpDocumentor 1.3.0RC3