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. if (preg_match("/.* opera (.+) .*/i", $HTTP_USER_AGENT, $matches)) {
  466. if (is_numeric((float) $matches[1])) {
  467. $this->browser_version = $matches[1];
  468. }
  469. }
  470. }
  471. // INTERNET EXPLORER
  472. // Determine flavour of browser. Practicality means that we
  473. // resolve this down to either IE or Netscape/Mozilla
  474. elseif (eregi("msie", $HTTP_USER_AGENT)) {
  475. $this->browser = BROWSER_IE;
  476. // IE has its own version number..
  477. if (preg_match("/.* msie (.+); .*/i", $HTTP_USER_AGENT, $matches)) {
  478. if (is_numeric((float) $matches[1])) {
  479. $this->browser_version = $matches[1];
  480. }
  481. }
  482. }
  483. // MOZILLA - NETSCAPE 4.xx
  484. elseif (eregi("mozilla", $HTTP_USER_AGENT)) {
  485. $this->browser = BROWSER_MOZILLA;
  486. // The Mozilla engine with version nos. less than 5.0 is
  487. // in fact that old dog the Netscape browser..
  488. if ($this->browser_version > 0 && $this->browser_version < 5) {
  489. $this->browser = BROWSER_NETSCAPE;
  490. }
  491. }
  492. // MOBILE PHONES..
  493. elseif (eregi($WAP_PHONES, $HTTP_USER_AGENT)) {
  494. $this->browser = BROWSER_PHONE;
  495. }
  496. // OTHER WEB BROWSER
  497. // This might be an xhtml-compatible phone or a
  498. // PDA of some kind, who knows..
  499. else {
  500. $this->browser = BROWSER_OTHER;
  501. }
  502.  
  503. // The site Domain and URL..
  504. $this->set_http_host($HTTP_HOST);
  505. $this->site_docroot = $DOCUMENT_ROOT;
  506. break;
  507.  
  508. default:
  509. $this->browser = BROWSER_NONE;
  510. $this->browser_version = "";
  511. // The site Domain and URL..
  512. $this->set_http_host($HTTP_HOST);
  513. $this->site_docroot = $DOCUMENT_ROOT;
  514. } // switch
  515.  
  516. if (dirname($PHP_SELF) != "/") {
  517. $this->site_url .= dirname($PHP_SELF);
  518. }
  519.  
  520. // Possible cache control directive. This is usually
  521. // passed in on the URL to force refresh or something..
  522. global $cachecontrol;
  523. if (isset($cachecontrol)) {
  524. $this->cachecontrol = strtolower($cachecontrol);
  525. }
  526.  
  527. // The page being requested and the query string.
  528. // These are just our local copies..
  529. $this->requested = "";
  530. $this->requested_query = "";
  531. if (isset($SCRIPT_NAME)) {
  532. $this->requested = $SCRIPT_NAME;
  533. }
  534. if (isset($QUERY_STRING)) {
  535. $this->requested_query = $QUERY_STRING;
  536. }
  537.  
  538. // Set default charset according to browser type.
  539. // This is just the initial setting & can be overriden..
  540. switch ($this->browser_type) {
  541. case BROWSER_TYPE_WML:
  542. case BROWSER_TYPE_WMLUP:
  543. $this->charset = "UTF-8";
  544. break;
  545. default:
  546. $this->charset = "ISO-8859-1";
  547. }
  548. } // response
  549. // ...................................................................
  550. /**
  551. * Initialise values
  552. * Initialise our main response parameters to normal values.
  553. * @access private
  554. */
  555. function initialise() {
  556. $this->cookiename = "session_id";
  557. $this->compression_type = NO_COMPRESSION;
  558. $this->compression_minsize = 0;
  559. $this->persistent_hosts = array();
  560. $this->auth_type = FORM_AUTHENTICATION;
  561. $this->auth_fail_option = AUTHFAIL_GUEST;
  562. $this->auth_fail_redirect = "";
  563. $this->multilang = MULTILANG_DISABLED;
  564. } // initialise
  565. // .....................................................................
  566. /**
  567. * Set the response timer up. Set it ticking.
  568. * @param boolean $mode If true then enable the response timer.
  569. */
  570. function enable_response_timer($mode=false) {
  571. if ($mode === true) {
  572. // Create the timer and start it..
  573. include_once("timer-defs.php");
  574. $this->timer = new microtimer();
  575. $this->timer->start();
  576. }
  577. else {
  578. // Remove any existing timer..
  579. if (isset($this->timer)) {
  580. unset($this->timer);
  581. }
  582. }
  583. } // enable_response_timer
  584. // ...................................................................
  585. /**
  586. * Determine the browser type
  587. * Examines the headers, if we are running as an apache module and
  588. * returns the browser type accordingly. If we are not running as
  589. * an apache module returns 'cgi' (command line).
  590. * @access private
  591. */
  592. function get_browser_type() {
  593. global $HTTP_USER_AGENT;
  594. global $WEB_BROWSERS, $WAP_PHONES;
  595.  
  596. // Starting point..
  597. $type = BROWSER_TYPE_UNKNOWN;
  598.  
  599. // If webserver then detect, else CLI script..
  600. if (isset($HTTP_USER_AGENT) && $HTTP_USER_AGENT != "") {
  601. // Determine accept headers..
  602. $headers = getallheaders();
  603. $this->accept = trim($headers["Accept"]);
  604. $this->accept_encoding = trim($headers["Accept-Encoding"]);
  605. $this->accept_language = trim($headers["Accept-Language"]);
  606.  
  607. // STANDARD BROWSERS - User Agent Detection
  608. if (eregi($WEB_BROWSERS, $HTTP_USER_AGENT)) {
  609. $type = BROWSER_TYPE_HTML;
  610. }
  611. // WAP PHONES - User Agent Detection
  612. elseif (eregi($WAP_PHONES, $HTTP_USER_AGENT)) {
  613. $type = BROWSER_TYPE_WML;
  614. }
  615.  
  616. // GENERIC - Accept Encodings Detection
  617. // This might override the more general user-agent detection
  618. // phase which has been undertaken above. Note that Vodafone
  619. // gateways do not pass through Accept headers.
  620. if (stristr($this->accept, "application/vnd.wap")) $type = BROWSER_TYPE_WML;
  621. elseif (stristr($this->accept, "text/vnd.wap")) $type = BROWSER_TYPE_WML;
  622. elseif (stristr($this->accept, "application/xhtml")) $type = BROWSER_TYPE_XHTML;
  623. elseif (stristr($this->accept, "text/html")) $type = BROWSER_TYPE_HTML;
  624.  
  625. // A bit of post-processing for WAP phones which
  626. // might have Phone.com extensions..
  627. if ($type == BROWSER_TYPE_WML) {
  628. if (stristr($this->accept, "application/x-up")
  629. || stristr($this->accept, "application/vnd.phonecom")
  630. ) {
  631. $type = BROWSER_TYPE_WMLUP;
  632. }
  633. elseif (eregi("(up)", $HTTP_USER_AGENT)) {
  634. $type = BROWSER_TYPE_WMLUP;
  635. }
  636. }
  637. }
  638. else {
  639. // Default browser type to CLI (command line)..
  640. $type = BROWSER_TYPE_CLI;
  641. }
  642.  
  643. // Fallback to default if unknown..
  644. if ($type == BROWSER_TYPE_UNKNOWN) {
  645. $type = BROWSER_TYPE_DEFAULT;
  646. }
  647. return $type;
  648. } // get_browser_type
  649. // .....................................................................
  650. /**
  651. * Set the DTDs array for all possible content types for this webpage.
  652. * The array is associative, with content type as the key, and the
  653. * DTD specifier as the value. Currently we only support two content
  654. * types: "html" and "wml".
  655. * @param array $DTD Array of DTD specifiers per content type
  656. */
  657. function set_dtd($DTD) {
  658. if (is_array($DTD)) {
  659. $this->DTD = $DTD;
  660. }
  661. } // set_dtd
  662. // ...................................................................
  663. /**
  664. * Set up the page attributes for our response. This is an important
  665. * call, and should be made just after including response-defs.php in
  666. * your source code. It sets up the page title, the template file which
  667. * defines the page structure, the theme and stylesheet.
  668. * @param string $title Webpage title string
  669. * @param string $template Template for this webpage
  670. * @param string $theme Theme to apply. This is for branding purposes
  671. * @param string $stylesheet Name of stylesheet to use eg: 'sitestyle.css'
  672. * @param string $dtd Override the DTD specifier for page
  673. */
  674. function page($title="", $template="main", $theme="", $stylesheet="", $dtd="") {
  675. // The ordering of these calls is important, since the
  676. // theme setting influences the path settings for the
  677. // template and the stylesheet..
  678. $this->set_title($title);
  679. $this->set_theme($theme);
  680. $this->set_template($template);
  681. $this->set_stylesheet($stylesheet);
  682. if ($dtd != "") {
  683. $this->head->set_dtd($dtd);
  684. }
  685. $this->check_group_membership();
  686. debug("page: template '$template' ", DBG_DEBUG);
  687. if ($theme != "") {
  688. debugbr("theme '$theme'", DBG_DEBUG);
  689. }
  690. else {
  691. debugbr(" (default theme)", DBG_DEBUG);
  692. }
  693. } // page
  694. // ...................................................................
  695. /**
  696. * Set up the Wap page (card) attributes for our response. This is
  697. * the exact equivalent to the page() method above, but for WAP
  698. * phones instead.
  699. * @param string $title Card title string
  700. * @param string $template Template for this WML card
  701. * @param string $theme Theme to apply. This is for branding purposes
  702. * @param string $stylesheet Name of stylesheet to use eg: 'sitestyle.css'
  703. * @param string $dtd Override the DTD specifier for WML page
  704. */
  705. function card($title="", $template="main", $theme="", $stylesheet="", $dtd="") {
  706. if ($this->browser != BROWSER_PHONE) {
  707. // Enable normal browsers to see Wap content..
  708. include_once("wml-defs.php");
  709. $this->body = new deck($title, $template, $theme, $stylesheet);
  710. }
  711. $this->page($title, $template, $theme, $stylesheet, $dtd);
  712. global $CARD;
  713. $CARD = new WMLcard(basename($template), $this->head->title);
  714. $this->check_group_membership();
  715. return $CARD;
  716. } // card
  717. // ...................................................................
  718. /**
  719. * Activate response
  720. * Activate the response object. This isn't done in the constructor
  721. * so that the application code can make various calls etc. to set
  722. * up the environment for the response, such as session parameters.
  723. * After this setup phase is complete, then this function is called.
  724. * @access private
  725. */
  726. function activate() {
  727. global $CONTEXT;
  728. global $tbxUsername, $user; // Username submitted by user form
  729. global $tbxPassword, $pass; // Password submitted
  730. global $tbxLogoff; // Logoff sequence submission
  731. global $PHP_AUTH_USER; // HTTP Authentication username
  732. global $PHP_AUTH_PW; // HTTP Authentication password
  733. global $cachecontrol; // Cache/page expiry control override
  734.  
  735. debug_trace($this);
  736.  
  737. // Set site-wide language, if multi-language mode, and given..
  738. if ($this->multilang) {
  739. debugbr("multilang: multi-language mode is enabled", DBG_DEBUG);
  740. if ($this->mbstring_avail) {
  741. mb_internal_encoding("UTF-8");
  742. mb_http_output("UTF-8");
  743. }
  744. // Use the session-specific language if present. How this session
  745. // var gets set is entirely application-specific. If it is defined
  746. // then it becomes the 'default' language by virtue of being first..
  747. if (isset($this->session_record["lang_id"]) && $this->session_record["lang_id"] != "") {
  748. $this->add_language($this->session_record["lang_id"]);
  749. }
  750. // Otherwise, use the language defaults. These are again in an
  751. // order, with the first one the designated default..
  752. else {
  753. $q = "SELECT lang_id FROM ax_language";
  754. $q .= " WHERE enabled=TRUE";
  755. $q .= " AND is_default=TRUE";
  756. $q .= " ORDER BY display_order";
  757. $langs = dbrecordset($q);
  758. if ($langs->hasdata) {
  759. do {
  760. $this->add_language( $langs->field("lang_id") );
  761. } while ($langs->get_next());
  762. }
  763. }
  764. } // multilang
  765.  
  766. // Create our parent webpage object now. We do not do this in
  767. // the constructor, due to timing. Only at this point do we
  768. // know what type of browser (html or wml) it is, and have
  769. // the relevant library included to support it..
  770. $this->webpage();
  771.  
  772. // Map alternative fieldnames onto standard ones..
  773. if (isset($user) && $user != "" && !isset($tbxUsername)) $tbxUsername = $user;
  774. if (isset($pass) && $pass != "" && !isset($tbxPassword)) $tbxPassword = $pass;
  775.  
  776. // Always disable buffering mode for command-line..
  777. if ($this->browser_type == BROWSER_TYPE_CLI) {
  778. $this->set_buffering_mode(UNBUFFERED);
  779. }
  780.  
  781. // See if we should disable webpage buffering..
  782. if ($this->buffering_mode == UNBUFFERED) {
  783. $this->discard();
  784. $this->buffered = false;
  785. }
  786.  
  787. // Check flag to see if we have to globalise everything in
  788. // sight. If this is the case, it is probably due to the website
  789. // being broken by setting 'register_globals = Off' in php.ini.
  790. if ($this->globalise_all) {
  791. $this->globals->globalise_all();
  792. }
  793. else {
  794. // By now we have the actual cookie name, so we make
  795. // sure it is globalised..
  796. $this->globalise($this->cookiename, "cookie");
  797. }
  798.  
  799. // Browser announcement
  800. $msg = "browser: $this->browser";
  801. if ($this->browser_version != "") $msg .= "/$this->browser_version";
  802. $msg .= " ($this->browser_type)";
  803. debugbr($msg, DBG_DEBUG);
  804. debugbr("accept=[$this->accept]", DBG_DEBUG);
  805. debugbr("UA=[$this->user_agent]", DBG_DEBUG);
  806.  
  807. if ($this->browser != BROWSER_NONE) {
  808. // HTTP AUTHENTICATION
  809. if ($this->auth_type == HTTP_AUTHENTICATION) {
  810. debugbr("HTTP Authentication", DBG_DEBUG);
  811. if (!isset($PHP_AUTH_USER)) {
  812. debugbr("sending HTTP authentication headers", DBG_DEBUG);
  813. header("WWW-Authenticate: Basic realm=\"" . APP_NAME . "\"");
  814. header("HTTP/1.0 401 Unauthorized");
  815. return;
  816. }
  817. else {
  818. // Get the HTTP authentication variables..
  819. if ($this->get_session_cookie()) {
  820. debugbr("already have a valid session..", DBG_DEBUG);
  821. if ($this->identify_user()
  822. && $this->userid == "guest"
  823. && strtolower($PHP_AUTH_USER != "guest")
  824. ) {
  825. debugbr("overriding guest session with supplied HTTP Auth login..", DBG_DEBUG);
  826. $tbxUsername = $PHP_AUTH_USER;
  827. if (isset($PHP_AUTH_PW)) $tbxPassword = $PHP_AUTH_PW;
  828. else $tbxPassword = "";
  829. }
  830. }
  831. else {
  832. // Transform it into our own kind of login sequence..
  833. debugbr("morphing to Axyl login..", DBG_DEBUG);
  834. $tbxUsername = $PHP_AUTH_USER;
  835. if (isset($PHP_AUTH_PW)) $tbxPassword = $PHP_AUTH_PW;
  836. else $tbxPassword = "";
  837. }
  838. }
  839. } // HTTP Auth
  840. else {
  841. debugbr("FORM Authentication.", DBG_DEBUG);
  842. }
  843. }
  844.  
  845. // IDENTIFY USER, LOGIN
  846. $logged_in = true;
  847. $retries = 2;
  848. do {
  849. // Create the user's keep if enabled..
  850. if ( $this->keep_enabled
  851. && $this->browser != BROWSER_NONE
  852. && $this->browser != BROWSER_PHONE
  853. ) {
  854. $this->keep = new keep("CATITKEEP" . APP_PREFIX, $this->lifetime);
  855. // Deal with logoff activity..
  856. if (isset($tbxLogoff) && $tbxLogoff == "Logoff") {
  857. $this->keep->forgetall();
  858. }
  859. }
  860.  
  861. // Get the session to login the user. We expect this step
  862. // to succeed unless they mucked up a login sequence, or
  863. // someone is hacking on our website..
  864. if (!$this->identify_user()) {
  865. // Deal with authentication/session create failure..
  866. debugbr("response-defs: user not identified.", DBG_DEBUG);
  867. if (!$this->isvalid()) {
  868. debugbr("response-defs: user invalid.", DBG_DEBUG);
  869. // Make sure the cookie is removed..
  870. $this->delete_cookie();
  871. if ($this->keep_enabled) {
  872. $this->keep->delete();
  873. }
  874.  
  875. switch ($this->auth_fail_option) {
  876. case AUTHFAIL_DIE_MSG:
  877. $this->crash(401, $this->error_message);
  878. break;
  879.  
  880. case AUTHFAIL_DIE_SILENT:
  881. $this->crash();
  882. break;
  883.  
  884. case AUTHFAIL_REDIRECT:
  885. log_sys("AUTHFAIL_REDIRECT: user=$tbxUsername dest=$this->auth_fail_redirect");
  886. header("Location: $this->auth_fail_redirect");
  887. exit;
  888. break;
  889.  
  890. // AUTHFAIL_GUEST and friends..
  891. default:
  892. if (isset($tbxUsername) && strtolower($tbxUsername) == "guest") {
  893. // Failed guest login should not happen if the guest user
  894. // exists and its 'enabled' flag is true..
  895. $this->crash(401, "AUTHFAIL_GUEST: Guest logins are not permitted.");
  896. }
  897. else {
  898. // Unset everything they might be logging in with, so that
  899. // the system will default them into guest mode..
  900. if (isset($tbxUsername)) {
  901. debugbr("AUTHFAIL_GUEST: tbxUsername is set '$tbxUsername', setting it to guest.", DBG_DEBUG);
  902. $tbxUsername = "guest";
  903. $tbxPassword = "";
  904. }
  905. if (isset($authid)) unset($authid);
  906. $logged_in = false;
  907. }
  908. break;
  909. } // switch
  910. }
  911. // Otherwise we failed authentication, but the user was
  912. // valid - a very strange state of affairs..!
  913. else {
  914. debugbr("user '$this->userid' valid but failed authentication", DBG_DEBUG);
  915. if ($this->authfail_option != AUTHFAIL_SILENT) {
  916. $this->crash(500, "No session!");
  917. }
  918. else die();
  919. }
  920. // Countdown for retries..
  921. $retries -= 1;
  922. } // if !identify_user
  923. else {
  924. // Affirm user identified..
  925. $logged_in = true;
  926. }
  927. } while (!$logged_in && $retries > 0);
  928.  
  929. // If login failed, then we have no options left..
  930. if ($logged_in) {
  931. if ($this->login_type == LOGIN_BY_PASSWD) {
  932. if ($this->password_expired() && $this->requested != "/axyl-login.php") {
  933. header("Location: /axyl-login.php");
  934. exit;
  935. }
  936. }
  937. }
  938. else {
  939. if ($this->authfail_option != AUTHFAIL_SILENT) {
  940. $this->crash(401);
  941. }
  942. else die();
  943. }
  944.  
  945. // CONTENT TYPE HEADER
  946. $this->set_encoding();
  947.  
  948. // CACHE HEADERS
  949. switch ($this->browser_type) {
  950. case BROWSER_TYPE_HTML:
  951. case BROWSER_TYPE_XHTML:
  952. header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
  953. if ($this->page_expiry_secs == -1 || (isset($cachecontrol) && $cachecontrol == "dynamic")) {
  954. header("Expires: Thu, 1 Jan 1970 01:00:00 GMT");
  955. header("Cache-Control: no-cache, must-revalidate");
  956. header("Pragma: no-cache");
  957. debugbr("page expiry: no cache", DBG_DEBUG);
  958. }
  959. else {
  960. $expirysecs = time() + $this->page_expiry_secs;
  961. header("Expires: " . gmdate("D, d M Y H:i:s", $expirysecs) . " GMT");
  962. debugbr("page expiry: cache for $this->page_expiry_secs seconds", DBG_DEBUG);
  963. }
  964. break;
  965.  
  966. case BROWSER_TYPE_WML:
  967. case BROWSER_TYPE_WMLUP:
  968. header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
  969. header("Last-Modified: " . gmdate("D, d M Y H:i:s T") );
  970. header("Cache-Control: no-cache, must revalidate");
  971. header("Pragma: no-cache");
  972. header("Accept-Ranges: none");
  973. break;
  974. } // switch
  975.  
  976. // CONTEXT
  977. if ($this->browser_type != BROWSER_TYPE_CLI
  978. && file_exists($this->site_docroot . "/context-defs.php")) {
  979. include_once("context-defs.php");
  980. $CONTEXT = new context();
  981. }
  982. debug_trace();
  983. } // activate
  984. // ...................................................................
  985. /**
  986. * Sets the status of the multi-language flag 'multilang'. If this flag
  987. * is true then multi-language facilities are enabled. This allows the
  988. * setting of tags to indicate webpage language(s), and for inputting
  989. * different character encodings via form elements etc.
  990. * @param boolean $mode Whether we should set multi-language mode
  991. */
  992. function set_multilang($mode=true) {
  993. $this->multilang = $mode;
  994. } // set_multilang
  995. // ...................................................................
  996. /**
  997. * Adds another language for the current webpage. Webpages might
  998. * contain content in multiple languages, hence the need for a list.
  999. * @param integer $langid The new language ID to add for the webpage
  1000. */
  1001. function add_language($langid) {
  1002. if ($this->multilang) {
  1003. if (!in_array($langid, $this->languages)) {
  1004. $this->languages[] = $langid;
  1005. if (isset($this->head)) {
  1006. $this->head->add_language($langid);
  1007. }
  1008. }
  1009. }
  1010. } // add_language
  1011. // ...................................................................
  1012. /**
  1013. * Sets the content-type header characterset encoding, and (optionally)
  1014. * allows you to override the content type itself although it should
  1015. * be set for you automatically, so you should only need to provide the
  1016. * second parameter for special purposes. This method will send the
  1017. * content-type: header to the user agent (browser). It can be called
  1018. * any number of times before send() is called.
  1019. * @param string $charset The character encoding to use for the webpage
  1020. * @param string $content_type The content type (defaults to proper one for browser)
  1021. */
  1022. function set_encoding($charset="", $content_type="") {
  1023. if ($charset != "") {
  1024. $this->charset = $charset;
  1025. }
  1026. if ($content_type == "") {
  1027. switch ($this->browser_type) {
  1028. case BROWSER_TYPE_HTML:
  1029. case BROWSER_TYPE_XHTML:
  1030. $content_type = "text/html";
  1031. break;
  1032.  
  1033. case BROWSER_TYPE_WML:
  1034. case BROWSER_TYPE_WMLUP:
  1035. $content_type = "text/vnd.wap.wml";
  1036. break;
  1037.  
  1038. default:
  1039. $content_type = "text/html";
  1040. }
  1041. }
  1042. // Insert prefix if not already provided..
  1043. if ( substr(strtolower($content_type), 0, 13) != "content-type:") {
  1044. $content_type = "content-type: $content_type";
  1045. }
  1046. // Set head section charset..
  1047. if (isset($this->head)) {
  1048. $this->head->set_charset($this->charset);
  1049. }
  1050.  
  1051. // Append charset code for header if provided..
  1052. if ($this->charset != "") {
  1053. $content_type .= "; charset=$this->charset";
  1054. }
  1055. // Also transmit a content-type header..
  1056. if ($this->browser_type != BROWSER_TYPE_CLI) {
  1057. header($content_type);
  1058. }
  1059. } // set_encoding
  1060. // ...................................................................
  1061. /**
  1062. * Set globalise all
  1063. * Flag that we should globalise all vars from anywhere. This is the
  1064. * same as setting 'register_globals = On' in php.ini. It gives
  1065. * backward compatibility with that setting, if you find that it has
  1066. * been set to 'Off' and this breaks your code.
  1067. * NB: This only takes effect when the session is activated with
  1068. * the activate() method of this class.
  1069. */
  1070. function globalise_all() {
  1071. $this->globalise_all = true;
  1072. } // globalise_all
  1073. // ...................................................................
  1074. /**
  1075. * Globalise specific vars
  1076. * @param string $varnames Comma-delimited list of variable names to globalise
  1077. * @param string $sources Comma-delimited list of allowed sources for values
  1078. */
  1079. function globalise($varnames="", $sources="env,get,post,cookie,server") {
  1080. $this->globals->globalise($varnames, $sources);
  1081. } // globalise
  1082. // ...................................................................
  1083. /**
  1084. * Register vars
  1085. * Register given variables for globalisation.
  1086. * @param string $varnames Comma-delimited list of variable names to globalise
  1087. * @param string $sources Comma-delimited list of allowed sources for values
  1088. */
  1089. function register($varnames, $sources="env,get,post,cookie,server") {
  1090. $this->globals->register($varnames, $sources);
  1091. } // register
  1092. // ...................................................................
  1093. /**
  1094. * Set keep enable status. If the keep is enabled then there is access to
  1095. * the remember() and forget() methods to control persistent vars using
  1096. * Php session handling functions.
  1097. * @see remember(), forget()
  1098. * @param boolean $keep_enabled If true then the keep methods are enabled
  1099. */
  1100. function set_keep($keep_enabled=true) {
  1101. $this->keep_enabled = $keep_enabled;
  1102. } // set_keep
  1103. // ...................................................................
  1104. /**
  1105. * Remember variables by name, across page requests using our keep
  1106. * functionality. This utilises Php session handling to maintain the value
  1107. * of variables named here. Pass a list of vars as a string delimited
  1108. * by a comma.
  1109. * @param string $varnames Comma-delimited list of variable names to keep
  1110. */
  1111. function remember($varnames) {
  1112. if ($this->keep_enabled && isset($this->keep)) {
  1113. $this->keep->remember($varnames);
  1114. }
  1115. } // remember
  1116. // ...................................................................
  1117. /**
  1118. * Forget kept variables by name. The named variables will have been
  1119. * passed to the remember() function beforehand, and this method causes
  1120. * them to be forgotten.
  1121. * @param string $varnames Comma-delimited list of variable names to forget
  1122. */
  1123. function forget($varnames) {
  1124. if ($this->keep_enabled && isset($this->keep)) {
  1125. $this->keep->forget($varnames);
  1126. }
  1127. } // forget
  1128. // ...................................................................
  1129. /**
  1130. * Define persistent hosts list.
  1131. * Set the list of hosts recognition strings to connect to with
  1132. * persistent database connections. You can pass either an array of strings
  1133. * or a single string containing a delimited list of hosts.
  1134. * @param mixed $hosts Array or delimited list of host names to connect persistently to
  1135. * @param string $delim Optional delimiter, defaults to a comma
  1136. */
  1137. function set_persistent_hosts($hosts="", $delim=",") {
  1138. if (is_array($hosts)) {
  1139. $this->persistent_hosts = $hosts;
  1140. }
  1141. else {
  1142. if ($hosts != "") {
  1143. $hosts = explode($delim, $hosts);
  1144. }
  1145. }
  1146. } // set_persistent_hosts
  1147. // ...................................................................
  1148. /**
  1149. * define a blocked IP list.
  1150. * Set the list of IP addresses which are persona non grata for our site.
  1151. * This might be a list of problem IPs which are hacking, for example.
  1152. * Note that this method may not return, since the IP checking is done
  1153. * immediately, and if the REMOTE_ADDR accessing the site right now is
  1154. * found to match a blocked IP, then we crash and burn the response.
  1155. *
  1156. * @param mixed $hosts Array or delimited list of host names to connect persistently to
  1157. * @param string $delim Optional delimiter, defaults to a comma
  1158. */
  1159. function set_blocked_ips($ips="", $delim=",") {
  1160. if ($ips != "") {
  1161. global $REMOTE_ADDR;
  1162. if (isset($REMOTE_ADDR) && $REMOTE_ADDR != "") {
  1163. if (!is_array($ips) && $ips != "") {
  1164. $ips = explode($delim, $ips);
  1165. }
  1166. foreach ($ips as $unwelcome) {
  1167. if (preg_match("/^$unwelcome/", $REMOTE_ADDR)) {
  1168. $this->crash(403, "Bad address");
  1169. exit();
  1170. }
  1171. }
  1172. }
  1173. }
  1174. } //set_blocked_ips
  1175. // ...................................................................
  1176. /**
  1177. * Set compression type
  1178. * Set the compression type to use for content delivery. Options are:
  1179. * NO_COMPRESSION Normal delivery of content
  1180. * BUILTIN_COMPRESSION Builtin PHP compression (Requires Php >= v4.04)
  1181. * CUSTOM_COMPRESSION Compression provided by the library
  1182. * @param integer $type Compression type: NO_COMPRESSION, BUILTIN_COMPRESSION, CUSTOM_COMPRESSION
  1183. */
  1184. function set_compression_type($type=NO_COMPRESSION) {
  1185. $this->compression_type = $type;
  1186. } // set_compression_type
  1187. // ...................................................................
  1188. /**
  1189. * Set buffering option
  1190. * Set the webstream buffering option. Usually we want to buffer the
  1191. * webpage output to do cool things with the content right up until
  1192. * we send it. If you select NO_BUFFERING, then output won't be
  1193. * buffered and you will probably be processing it yourself. If in
  1194. * doubt, leave it as BUFFERING, the default.
  1195. * Possible options..
  1196. * BUFFERED Output webstream uses Php buffering (default)
  1197. * UNBUFFERED No buffering of output webstream
  1198. * @param bool $buffering Buffering option: NO_BUFFERING, or BUFFERING
  1199. */
  1200. function set_buffering_mode($mode=BUFFERED) {
  1201. $this->buffering_mode = $mode;
  1202. } // set_buffering_mode
  1203. // ...................................................................
  1204. /**
  1205. * Set metadata mode
  1206. * This setting determines whether Axyl will implement the metadata
  1207. * enhancements that it has. If true, content-managed layouts will get
  1208. * an extra button 'META', which enables page metadata to be edited
  1209. * Also, when page generation takes place, metadata elements will be
  1210. * procuced in the output.
  1211. * @param bool $mode Metadata enable mode, true or false
  1212. */
  1213. function set_metadata_mode($mode=METADATA_ENABLED) {
  1214. $this->metadata_mode = $mode;
  1215. } // set_metadata_mode
  1216. // ...................................................................
  1217. /**
  1218. * Set microsites mode
  1219. * This setting determines whether Axyl will implement the microsites
  1220. * enhancements that it has. If true, then users with content manager
  1221. * privileges will be able to create and maintain "microsites" within
  1222. * the current Axyl website framework. These are essentially simple
  1223. * themes, using Axyl themeing.
  1224. * @param bool $mode Microsites feature enable mode, true or false
  1225. */
  1226. function set_microsites_mode($mode=MICROSITES_ENABLED) {
  1227. $this->microsites_mode = $mode;
  1228. } // set_microsites_mode
  1229. // ...................................................................
  1230. /**
  1231. * Set page expiry in seconds. This affects all of the pages returned by Axyl.
  1232. * Normally this is left at -1, which causes the system to tell the user browser
  1233. * to NOT cache the webpage, and revalidate every time. This is the usual case
  1234. * for a dynamic website where content is always changing. If set to a positive
  1235. * value, the user browser will (probably) keep the page cached for this time.
  1236. *
  1237. * @param integer $secs Time to allow website pages to live in the user browser.
  1238. */
  1239. function set_page_expirysecs($secs=-1) {
  1240. $this->page_expiry_secs = $secs;
  1241. } // set_page_expirysecs
  1242. // ...................................................................
  1243. /**
  1244. * Set compression threshold
  1245. * Set the threshold size of content before we use compression.
  1246. * @param integer $size Pagesize in bytes below which we will not compress
  1247. */
  1248. function set_compression_minsize($size=0) {
  1249. $this->compression_minsize = $size;
  1250. } // set_compression_minsize
  1251. // ...................................................................
  1252. /**
  1253. * Set website authentication
  1254. * Set the authentication option for the website. Note that although there
  1255. * is NO_AUTHENTICATION, this has no real effect and is mainly there so
  1256. * you can indicate your intent not to bother with authentication. If no
  1257. * username/password is passed then the system will always log the session
  1258. * as a "guest" anyway, regardless of this setting. Options are:
  1259. * NO_AUTHENTICATION Redundant case, no authentication
  1260. * HTTP_AUTHENTICATION User sees a browser username/password popup
  1261. * FORM_AUTHENTICATION Custom form fields $tbxUsername/$tbxPassword
  1262. * @param integer $authtype Authentication option type
  1263. */
  1264. function set_authentication_type($authtype=HTTP_AUTHENTICATION) {
  1265. $this->auth_type = $authtype;
  1266. } // set_authentication_type
  1267. // ...................................................................
  1268. /**
  1269. * Set authentication failure option
  1270. * This sets the option for when authentication fails due to invalid
  1271. * username/password. Options are:
  1272. * AUTHFAIL_DIE_MSG Die, with 'not authorised' message
  1273. * AUTHFAIL_DIE_SILENT Die silently
  1274. * AUTHFAIL_REDIRECT Re-direct to alternate URL
  1275. * AUTHFAIL_GUEST Welcome the user as a guest (the default)
  1276. */
  1277. function on_authentication_fail($option=AUTHFAIL_GUEST, $redirect="") {
  1278. $this->auth_fail_option = $option;
  1279. $this->auth_fail_redirect = $redirect;
  1280. } // on_authentication_fail
  1281. // ...................................................................
  1282. /**
  1283. * Set the hostname of the machine serving this Axyl website. This is
  1284. * usually the same as that in the global $HTTP_HOST variable.
  1285. * @param string $http_host The hostname of the machine serving this website
  1286. */
  1287. function set_http_host($http_host="") {
  1288. if ($http_host != "") {
  1289. $this->http_host = $http_host;
  1290. $this->site_url = "http://$this->http_host";
  1291. }
  1292. } // set_http_host
  1293. // ...................................................................
  1294. /**
  1295. * Add database
  1296. * Add a new database to the list of datasources which are going to be used to
  1297. * serve this response. The dbtype and the name are the only mandatory parameters.
  1298. * @param string $dbtype The type of database eg: 'postgres', 'mssql' etc.
  1299. * @param string $name The name of the database
  1300. * @param string $user Name of a user who can access the database
  1301. * @param string $passwd The password the user can access the database with
  1302. * @param string $host The hostname of the machine running the database (TCP/IP)
  1303. * @param integer $port The port number of the database server
  1304. * @param string $enc The database character encoding (eg. 'US_ASCII', 'UNICODE')
  1305. * @param string $datestyle The database date style (eg. 'ISO')
  1306. * @param boolean $default True if the database is the default database
  1307. */
  1308. function add_database(
  1309. $dbtype,
  1310. $name, $user="", $passwd="",
  1311. $host="", $port="",
  1312. $enc="UNICODE", $datestyle="ISO",
  1313. $default=false)
  1314. {
  1315. if ($this->db_backed) {
  1316. if (!isset($this->datasource)) {
  1317. $this->datasource = new datasources();
  1318. }
  1319. $this->datasource->add_database($dbtype, $name, $user, $passwd, $host, $port, $enc, $datestyle, $default);
  1320. }
  1321. } // add_database
  1322. // ...................................................................
  1323. /**
  1324. * Selects a database to use
  1325. * This will connect it if it isn't already connected. Calling this
  1326. * with no database name will select the default one. Returns the
  1327. * database unique identifier, or false if none was selected.
  1328. * The named database must have been already defined. @see add_database()
  1329. * @see datasources::add_database()
  1330. * @param string $dbname The name of the database to select
  1331. * @return resource The database resource ID
  1332. */
  1333. function select_database($db_name="") {
  1334. if ($this->db_backed && isset($this->datasource)) {
  1335. return $this->datasource->select($db_name);
  1336. }
  1337. else {
  1338. return false;
  1339. }
  1340. } // select_database
  1341. // ...................................................................
  1342. /**
  1343. * Is host in peristent list
  1344. * Returns true if the given host is in our list of persistent
  1345. * hosts, else returns false. The persistent hosts list we hold
  1346. * will general contain partial hostnames. We therefore check
  1347. * to see if this partial name occurs anywhere in the given
  1348. * hostname.
  1349. * @param string $hostname The name of the host to check
  1350. */
  1351. function InPersistentHostsList($hostname) {
  1352. if (count($this->persistent_hosts) > 0) {
  1353. foreach ($this->persistent_hosts as $host) {
  1354. if (stristr($hostname, $host)) {
  1355. return true;
  1356. }
  1357. }
  1358. }
  1359. return false;
  1360. } // InPersistentHostsList
  1361. // ...................................................................
  1362. /**
  1363. * Allowed groups
  1364. * This defines the allowed user-groups for this response, otherwise
  1365. * they get an error page returned. The list of allowed groups
  1366. * should be a comma-delimited string.
  1367. * NB: We look for globals $admin_auth_code, and $auth_code and if
  1368. * available, use these for authorisation.
  1369. * @param string $allowed_groups Comma-delimited list of allowed groups
  1370. */
  1371. function allowed_groups($allowed_groups) {
  1372. global $WEBMASTER_EMAIL, $WEBMASTER_PERSON;
  1373. global $auth_code;
  1374. global $admin_auth_code;
  1375. if (!$this->ismemberof_group_in($allowed_groups)) {
  1376. if (isset($admin_auth_code)) $auth = $admin_auth_code;
  1377. elseif (isset($auth_code)) $auth = $auth_code;
  1378. if (isset($auth)) {
  1379. $user = new authorised_user($auth);
  1380. if ($user->ismemberof_group_in($allowed_groups)) {
  1381. return;
  1382. }
  1383. }
  1384. // On failure follow the login settings for action..
  1385. switch ($this->auth_fail_option) {
  1386. case AUTHFAIL_DIE_MSG:
  1387. $msg = "<p><center><h4>"
  1388. . "You are not permitted to view this page.<br>"
  1389. . "For further information, please contact "
  1390. . "<a href=\"mailto:$WEBMASTER_EMAIL\">$WEBMASTER_PERSON</a>"
  1391. . "</h4></center></p>"
  1392. . "<p><center><h4><a href=\"/\">HOME</a></p></h4></center></p>"
  1393. ;
  1394. $this->set_template("plain");
  1395. $this->plugin("MAIN_CONTENT", $msg);
  1396. $this->send();
  1397. exit;
  1398. break;
  1399. case AUTHFAIL_DIE_SILENT:
  1400. $this->crash();
  1401. break;
  1402. case AUTHFAIL_REDIRECT:
  1403. header("Location: $this->auth_fail_redirect");
  1404. exit;
  1405. break;
  1406. default:
  1407. $this->crash(401, $this->error_message);
  1408. exit;
  1409. } // switch
  1410. }
  1411. } // allowed_groups
  1412. // ...................................................................
  1413. /**
  1414. * Check group membership
  1415. * This check whether the user requesting the page fulfils any group
  1416. * membership requirements. These are optionally expressed as the
  1417. * presence of 'ax_sitepage_group' records. A set of these records
  1418. * represents a set of groups that the user must be member of at
  1419. * least one of, to have access to the page.
  1420. */
  1421. function check_group_membership() {
  1422. // Find page and group permissions if we can..
  1423. $q = "SELECT * FROM ax_sitepage p, ax_sitepage_group sg, ax_group g";
  1424. $q .= " WHERE p.page_path='" . addslashes($this->requested) . "'";
  1425. $q .= " AND p.page_title='" . addslashes($this->head->title) . "'";
  1426. $q .= " AND sg.page_id=p.page_id";
  1427. $q .= " AND g.group_id=sg.group_id";
  1428. $allowed = dbrecordset($q);
  1429. if ($allowed->hasdata) {
  1430. $groups = array();
  1431. do {
  1432. $groups[] = $allowed->field("group_desc");
  1433. } while ($allowed->get_next());
  1434. // Check membership and die if not authorised..
  1435. debugbr("sitepage group membership: " . implode(",", $groups), DBG_DEBUG);
  1436. $this->allowed_groups( implode(",", $groups) );
  1437. }
  1438. } // check_group_membership
  1439. // ...................................................................
  1440. /**
  1441. * Crash the response with message
  1442. * A fatal error ocurred. We die with a message to the system log
  1443. * and to the user. Code supplied is optional.
  1444. * @param integer $code The HTTP/1.0 code to use
  1445. * @param string $msg The message to display and log
  1446. */
  1447. function crash($code=false, $msg="") {
  1448. // Echo debugging output, but only if
  1449. // we are in debugging mode..
  1450. echo debug_render();
  1451.  
  1452. // For the system log..
  1453. $logmsg = APP_PREFIX . " CRASH: ";
  1454. if ($msg != "") $logmsg .= $msg;
  1455. else $logmsg = "(no reason provided)";
  1456. if ($code) $logmsg .= " ($code)";
  1457. error_log(APP_PREFIX . " CRASH: $logmsg");
  1458. // For the user..
  1459. if ($code !== false || $msg != "") {
  1460. $umsg = "";
  1461. if ($code !== false) $umsg .= HTTPError($code) . " ";
  1462. if ($msg != "") $umsg .= $msg;
  1463. die($umsg);
  1464. }
  1465. else die();
  1466. } // fatal
  1467.  
  1468. } // response class
  1469. // -----------------------------------------------------------------------
  1470. // CREATE THe RESPONSE OBJECT
  1471.  
  1472. $RESPONSE = new response();
  1473.  
  1474. // -----------------------------------------------------------------------
  1475. // OUTPUT GENERATION INCLUDES
  1476.  
  1477. switch ($RESPONSE->browser_type) {
  1478. case BROWSER_TYPE_WML:
  1479. case BROWSER_TYPE_WMLUP:
  1480. include_once("wml-defs.php");
  1481. break;
  1482. default:
  1483. include_once("html-defs.php");
  1484. } // switch
  1485. // -----------------------------------------------------------------------
  1486. // APPLY APPLICATION RESPONSE SETTINGS
  1487. // These settings are the ones sourced from the application.xml file
  1488. // for this particular website.
  1489.  
  1490. if (file_exists("$DOCUMENT_ROOT/application.xml") && isset($application) && $application->valid) {
  1491. $firstDB = true;
  1492. foreach ($application->settings as $setting) {
  1493. if (isset($setting->agent) && $setting->agent != "") {
  1494. $methodname = $setting->agent;
  1495. $parms = array();
  1496. foreach ($setting->parameters as $parameter) {
  1497. $parms[] = $parameter->get_decodedvalue();
  1498. }
  1499. if ($setting->name == "database") {
  1500. // Make sure number of database params is right..
  1501. if (count($parms) < 8) {
  1502. $RESPONSE->crash(403,
  1503. "Database '" . $parms[1] . "': Wrong number of database parameters "
  1504. . "for this version of Axyl. Check your 'application.xml' schema is "
  1505. . "up to date, and run the latest version of control-panel.php, if "
  1506. . "necessary, to update it."
  1507. );
  1508. }
  1509. // Set the 'default=true' parameter for first database..
  1510. if ($firstDB) {
  1511. $parms[] = true;
  1512. $firstDB = false;
  1513. }
  1514. }
  1515. // Apply the RESPONSE setting..
  1516. call_user_method_array($methodname, $RESPONSE, $parms);
  1517. }
  1518. }
  1519.  
  1520. // UNICODE
  1521. // If the above loop brought in the multilang setting as true
  1522. // then we will be needing the Unicode functions..
  1523. if ($RESPONSE->multilang) {
  1524. include_once("unicode-defs.php");
  1525. }
  1526.  
  1527. // WEBMASTER SETTINGS
  1528. if ($WEBMASTER_PERSON == "") {
  1529. $WEBMASTER_PERSON = "The " . ((APP_NAME != "") ? (APP_NAME . " ") : "") . "Webmaster";
  1530. }
  1531. if ($WEBMASTER_EMAIL == "") {
  1532. $WEBMASTER_EMAIL = "webmaster@" . $this->http_host;
  1533. }
  1534.  
  1535. // DEBUGGING
  1536. $debugging = $application->getparameter("debug_on", "debug_on");
  1537. if ($debugging) {
  1538. debug_on($application->getparameter("debug_classes", "debug_classes"));
  1539. debug_output($application->getparameter("debug_output", "debug_output"));
  1540. }
  1541.  
  1542. // MOBILE PHONES
  1543. // No cookie-based 'keep' feature for these..
  1544. if ($RESPONSE->browser == BROWSER_NONE
  1545. || $RESPONSE->browser == BROWSER_PHONE) {
  1546. $RESPONSE->set_keep(false);
  1547. }
  1548.  
  1549. // ABSOLUTE REFERENCES
  1550. // Turm relative references to web docroot absolute..
  1551. if (isset($TEMPLATESDIR) && substr($TEMPLATESDIR,0,1) != "/") {
  1552. $TEMPLATESDIR = "/$TEMPLATESDIR";
  1553. }
  1554. if (isset($IMAGESDIR) && substr($IMAGESDIR,0,1) != "/") {
  1555. $IMAGESDIR = "/$IMAGESDIR";
  1556. }
  1557. if (isset($CMDIR) && substr($CMDIR,0,1) != "/") {
  1558. $CMDIR = "/$CMDIR";
  1559. }
  1560. if (isset($CATALOGDIR) && substr($CATALOGDIR,0,1) != "/") {
  1561. $CATALOGDIR = "/$CATALOGDIR";
  1562. }
  1563. if (isset($INCDIR) && substr($INCDIR,0,1) != "/") {
  1564. $INCDIR = "/$INCDIR";
  1565. }
  1566.  
  1567. // ACTIVATION
  1568. // No longer required..
  1569. unset($application);
  1570. // Activate the response, determine user etc..
  1571. $RESPONSE->activate();
  1572.  
  1573. // SET MICROSITE THEME
  1574. if ($RESPONSE->microsites_mode == MICROSITES_ENABLED) {
  1575. debugbr("microsite features are enabled", DBG_DEBUG);
  1576. // Get the hostname/URL of this request..
  1577. //$hostbits = explode(".", $HTTP_HOST);
  1578. $hostname = strtolower($HTTP_HOST);
  1579. $hostname = str_replace("-test", "", $hostname);
  1580. // Check this hostname against our microsite domains..
  1581. $q = "SELECT mi.microsite_name,mi.microsite_domain,m.menu_name";
  1582. $q .= " FROM ax_microsite mi, ax_menu m";
  1583. $q .= " WHERE mi.currently_installed=TRUE";
  1584. $q .= " AND mi.req_microsite_remove=FALSE";
  1585. $q .= " AND m.menu_id=mi.menu_id";
  1586. $microsites = dbrecordset($q);
  1587. if ($microsites->hasdata) {
  1588. do {
  1589. $microsite_domain = $microsites->field("microsite_domain");
  1590. if (stristr($hostname, $microsite_domain)) {
  1591. debugbr("microsite scan hit: [$microsite_domain]", DBG_DEBUG);
  1592. $RESPONSE->microsite_detected = $microsites->field("microsite_name");
  1593. $theme = $RESPONSE->microsite_detected;
  1594. $THEME_TITLE = $microsites->field("microsite_desc");
  1595. $THEME_MENU = $microsites->field("menu_name");
  1596. break;
  1597. }
  1598. } while ($microsites->get_next());
  1599. // Detect index page request..
  1600. if (isset($RESPONSE->microsite_detected)) {
  1601. switch ($RESPONSE->requested) {
  1602. case "":
  1603. case "/":
  1604. case "/index.php":
  1605. $q = "SELECT * FROM ax_microsite_page mp, ax_sitepage p";
  1606. $q .= " WHERE mp.microsite_name='" . addslashes($RESPONSE->microsite_detected) . "'";
  1607. $q .= " AND mp.microsite_homepage=TRUE";
  1608. $q .= " AND p.page_id=mp.page_id";
  1609. $home = dbrecordset($q);
  1610. if ($home->hasdata) {
  1611. $homepath = $home->field("page_path");
  1612. if ($homepath != "") {
  1613. // Re-direct to the correct page and exit..
  1614. $redirect_url = $RESPONSE->site_url . $homepath;
  1615. $RESPONSE->discard();
  1616. header("Location: $redirect_url");
  1617. exit;
  1618. }
  1619. }
  1620. break;
  1621. } // switch
  1622. }
  1623. }
  1624. } // microsites enabled
  1625. }
  1626. // -----------------------------------------------------------------------
  1627. ?>

Documentation generated by phpDocumentor 1.3.0RC3