Source for file response-defs.php

Documentation is available at response-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: response-defs.php */
  22. /* Author: Paul Waite */
  23. /* Description: Definitions for managing the RESPONSE object. */
  24. /* */
  25. /* ******************************************************************** */
  26. /** @package core */// AUTHENTICATION OPTIONS
  27. /** Authentication option: Redundant case, no authentication */
  28. ("NO_AUTHENTICATION", 0 );
  29. /** Authentication option: Browser popup form */
  30. ("HTTP_AUTHENTICATION", 1 );
  31. /** Authentication option: Username/password from custom form fields */
  32. ("FORM_AUTHENTICATION", 2 );
  33.  
  34. // -----------------------------------------------------------------------
  35. // RESPONSE COMPRESSION OPTIONS
  36.  
  37. /** Webpage compression: None. Just straight HTML */
  38. ("NO_COMPRESSION", 0 );
  39. /** Webpage compression: Use the builtin Php compression system. Requires Php >= v4.04 */
  40. ("BUILTIN_COMPRESSION", 1 );
  41. /** Webpage compression: Use custom Phplib compression. For Php < v4.04 */
  42. ("CUSTOM_COMPRESSION", 2 );
  43.  
  44. // -----------------------------------------------------------------------
  45. // FAILED AUTHENTICATION RESPONSE OPTIONS
  46. // Here's what we can do when the user fails authentication.
  47.  
  48.  
  49.  
  50. /** Failed authentication: Die, with 'not authorised' message. */
  51. ("AUTHFAIL_DIE_MSG", 0);
  52. /** Failed authentication: Die silently. */
  53. ("AUTHFAIL_DIE_SILENT", 1);
  54. /** Failed authentication: Re-direct to specified URL. */
  55. ("AUTHFAIL_REDIRECT", 2);
  56. /** Failed authentication: Welcome the user as a guest instead. */
  57. ("AUTHFAIL_GUEST", 3);
  58.  
  59. // -----------------------------------------------------------------------
  60. // KEEP OPTIONS
  61.  
  62. /** Enable keeping variables across requests using Php session handling */
  63. ("KEEP_ENABLED", true );
  64. /** Disable keeping variables across requests using Php session handling */
  65. ("KEEP_DISABLED", false );
  66.  
  67. // -----------------------------------------------------------------------
  68. // METADATA OPTIONS
  69.  
  70. /** Enable metadata editing and generation enhancements */
  71. ("METADATA_ENABLED", true );
  72. /** Disable metadata editing and generation enhancements */
  73. ("METADATA_DISABLED", false );
  74.  
  75. // -----------------------------------------------------------------------
  76. // MICROSITE OPTIONS
  77.  
  78. /** Enable microsites editing and generation enhancements */
  79. ("MICROSITES_ENABLED", true );
  80. /** Disable microsites editing and generation enhancements */
  81. ("MICROSITES_DISABLED", false );
  82.  
  83. // -----------------------------------------------------------------------
  84. // MULIT-LANGUAGE OPTIONS
  85.  
  86. /** Enable multi-language extensions */
  87. ("MULTILANG_ENABLED", true );
  88. /** Disable multi-language extensions */
  89. ("MULTILANG_DISABLED", false );
  90.  
  91. // -----------------------------------------------------------------------
  92. // BROWSER MAKES
  93. // We recognise Internet Explorer, Mozilla (includes Netscape), and then
  94. // class all the others under the "other" umbrella. Other browsers may
  95. // be added in the future as requirements dictate.
  96.  
  97.  
  98.  
  99. /** Microsoft internet Explorer */
  100. ("BROWSER_IE", "msie");
  101. /** Netscape, Mozilla */
  102. ("BROWSER_MOZILLA", "mozilla");
  103. /** Netscape only, this is Mozilla <5.0 */
  104. ("BROWSER_NETSCAPE", "netscape");
  105. /** Opera */
  106. ("BROWSER_OPERA", "opera");
  107. /** Browser detection: Any WAP phone browser */
  108. ("BROWSER_PHONE", "phone");
  109. /** Browser detection: Other browsers */
  110. ("BROWSER_OTHER", "other");
  111. /** Browser detection: No browser; command line interface */
  112. ("BROWSER_NONE", "none");
  113.  
  114. // -----------------------------------------------------------------------
  115. // DEFAULT DTD's
  116.  
  117. /** These Document Type Definition specifier strings are the defaults
  118. * which are used in the event that (a) they are not specified in the
  119. * application.php file, and (b) not specified in the template(s).
  120. */
  121. $DEFAULT_DTD = array(
  122. BROWSER_TYPE_HTML => "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">",
  123. BROWSER_TYPE_WML => "<!DOCTYPE wml PUBLIC \"-//WAPFORUM//DTD WML 1.1//EN\" \"http://www.wapforum.org/DTD/wml_1.1.xml\">"
  124. );
  125.  
  126. // -----------------------------------------------------------------------
  127. /** List of recognition patterns for web-browsers. */
  128. = "(wget)"
  129. . "|(mozilla)"
  130. . "|(opera)"
  131. . "|(lynx)"
  132. . "|(msie)"
  133. . "|(konqueror)"
  134. . "|(libwww-perl)"
  135. ;
  136. /** List of recognition patterns for WAP-phones. */
  137. = "(UP\.Browser)"
  138. . "|(Nokia)"
  139. . "|(Sharp)"
  140. . "|(Panasonic)"
  141. . "|(Ericsson)"
  142. . "|(SonyEricsson)"
  143. ;
  144.  
  145. // -----------------------------------------------------------------------
  146. // SET APPLICATION DEFINES & GLOBALS
  147. // At this point the document root should be set, but if not we fall back
  148. // to the current working directory..
  149.  
  150. if (empty($DOCUMENT_ROOT)) {
  151. $DOCUMENT_ROOT = getcwd();
  152. }
  153. if (file_exists("$DOCUMENT_ROOT/application.xml")) {
  154. /** Application management classes */
  155. ("application-defs.php");
  156. $application = new application("$DOCUMENT_ROOT/application.xml");
  157. if ($application->valid) {
  158. foreach ($application->definitions as $defname => $defval) {
  159. define($defname, $defval);
  160. }
  161. foreach ($application->globals as $globname => $globval) {
  162. $$globname = $globval;
  163. }
  164. }
  165. }
  166.  
  167. // -----------------------------------------------------------------------
  168. // SITE CLOSED CHECK
  169. // We implement a nice simple method of closing a website without
  170. // recourse to using the database which may of course be down for some
  171. // maintenance. If this file exists, we always display it, and exit..
  172.  
  173. if (file_exists("$DOCUMENT_ROOT/closed.php")) {
  174. include("$DOCUMENT_ROOT/closed.php");
  175. exit;
  176. }
  177.  
  178. // -----------------------------------------------------------------------
  179. // REQUIRED SYSTEM INCLUDES
  180.  
  181. /** Various constants */
  182. ("constants.php");
  183. /** MIME types and categories */
  184. ("mime-types.php");
  185. /** Simple anti-hack filtering */
  186. ("antihack.php");
  187. /** Basic renderable classes */
  188. ("renderable.php");
  189. /** Filesystem access classes */
  190. ("file-defs.php");
  191. /** Database query classes */
  192. ("query-defs.php");
  193. /** Built-in debugger */
  194. ("debugger.php");
  195. /** User identification and management */
  196. ("user-defs.php");
  197. /** Misc. utility functions */
  198. ("utils.php");
  199. /** User session management */
  200. ("session-defs.php");
  201. /** Generic configuration classes */
  202. ("configuration-defs.php");
  203. /** Database access classes */
  204. ("database-defs.php");
  205. /** Php globals management */
  206. ("globals-defs.php");
  207. /** Axyl keep-alive classes */
  208. ("keep-defs.php");
  209. /** Core webpage classes */
  210. ("webpage-defs.php");
  211.  
  212. // -----------------------------------------------------------------------
  213. /**
  214. * THE RESPONSE CLASS
  215. * This object is a container for all things to do with the response which
  216. * we will send back to the requester (the client browser). It is a
  217. * descendant of the webpage class, and before that, the session and the
  218. * user classes.
  219. *
  220. * If you use the Phplib framework then a response object is automatically
  221. * instantiated for you. This object is assigned to the global variable
  222. * called $RESPONSE. The framework also sets up the response parameters,
  223. * and then calls the activate() method.
  224. * @package core
  225. */
  226. class response extends webpage {
  227. // Public
  228. /** The make of browser */
  229.  
  230. var $browser;
  231. /** The version of browser requesting this response */
  232.  
  233. var $browser_version = 0;
  234. /** The type of browser requesting this response */
  235.  
  236. var $browser_type = BROWSER_TYPE_HTML;
  237. /** The user-agent */
  238.  
  239. var $user_agent = "";
  240. /** The remote IP address */
  241.  
  242. var $remote_address = "";
  243. /** The browser accept string, as submitted by user-agent */
  244.  
  245. var $accept = "";
  246. /** The browser accept-encoding string */
  247.  
  248. var $accept_encoding = "";
  249. /** The browser accept-language string */
  250.  
  251. var $accept_language = "";
  252. /** Whether we are in multi-language mode or not, If this is true then
  253. we enable facilities to set language tags on webpages, and also
  254. deliver http content encoded in UTF-8. */
  255. var $multilang = false;
  256. /** IDs of all languages contained in this page */
  257.  
  258. var $languages = array();
  259. /** Charset for this page */
  260.  
  261. var $charset = "ISO-8859-1";
  262. /** Page ID - key to ax_sitepage record */
  263.  
  264. var $page_id;
  265. /** Whether we have multi-byte string fns available */
  266.  
  267. var $mbstring_avail = false;
  268. /** Datasources associated with this response */
  269.  
  270. var $datasource;
  271. /** Metadata edit/generation mode we are in */
  272.  
  273. var $metadata_mode = METADATA_DISABLED;
  274. /** Microsites edit/generation mode we are in */
  275.  
  276. var $microsites_mode = MICROSITES_DISABLED;
  277. /** Name of the microsite detected, or undefined */
  278.  
  279. var $microsite_detected;
  280. /** The URL of this website */
  281.  
  282. var $site_url;
  283. /** The host of this website ie. 'foo.thingy.co.nz' */
  284.  
  285. var $http_host;
  286. /** Path to the site document root */
  287.  
  288. var $site_docroot;
  289. /** Path to the requested script/page */
  290.  
  291. var $requested;
  292. /** Query string (if any) supplied to requested page */
  293.  
  294. var $requested_query;
  295.  
  296. // Private
  297. /** Buffering option to use
  298. @access private */
  299. var $buffering_mode = BUFFERED;
  300. /** Array of hosts we wish to connect persistently to
  301. @access private */
  302. var $persistent_hosts = array();
  303. /** Compression type to use for response content
  304. @access private */
  305. var $compression_type;
  306. /** Minimum size in bytes before invoking compression
  307. @access private */
  308. var $compression_minsize;
  309. /** The debugger for this response
  310. @access private */
  311. var $debugger;
  312. /** Type of authentication in effect
  313. @access private */
  314. var $auth_type;
  315. /** Option to take on auth failure
  316. @access private */
  317. var $auth_fail_option;
  318. /** URL to redirect to on auth failure
  319. @access private */
  320. var $auth_fail_redirect;
  321. /** Our keep enabled flag (default enabled)
  322. @access private */
  323. var $keep_enabled = KEEP_ENABLED;
  324. /** Our keep. Keeps variables alive in session
  325. @access private */
  326. var $keep;
  327. /** Globals object. Manages the global vars in this response
  328. @access private */
  329. var $globals;
  330. /** Cache control directive, usually passed on URL
  331. @access private */
  332. var $cachecontrol;
  333. /** Dynamic page expiry in seconds. Time to allow a dynamic page to
  334. 'live' in user browser. Note this defaults to -1, which means
  335. 'in the past', and which causes us to force the users browser
  336. to NOT cache the page at all, and revalidate every time.
  337. @access private */
  338. var $page_expiry_secs = -1;
  339. /** Array of DTD specifiers for this response. @see set_dtd()
  340. @access private */
  341. var $DTD;
  342. /** Reponse timer */
  343.  
  344. var $timer;
  345. // ...................................................................
  346. /**
  347. * Constructor
  348. * Create a new response.
  349. * One of these objects must be created to respond to each request
  350. * from the user agent for a webpage. This object manages that response
  351. * and is a central marshalling point for all data and functions
  352. * associated with that process. A response object is automatically
  353. * created for you at the bottom of this module, and is assigned to
  354. * the global variable $RESPONSE.
  355. */
  356. function response() {
  357. // Initialise DTD array..
  358. global $DEFAULT_DTD;
  359. $this->DTD = $DEFAULT_DTD;
  360. $this->mbstring_avail = extension_loaded("mbstring");
  361.  
  362. // Create the debugger..
  363. $this->debugger = new webdebugger();
  364.  
  365. // Create the globaliser..
  366. $this->globals = new globals();
  367.  
  368. // Globalise all server vars..
  369. $this->register(
  370. "DOCUMENT_ROOT," // List of Web Server vars to globalise.
  371. . "^HTTP_.*," // Note the use of Perl regex to specify
  372. . "^REMOTE_.*," // groups of server vars to globalise.
  373. . "^SERVER_.*,"
  374. . "PATH,"
  375. . "SCRIPT_FILENAME,"
  376. . "PHP_SELF,"
  377. . "UNIQUE_ID,"
  378. . "GATEWAY_INTERFACE,"
  379. . "SERVER_PROTOCOL,"
  380. . "REQUEST_METHOD,"
  381. . "QUERY_STRING,"
  382. . "REQUEST_URI,"
  383. . "SCRIPT_NAME,"
  384. . "PATH_TRANSLATED,"
  385. . "PHP_SELF"
  386. ,
  387. "server"
  388. );
  389.  
  390. // Globalise vars used for login/logout..
  391. $this->register(
  392. "tbxUsername,user"
  393. . "tbxPassword,pass"
  394. . "tbxLogoff,"
  395. . "chkRememberMe,"
  396. . "authid,"
  397. . "auth_code,"
  398. . "admin_auth_code,"
  399. . "PHP_AUTH_USER,"
  400. . "PHP_AUTH_PW,"
  401. . "MAX_FILE_SIZE,"
  402. . "cachecontrol,"
  403. . "^_.*,"
  404. . "^recmaint.*,"
  405. . "theme"
  406. ,
  407. "get,post"
  408. );
  409.  
  410. // Do the globalisation thing..
  411. $this->globalise();
  412.  
  413. // Some globals we need to use right now..
  414. global $HTTP_USER_AGENT;
  415. global $HTTP_HOST;
  416. global $REMOTE_ADDR;
  417. global $PHP_SELF;
  418. global $SCRIPT_NAME;
  419. global $QUERY_STRING;
  420. global $WEB_BROWSERS, $WAP_PHONES;
  421. global $DOCUMENT_ROOT;
  422.  
  423. // Initialise some vars..
  424. $this->initialise();
  425.  
  426. // BROWSER TYPE IDENTIFICATION..
  427. $this->user_agent = $HTTP_USER_AGENT;
  428. $this->remote_address = $REMOTE_ADDR;
  429. $this->browser_type = $this->get_browser_type();
  430.  
  431. // WEB-BROWSER IDENTIFICATION..
  432. switch ($this->browser_type) {
  433. case BROWSER_TYPE_CLI:
  434. $this->browser = BROWSER_NONE;
  435. $this->browser_version = "";
  436. // The site Domain and URL..
  437. $this->set_http_host(trim(`hostname --fqdn`));
  438. $this->site_docroot = getcwd();
  439. // For debugging, set output mode..
  440. $this->debugger->debug_output(DBG_O_CLI);
  441. break;
  442.  
  443. case BROWSER_TYPE_WML:
  444. case BROWSER_TYPE_WMLUP:
  445. $this->browser = BROWSER_PHONE;
  446. $this->browser_version = "";
  447. // The site Domain and URL..
  448. $this->set_http_host($HTTP_HOST);
  449. $this->site_docroot = $DOCUMENT_ROOT;
  450. break;
  451.  
  452. case BROWSER_TYPE_HTML:
  453. case BROWSER_TYPE_XHTML:
  454. // First try to determine browser version. We assume that the people
  455. // who made it will be sticking to the rule that the first word
  456. // is the browser/version string.
  457. $agentbits = explode(" ", $HTTP_USER_AGENT);
  458. $verbits = explode("/", $agentbits[0]);
  459. if (is_numeric((float) $verbits[1])) {
  460. $this->browser_version = $verbits[1];
  461. }
  462. // OPERA
  463. if (eregi("opera", $HTTP_USER_AGENT)) {
  464. $this->browser = BROWSER_OPERA;
  465. $matches = array();
  466. if (preg_match("/.* opera (.+) .*/i", $HTTP_USER_AGENT, $matches)) {
  467. if (is_numeric((float) $matches[1])) {
  468. $this->browser_version = $matches[1];
  469. }
  470. }
  471. }
  472. // INTERNET EXPLORER
  473. // Determine flavour of browser. Practicality means that we
  474. // resolve this down to either IE or Netscape/Mozilla
  475. elseif (eregi("msie", $HTTP_USER_AGENT)) {
  476. $this->browser = BROWSER_IE;
  477. // IE has its own version number..
  478. $matches = array();
  479. if (preg_match("/.* msie (.+); .*/i", $HTTP_USER_AGENT, $matches)) {
  480. if (is_numeric((float) $matches[1])) {
  481. $this->browser_version = $matches[1];
  482. }
  483. }
  484. }
  485. // MOZILLA - NETSCAPE 4.xx
  486. elseif (eregi("mozilla", $HTTP_USER_AGENT)) {
  487. $this->browser = BROWSER_MOZILLA;
  488. // The Mozilla engine with version nos. less than 5.0 is
  489. // in fact that old dog the Netscape browser..
  490. if ($this->browser_version > 0 && $this->browser_version < 5) {
  491. $this->browser = BROWSER_NETSCAPE;
  492. }
  493. }
  494. // MOBILE PHONES..
  495. elseif (eregi($WAP_PHONES, $HTTP_USER_AGENT)) {
  496. $this->browser = BROWSER_PHONE;
  497. }
  498. // OTHER WEB BROWSER
  499. // This might be an xhtml-compatible phone or a
  500. // PDA of some kind, who knows..
  501. else {
  502. $this->browser = BROWSER_OTHER;
  503. }
  504.  
  505. // The site Domain and URL..
  506. $this->set_http_host($HTTP_HOST);
  507. $this->site_docroot = $DOCUMENT_ROOT;
  508. break;
  509.  
  510. default:
  511. $this->browser = BROWSER_NONE;
  512. $this->browser_version = "";
  513. // The site Domain and URL..
  514. $this->set_http_host($HTTP_HOST);
  515. $this->site_docroot = $DOCUMENT_ROOT;
  516. } // switch
  517.  
  518. if (dirname($PHP_SELF) != "/") {
  519. $this->site_url .= dirname($PHP_SELF);
  520. }
  521.  
  522. // Possible cache control directive. This is usually
  523. // passed in on the URL to force refresh or something..
  524. global $cachecontrol;
  525. if (isset($cachecontrol)) {
  526. $this->cachecontrol = strtolower($cachecontrol);
  527. }
  528.  
  529. // The page being requested and the query string.
  530. // These are just our local copies..
  531. $this->requested = "";
  532. $this->requested_query = "";
  533. if (isset($SCRIPT_NAME)) {
  534. $this->requested = $SCRIPT_NAME;
  535. }
  536. if (isset($QUERY_STRING)) {
  537. $this->requested_query = $QUERY_STRING;
  538. }
  539.  
  540. // Set default charset according to browser type.
  541. // This is just the initial setting & can be overriden..
  542. switch ($this->browser_type) {
  543. case BROWSER_TYPE_WML:
  544. case BROWSER_TYPE_WMLUP:
  545. $this->charset = "UTF-8";
  546. break;
  547. default:
  548. $this->charset = "ISO-8859-1";
  549. }
  550. } // response
  551. // ...................................................................
  552. /**
  553. * Initialise values
  554. * Initialise our main response parameters to normal values.
  555. * @access private
  556. */
  557. function initialise() {
  558. $this->cookiename = "session_id";
  559. $this->compression_type = NO_COMPRESSION;
  560. $this->compression_minsize = 0;
  561. $this->persistent_hosts = array();
  562. $this->auth_type = FORM_AUTHENTICATION;
  563. $this->auth_fail_option = AUTHFAIL_GUEST;
  564. $this->auth_fail_redirect = "";
  565. $this->multilang = MULTILANG_DISABLED;
  566. } // initialise
  567. // .....................................................................
  568. /**
  569. * Set the response timer up. Set it ticking.
  570. * @param boolean $mode If true then enable the response timer.
  571. */
  572. function enable_response_timer($mode=false) {
  573. if ($mode === true) {
  574. // Create the timer and start it..
  575. include_once("timer-defs.php");
  576. $this->timer = new microtimer();
  577. $this->timer->start();
  578. }
  579. else {
  580. // Remove any existing timer..
  581. if (isset($this->timer)) {
  582. unset($this->timer);
  583. }
  584. }
  585. } // enable_response_timer
  586. // ...................................................................
  587. /**
  588. * Determine the browser type
  589. * Examines the headers, if we are running as an apache module and
  590. * returns the browser type accordingly. If we are not running as
  591. * an apache module returns 'cgi' (command line).
  592. * @access private
  593. */
  594. function get_browser_type() {
  595. global $HTTP_USER_AGENT;
  596. global $WEB_BROWSERS, $WAP_PHONES;
  597.  
  598. // Starting point..
  599. $type = BROWSER_TYPE_UNKNOWN;
  600.  
  601. // If webserver then detect, else CLI script..
  602. if (isset($HTTP_USER_AGENT) && $HTTP_USER_AGENT != "") {
  603. // Determine accept headers..
  604. $headers = getallheaders();
  605. $this->accept = trim($headers["Accept"]);
  606. $this->accept_encoding = trim($headers["Accept-Encoding"]);
  607. $this->accept_language = trim($headers["Accept-Language"]);
  608.  
  609. // STANDARD BROWSERS - User Agent Detection
  610. if (eregi($WEB_BROWSERS, $HTTP_USER_AGENT)) {
  611. $type = BROWSER_TYPE_HTML;
  612. }
  613. // WAP PHONES - User Agent Detection
  614. elseif (eregi($WAP_PHONES, $HTTP_USER_AGENT)) {
  615. $type = BROWSER_TYPE_WML;
  616. }
  617.  
  618. // GENERIC - Accept Encodings Detection
  619. // This might override the more general user-agent detection
  620. // phase which has been undertaken above. Note that Vodafone
  621. // gateways do not pass through Accept headers.
  622. if (stristr($this->accept, "application/vnd.wap")) $type = BROWSER_TYPE_WML;
  623. elseif (stristr($this->accept, "text/vnd.wap")) $type = BROWSER_TYPE_WML;
  624. elseif (stristr($this->accept, "application/xhtml")) $type = BROWSER_TYPE_XHTML;
  625. elseif (stristr($this->accept, "text/html")) $type = BROWSER_TYPE_HTML;
  626.  
  627. // A bit of post-processing for WAP phones which
  628. // might have Phone.com extensions..
  629. if ($type == BROWSER_TYPE_WML) {
  630. if (stristr($this->accept, "application/x-up")
  631. || stristr($this->accept, "application/vnd.phonecom")
  632. ) {
  633. $type = BROWSER_TYPE_WMLUP;
  634. }
  635. elseif (eregi("(up)", $HTTP_USER_AGENT)) {
  636. $type = BROWSER_TYPE_WMLUP;
  637. }
  638. }
  639. }
  640. else {
  641. // Default browser type to CLI (command line)..
  642. $type = BROWSER_TYPE_CLI;
  643. }
  644.  
  645. // Fallback to default if unknown..
  646. if ($type == BROWSER_TYPE_UNKNOWN) {
  647. $type = BROWSER_TYPE_DEFAULT;
  648. }
  649. return $type;
  650. } // get_browser_type
  651. // .....................................................................
  652. /**
  653. * Set the DTDs array for all possible content types for this webpage.
  654. * The array is associative, with content type as the key, and the
  655. * DTD specifier as the value. Currently we only support two content
  656. * types: "html" and "wml".
  657. * @param array $DTD Array of DTD specifiers per content type
  658. */
  659. function set_dtd($DTD) {
  660. if (is_array($DTD)) {
  661. $this->DTD = $DTD;
  662. }
  663. } // set_dtd
  664. // ...................................................................
  665. /**
  666. * Set up the page attributes for our response. This is an important
  667. * call, and should be made just after including response-defs.php in
  668. * your source code. It sets up the page title, the template file which
  669. * defines the page structure, the theme and stylesheet.
  670. * @param string $title Webpage title string
  671. * @param string $template Template for this webpage
  672. * @param string $theme Theme to apply. This is for branding purposes
  673. * @param string $stylesheet Name of stylesheet to use eg: 'sitestyle.css'
  674. * @param string $dtd Override the DTD specifier for page
  675. */
  676. function page($title="", $template="main", $theme="", $stylesheet="", $dtd="") {
  677. // The ordering of these calls is important, since the
  678. // theme setting influences the path settings for the
  679. // template and the stylesheet..
  680. $this->set_title($title);
  681. $this->set_theme($theme);
  682. $this->set_template($template);
  683. $this->set_stylesheet($stylesheet);
  684. if ($dtd != "") {
  685. $this->head->set_dtd($dtd);
  686. }
  687. $this->check_group_membership();
  688. debug("page: template '$template' ", DBG_DEBUG);
  689. if ($theme != "") {
  690. debugbr("theme '$theme'", DBG_DEBUG);
  691. }
  692. else {
  693. debugbr(" (default theme)", DBG_DEBUG);
  694. }
  695. } // page
  696. // ...................................................................
  697. /**
  698. * Set up the Wap page (card) attributes for our response. This is
  699. * the exact equivalent to the page() method above, but for WAP
  700. * phones instead.
  701. * @param string $title Card title string
  702. * @param string $template Template for this WML card
  703. * @param string $theme Theme to apply. This is for branding purposes
  704. * @param string $stylesheet Name of stylesheet to use eg: 'sitestyle.css'
  705. * @param string $dtd Override the DTD specifier for WML page
  706. */
  707. function card($title="", $template="main", $theme="", $stylesheet="", $dtd="") {
  708. if ($this->browser != BROWSER_PHONE) {
  709. // Enable normal browsers to see Wap content..
  710. include_once("wml-defs.php");
  711. $this->body = new deck($title, $template, $theme, $stylesheet);
  712. }
  713. $this->page($title, $template, $theme, $stylesheet, $dtd);
  714. global $CARD;
  715. $CARD = new WMLcard(basename($template), $this->head->title);
  716. $this->check_group_membership();
  717. return $CARD;
  718. } // card
  719. // ...................................................................
  720. /**
  721. * Activate response
  722. * Activate the response object. This isn't done in the constructor
  723. * so that the application code can make various calls etc. to set
  724. * up the environment for the response, such as session parameters.
  725. * After this setup phase is complete, then this function is called.
  726. * @access private
  727. */
  728. function activate() {
  729. global $CONTEXT;
  730. global $tbxUsername, $user; // Username submitted by user form
  731. global $tbxPassword, $pass; // Password submitted
  732. global $tbxLogoff; // Logoff sequence submission
  733. global $PHP_AUTH_USER; // HTTP Authentication username
  734. global $PHP_AUTH_PW; // HTTP Authentication password
  735. global $cachecontrol; // Cache/page expiry control override
  736.  
  737. debug_trace($this);
  738.  
  739. // Set site-wide language, if multi-language mode, and given..
  740. if ($this->multilang) {
  741. debugbr("multilang: multi-language mode is enabled", DBG_DEBUG);
  742. if ($this->mbstring_avail) {
  743. mb_internal_encoding("UTF-8");
  744. mb_http_output("UTF-8");
  745. }
  746. // Use the session-specific language if present. How this session
  747. // var gets set is entirely application-specific. If it is defined
  748. // then it becomes the 'default' language by virtue of being first..
  749. if (isset($this->session_record["lang_id"]) && $this->session_record["lang_id"] != "") {
  750. $this->add_language($this->session_record["lang_id"]);
  751. }
  752. // Otherwise, use the language defaults. These are again in an
  753. // order, with the first one the designated default..
  754. else {
  755. $q = "SELECT lang_id FROM ax_language";
  756. $q .= " WHERE enabled=TRUE";
  757. $q .= " AND is_default=TRUE";
  758. $q .= " ORDER BY display_order";
  759. $langs = dbrecordset($q);
  760. if ($langs->hasdata) {
  761. do {
  762. $this->add_language( $langs->field("lang_id") );
  763. } while ($langs->get_next());
  764. }
  765. }
  766. } // multilang
  767.  
  768. // Create our parent webpage object now. We do not do this in
  769. // the constructor, due to timing. Only at this point do we
  770. // know what type of browser (html or wml) it is, and have
  771. // the relevant library included to support it..
  772. $this->webpage();
  773.  
  774. // Map alternative fieldnames onto standard ones..
  775. if (isset($user) && $user != "" && !isset($tbxUsername)) $tbxUsername = $user;
  776. if (isset($pass) && $pass != "" && !isset($tbxPassword)) $tbxPassword = $pass;
  777.  
  778. // Always disable buffering mode for command-line..
  779. if ($this->browser_type == BROWSER_TYPE_CLI) {
  780. $this->set_buffering_mode(UNBUFFERED);
  781. }
  782.  
  783. // See if we should disable webpage buffering..
  784. if ($this->buffering_mode == UNBUFFERED) {
  785. $this->discard();
  786. $this->buffered = false;
  787. }
  788.  
  789. // Check flag to see if we have to globalise everything in
  790. // sight. If this is the case, it is probably due to the website
  791. // being broken by setting 'register_globals = Off' in php.ini.
  792. if ($this->globalise_all) {
  793. $this->globals->globalise_all();
  794. }
  795. else {
  796. // By now we have the actual cookie name, so we make
  797. // sure it is globalised..
  798. $this->globalise($this->cookiename, "cookie");
  799. }
  800.  
  801. // Browser announcement
  802. $msg = "browser: $this->browser";
  803. if ($this->browser_version != "") $msg .= "/$this->browser_version";
  804. $msg .= " ($this->browser_type)";
  805. debugbr($msg, DBG_DEBUG);
  806. debugbr("accept=[$this->accept]", DBG_DEBUG);
  807. debugbr("UA=[$this->user_agent]", DBG_DEBUG);
  808.  
  809. if ($this->browser != BROWSER_NONE) {
  810. // HTTP AUTHENTICATION
  811. if ($this->auth_type == HTTP_AUTHENTICATION) {
  812. debugbr("HTTP Authentication", DBG_DEBUG);
  813. if (!isset($PHP_AUTH_USER)) {
  814. debugbr("sending HTTP authentication headers", DBG_AUTH);
  815. header("WWW-Authenticate: Basic realm=\"" . APP_NAME . "\"");
  816. header("HTTP/1.0 401 Unauthorized");
  817. return;
  818. }
  819. else {
  820. // Get the HTTP authentication variables..
  821. if ($this->get_session_cookie()) {
  822. debugbr("we already have a valid session", DBG_AUTH);
  823. if ($this->identify_user()
  824. && $this->userid == "guest"
  825. && strtolower($PHP_AUTH_USER != "guest")
  826. ) {
  827. debugbr("overriding guest session with supplied HTTP Auth login", DBG_AUTH);
  828. $tbxUsername = $PHP_AUTH_USER;
  829. if (isset($PHP_AUTH_PW)) $tbxPassword = $PHP_AUTH_PW;
  830. else $tbxPassword = "";
  831. }
  832. }
  833. else {
  834. // Transform it into our own kind of login sequence..
  835. debugbr("morphing to Axyl login", DBG_AUTH);
  836. $tbxUsername = $PHP_AUTH_USER;
  837. if (isset($PHP_AUTH_PW)) $tbxPassword = $PHP_AUTH_PW;
  838. else $tbxPassword = "";
  839. }
  840. }
  841. } // HTTP Auth
  842. else {
  843. debugbr("FORM Authentication", DBG_DEBUG);
  844. }
  845. }
  846.  
  847. // IDENTIFY USER, LOGIN
  848. $logged_in = true;
  849. $retries = 2;
  850. do {
  851. // Create the user's keep if enabled..
  852. if ( $this->keep_enabled
  853. && $this->browser != BROWSER_NONE
  854. && $this->browser != BROWSER_PHONE
  855. ) {
  856. $this->keep = new keep("CATITKEEP" . APP_PREFIX, $this->lifetime);
  857. // Deal with logoff activity..
  858. if (isset($tbxLogoff) && $tbxLogoff == "Logoff") {
  859. $this->keep->forgetall();
  860. }
  861. }
  862.  
  863. // Get the session to login the user. We expect this step
  864. // to succeed unless they mucked up a login sequence, or
  865. // someone is hacking on our website..
  866. if (!$this->identify_user()) {
  867. // Deal with authentication/session create failure..
  868. if (!$this->isvalid()) {
  869. debugbr("response-defs: user is invalid", DBG_AUTH);
  870. // Make sure the cookie is removed..
  871. $this->delete_cookie();
  872. if ($this->keep_enabled) {
  873. $this->keep->delete();
  874. }
  875.  
  876. switch ($this->auth_fail_option) {
  877. case AUTHFAIL_DIE_MSG:
  878. $this->crash(401, $this->error_message);
  879. break;
  880.  
  881. case AUTHFAIL_DIE_SILENT:
  882. $this->crash();
  883. break;
  884.  
  885. case AUTHFAIL_REDIRECT:
  886. log_sys("authfail_redirect: user=$tbxUsername dest=$this->auth_fail_redirect");
  887. header("Location: $this->auth_fail_redirect");
  888. exit;
  889. break;
  890.  
  891. // AUTHFAIL_GUEST and friends..
  892. default:
  893. if (isset($tbxUsername) && strtolower($tbxUsername) == "guest") {
  894. // Failed guest login should not happen if the guest user
  895. // exists and its 'enabled' flag is true..
  896. $this->crash(401, "authfail_guest: Guest logins are not permitted.");
  897. }
  898. else {
  899. // Unset everything they might be logging in with, so that
  900. // the system will default them into guest mode..
  901. if (isset($tbxUsername)) {
  902. debugbr("authfail_guest: tbxUsername is set [$tbxUsername], setting it to guest.", DBG_AUTH);
  903. $tbxUsername = "guest";
  904. $tbxPassword = "";
  905. }
  906. if (isset($authid)) unset($authid);
  907. $logged_in = false;
  908. }
  909. break;
  910. } // switch
  911. }
  912. // Otherwise we failed authentication, but the user was
  913. // valid - a very strange state of affairs..!
  914. else {
  915. debugbr("user [$this->userid] valid but failed authentication", DBG_AUTH);
  916. if ($this->authfail_option != AUTHFAIL_SILENT) {
  917. $this->crash(500, "No session!");
  918. }
  919. else die();
  920. }
  921. // Countdown for retries..
  922. $retries -= 1;
  923. } // if !identify_user
  924. else {
  925. // Affirm user identified..
  926. $logged_in = true;
  927. }
  928. } while (!$logged_in && $retries > 0);
  929.  
  930. // If login failed, then we have no options left..
  931. if ($logged_in) {
  932. if ($this->login_type == LOGIN_BY_PASSWD) {
  933. if ($this->password_expired() && $this->requested != "/axyl-login.php") {
  934. if ($this->browser_type == BROWSER_TYPE_WML || $this->browser_type == BROWSER_TYPE_WMLUP) {
  935. header("Location: /axyl-login.php?authid=".$this->get_auth_code());
  936. exit;
  937. } else {
  938. header("Location: /axyl-login.php");
  939. exit;
  940. }
  941. }
  942. }
  943. }
  944. else {
  945. if ($this->authfail_option != AUTHFAIL_SILENT) {
  946. $this->crash(401);
  947. }
  948. else die();
  949. }
  950.  
  951. // CONTENT TYPE HEADER
  952. $this->set_encoding();
  953.  
  954. // CACHE HEADERS
  955. switch ($this->browser_type) {
  956. case BROWSER_TYPE_HTML:
  957. case BROWSER_TYPE_XHTML:
  958. header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
  959. if ($this->page_expiry_secs == -1 || (isset($cachecontrol) && $cachecontrol == "dynamic")) {
  960. header("Expires: Thu, 1 Jan 1970 01:00:00 GMT");
  961. header("Cache-Control: no-cache, must-revalidate");
  962. header("Pragma: no-cache");
  963. debugbr("page expiry: no cache", DBG_DEBUG);
  964. }
  965. else {
  966. $expirysecs = time() + $this->page_expiry_secs;
  967. header("Expires: " . gmdate("D, d M Y H:i:s", $expirysecs) . " GMT");
  968. debugbr("page expiry: cache for $this->page_expiry_secs seconds", DBG_DEBUG);
  969. }
  970. break;
  971.  
  972. case BROWSER_TYPE_WML:
  973. case BROWSER_TYPE_WMLUP:
  974. header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
  975. header("Last-Modified: " . gmdate("D, d M Y H:i:s T") );
  976. header("Cache-Control: no-cache, must revalidate");
  977. header("Pragma: no-cache");
  978. header("Accept-Ranges: none");
  979. break;
  980. } // switch
  981.  
  982. // CONTEXT
  983. if ($this->browser_type != BROWSER_TYPE_CLI
  984. && file_exists($this->site_docroot . "/context-defs.php")) {
  985. include_once("context-defs.php");
  986. $CONTEXT = new context();
  987. }
  988. debug_trace();
  989. } // activate
  990. // ...................................................................
  991. /**
  992. * Sets the status of the multi-language flag 'multilang'. If this flag
  993. * is true then multi-language facilities are enabled. This allows the
  994. * setting of tags to indicate webpage language(s), and for inputting
  995. * different character encodings via form elements etc.
  996. * @param boolean $mode Whether we should set multi-language mode
  997. */
  998. function set_multilang($mode=true) {
  999. $this->multilang = $mode;
  1000. } // set_multilang
  1001. // ...................................................................
  1002. /**
  1003. * Adds another language for the current webpage. Webpages might
  1004. * contain content in multiple languages, hence the need for a list.
  1005. * @param integer $langid The new language ID to add for the webpage
  1006. */
  1007. function add_language($langid) {
  1008. if ($this->multilang) {
  1009. if (!in_array($langid, $this->languages)) {
  1010. $this->languages[] = $langid;
  1011. if (isset($this->head)) {
  1012. $this->head->add_language($langid);
  1013. }
  1014. }
  1015. }
  1016. } // add_language
  1017. // ...................................................................
  1018. /**
  1019. * Sets the content-type header characterset encoding, and (optionally)
  1020. * allows you to override the content type itself although it should
  1021. * be set for you automatically, so you should only need to provide the
  1022. * second parameter for special purposes. This method will send the
  1023. * content-type: header to the user agent (browser). It can be called
  1024. * any number of times before send() is called.
  1025. * @param string $charset The character encoding to use for the webpage
  1026. * @param string $content_type The content type (defaults to proper one for browser)
  1027. */
  1028. function set_encoding($charset="", $content_type="") {
  1029. if ($charset != "") {
  1030. $this->charset = $charset;
  1031. }
  1032. if ($content_type == "") {
  1033. switch ($this->browser_type) {
  1034. case BROWSER_TYPE_HTML:
  1035. case BROWSER_TYPE_XHTML:
  1036. $content_type = "text/html";
  1037. break;
  1038.  
  1039. case BROWSER_TYPE_WML:
  1040. case BROWSER_TYPE_WMLUP:
  1041. $content_type = "text/vnd.wap.wml";
  1042. break;
  1043.  
  1044. default:
  1045. $content_type = "text/html";
  1046. }
  1047. }
  1048. // Insert prefix if not already provided..
  1049. if ( substr(strtolower($content_type), 0, 13) != "content-type:") {
  1050. $content_type = "content-type: $content_type";
  1051. }
  1052. // Set head section charset..
  1053. if (isset($this->head)) {
  1054. $this->head->set_charset($this->charset);
  1055. }
  1056.  
  1057. // Append charset code for header if provided..
  1058. if ($this->charset != "") {
  1059. $content_type .= "; charset=$this->charset";
  1060. }
  1061. // Also transmit a content-type header..
  1062. if ($this->browser_type != BROWSER_TYPE_CLI) {
  1063. header($content_type);
  1064. }
  1065. } // set_encoding
  1066. // ...................................................................
  1067. /**
  1068. * Set globalise all
  1069. * Flag that we should globalise all vars from anywhere. This is the
  1070. * same as setting 'register_globals = On' in php.ini. It gives
  1071. * backward compatibility with that setting, if you find that it has
  1072. * been set to 'Off' and this breaks your code.
  1073. * NB: This only takes effect when the session is activated with
  1074. * the activate() method of this class.
  1075. */
  1076. function globalise_all() {
  1077. $this->globalise_all = true;
  1078. } // globalise_all
  1079. // ...................................................................
  1080. /**
  1081. * Globalise specific vars
  1082. * @param string $varnames Comma-delimited list of variable names to globalise
  1083. * @param string $sources Comma-delimited list of allowed sources for values
  1084. */
  1085. function globalise($varnames="", $sources="env,get,post,cookie,server") {
  1086. $this->globals->globalise($varnames, $sources);
  1087. } // globalise
  1088. // ...................................................................
  1089. /**
  1090. * Register vars
  1091. * Register given variables for globalisation.
  1092. * @param string $varnames Comma-delimited list of variable names to globalise
  1093. * @param string $sources Comma-delimited list of allowed sources for values
  1094. */
  1095. function register($varnames, $sources="env,get,post,cookie,server") {
  1096. $this->globals->register($varnames, $sources);
  1097. } // register
  1098. // ...................................................................
  1099. /**
  1100. * Set keep enable status. If the keep is enabled then there is access to
  1101. * the remember() and forget() methods to control persistent vars using
  1102. * Php session handling functions.
  1103. * @see remember(), forget()
  1104. * @param boolean $keep_enabled If true then the keep methods are enabled
  1105. */
  1106. function set_keep($keep_enabled=true) {
  1107. $this->keep_enabled = $keep_enabled;
  1108. } // set_keep
  1109. // ...................................................................
  1110. /**
  1111. * Remember variables by name, across page requests using our keep
  1112. * functionality. This utilises Php session handling to maintain the value
  1113. * of variables named here. Pass a list of vars as a string delimited
  1114. * by a comma.
  1115. * @param string $varnames Comma-delimited list of variable names to keep
  1116. */
  1117. function remember($varnames) {
  1118. if ($this->keep_enabled && isset($this->keep)) {
  1119. $this->keep->remember($varnames);
  1120. }
  1121. } // remember
  1122. // ...................................................................
  1123. /**
  1124. * Forget kept variables by name. The named variables will have been
  1125. * passed to the remember() function beforehand, and this method causes
  1126. * them to be forgotten.
  1127. * @param string $varnames Comma-delimited list of variable names to forget
  1128. */
  1129. function forget($varnames) {
  1130. if ($this->keep_enabled && isset($this->keep)) {
  1131. $this->keep->forget($varnames);
  1132. }
  1133. } // forget
  1134. // ...................................................................
  1135. /**
  1136. * Define persistent hosts list.
  1137. * Set the list of hosts recognition strings to connect to with
  1138. * persistent database connections. You can pass either an array of strings
  1139. * or a single string containing a delimited list of hosts.
  1140. * @param mixed $hosts Array or delimited list of host names to connect persistently to
  1141. * @param string $delim Optional delimiter, defaults to a comma
  1142. */
  1143. function set_persistent_hosts($hosts="", $delim=",") {
  1144. if (is_array($hosts)) {
  1145. $this->persistent_hosts = $hosts;
  1146. }
  1147. else {
  1148. if ($hosts != "") {
  1149. $hosts = explode($delim, $hosts);
  1150. }
  1151. }
  1152. } // set_persistent_hosts
  1153. // ...................................................................
  1154. /**
  1155. * define a blocked IP list.
  1156. * Set the list of IP addresses which are persona non grata for our site.
  1157. * This might be a list of problem IPs which are hacking, for example.
  1158. * Note that this method may not return, since the IP checking is done
  1159. * immediately, and if the REMOTE_ADDR accessing the site right now is
  1160. * found to match a blocked IP, then we crash and burn the response.
  1161. *
  1162. * @param mixed $hosts Array or delimited list of host names to connect persistently to
  1163. * @param string $delim Optional delimiter, defaults to a comma
  1164. */
  1165. function set_blocked_ips($ips="", $delim=",") {
  1166. if ($ips != "") {
  1167. global $REMOTE_ADDR;
  1168. if (isset($REMOTE_ADDR) && $REMOTE_ADDR != "") {
  1169. if (!is_array($ips) && $ips != "") {
  1170. $ips = explode($delim, $ips);
  1171. }
  1172. foreach ($ips as $unwelcome) {
  1173. if (preg_match("/^$unwelcome/", $REMOTE_ADDR)) {
  1174. $this->crash(403, "Bad address");
  1175. exit();
  1176. }
  1177. }
  1178. }
  1179. }
  1180. } //set_blocked_ips
  1181. // ...................................................................
  1182. /**
  1183. * Set compression type
  1184. * Set the compression type to use for content delivery. Options are:
  1185. * NO_COMPRESSION Normal delivery of content
  1186. * BUILTIN_COMPRESSION Builtin PHP compression (Requires Php >= v4.04)
  1187. * CUSTOM_COMPRESSION Compression provided by the library
  1188. * @param integer $type Compression type: NO_COMPRESSION, BUILTIN_COMPRESSION, CUSTOM_COMPRESSION
  1189. */
  1190. function set_compression_type($type=NO_COMPRESSION) {
  1191. $this->compression_type = $type;
  1192. } // set_compression_type
  1193. // ...................................................................
  1194. /**
  1195. * Set buffering option
  1196. * Set the webstream buffering option. Usually we want to buffer the
  1197. * webpage output to do cool things with the content right up until
  1198. * we send it. If you select NO_BUFFERING, then output won't be
  1199. * buffered and you will probably be processing it yourself. If in
  1200. * doubt, leave it as BUFFERING, the default.
  1201. * Possible options..
  1202. * BUFFERED Output webstream uses Php buffering (default)
  1203. * UNBUFFERED No buffering of output webstream
  1204. * @param bool $buffering Buffering option: NO_BUFFERING, or BUFFERING
  1205. */
  1206. function set_buffering_mode($mode=BUFFERED) {
  1207. $this->buffering_mode = $mode;
  1208. } // set_buffering_mode
  1209. // ...................................................................
  1210. /**
  1211. * Set metadata mode
  1212. * This setting determines whether Axyl will implement the metadata
  1213. * enhancements that it has. If true, content-managed layouts will get
  1214. * an extra button 'META', which enables page metadata to be edited
  1215. * Also, when page generation takes place, metadata elements will be
  1216. * procuced in the output.
  1217. * @param bool $mode Metadata enable mode, true or false
  1218. */
  1219. function set_metadata_mode($mode=METADATA_ENABLED) {
  1220. $this->metadata_mode = $mode;
  1221. } // set_metadata_mode
  1222. // ...................................................................
  1223. /**
  1224. * Set microsites mode
  1225. * This setting determines whether Axyl will implement the microsites
  1226. * enhancements that it has. If true, then users with content manager
  1227. * privileges will be able to create and maintain "microsites" within
  1228. * the current Axyl website framework. These are essentially simple
  1229. * themes, using Axyl themeing.
  1230. * @param bool $mode Microsites feature enable mode, true or false
  1231. */
  1232. function set_microsites_mode($mode=MICROSITES_ENABLED) {
  1233. $this->microsites_mode = $mode;
  1234. } // set_microsites_mode
  1235. // ...................................................................
  1236. /**
  1237. * Set page expiry in seconds. This affects all of the pages returned by Axyl.
  1238. * Normally this is left at -1, which causes the system to tell the user browser
  1239. * to NOT cache the webpage, and revalidate every time. This is the usual case
  1240. * for a dynamic website where content is always changing. If set to a positive
  1241. * value, the user browser will (probably) keep the page cached for this time.
  1242. *
  1243. * @param integer $secs Time to allow website pages to live in the user browser.
  1244. */
  1245. function set_page_expirysecs($secs=-1) {
  1246. $this->page_expiry_secs = $secs;
  1247. } // set_page_expirysecs
  1248. // ...................................................................
  1249. /**
  1250. * Set compression threshold
  1251. * Set the threshold size of content before we use compression.
  1252. * @param integer $size Pagesize in bytes below which we will not compress
  1253. */
  1254. function set_compression_minsize($size=0) {
  1255. $this->compression_minsize = $size;
  1256. } // set_compression_minsize
  1257. // ...................................................................
  1258. /**
  1259. * Set website authentication
  1260. * Set the authentication option for the website. Note that although there
  1261. * is NO_AUTHENTICATION, this has no real effect and is mainly there so
  1262. * you can indicate your intent not to bother with authentication. If no
  1263. * username/password is passed then the system will always log the session
  1264. * as a "guest" anyway, regardless of this setting. Options are:
  1265. * NO_AUTHENTICATION Redundant case, no authentication
  1266. * HTTP_AUTHENTICATION User sees a browser username/password popup
  1267. * FORM_AUTHENTICATION Custom form fields $tbxUsername/$tbxPassword
  1268. * @param integer $authtype Authentication option type
  1269. */
  1270. function set_authentication_type($authtype=HTTP_AUTHENTICATION) {
  1271. $this->auth_type = $authtype;
  1272. } // set_authentication_type
  1273. // ...................................................................
  1274. /**
  1275. * Set authentication failure option
  1276. * This sets the option for when authentication fails due to invalid
  1277. * username/password. Options are:
  1278. * AUTHFAIL_DIE_MSG Die, with 'not authorised' message
  1279. * AUTHFAIL_DIE_SILENT Die silently
  1280. * AUTHFAIL_REDIRECT Re-direct to alternate URL
  1281. * AUTHFAIL_GUEST Welcome the user as a guest (the default)
  1282. */
  1283. function on_authentication_fail($option=AUTHFAIL_GUEST, $redirect="") {
  1284. $this->auth_fail_option = $option;
  1285. $this->auth_fail_redirect = $redirect;
  1286. } // on_authentication_fail
  1287.  
  1288. // ...................................................................
  1289. /**
  1290. * Set the hostname of the machine serving this Axyl website. This is
  1291. * usually the same as that in the global $HTTP_HOST variable.
  1292. * @param string $http_host The hostname of the machine serving this website
  1293. */
  1294. function set_http_host($http_host="") {
  1295. if ($http_host != "") {
  1296. $this->http_host = $http_host;
  1297. $this->site_url = "http://$this->http_host";
  1298. }
  1299. } // set_http_host
  1300.  
  1301. // ...................................................................
  1302. /**
  1303. * Add database
  1304. * Add a new database to the list of datasources which are going to be used to
  1305. * serve this response. The dbtype and the name are the only mandatory parameters.
  1306. * @param string $dbtype The type of database eg: 'postgres', 'mssql' etc.
  1307. * @param string $name The name of the database
  1308. * @param string $user Name of a user who can access the database
  1309. * @param string $passwd The password the user can access the database with
  1310. * @param string $host The hostname of the machine running the database (TCP/IP)
  1311. * @param integer $port The port number of the database server
  1312. * @param string $enc The database character encoding (eg. 'US_ASCII', 'UNICODE')
  1313. * @param string $datestyle The database date style (eg. 'ISO')
  1314. * @param boolean $default True if the database is the default database
  1315. */
  1316. function add_database(
  1317. $dbtype,
  1318. $name, $user="", $passwd="",
  1319. $host="", $port="",
  1320. $enc="UNICODE", $datestyle="ISO",
  1321. $default=false)
  1322. {
  1323. if ($this->db_backed) {
  1324. if (!isset($this->datasource)) {
  1325. $this->datasource = new datasources();
  1326. }
  1327. $this->datasource->add_database($dbtype, $name, $user, $passwd, $host, $port, $enc, $datestyle, $default);
  1328. }
  1329. } // add_database
  1330. // ...................................................................
  1331. /**
  1332. * Selects a database to use
  1333. * This will connect it if it isn't already connected. Calling this
  1334. * with no database name will select the default one. Returns the
  1335. * database unique identifier, or false if none was selected.
  1336. * The named database must have been already defined. @see add_database()
  1337. * @see datasources::add_database()
  1338. * @param string $dbname The name of the database to select
  1339. * @return resource The database resource ID
  1340. */
  1341. function select_database($db_name="") {
  1342. if ($this->db_backed && isset($this->datasource)) {
  1343. return $this->datasource->select($db_name);
  1344. }
  1345. else {
  1346. return false;
  1347. }
  1348. } // select_database
  1349. // ...................................................................
  1350. /**
  1351. * Is host in peristent list
  1352. * Returns true if the given host is in our list of persistent
  1353. * hosts, else returns false. The persistent hosts list we hold
  1354. * will general contain partial hostnames. We therefore check
  1355. * to see if this partial name occurs anywhere in the given
  1356. * hostname.
  1357. * @param string $hostname The name of the host to check
  1358. */
  1359. function InPersistentHostsList($hostname) {
  1360. if (count($this->persistent_hosts) > 0) {
  1361. foreach ($this->persistent_hosts as $host) {
  1362. if (stristr($hostname, $host)) {
  1363. return true;
  1364. }
  1365. }
  1366. }
  1367. return false;
  1368. } // InPersistentHostsList
  1369. // ...................................................................
  1370. /**
  1371. * Allowed groups
  1372. * This defines the allowed user-groups for this response, otherwise
  1373. * they get an error page returned. The list of allowed groups
  1374. * should be a comma-delimited string.
  1375. * NB: We look for globals $admin_auth_code, and $auth_code and if
  1376. * available, use these for authorisation.
  1377. * @param string $allowed_groups Comma-delimited list of allowed groups
  1378. */
  1379. function allowed_groups($allowed_groups) {
  1380. global $WEBMASTER_EMAIL, $WEBMASTER_PERSON;
  1381. global $auth_code;
  1382. global $admin_auth_code;
  1383. if (!$this->ismemberof_group_in($allowed_groups)) {
  1384. if (isset($admin_auth_code)) $auth = $admin_auth_code;
  1385. elseif (isset($auth_code)) $auth = $auth_code;
  1386. if (isset($auth)) {
  1387. $user = new authorised_user($auth);
  1388. if ($user->ismemberof_group_in($allowed_groups)) {
  1389. return;
  1390. }
  1391. }
  1392. // On failure follow the login settings for action..
  1393. switch ($this->auth_fail_option) {
  1394. case AUTHFAIL_DIE_MSG:
  1395. $msg = "<p><center><h4>"
  1396. . "You are not permitted to view this page.<br>"
  1397. . "For further information, please contact "
  1398. . "<a href=\"mailto:$WEBMASTER_EMAIL\">$WEBMASTER_PERSON</a>"
  1399. . "</h4></center></p>"
  1400. . "<p><center><h4><a href=\"/\">HOME</a></p></h4></center></p>"
  1401. ;
  1402. $this->set_template("plain");
  1403. $this->plugin("MAIN_CONTENT", $msg);
  1404. $this->send();
  1405. exit;
  1406. break;
  1407. case AUTHFAIL_DIE_SILENT:
  1408. $this->crash();
  1409. break;
  1410. case AUTHFAIL_REDIRECT:
  1411. header("Location: $this->auth_fail_redirect");
  1412. exit;
  1413. break;
  1414. default:
  1415. $this->crash(401, $this->error_message);
  1416. exit;
  1417. } // switch
  1418. }
  1419. } // allowed_groups
  1420. // ...................................................................
  1421. /**
  1422. * Check group membership
  1423. * This check whether the user requesting the page fulfils any group
  1424. * membership requirements. These are optionally expressed as the
  1425. * presence of 'ax_sitepage_group' records. A set of these records
  1426. * represents a set of groups that the user must be member of at
  1427. * least one of, to have access to the page.
  1428. */
  1429. function check_group_membership() {
  1430. // Find page and group permissions if we can..
  1431. $q = "SELECT * FROM ax_sitepage p, ax_sitepage_group sg, ax_group g";
  1432. $q .= " WHERE p.page_path='" . escape_string($this->requested) . "'";
  1433. $q .= " AND p.page_title='" . escape_string($this->head->title) . "'";
  1434. $q .= " AND sg.page_id=p.page_id";
  1435. $q .= " AND g.group_id=sg.group_id";
  1436. $allowed = dbrecordset($q);
  1437. if ($allowed->hasdata) {
  1438. $groups = array();
  1439. do {
  1440. $groups[] = $allowed->field("group_desc");
  1441. } while ($allowed->get_next());
  1442. // Check membership and die if not authorised..
  1443. debugbr("sitepage group membership: " . implode(",", $groups), DBG_DEBUG);
  1444. $this->allowed_groups( implode(",", $groups) );
  1445. }
  1446. } // check_group_membership
  1447. // ...................................................................
  1448. /**
  1449. * Crash the response with message
  1450. * A fatal error ocurred. We die with a message to the system log
  1451. * and to the user. Code supplied is optional.
  1452. * @param integer $code The HTTP/1.0 code to use
  1453. * @param string $msg The message to display and log
  1454. */
  1455. function crash($code=false, $msg="") {
  1456. // Echo debugging output, but only if
  1457. // we are in debugging mode..
  1458. echo debug_render();
  1459.  
  1460. // For the system log..
  1461. $logmsg = APP_PREFIX . " CRASH: ";
  1462. if ($msg != "") $logmsg .= $msg;
  1463. else $logmsg = "(no reason provided)";
  1464. if ($code) $logmsg .= " ($code)";
  1465. error_log(APP_PREFIX . " CRASH: $logmsg");
  1466. // For the user..
  1467. if ($code !== false || $msg != "") {
  1468. $umsg = "";
  1469. if ($code !== false) $umsg .= HTTPError($code) . " ";
  1470. if ($msg != "") $umsg .= $msg;
  1471. die($umsg);
  1472. }
  1473. else die();
  1474. } // fatal
  1475.  
  1476. } // response class
  1477. // -----------------------------------------------------------------------
  1478. // CREATE THe RESPONSE OBJECT
  1479.  
  1480. $RESPONSE = new response();
  1481.  
  1482. // -----------------------------------------------------------------------
  1483. // OUTPUT GENERATION INCLUDES
  1484.  
  1485. switch ($RESPONSE->browser_type) {
  1486. case BROWSER_TYPE_WML:
  1487. case BROWSER_TYPE_WMLUP:
  1488. include_once("wml-defs.php");
  1489. break;
  1490. default:
  1491. include_once("html-defs.php");
  1492. } // switch
  1493. // -----------------------------------------------------------------------
  1494. // APPLY APPLICATION RESPONSE SETTINGS
  1495. // These settings are the ones sourced from the application.xml file
  1496. // for this particular website.
  1497.  
  1498. if (file_exists("$DOCUMENT_ROOT/application.xml") && isset($application) && $application->valid) {
  1499. $firstDB = true;
  1500. foreach ($application->settings as $setting) {
  1501. if (isset($setting->agent) && $setting->agent != "") {
  1502. $methodname = $setting->agent;
  1503. $parms = array();
  1504. foreach ($setting->parameters as $parameter) {
  1505. $parms[] = $parameter->get_decodedvalue();
  1506. }
  1507. if ($setting->name == "database") {
  1508. // Make sure number of database params is right..
  1509. if (count($parms) < 8) {
  1510. $RESPONSE->crash(403,
  1511. "Database '" . $parms[1] . "': Wrong number of database parameters "
  1512. . "for this version of Axyl. Check your 'application.xml' schema is "
  1513. . "up to date, and run the latest version of control-panel.php, if "
  1514. . "necessary, to update it."
  1515. );
  1516. }
  1517. // Set the 'default=true' parameter for first database..
  1518. if ($firstDB) {
  1519. $parms[] = true;
  1520. $firstDB = false;
  1521. }
  1522. }
  1523. // Apply the RESPONSE setting..
  1524. call_user_method_array($methodname, $RESPONSE, $parms);
  1525. }
  1526. }
  1527.  
  1528. // UNICODE
  1529. // If the above loop brought in the multilang setting as true
  1530. // then we will be needing the Unicode functions..
  1531. if ($RESPONSE->multilang) {
  1532. include_once("unicode-defs.php");
  1533. }
  1534.  
  1535. // WEBMASTER SETTINGS
  1536. if ($WEBMASTER_PERSON == "") {
  1537. $WEBMASTER_PERSON = "The " . ((APP_NAME != "") ? (APP_NAME . " ") : "") . "Webmaster";
  1538. }
  1539. if ($WEBMASTER_EMAIL == "") {
  1540. $WEBMASTER_EMAIL = "webmaster@" . $this->http_host;
  1541. }
  1542.  
  1543. // DEBUGGING
  1544. $debugging = $application->getparameter("debug_on", "debug_on");
  1545. if ($debugging) {
  1546. debug_on($application->getparameter("debug_classes", "debug_classes"));
  1547. debug_output($application->getparameter("debug_output", "debug_output"));
  1548. }
  1549.  
  1550. // MOBILE PHONES
  1551. // No cookie-based 'keep' feature for these..
  1552. if ($RESPONSE->browser == BROWSER_NONE
  1553. || $RESPONSE->browser == BROWSER_PHONE) {
  1554. $RESPONSE->set_keep(false);
  1555. }
  1556.  
  1557. // ABSOLUTE REFERENCES
  1558. // Turm relative references to web docroot absolute..
  1559. if (isset($TEMPLATESDIR) && substr($TEMPLATESDIR,0,1) != "/") {
  1560. $TEMPLATESDIR = "/$TEMPLATESDIR";
  1561. }
  1562. if (isset($IMAGESDIR) && substr($IMAGESDIR,0,1) != "/") {
  1563. $IMAGESDIR = "/$IMAGESDIR";
  1564. }
  1565. if (isset($CMDIR) && substr($CMDIR,0,1) != "/") {
  1566. $CMDIR = "/$CMDIR";
  1567. }
  1568. if (isset($CATALOGDIR) && substr($CATALOGDIR,0,1) != "/") {
  1569. $CATALOGDIR = "/$CATALOGDIR";
  1570. }
  1571. if (isset($INCDIR) && substr($INCDIR,0,1) != "/") {
  1572. $INCDIR = "/$INCDIR";
  1573. }
  1574.  
  1575. // ACTIVATION
  1576. // No longer required..
  1577. unset($application);
  1578. // Activate the response, determine user etc..
  1579. $RESPONSE->activate();
  1580.  
  1581. // SEARCH ENGINE
  1582. // Determine the basics - do we have one available?
  1583. if (isset($CONTEXT) && ($CONTEXT->configvalue("Search Engine Host") != "")) {
  1584. $SE_AVAILABLE = true;
  1585. $SE_HOST = $CONTEXT->configvalue("Search Engine Host");
  1586. $SE_PORT = $CONTEXT->configvalue("Search Engine Port");
  1587. debugbr("search engine available: host [$SE_HOST] port [$SE_PORT]", DBG_DEBUG);
  1588. }
  1589. else {
  1590. $SE_AVAILABLE = false;
  1591. debugbr("search engine not available", DBG_DEBUG);
  1592. }
  1593.  
  1594. // SET MICROSITE THEME
  1595. if ($RESPONSE->microsites_mode == MICROSITES_ENABLED) {
  1596. debugbr("microsite features are enabled", DBG_DEBUG);
  1597. // Get the hostname/URL of this request..
  1598. //$hostbits = explode(".", $HTTP_HOST);
  1599. $hostname = strtolower($HTTP_HOST);
  1600. $hostname = str_replace("-test", "", $hostname);
  1601. // Check this hostname against our microsite domains..
  1602. $q = "SELECT mi.microsite_name,mi.microsite_domain,m.menu_name";
  1603. $q .= " FROM ax_microsite mi, ax_menu m";
  1604. $q .= " WHERE mi.currently_installed=TRUE";
  1605. $q .= " AND mi.req_microsite_remove=FALSE";
  1606. $q .= " AND m.menu_id=mi.menu_id";
  1607. $microsites = dbrecordset($q);
  1608. if ($microsites->hasdata) {
  1609. do {
  1610. $microsite_domain = $microsites->field("microsite_domain");
  1611. if (stristr($hostname, $microsite_domain)) {
  1612. debugbr("microsite scan hit: [$microsite_domain]", DBG_DEBUG);
  1613. $RESPONSE->microsite_detected = $microsites->field("microsite_name");
  1614. $theme = $RESPONSE->microsite_detected;
  1615. $THEME_TITLE = $microsites->field("microsite_desc");
  1616. $THEME_MENU = $microsites->field("menu_name");
  1617. break;
  1618. }
  1619. } while ($microsites->get_next());
  1620. // Detect index page request..
  1621. if (isset($RESPONSE->microsite_detected)) {
  1622. switch ($RESPONSE->requested) {
  1623. case "":
  1624. case "/":
  1625. case "/index.php":
  1626. $q = "SELECT * FROM ax_microsite_page mp, ax_sitepage p";
  1627. $q .= " WHERE mp.microsite_name='" . escape_string($RESPONSE->microsite_detected) . "'";
  1628. $q .= " AND mp.microsite_homepage=TRUE";
  1629. $q .= " AND p.page_id=mp.page_id";
  1630. $home = dbrecordset($q);
  1631. if ($home->hasdata) {
  1632. $homepath = $home->field("page_path");
  1633. if ($homepath != "") {
  1634. // Re-direct to the correct page and exit..
  1635. $redirect_url = $RESPONSE->site_url . $homepath;
  1636. $RESPONSE->discard();
  1637. header("Location: $redirect_url");
  1638. exit;
  1639. }
  1640. }
  1641. break;
  1642. } // switch
  1643. }
  1644. }
  1645. } // microsites enabled
  1646. }
  1647. // -----------------------------------------------------------------------
  1648. ?>

Documentation generated by phpDocumentor 1.3.0RC3