Your browser must have JavaScript enabled in order to view this page.
 >  >
 
Welcome Guest#216 Login/register    Go to Bottom
Go to Top

Source for file dpcurrentrequest.php

Documentation is available at dpcurrentrequest.php

  1. <?php
  2. /**
  3.  * Handles the current HTTP page or AJAX request by the user
  4.  *
  5.  * DutchPIPE version 0.4; PHP version 5
  6.  *
  7.  * LICENSE: This source file is subject to version 1.0 of the DutchPIPE license.
  8.  * If you did not receive a copy of the DutchPIPE license, you can obtain one at
  9.  * http://dutchpipe.org/license/1_0.txt or by sending a note to
  10.  * license@dutchpipe.org, in which case you will be mailed a copy immediately.
  11.  *
  12.  * @package    DutchPIPE
  13.  * @subpackage lib
  14.  * @author     Lennert Stock <ls@dutchpipe.org>
  15.  * @copyright  2006, 2007 Lennert Stock
  16.  * @license    http://dutchpipe.org/license/1_0.txt  DutchPIPE License
  17.  * @version    Subversion: $Id: dpcurrentrequest.php 311 2007-09-03 12:48:09Z ls $
  18.  * @link       http://dutchpipe.org/manual/package/DutchPIPE
  19.  * @see        dpuniverse.php
  20.  */
  21.  
  22. /**
  23.  * Common functions for templates available to universe objects and dpclient.php
  24.  */
  25. require_once(DPUNIVERSE_LIB_PATH 'dptemplates.php');
  26.  
  27. /**
  28.  * Handles the current HTTP page or AJAX request by the user
  29.  *
  30.  * Each time a user requests a page or performs an AJAX check, an instance of
  31.  * this class is created by the universe object, user data is set, and methods
  32.  * are called in it to handle this user. After that the object is destroyed.
  33.  *
  34.  * @access     private
  35.  * @package    DutchPIPE
  36.  * @subpackage lib
  37.  * @author     Lennert Stock <ls@dutchpipe.org>
  38.  * @copyright  2006, 2007 Lennert Stock
  39.  * @license    http://dutchpipe.org/license/1_0.txt  DutchPIPE License
  40.  * @version    Release: 0.2.1
  41.  * @link       http://dutchpipe.org/manual/package/DutchPIPE
  42.  */
  43. class DpCurrentRequest
  44. {
  45.     /**
  46.      * @var         object     Reference to the universe object
  47.      * @access      private
  48.      */
  49.     private $mrDpUniverse;
  50.  
  51.     /**
  52.      * @var         array      User server variables
  53.      * @access      private
  54.      */
  55.     private $__SERVER;
  56.  
  57.     /**
  58.      * @var         array      User session variables
  59.      * @access      private
  60.      */
  61.     private $__SESSION;
  62.  
  63.     /**
  64.      * @var         array      User cookie variables
  65.      * @access      private
  66.      */
  67.     private $__COOKIE;
  68.  
  69.     /**
  70.      * @var         array      User get variables
  71.      * @access      private
  72.      */
  73.     private $__GET;
  74.  
  75.     /**
  76.      * @var         array      User post variables
  77.      * @access      private
  78.      */
  79.     private $__POST;
  80.  
  81.     /**
  82.      * @var         array      User files variables
  83.      * @access      private
  84.      */
  85.     private $__FILES;
  86.  
  87.     /**
  88.      * @var         object     Reference to the environment of user
  89.      * @access      private
  90.      */
  91.     private $mrEnvironment;
  92.  
  93.     /**
  94.      * @var         object     Reference to the user object in the universe
  95.      * @access      private
  96.      */
  97.     private $mrUser;
  98.  
  99.     /**
  100.      * @var         boolean    Is this request coming from a registered user?
  101.      * @access      private
  102.      */
  103.     private $mIsRegistered FALSE;
  104.  
  105.     /**
  106.      * @var         string     The user name behind the current client request
  107.      * @access      private
  108.      */
  109.     private $mUsername;
  110.  
  111.     /**
  112.      * @var         string     The user's avatar number
  113.      * @access      private
  114.      */
  115.     private $mUserAvatarNr FALSE;
  116.  
  117.     /**
  118.      * @var         string     File name of custom avatar, if any
  119.      * @access      private
  120.      */
  121.     private $mUserAvatarCustom FALSE;
  122.  
  123.     /**
  124.      * @var         string     The user's display mode (abstract or graphical)
  125.      * @access      private
  126.      */
  127.     private $mUserDisplayMode FALSE;
  128.  
  129.     /**
  130.      * @var         string     Events shown to the current user
  131.      * @access      private
  132.      */
  133.     private $mUserAlertEvents FALSE;
  134.  
  135.     /**
  136.      * @var         string     Input area mode, "say" or "cmd"
  137.      * @access      private
  138.      */
  139.     private $mUserInputMode FALSE;
  140.  
  141.     /**
  142.      * @var         string     Is input field visibile? Either "on" or "off"
  143.      * @access      private
  144.      */
  145.     private $mUserInputEnabled FALSE;
  146.  
  147.     /**
  148.      * @var         string     Show input area after page changes?
  149.      * @access      private
  150.      */
  151.     private $mUserInputPersistent FALSE;
  152.  
  153.     /**
  154.      * The 'cookie id' of the user client behind the current request
  155.      *
  156.      * We don't store the users real username and password in his cookie, but
  157.      * something we generated and stored in the user's database entry. If the
  158.      * cookie is stolen, the username/password isn't.
  159.      *
  160.      * @var         string     The cookie id of the current user
  161.      * @access      private
  162.      */
  163.     private $mCookieId;
  164.  
  165.     /**
  166.      * The 'cookie password' of the user client behind the current request
  167.      *
  168.      * We don't store the users real username and password in his cookie, but
  169.      * something we generated and stored in the user's database entry. If the
  170.      * cookie is stolen, the username/password isn't.
  171.      *
  172.      * @var         string     The cookie password of the current user
  173.      * @access      private
  174.      */
  175.     private $mCookiePass;
  176.  
  177.     /**
  178.      * @var         boolean    Has the user been told anything this request?
  179.      * @access      private
  180.      */
  181.     private $mToldSomething;
  182.  
  183.     /**
  184.      * Used if the experimental PHP runkit module is used. If for instance a
  185.      * page object contins a syntax error and a user tries to go there, this
  186.      * flag will be true.
  187.      *
  188.      * @ignore
  189.      * @var         boolean    TRUE if the user tried to move but failed
  190.      * @access      private
  191.      */
  192.     /* private $mMoveError; */
  193.  
  194.     /**
  195.      * :KLUDGE: Used as a kludge to handle user movements within this request
  196.      *
  197.      * @var         boolean    TRUE if the user moved
  198.      * @access      private
  199.      */
  200.     private $mHasMoved;
  201.  
  202.     /**
  203.      * @var         boolean    Is this user a known search bot/spider/crawler?
  204.      * @access      private
  205.      */
  206.     private $mIsKnownBot FALSE;
  207.  
  208.     /**
  209.      * @var         mixed      User agent string reported by browser or FALSE
  210.      * @access      private
  211.      */
  212.     private $mUserAgent;
  213.  
  214.     /**
  215.      * Sets up the object handling the current user request
  216.      *
  217.      * @param   array   &$rDpUniverse  Reference to the universe object
  218.      * @param   array   &$rServerVars  User server variables
  219.      * @param   array   &$rSessionVars User session variables
  220.      * @param   array   &$rCookieVars  User cookie variables
  221.      * @param   array   &$rGetVars     User get variables
  222.      * @param   array   &$rPostVars    User post variables
  223.      * @param   array   &$rFilesVars   User files variables
  224.      */
  225.     function __construct(&$rDpUniverse&$rServerVars&$rSessionVars,
  226.                          &$rCookieVars&$rGetVars&$rPostVars&$rFilesVars)
  227.     {
  228.         $this->mrDpUniverse $rDpUniverse;
  229.  
  230.         if (!is_null($rServerVars)) {
  231.             $this->__SERVER $rServerVars;
  232.         }
  233.         if (!is_null($rSessionVars)) {
  234.             $this->__SESSION $rSessionVars;
  235.         }
  236.         if (!is_null($rCookieVars)) {
  237.             $this->__COOKIE $rCookieVars;
  238.         }
  239.         if (!is_null($rGetVars)) {
  240.             $this->__GET $rGetVars;
  241.         }
  242.         if (!is_null($rPostVars)) {
  243.             $this->__POST $rPostVars;
  244.         }
  245.         if (!is_null($rFilesVars)) {
  246.             $this->__FILES $rFilesVars;
  247.         }
  248.     }
  249.  
  250.     /**
  251.      * Handles the HTTP request to the server
  252.      */
  253.     function handleRequest()
  254.     {
  255.         if (FALSE === $this->_findOrCreateDpUser()) {
  256.             return;
  257.         }
  258.         if (isset($this->__GET['gethistory'])) {
  259.             $this->mrUser->tell('<history>' implode('@SEP@',
  260.                 $this->mrUser->mActionHistory'</history>');
  261.             return;
  262.         }
  263.  
  264.         $this->mrUser->setVars($this->__SERVER$this->__SESSION,
  265.             $this->__COOKIE$this->__GET$this->__POST$this->__FILES);
  266.  
  267.         $this->_handleLocation();
  268.     }
  269.  
  270.     /**
  271.      * Finds if user is already on this site, otherwise creates a user object
  272.      *
  273.      * Tries to find cookie info that goes with the HTTP request to link the
  274.      * request to a user object already on this site. Otherwise, creates either
  275.      * a new guest or registered user object in the universe. Registered users
  276.      * should have a cookie set in their browser with login info.
  277.      *
  278.      * Returns true if a user object was found or created, or FALSE in case of
  279.      * an error.
  280.      *
  281.      * @return  boolean TRUE for user object found or created, FALSE otherwise
  282.      */
  283.     private function _findOrCreateDpUser()
  284.     {
  285.         if (TRUE === $this->_findCookieData(&&
  286.                 FALSE !== ($u $this->mrDpUniverse->findCurrentDpUser(
  287.                 $this->mCookieId$this->mCookiePass))) {
  288.             /* This user is already on this site */
  289.             $this->_initExistingDpUser($u);
  290.             return TRUE;
  291.         }
  292.  
  293.         /* This only works with tight cache expire control, otherwise you get a
  294.            false "no cookies" message when someone enters a cached DutchPIPE
  295.            page after leaving the site. Advantage: cookieless people don't get
  296.            an avatar.
  297.         if (isset($this->__GET) && isset($this->__GET['ajax']) &&
  298.                 (!isset($this->__GET['standalone']) ||
  299.                 (isset($this->__GET['seq']) && (int)$this->__GET['seq'] > 0))) {
  300.          */
  301.  
  302.         if (isset($this->__GET&& isset($this->__GET['ajax']&&
  303.                 isset($this->__GET['seq']&& (int)$this->__GET['seq'0{
  304.  
  305.             /*
  306.              * There's an AJAX request coming from someone without cookies.
  307.              * The DutchPIPE cookie should have been set in the page request
  308.              * which comes first.
  309.              */
  310.             $this->mCookieId FALSE;
  311.             //echo dp_text("NO COOKIE\n");
  312.             return FALSE;
  313.         }
  314.         /*
  315.          * A page request from someone entering the site. Initialize data
  316.          * for either a registered user (by obtaining a cookie) or a guest
  317.          * user.
  318.          */
  319.         if ((!isset($this->mCookieId|| !isset($this->mCookiePass)
  320.                 || FALSE === $this->findAndInitRegisteredDpUser(
  321.                 $this->mCookieId$this->mCookiePass))
  322.                 && FALSE === $this->_initDpGuest()) {
  323.             return FALSE;
  324.         }
  325.  
  326.         /* Create the new user object with the initialized data */
  327.         $this->_newDpUser();
  328.  
  329.         return TRUE;
  330.     }
  331.  
  332.     /**
  333.      * Checks if the current connection can be tied to a user.
  334.      *
  335.      * Checks and possibly creates user and location objects, handles passing of
  336.      * variables such server, cookie and get arrays.
  337.      *
  338.      * @return  boolean TRUE for valid user request, FALSE otherwise
  339.      */
  340.     private function _findCookieData()
  341.     {
  342.         if (isset($this->__COOKIE)
  343.                 && isset($this->__COOKIE[DPSERVER_COOKIE_NAME])
  344.                 && dp_strlen($this->__COOKIE[DPSERVER_COOKIE_NAME])
  345.                 && dp_strlen($cookie_data =
  346.                     trim($this->__COOKIE[DPSERVER_COOKIE_NAME]';'))
  347.                 && sizeof($cookie_data explode(';'$cookie_data))
  348.                 && === sizeof($cookie_data)) {
  349.             $this->mCookieId $cookie_data[0];
  350.             $this->mCookiePass $cookie_data[1];
  351.  
  352.             return dp_strlen($this->mCookieId&& dp_strlen($this->mCookiePass);
  353.         }
  354.         return FALSE;
  355.     }
  356.  
  357.     /**
  358.      * Initializes this request's user data for an existing user in the universe
  359.      *
  360.      * @param   array   &$user      information about this user in the universe
  361.      */
  362.     private function _initExistingDpUser(&$user)
  363.     {
  364.         $this->mrUser &$user[_DPUSER_OBJECT];
  365.         $this->mUsername $user[_DPUSER_NAME];
  366.  
  367.         if ($user[_DPUSER_ISREGISTERED== '1'{
  368.             $this->mrUser->isRegistered TRUE;
  369.             $this->mIsRegistered TRUE;
  370.         else {
  371.             $this->mrUser->isRegistered FALSE;
  372.         }
  373.     }
  374.  
  375.     /**
  376.      * Finds and initializes user data for a registered user entering the site
  377.      *
  378.      * If cookie data was sent by the browser and it is valid data for a
  379.      * registered user, TRUE is returned, otherwise FALSE is returned.
  380.      *
  381.      * @param      string    $cookieId   'cookie id' of current user
  382.      * @param      string    $cookiePass 'cookie password' of the current user
  383.      * @return  boolean TRUE for request from registered user, FALSE otherwise
  384.      */
  385.     function findAndInitRegisteredDpUser($cookieId$cookiePass)
  386.     {
  387.         /*
  388.          * A registered user. Skip Ajax database check for now, but what
  389.          * are the security implications?
  390.          */
  391.  
  392.         if (empty($cookieId|| empty($cookiePass)) {
  393.             return FALSE;
  394.         }
  395.  
  396.         $result dp_db_query('
  397.             SELECT
  398.                 userUsername,userAvatarNr,userDisplayMode,
  399.                 userEventPeopleEntering,userEventPeopleLeaving,
  400.                 userEventBotsEntering,userInputMode,userInputEnabled,
  401.                 userInputPersistent,userAvatarCustom
  402.             FROM
  403.                 Users
  404.             WHERE
  405.                 userCookieId=' dp_db_quote($cookieId'text''
  406.             AND
  407.                 userCookiePassword=' dp_db_quote($cookiePass'text'));
  408.  
  409.         if (empty($result|| !($row dp_db_fetch_row($result))) {
  410.             dp_db_free($result);
  411.             return FALSE;
  412.         }
  413.         dp_db_free($result);
  414.         $this->mUsername $row[0];
  415.         $this->mUserAvatarNr $row[1];
  416.         $this->mUserDisplayMode $row[2];
  417.         $alert_events array();
  418.         if ('1' === $row[3]{
  419.             $alert_events['people_entering'TRUE;
  420.         }
  421.         if ('1' === $row[4]{
  422.             $alert_events['people_leaving'TRUE;
  423.         }
  424.         if ('1' === $row[5]{
  425.             $alert_events['bots_entering'TRUE;
  426.         }
  427.         if (count($alert_events)) {
  428.             $this->mUserAlertEvents $alert_events;
  429.         }
  430.         $this->mUserInputMode $row[6];
  431.         $this->mUserInputEnabled $row[7];
  432.         $this->mUserInputPersistent $row[8];
  433.         $this->mIsRegistered TRUE;
  434.         if (DPUNIVERSE_AVATAR_CUSTOM_ENABLED && function_exists('gd_info')
  435.                 && $row[9&& file_exists(DPUNIVERSE_AVATAR_CUSTOM_REG_PATH
  436.                 . $row[9])) {
  437.             $this->mUserAvatarCustom $row[9];
  438.         }
  439.  
  440.         return $row;
  441.     }
  442.     /**
  443.      * Initializes guest variables, sets cookie
  444.      *
  445.      * Sets up a random Guest#X user name and sends a cookie to the guest to
  446.      * store user information.
  447.      *
  448.      * Some experimental stuff is going on with search bots, so you can see
  449.      * them crawling the site. This will later be turned into an option.
  450.      *
  451.      * FALSE is returned if the user's client didn't report a "user agent"
  452.      * string. This is mandatory. The guest member variables will not be set up.
  453.      *
  454.      * @return  boolean TRUE for succesful setup, FALSE otherwise
  455.      */
  456.     private function _initDpGuest()
  457.     {
  458.         $this->mIsKnownBot $this->_findAgentAndKnownBots();
  459.  
  460.         if (FALSE === $this->mUserAgent{
  461.             return FALSE;
  462.         }
  463.  
  464.         if (FALSE === $this->mIsKnownBot{
  465.             $this->mUsername sprintf(dp_text('Guest#%d'),
  466.                 $this->mrDpUniverse->getGuestCnt());
  467.         else {
  468.             $this->mUsername $this->mIsKnownBot;
  469.         }
  470.  
  471.         $this->mCookieId make_random_id();
  472.         $this->mCookiePass make_random_id();
  473.         $this->mIsRegistered FALSE;
  474.  
  475.         //echo "Set-Login: {$this->mCookieId};{$this->mCookiePass}\n";
  476.         $this->mrDpUniverse->tellCurrentDpUserRequest(
  477.             "Set-Login: {$this->mCookieId};{$this->mCookiePass}");
  478.         return TRUE;
  479.     }
  480.  
  481.     /**
  482.      * Finds if the HTTP request came from a known search bot
  483.      *
  484.      * Every browser sends a "user agent" string, DutchPIPE stores some of the
  485.      * more well-known user agent strings for search bots in the database, and
  486.      * assigns them a special avatar when they enter the site.
  487.      *
  488.      * :WARNING: Browsers/spiders/bots that do not report a user agent, are
  489.      * denied access.
  490.      *
  491.      * @return  string|boolean Avatar title for known bots, FALSE otherwise
  492.      */
  493.     private function _findAgentAndKnownBots()
  494.     {
  495.         /* Gets the browser name of the user, a.k.a. the user agent */
  496.         $this->mUserAgent !isset($this->__SERVER['HTTP_USER_AGENT'])
  497.                 || === dp_strlen($this->__SERVER['HTTP_USER_AGENT'])
  498.             ? FALSE $this->__SERVER['HTTP_USER_AGENT'];
  499.  
  500.         if (FALSE === $this->mUserAgent{
  501.             //echo dp_text("No agent\n");
  502.             return FALSE;
  503.         }
  504.  
  505.         /*
  506.          * Give special guest names to some well known search bots.
  507.          * Otherwise the name will be Guest#<number>.
  508.          */
  509.         $result = dp_db_query('SELECT userAgentTitle FROM UserAgentTitles '
  510.             . 'WHERE userAgentString='
  511.             . dp_db_quote($this->mUserAgent'text'));
  512.  
  513.         $rval $this->mIsKnownBot (FALSE === $result
  514.             || !($row dp_db_fetch_row($result)) FALSE $row[0]);
  515.         dp_db_free($result);
  516.         return $rval;
  517.     }
  518.  
  519.     /**
  520.      * Gets the current user object
  521.      *
  522.      * @return  object  the current user object or FALSE for no user
  523.      */
  524.     function &getUser()
  525.     {
  526.         $rval = !isset($this->mrUserFALSE $this->mrUser;
  527.         return $rval;
  528.     }
  529.  
  530.     /**
  531.      * Sets the current user's name
  532.      *
  533.      * @param   string  $userName   name of the current user
  534.      */
  535.     function setUsername($userName)
  536.     {
  537.         $this->mUsername $userName;
  538.     }
  539.  
  540.     /**
  541.      * Checks if a cookie was succesfully set in the user's browser
  542.      *
  543.      * @return  boolean TRUE if cookie enabled, FALSE otherwise
  544.      */
  545.     function isCookieEnabled()
  546.     {
  547.         return FALSE !== $this->mCookieId;
  548.     }
  549.  
  550.     /**
  551.      * Creates a new user object in the universe
  552.      *
  553.      * An object to represent either a guest or a registered user in the
  554.      * universe is created, and added to the universe's user list. This method
  555.      * should only be called if the user does not exist yet in the universe,
  556.      * that is, the user entered the site. The user is created based on member
  557.      * values set in this object. After this method was called, the user object
  558.      * has been fully set-up, but has no environment yet.
  559.      */
  560.     private function _newDpUser()
  561.     {
  562.         $this->mrUser $this->mrDpUniverse->newDpObject(DPUNIVERSE_STD_PATH
  563.             . 'DpUser.php');
  564.         $this->initDpUser();
  565.  
  566.         $this->mrDpUniverse->addDpUser($this->mrUser$this->mUsername,
  567.             $this->mCookieId$this->mCookiePass$this->mIsRegistered);
  568.         echo sprintf(dp_text("User %s created\n")$this->mUsername);
  569.     }
  570.  
  571.     /**
  572.      * Creates a new user object in the universe
  573.      *
  574.      * An object to represent either a guest or a registered user in the
  575.      * universe is created, and added to the universe's user list. This method
  576.      * should only be called if the user does not exist yet in the universe,
  577.      * that is, the user entered the site. The user is created based on member
  578.      * values set in this object. After this method was called, the user object
  579.      * has been fully set-up, but has no environment yet.
  580.      */
  581.     function initDpUser()
  582.     {
  583.         $this->mrUser->addId($this->mUsername);
  584.         $this->mrUser->setTitle(ucfirst($this->mUsername));
  585.  
  586.         if (DPUNIVERSE_AVATAR_CUSTOM_ENABLED && function_exists('gd_info')
  587.                 && FALSE !== $this->mUserAvatarCustom{
  588.             $this->mrUser->avatarCustom $this->mUserAvatarCustom;
  589.             $this->mrUser->avatarNr $this->mUserAvatarNr;
  590.             $this->mrUser->setTitleImg((!$this->
  591. mIsRegistered
  592.                 ? DPUNIVERSE_AVATAR_CUSTOM_GUEST_URL
  593.                 : DPUNIVERSE_AVATAR_CUSTOM_REG_URL$this->mUserAvatarCustom);
  594.             $this->mrUser->setBody('<img src="' (!$this->
  595. mIsRegistered
  596.                 ? DPUNIVERSE_AVATAR_CUSTOM_GUEST_URL
  597.                 : DPUNIVERSE_AVATAR_CUSTOM_REG_URL$this->
  598. mUserAvatarCustom
  599.                 . '" border="0" alt="" align="left" '
  600.                 . 'style="margin-right: 15px" />' dp_text('A user.')
  601.                 . '<br />');
  602.         } elseif (FALSE !== $this->mUserAvatarNr{
  603.             $this->mrUser->avatarNr $this->mUserAvatarNr;
  604.             $this->mrUser->setTitleImg(DPUNIVERSE_AVATAR_STD_URL 'user'
  605.                 . $this->mUserAvatarNr '.gif');
  606.             $this->mrUser->setBody('<img src="' DPUNIVERSE_AVATAR_STD_URL
  607.                 . 'user' $this->mUserAvatarNr '_body.gif" border="0" '
  608.                 . 'alt="" align="left" style="margin-right: 15px" />'
  609.                 . dp_text('A user.''<br />');
  610.         }
  611.  
  612.         if (FALSE !== $this->mUserDisplayMode{
  613.             $this->mrUser->displayMode $this->mUserDisplayMode;
  614.         }
  615.  
  616.         if (FALSE !== $this->mUserAlertEvents{
  617.             $this->mrUser->mAlertEvents $this->mUserAlertEvents;
  618.             foreach ($this->mUserAlertEvents as $event => $foo{
  619.                 get_current_dpuniverse()->addAlertEvent($event$this->mrUser);
  620.             }
  621.         }
  622.  
  623.         if (FALSE !== $this->mUserInputMode{
  624.             $this->mrUser->inputMode $this->mUserInputMode;
  625.         }
  626.         if (FALSE !== $this->mUserInputEnabled{
  627.             $this->mrUser->inputEnabled $this->mUserInputEnabled;
  628.         }
  629.         if (FALSE !== $this->mUserInputPersistent{
  630.             $this->mrUser->inputPersistent $this->mUserInputPersistent;
  631.         }
  632.  
  633.         if (FALSE !== $this->mIsKnownBot{
  634.             $this->mrUser->setTitleImg(DPUNIVERSE_IMAGE_URL 'bot.gif');
  635.             $this->mrUser->setBody('<img src="' DPUNIVERSE_IMAGE_URL
  636.                 . 'bot.gif" border="0" alt="" align="left" '
  637.                 . 'style="margin-right: 15px" />'
  638.                 . dp_text('This is a search engine indexing this site.<br />'));
  639.             $this->mrUser->isKnownBot TRUE;
  640.         }
  641.  
  642.         if (FALSE !== $this->mIsRegistered{
  643.             $this->mrUser->isRegistered TRUE;
  644.         }
  645.         if (in_array($this->mUsername,
  646.                 explode('#'DPUNIVERSE_ADMINISTRATORS))) {
  647.             $this->mrUser->isAdmin TRUE;
  648.         }
  649.         if (FALSE === $this->mCookieId{
  650.             $this->mrUser->noCookies TRUE;
  651.         }
  652.     }
  653.  
  654.     /**
  655.      * Checks the location of the user currently connected.
  656.      *
  657.      * Checks if the user moved or entered the site, so the user gets a new
  658.      * or a first environment. Also handles pages "outside" dpuniverse and
  659.      * method calls from the AJAX client.
  660.      */
  661.     function _handleLocation()
  662.     {
  663.         /* Initializes a location based on the location=x part in the URL */
  664.         $this->_getLocation();
  665.         //echo "_handleLocation()... " . $this->__GET['location']  . "\n";
  666.  
  667.         //echo sprintf(dp_text("Getting location %s given by client for %s\n"),
  668.         //    $this->__GET['location'], $this->mUsername);
  669.  
  670.         $sublocation !isset($this->__GET['sublocation']FALSE
  671.             : $this->__GET['sublocation'];
  672.  
  673.         $tmp $this->mrDpUniverse->getDpObject($this->__GET['location'],
  674.             $sublocation);
  675.         if (FALSE === $tmp{
  676.             $tmp = $this->mrDpUniverse->getDpObject(DPUNIVERSE_PAGE_PATH
  677.                 . 'index.php');
  678.             $this->mrUser->tell('<location>' DPSERVER_CLIENT_DIR
  679.                 . '</location>');
  680.         } elseif (!$tmp->standaloneTitleSet && isset($this->__GET['title'])) {
  681.             /*
  682.              * Standalone pages send their title in the first AJAX call. Could
  683.              * be improved as it always does that, while it is only needed once.
  684.              */
  685.             $tmp->title $this->__GET['title'];
  686.             $tmp->standaloneTitleSet new_dp_property(TRUE);
  687.         }
  688.  
  689.         //echo "\n";
  690.         $this->mrEnvironment $tmp;
  691.  
  692.         if (FALSE === ($from_env $this->mrUser->getEnvironment())
  693.                 || $from_env !== $this->mrEnvironment{
  694.             /* User entered the site or left to another environment */
  695.             $this->_handleNewEnvironment($from_env);
  696.         }
  697.         elseif (!isset($this->__GET['ajax'])
  698.                 && !isset($this->__GET['method'])) {
  699.             /* A page request from a user whose environment did not change */
  700.             $this->_handleReloadEnvironment();
  701.         }
  702.         elseif (isset($this->__GET['method'])) {
  703.             $this->_handleMethodCall();
  704.         }
  705.  
  706.         if (isset($this->__GET['getdivs'])) {
  707.             $this->_handleGetDivsCall();
  708.         }
  709.         $this->mToldSomething FALSE;
  710.     }
  711.  
  712.     /**
  713.      * Initialize a location based on the location=x part in the URL.
  714.      */
  715.     private function _getLocation()
  716.     {
  717.         //echo "_getLocation()... ";
  718.         if (FALSE === $this->_isValidLocation()) {
  719.             //echo "Not valid location\n";
  720.             $tmp = $this->mrUser->getEnvironment();
  721.             if (isset($this->__GET['method']&& FALSE !== $tmp{
  722.                 $this->__GET['location'$tmp->location;
  723.                 $this->__GET['sublocation'$tmp->sublocation;
  724.             } elseif (isset($this->mrUser->_GET['proxy'])
  725.                     || (FALSE !== $tmp && (isset($this->mrUser->_GET['ajax'])
  726.                     || isset($this->__GET['method']))
  727.                     && isset($tmp->isLayered&& FALSE !== $tmp->isLayered)) {
  728.                 $this->__GET['location'$tmp->location;
  729.             } else {
  730.                 $this->__GET['location'DPUNIVERSE_PAGE_PATH 'index.php';
  731.             }
  732.         } else {
  733.             //echo "Valid location\n";
  734.         }
  735.     }
  736.  
  737.     /**
  738.      * Checks if the given location exists
  739.      *
  740.      * @return  boolean TRUE for valid location, FALSE otherwise
  741.      */
  742.     private function _isValidLocation()
  743.     {
  744.         //echo dp_text("_isValidLocation: checking location \"%s\"\n",
  745.         //    !isset($this->__GET['location']) ? '' : $this->__GET['location']);
  746.         if (isset($this->__GET['location'])
  747.                 && !dp_strlen($this->__GET['location'])) {
  748.             return TRUE;
  749.         }
  750.  
  751.         if (!isset($this->__GET['location'])) {
  752.             return isset($this->__GET['getdivs']);
  753.         }
  754.  
  755.         if (FALSE !== dp_strpos($this->__GET['location']'..')) {
  756.             return FALSE;
  757.         }
  758.  
  759.         if (FALSE !== ($pos = dp_strpos($this->__GET['location']'?'))) {
  760.             $this->__GET['location'=
  761.                 dp_substr($this->__GET['location']0$pos);
  762.         }
  763.  
  764.         if (FALSE !== ($pos = dp_strpos($this->__GET['location']'#'))) {
  765.             $this->__GET['location'=
  766.                 dp_substr($this->__GET['location']0$pos);
  767.         }
  768.  
  769.         /* Experimental */
  770.         if (isset($this->__GET['proxy'])
  771.                 || === dp_strpos($this->__GET['location']'/mailman2/')) {
  772.             return TRUE;
  773.         }
  774.  
  775.         if (($len = dp_strlen(DPSERVER_HOST_URL))
  776.                 < dp_strlen($this->__GET['location'])
  777.                 && DPSERVER_HOST_URL === dp_substr($this->__GET['location']0,
  778.                 $len)) {
  779.             return TRUE;
  780.         }
  781.         return (file_exists(DPUNIVERSE_PREFIX_PATH . $this->__GET['location'])
  782.                 && is_file(DPUNIVERSE_PREFIX_PATH $this->__GET['location']))
  783.             || (file_exists(DPUNIVERSE_WWW_PATH $this->__GET['location'])
  784.                 && is_file(DPUNIVERSE_WWW_PATH $this->__GET['location']));
  785.     }
  786.  
  787.     /**
  788.      * The user behind the request made a move, handles movement and messages
  789.      *
  790.      * @param   mixed   $from_env   the old environment or FALSE if there's none
  791.      */
  792.     private function _handleNewEnvironment($from_env)
  793.     {
  794.         if (!$from_env) {
  795.             $arrive_msg = sprintf(dp_text("%s enters the site.<br />"),
  796.                 ucfirst($this->mrUser->getTitle(
  797.                 DPUNIVERSE_TITLE_TYPE_DEFINITE)));
  798.             $remote_address = isset($this->__SERVER['REMOTE_ADDR'])
  799.                 ? '<a href="http://www.ipandroid.com/mediumllmap.php?newip=' .
  800.                 $this->__SERVER['REMOTE_ADDR''" target="_blank" '
  801.                 . 'class="col2">'
  802.                 . gethostbyaddr($this->__SERVER['REMOTE_ADDR']'</a>'
  803.                 : '<em>' dp_text('unknown remote address''</em>';
  804.             $time strftime(dp_text('%H:%M'));
  805.             $admin_msg ' ' sprintf(
  806.                 dp_text("<span class=\"col2\">%s</span> %s <span class=\"col2\">(%s)</span> enters the site from <span class=\"col2\">%s</span> using <span class=\"col2\">%s</span>.<br />"),
  807.                 $time,
  808.                 ucfirst($this->mrUser->getTitle(
  809.                 DPUNIVERSE_TITLE_TYPE_DEFINITE)),
  810.                 $remote_address,
  811.                 (!isset($this->__SERVER['HTTP_REFERER'])
  812.                 || !dp_strlen($this->__SERVER['HTTP_REFERER']'-'
  813.                 : '<a href="' $this->__SERVER['HTTP_REFERER']
  814.                 . '" target="_blank" class="col2">'
  815.                 . $this->__SERVER['HTTP_REFERER''</a>'),
  816.                 (!isset($this->__SERVER['HTTP_USER_AGENT'])
  817.                 || !dp_strlen($this->__SERVER['HTTP_USER_AGENT']'-'
  818.                 : $this->__SERVER['HTTP_USER_AGENT']));
  819.             if (!$this->mIsKnownBot{
  820.                 $listeners = get_current_dpuniverse()->getAlertEvent(
  821.                     'people_entering');
  822.                 if (is_array($listeners)) {
  823.                     $listener_msg = ' ' . sprintf(
  824.                         dp_text("<span class=\"col2\">%s</span> %s enters the site at %s.<br />"),
  825.                         $time,
  826.                         ucfirst($this->mrUser->getTitle(
  827.                         DPUNIVERSE_TITLE_TYPE_DEFINITE)),
  828.                         $this->mrEnvironment->title);
  829.                     $listener_admin_msg ' ' sprintf(
  830.                         dp_text("<span class=\"col2\">%s</span> %s <span class=\"col2\">(%s)</span> enters the site at %s from <span class=\"col2\">%s</span> using <span class=\"col2\">%s</span>.<br />"),
  831.                         $time,
  832.                         ucfirst($this->mrUser->getTitle(
  833.                         DPUNIVERSE_TITLE_TYPE_DEFINITE)),
  834.                         $remote_address,
  835.                         $this->mrEnvironment->title,
  836.                         (!isset($this->__SERVER['HTTP_REFERER'])
  837.                         || !dp_strlen($this->__SERVER['HTTP_REFERER']'-'
  838.                         : '<a href="' $this->__SERVER['HTTP_REFERER']
  839.                         . '" target="_blank" class="col2">'
  840.                         . $this->__SERVER['HTTP_REFERER''</a>'),
  841.                         (!isset($this->__SERVER['HTTP_USER_AGENT'])
  842.                         || !dp_strlen($this->__SERVER['HTTP_USER_AGENT']'-'
  843.                         : $this->__SERVER['HTTP_USER_AGENT']));
  844.  
  845.                     foreach ($listeners as &$listener{
  846.                         if ($listener !== $this->
  847. mrUser
  848.                                 && $listener->getEnvironment(!==
  849.                                 $this->mrEnvironment{
  850.                             $listener->tell(!$listener->isAdmin $listener_msg
  851.                             : $listener_admin_msg);
  852.                         }
  853.                     }
  854.                 }
  855.             } else {
  856.                 $listeners = get_current_dpuniverse()->getAlertEvent(
  857.                     'bots_entering');
  858.                 if (is_array($listeners)) {
  859.                     $listener_msg = ' ' . sprintf(
  860.                         dp_text("<span class=\"col2\">%s</span> %s indexes %s.<br />"),
  861.                         $time,
  862.                         ucfirst($this->mrUser->getTitle(
  863.                         DPUNIVERSE_TITLE_TYPE_DEFINITE)),
  864.                         $this->mrEnvironment->title);
  865.                     $listener_admin_msg ' ' sprintf(
  866.                         dp_text("<span class=\"col2\">%s</span> %s <span class=\"col2\">(%s)</span> indexes %s.<br />"),
  867.                         $time,
  868.                         ucfirst($this->mrUser->getTitle(
  869.                         DPUNIVERSE_TITLE_TYPE_DEFINITE)),
  870.                         $remote_address,
  871.                         $this->mrEnvironment->title);
  872.                     foreach ($listeners as &$listener{
  873.                         if ($listener !== $this->
  874. mrUser
  875.                                 && $listener->getEnvironment(!==
  876.                                 $this->mrEnvironment{
  877.                             $listener->tell(!$listener->isAdmin $listener_msg
  878.                             : $listener_admin_msg);
  879.                         }
  880.                     }
  881.                 }
  882.             }
  883.         } else {
  884.             $from_env->tell(sprintf(dp_text("%s leaves to %s.<br />"),
  885.                 ucfirst($this->mrUser->getTitle(
  886.                 DPUNIVERSE_TITLE_TYPE_DEFINITE)),
  887.                 $this->mrEnvironment->title)$this->mrUser);
  888.             $arrive_msg $admin_msg sprintf(
  889.                 dp_text("%s arrives from %s.<br />"),
  890.                 ucfirst($this->mrUser->getTitle(
  891.                 DPUNIVERSE_TITLE_TYPE_DEFINITE))$from_env->title);
  892.         }
  893.         $this->mrUser->moveDpObject($this->mrEnvironment);
  894.         $inv $this->mrEnvironment->getInventory();
  895.         foreach ($inv as &$ob{
  896.             if ($ob !== $this->mrUser{
  897.                 $ob->tell(!$ob->isAdmin $arrive_msg $admin_msg);
  898.             }
  899.         }
  900.     }
  901.  
  902.     /**
  903.      * Handles page requests from users whose environment did not change
  904.      */
  905.     private function _handleReloadEnvironment()
  906.     {
  907.         $this->mrUser->lastActionTime !isset($this->mrUser->lastActionTime)
  908.             ? new_dp_property(time()) time();
  909.  
  910.         if (FALSE !== ($body $this->mrEnvironment->getAppearance(0TRUE,
  911.             NULL$this->mrUser->displayMode))) {
  912.             $template_file = is_null($this->mrEnvironment->template''
  913.                 : ' template="' $this->mrEnvironment->template '"';
  914.  
  915.             $this->mrUser->tell('<div id="dppage"' $template_file '>'
  916.                 . $body '</div>');
  917.             $this->mrUser->tell('<inputpersistent persistent="'
  918.                 . ('once' === $this->mrUser->inputPersistent
  919.                 || 'off' === $this->mrUser->inputEnabled
  920.                 ? $this->mrUser->inputPersistent 'always''">&nbsp;'
  921.                 . '</inputpersistent>');
  922.             if ($type $this->mrEnvironment->isMovingArea{
  923.                 $this->mrUser->tell('<script type="text/javascript" ' .
  924.                     'src="' DPUNIVERSE_WWW_URL
  925.                     . 'interface/iutil.js"></script>');
  926.                 $this->mrUser->tell('<script type="text/javascript" ' .
  927.                     'src="' DPUNIVERSE_WWW_URL
  928.                     . 'interface/idrag.js"></script>');
  929.                 $containment $type === "containment : 'parent',\n" '';
  930.                 $cssfix $type == '.dpinventory, .dpinventory2'
  931.                     : '.dpinventory';
  932.                 $this->mrUser->tell("<script>
  933. function init_drag() {
  934.     if (\$.iDrag == undefined) return;
  935.     \$('div.draggable').DraggableDestroy();
  936.     \$('div.draggable').Draggable({
  937.         handle: 'img.draggable',
  938.         zIndex: 1000,
  939.         ghosting: true,
  940.         opacity: 0.7,{$containment}
  941.         onChange : function() { stopdrag(this) }
  942.     });
  943.     \$('{$cssfix}').css('position', 'relative');
  944.     \$('{$cssfix}').css('overflow', 'hidden');
  945. }
  946. \$(function(){init_drag();});</script>\n");
  947.             }
  948.         }
  949.     }
  950.  
  951.     /**
  952.      * Handles calls to methods in DutchPIPE objects from users' clients
  953.      */
  954.     private function _handleMethodCall()
  955.     {
  956.         if (!isset($this->__GET['call_object'])
  957.                 || !dp_strlen($call_object $this->__GET['call_object'])) {
  958.             if (!isset($this->__GET['param'])) {
  959.                 $this->mrEnvironment->{$this->__GET['method']}();
  960.             } else {
  961.                 $this->mrEnvironment->
  962.                     {$this->__GET['method']}($this->__GET['param']);
  963.             }
  964.         }
  965.         else {
  966.             if (FALSE !== ($call_object =
  967.                     $this->mrDpUniverse->findDpObject($call_object))) {
  968.                 if (isset($this->__GET['method'])
  969.                         && dp_strlen($method $this->__GET['method'])
  970.                         && $call_object->isValidClientCall($method)) {
  971.                     if (!isset($this->__GET['param'])) {
  972.                         $call_object->{$this->__GET['method']}();
  973.                     } else {
  974.                         $call_object->{$this->__GET['method']}
  975.                             ($this->__GET['param']);
  976.                     }
  977.                 }
  978.             }
  979.         }
  980.     }
  981.  
  982.     /**
  983.      * Handles insertion of main DutchPIPE elements to standalone pages
  984.      *
  985.      * Communicates with the user's client to insert avatars and object images
  986.      * (the inventory), the message area and login/logout link. Used by
  987.      * standalone pages.
  988.      */
  989.     private function _handleGetDivsCall()
  990.     {
  991.         //echo "getdivs: {$this->__GET['getdivs']}\n";
  992.         $getdivs = explode('#', trim($this->__GET['getdivs']'#'));
  993.         foreach ($getdivs as $getdiv{
  994.             //echo "getdiv: $getdiv\n";
  995.             if ($getdiv == 'dpinventory') {
  996.                 $this->mrUser->tell($this->mrEnvironment->
  997.                     getAppearanceInventory(0TRUE$this->mrUser,
  998.                     $this->mrUser->displayMode));
  999.             } elseif ($getdiv == 'dpmessagearea') {
  1000.                 $this->mrUser->tell('<div id="dpmessagearea">'
  1001.                     . '<div id="dpmessagearea_inner">'
  1002.                     . '<div id="messages"></div><div class="dpclr">&nbsp;'
  1003.                     . '</div>');
  1004.             } elseif ($getdiv == 'dpinput_wrap') {
  1005.                 $template_file = is_null($this->mrEnvironment->template)
  1006.                     ? FAlSE $this->mrEnvironment->template;
  1007.                 $subtemplates dp_get_subtemplates(array('input''input_say'),
  1008.                     $template_file);
  1009.                 $inputpersistent $this->mrUser->inputPersistent;
  1010.  
  1011.                 ob_start();
  1012.                 include($subtemplates['input']);
  1013.                 if ('always' === $inputpersistent{
  1014.                     $dpinput_say = ob_get_contents();
  1015.                 } else {
  1016.                     $dpinput = ob_get_contents();
  1017.                 }
  1018.                 ob_end_clean();
  1019.  
  1020.                 ob_start();
  1021.                 include($subtemplates['input_say']);
  1022.                 if ('always' === $inputpersistent) {
  1023.                     $dpinput = ob_get_contents();
  1024.                 } else {
  1025.                     $dpinput_say = ob_get_contents();
  1026.                 }
  1027.                 ob_end_clean();
  1028.  
  1029.                 $this->mrUser->tell('<div id="dpinput_wrap"><div id="dpinput">'
  1030.                     . '<div id="dpinput_inner">' $dpinput '</div></div>'
  1031.                     . '<div id="dpinput_say"><div id="dpinput_inner">'
  1032.                     . $dpinput_say '</div></div></div>');
  1033.                 $this->mrUser->tell("<script>jQuery('#dpaction').bind("
  1034.                     . "'keydown', bindKeyDown);"
  1035.                     . "if (!jQuery('#dpinput[input]').length) jQuery(document)."
  1036.                     . "bind('keypress', show_input); else jQuery(document)."
  1037.                     . "unbind('keypress', show_input)</script>");
  1038.             } elseif ($getdiv == 'dploginout') {
  1039.                 $login_link = !isset($this->mrUser->isRegistered||
  1040.                     TRUE !== $this->mrUser->isRegistered
  1041.                     ? '<a href="' DPSERVER_CLIENT_URL '?location='
  1042.                     . DPUNIVERSE_PAGE_PATH'login.php" style='
  1043.                     . '"padding-left: 4px">' dp_text('Login/register')
  1044.                     . '</a>'
  1045.                     : '<a href="' DPSERVER_CLIENT_URL '?location='
  1046.                     . DPUNIVERSE_PAGE_PATH 'login.php&amp;act=logout" '
  1047.                     . 'style="padding-left: 4px">' dp_text('Logout')
  1048.                     . '</a>';
  1049.                 $bottom dp_text('Go to Bottom');
  1050.                 $this->mrUser->tell('<div id="dploginout">' sprintf(
  1051.                         dp_text('Welcome %s')'<span id="username">'
  1052.                         . $this->mrUser->title '</span>')
  1053.                         . ' <span id="loginlink">'
  1054.                         . $login_link '</span>&#160;&#160;&#160;&#160;'
  1055.                         . '<img id="butbottom" src="/images/bottom.gif" '
  1056.                         . 'align="absbottom" width="11" height="11" border="0" '
  1057.                         . 'alt="' $bottom '" title="' $bottom '" '
  1058.                         . 'onClick="_gel(\'dpaction\').focus(); '
  1059.                         . 'scroll(0, 999999)" /></div>');
  1060.             }
  1061.         }
  1062.     }
  1063.  
  1064.     /**
  1065.      * Handles this user request after we have a user object and environment
  1066.      *
  1067.      * Checks for waiting messages and actions performed.
  1068.      */
  1069.     function handleUser()
  1070.     {
  1071.         $this->mrUser->isAjaxCapable = isset($this->__GET['ajax']);
  1072.  
  1073.         if ($this->mrUser->isAjaxCapable
  1074.                 && !empty($this->mrUser->browseAvatarCustom)) {
  1075.             echo "Unsetting browseAvatarCustom\n";
  1076.             unset($this->mrUser->browseAvatarCustom);
  1077.         }
  1078.  
  1079.         /*
  1080.          * Skip once if the user has moved and hence the request died. Need to
  1081.          * think if this must account for the three other calls below too.
  1082.          */
  1083.         if (!isset($this->mHasMoved)) {
  1084.             $this->_handleMessages();
  1085.         }
  1086.         $this->_handleAction();
  1087.         /* $this->handleMoverror(); */
  1088.         $this->_handleNothingTold();
  1089.     }
  1090.  
  1091.     /**
  1092.      * Checks for and handles actions by the current user
  1093.      */
  1094.     function _handleAction()
  1095.     {
  1096.         if (isset($this->__GET&& is_array($this->__GET)
  1097.                 && isset($this->__GET['dpaction'])) {
  1098.             $this->mrUser->performAction(htmlspecialchars(
  1099.                 (string)$this->__GET['dpaction']));
  1100.         }
  1101.     }
  1102.  
  1103.     /**
  1104.      * Checks for stored messages for the current user
  1105.      */
  1106.     function _handleMessages()
  1107.     {
  1108.         if (FALSE !== ($messages =
  1109.                 $this->mrDpUniverse->getCurrentDpUserMessages())) {
  1110.             /* Tell user all stored messages */
  1111.             foreach ($messages as &$message) {
  1112.                 if (is_null($message[1])
  1113.                         || (FALSE !== ($env = $this->mrUser->getEnvironment())
  1114.                         && $env === $message[1])) {
  1115.                     $this->mrUser->tell($message[0]);
  1116.                     $this->mToldSomething TRUE;
  1117.                 }
  1118.             }
  1119.             /* Delete these stored messages */
  1120.             $this->mrDpUniverse->clearCurrentDpUserMessages();
  1121.         }
  1122.     }
  1123.  
  1124.     /**
  1125.      * Handles sending '1' for AJAX if no other talkback was sent
  1126.      */
  1127.     function _handleNothingTold()
  1128.     {
  1129.         if (isset($this->__GET['ajax']&& !isset($this->__GET['method'])) {
  1130.             if (FALSE === $this->mToldSomething{
  1131.                 $this->mrUser->tell("empty");
  1132.             }/* else {
  1133.                 echo "---------------------------\n";
  1134.             }*/
  1135.         }/* else {
  1136.             echo "---------------------------\n";
  1137.         }*/
  1138.     }
  1139.  
  1140.     /**
  1141.      * Sets the user been told anything this request
  1142.      */
  1143.     final function setToldSomething()
  1144.     {
  1145.         $this->mToldSomething TRUE;
  1146.     }
  1147.  
  1148.     /**
  1149.      * Has the user been told anything this request?
  1150.      *
  1151.      * @return  boolean TRUE if user was told something, FALSE otherwise
  1152.      */
  1153.     final function isToldSomething()
  1154.     {
  1155.         return isset($this->mToldSomething&& TRUE === $this->mToldSomething;
  1156.     }
  1157.  
  1158.     /**
  1159.      * Is this a registered user?
  1160.      *
  1161.      * @return  boolean TRUE for a registered user, FALSE otherwise
  1162.      */
  1163.     final function isRegistered()
  1164.     {
  1165.         return $this->mIsRegistered;
  1166.     }
  1167.  
  1168.     /**
  1169.      * :KLUDGE: Used as a kludge to handle user movements within this request
  1170.      */
  1171.     final function setHasMoved()
  1172.     {
  1173.         $this->mHasMoved TRUE;
  1174.     }
  1175.  
  1176.     /**
  1177.      * Gets the "user agent" reported by the current user's browser
  1178.      *
  1179.      * @return  mixed   User agent string or FALSE for no agent reported
  1180.      */
  1181.     function getUserAgent()
  1182.     {
  1183.         return $this->mUserAgent;
  1184.     }

Documentation generated on Mon, 03 Sep 2007 22:19:06 +0200 by phpDocumentor 1.3.0RC6

Click me!
Guest#216
 
 
 
  Go to Top
 
 
Input Field OptionsClose Input Field Go to Top
 
Legal Notices | Copyright © 2006, 2007 Lennert Stock. All rights reserved. Last update: Mon Sep 03 2007, 21:50 CET.