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

Source for file dpuniverse.php

Documentation is available at dpuniverse.php

  1. <?php
  2. /**
  3.  * Provides 'DpUniverse' class to handle a specific 'universe'
  4.  *
  5.  * Defines DpObjects, users, pages, etc. (our 'rules of nature')
  6.  *
  7.  * DutchPIPE version 0.4; PHP version 5
  8.  *
  9.  * LICENSE: This source file is subject to version 1.0 of the DutchPIPE license.
  10.  * If you did not receive a copy of the DutchPIPE license, you can obtain one at
  11.  * http://dutchpipe.org/license/1_0.txt or by sending a note to
  12.  * license@dutchpipe.org, in which case you will be mailed a copy immediately.
  13.  *
  14.  * @package    DutchPIPE
  15.  * @subpackage lib
  16.  * @author     Lennert Stock <ls@dutchpipe.org>
  17.  * @copyright  2006, 2007 Lennert Stock
  18.  * @license    http://dutchpipe.org/license/1_0.txt  DutchPIPE License
  19.  * @version    Subversion: $Id: dpuniverse.php 311 2007-09-03 12:48:09Z ls $
  20.  * @link       http://dutchpipe.org/manual/package/DutchPIPE
  21.  * @see        currentdpuserrequest.php, dpserver.php, dpfunctions.php
  22.  */
  23.  
  24. /* Shows all possible errors */
  25. error_reporting(E_ALL E_STRICT);
  26.  
  27. /**
  28.  * The universe object handling the current http user request. Do not access
  29.  * this variable directly, use get_current_dpuniverse() instead.
  30.  */
  31. $grCurrentDpUniverse NULL;
  32.  
  33. /**
  34.  * The object responsible for the current chain of execution. Do not access
  35.  * this variable directly, use get_current_dpobject() instead.
  36.  */
  37. $grCurrentDpObject NULL;
  38.  
  39. define('_DPUSER_OBJECT'0);           /* Reference to /std/DpUser.php object */
  40. define('_DPUSER_MESSAGES'1);         /* Array of strings with messages */
  41. define('_DPUSER_NAME'2);             /* Name of user behind http request */
  42. define('_DPUSER_COOKIEID'3);         /* Cookie Id used for authorization */
  43. define('_DPUSER_COOKIEPASS'4);       /* Cookie Pass used for authorization */
  44. define('_DPUSER_ISREGISTERED'5);     /* Is it a registered user? */
  45. define('_DPUSER_TIME_LASTREQUEST'6)/* Last http request UNIX time */
  46. define('_DPUSER_CURRENT_SCRIPTID'7)/* Script id of current AJAX request */
  47. define('_DPUSER_LAST_SCRIPTID'8);    /* Script id of last AJAX request */
  48.  
  49. /**
  50.  * A DutchPIPE universe, handling objects, users, pages, etc. (rules of nature)
  51.  *
  52.  * @package    DutchPIPE
  53.  * @subpackage lib
  54.  * @author     Lennert Stock <ls@dutchpipe.org>
  55.  * @copyright  2006, 2007 Lennert Stock
  56.  * @license    http://dutchpipe.org/license/1_0.txt  DutchPIPE License
  57.  * @version    Release: 0.2.1
  58.  * @link       http://dutchpipe.org/manual/package/DutchPIPE
  59.  */
  60. final class DpUniverse
  61. {
  62.     /**
  63.      * @var         array      All objects on the site
  64.      * @access      private
  65.      */
  66.     private $mDpObjects array();
  67.  
  68.     /**
  69.      * @var         array      Reset queue, first element will reset first
  70.      * @access      private
  71.      */
  72.     private $mDpObjectResets array();
  73.  
  74.     /**
  75.      * The environment of each object on the site in env => ob pairs.
  76.      *
  77.      * @var         array      The environments of objects
  78.      * @access      private
  79.      */
  80.     private $mEnvironments array();
  81.  
  82.     /**
  83.      * All user objects on the site + data
  84.      *
  85.      * Each element in the array represents a user. A user is stored in another
  86.      * array, with the elements as defined by the _DPUNIVERSE_USER_ definitions.
  87.      *
  88.      * @var         array      All user objects on the site + data
  89.      * @access      private
  90.      */
  91.     private $mDpUsers array();
  92.  
  93.     /**
  94.      * @var         array      All pending timeouts after use of setTimeout()
  95.      * @access      private
  96.      */
  97.     private $mTimeouts array();
  98.  
  99.     /**
  100.      * Increasing guest counter used to form unique names for guests, for
  101.      * example "Guest#8'
  102.      *
  103.      * @var         int        Increasing guest counter for unique guest names
  104.      * @access      private
  105.      */
  106.     private $mGuestCnt;
  107.  
  108.     /**
  109.      * DpObject counter increased by newDpObject, used to generate unique object
  110.      * ids
  111.      *
  112.      * @var         int        Used to generate unique object
  113.      * @access      private
  114.      */
  115.     private $mUniqueDpObjectCnt 1;
  116.  
  117.     /**
  118.      * @var         object     The server object that called us
  119.      * @access      private
  120.      */
  121.     private $mrDpServer;
  122.  
  123.     /**
  124.      * @var         array      Info on the current HTTP user request
  125.      * @access      private
  126.      */
  127.     private $mrCurrentDpUserRequest;
  128.  
  129.     /**
  130.      * @var         array      The key of the current users' entry in mDpUsers
  131.      * @access      private
  132.      */
  133.     private $mCurrentDpUserKey;
  134.  
  135.     /**
  136.      * @var         boolean    Do not tell anything to the current http request?
  137.      * @access      private
  138.      */
  139.     private $mNoDirectTell FALSE;
  140.  
  141.     /**
  142.      * Error messages for the last new user registration attempt
  143.      *
  144.      * @var         array 
  145.      * @access      private
  146.      */
  147.     private $mLastNewUserErrors array();
  148.  
  149.     /**
  150.      * UNIX timestamp when next reset in an object will occur
  151.      *
  152.      * @var         integer 
  153.      * @access      private
  154.      */
  155.     private $mNextResetTime;
  156.  
  157.     /**
  158.      * UNIX time stamp when cleanup mechanism was last called
  159.      *
  160.      * @var         array 
  161.      * @access      private
  162.      */
  163.     private $mLastCleanUpTime 0;
  164.  
  165.     /**
  166.      * Lists of objects listening to certain events
  167.      *
  168.      * @var         array 
  169.      * @access      private
  170.      */
  171.     private $mAlertEvents array();
  172.  
  173.     /**
  174.      * Constructs this universe based on a universe ini file
  175.      *
  176.      * @param      string    $iniFile    path to settings file for this universe
  177.      */
  178.     function __construct($iniFile 'dpuniverse-ini.php')
  179.     {
  180.         /* Gets the universe settings */
  181.         require_once($iniFile);
  182.  
  183.         $this->mGuestCnt mt_rand(2575);
  184.         $this->mLastCleanUpTime time();
  185.  
  186.         require_once(DPUNIVERSE_LIB_PATH 'dpcurrentrequest.php');
  187.  
  188.         /* These functions will be available for all objects */
  189.         require_once(DPUNIVERSE_LIB_PATH 'dptext.php');
  190.         require_once(DPUNIVERSE_LIB_PATH 'dpfunctions.php');
  191.         require_once(DPUNIVERSE_LIB_PATH 'dptemplates.php');
  192.         require_once(DPUNIVERSE_LIB_PATH 'dpmbstring_'
  193.             . (!DPSERVER_ENABLE_MBSTRING || !function_exists('mb_strlen')
  194.             ? 'disabled' 'enabled''.php');
  195.  
  196.         if (!DPUNIVERSE_MDB2_ENABLED{
  197.             require_once(DPUNIVERSE_LIB_PATH 'dpdb_mysql.php');
  198.         else {
  199.             require_once(DPUNIVERSE_LIB_PATH 'dpdb_mdb2.php');
  200.         }
  201.  
  202.         // Clean up guest avatar directory
  203.                 && ($dir @opendir(DPUNIVERSE_AVATAR_CUSTOM_GUEST_PATH))) {
  204.             while (FALSE !== ($entry readdir($dir))) {
  205.                 if ('.' != $entry && '..' != $entry)
  206.                     @unlink(DPUNIVERSE_AVATAR_CUSTOM_GUEST_PATH $entry);
  207.             }
  208.         }
  209.     }
  210.  
  211.     /**
  212.      * Gets an unique suffix to make Guest#x names
  213.      *
  214.      * @return     integer   A unique number, currently a counter
  215.      */
  216.     function getGuestCnt()
  217.     {
  218.         return $this->mGuestCnt++;
  219.     }
  220.  
  221.     /**
  222.      * Handles user requests passed on from the DutchPIPE server
  223.      *
  224.      * Called each time a user's browser does a normal page or AJAX request.
  225.      * Several variables are passed which represent their corresponding PHP
  226.      * global arrays: $_SERVER, $_COOKIE, etc.
  227.      *
  228.      * @param   array   &$rDpServer    Reference to the server object
  229.      * @param   array   &$rServerVars  User server variables
  230.      * @param   array   &$rSessionVars User session variables
  231.      * @param   array   &$rCookieVars  User cookie variables
  232.      * @param   array   &$rGetVars     User get variables
  233.      * @param   array   &$rPostVars    User post variables
  234.      * @param   array   &$rFilesVars   User files variables
  235.      */
  236.     function handleCurrentDpUserRequest(&$rDpServer NULL,
  237.             &$rServerVars NULL&$rSessionVars NULL&$rCookieVars NULL,
  238.             &$rGetVars NULL&$rPostVars NULL&$rFilesVars NULL)
  239.     {
  240.         if (!is_null($rDpServer)) {
  241.             $this->mrDpServer $rDpServer;
  242.         }
  243.  
  244.         $GLOBALS['grCurrentDpUniverse'&$this;
  245.  
  246.         /*
  247.          * Because we don't use a 'ticks' system or something similar yet, user
  248.          * user requests are used to handle some generic cyclic calls
  249.          */
  250.         $this->handleLinkdead();
  251.         if (isset($this->mNextResetTime&& $this->mNextResetTime <= time()) {
  252.             $this->handleReset();
  253.         }
  254.  
  255.         $this->mrCurrentDpUserRequest new DpCurrentRequest($this,
  256.             $rServerVars$rSessionVars$rCookieVars$rGetVars$rPostVars,
  257.             $rFilesVars);
  258.         $this->mrCurrentDpUserRequest->handleRequest();
  259.  
  260.         if (FALSE === $this->mrCurrentDpUserRequest->isRegistered()
  261.                 && FALSE === $this->mrCurrentDpUserRequest->getUserAgent()) {
  262.             if (!isset($rGetVars['ajax'])) {
  263.                 $this->tellCurrentDpUserRequest('<event><div id="dppage">'
  264.                     . '<![CDATA['
  265.                     . dp_text('Your browser did not report a User Agent string to the server. This is required.<br />')
  266.                     . ']]></div></event>');
  267.             }
  268.             unset($this->mrCurrentDpUserRequest);
  269.             unset($this->mCurrentDpUserKey);
  270.             return;
  271.         }
  272.         if (FALSE === $this->mrCurrentDpUserRequest->isCookieEnabled()) {
  273.             $this->tellCurrentDpUserRequest('2');
  274.             unset($this->mrCurrentDpUserRequest);
  275.             unset($this->mCurrentDpUserKey);
  276.             return;
  277.         }
  278.  
  279.         if (isset($this->mCurrentDpUserKey)) {
  280.             $user_arr_key $this->mCurrentDpUserKey;
  281.         else {
  282.             end($this->mDpUsers);
  283.             $user_arr_key key($this->mDpUsers);
  284.         }
  285.  
  286.         $this->mDpUsers[$user_arr_key][_DPUSER_TIME_LASTREQUESTtime();
  287.  
  288.         /*
  289.          * scriptids are used to detect if a user has multiple browser windows
  290.          * open. Each initiated dpclient-js.php sets such a random id
  291.          */
  292.         $old_scriptid =
  293.             $this->mDpUsers[$user_arr_key][_DPUSER_CURRENT_SCRIPTID];
  294.         $new_scriptid is_null($rGetVars|| !isset($rGetVars['ajax'])
  295.             || !isset($rGetVars['scriptid']|| === (int)$rGetVars['scriptid']
  296.             ? FALSE $rGetVars['scriptid'];
  297.  
  298.         if (FALSE !== $old_scriptid && FALSE !== $new_scriptid
  299.                 && $old_scriptid !== $new_scriptid{
  300.             $this->mDpUsers[$user_arr_key][_DPUSER_LAST_SCRIPTIDFALSE;
  301.             $this->mDpUsers[$user_arr_key][_DPUSER_CURRENT_SCRIPTIDFALSE;
  302.             $this->mDpUsers[$user_arr_key][_DPUSER_OBJECT]->tell(
  303.                 'close_window');
  304.         else {
  305.             $this->mDpUsers[$user_arr_key][_DPUSER_LAST_SCRIPTID=
  306.                 $old_scriptid;
  307.             $this->mDpUsers[$user_arr_key][_DPUSER_CURRENT_SCRIPTID=
  308.                 $new_scriptid;
  309.         }
  310.  
  311.         /*
  312.          * Because we don't use a 'ticks' system or something similar yet, user
  313.          * user requests are used to handle some generic cyclic calls
  314.          */
  315.         $this->handleTimeouts();
  316.  
  317.         $this->mrCurrentDpUserRequest->handleUser();
  318.  
  319.         unset($this->mrCurrentDpUserRequest);
  320.         unset($this->mCurrentDpUserKey);
  321.  
  322.         if ($this->mLastCleanUpTime time(DPUNIVERSE_RESET_CYCLE 2{
  323.             $this->handleCleanUps();
  324.             $this->mLastCleanUpTime time();
  325.         }
  326.     }
  327.  
  328.     /**
  329.      * Adds a new, given user object to the universe
  330.      *
  331.      * :WARNING: Should normally only be called from lib/dpcurrentrequest.php.
  332.      *
  333.      * @access     private
  334.      * @param      object    &$user        a new DpUser object
  335.      * @param      string    $username     the user's username
  336.      * @param      string    $cookieID     the user's cookie ID
  337.      * @param      string    $cookiePass   the user's cookie password
  338.      * @param      boolean   $isRegistered TRUE for registered user, else FALSE
  339.      */
  340.     function addDpUser(&$user$username$cookieId$cookiePass,
  341.             $isRegistered{
  342.         $this->mDpUsers[array($userarray()$username$cookieId,
  343.             $cookiePass$isRegistered0FALSEFALSE);
  344.     }
  345.  
  346.     /**
  347.      * Gets pending messages for the current user request
  348.      *
  349.      * :WARNING: Should normally only be called from lib/dpcurrentrequest.php.
  350.      *
  351.      * @access     private
  352.      * @return     mixed     array with messages of FALSE for no messages
  353.      */
  354.     function &getCurrentDpUserMessages()
  355.     {
  356.         $rval FALSE;
  357.  
  358.         if (isset($this->mCurrentDpUserKey)
  359.                 && isset($this->mDpUsers[$this->mCurrentDpUserKey])) {
  360.             return $this->mDpUsers[$this->mCurrentDpUserKey][_DPUSER_MESSAGES];
  361.         }
  362.  
  363.         return $rval;
  364.     }
  365.  
  366.     /**
  367.      * Clears pending messages for the current user request
  368.      *
  369.      * :WARNING: Should normally only be called from lib/dpcurrentrequest.php.
  370.      *
  371.      * @access     private
  372.      */
  373.     function clearCurrentDpUserMessages()
  374.     {
  375.         $this->mDpUsers[$this->mCurrentDpUserKey][_DPUSER_MESSAGESarray();
  376.     }
  377.  
  378.     /**
  379.      * Finds if a user is on this site based on cookie data
  380.      *
  381.      * If found, sets $this->mCurrentDpUserKey to the key to the user info in
  382.      * the universe's user array.
  383.      *
  384.      * :WARNING: Should normally only be called from lib/dpcurrentrequest.php.
  385.      *
  386.      * @access     private
  387.      * @param      string    $cookieID     the user's cookie ID
  388.      * @param      string    $cookiePass   the user's cookie password
  389.      * @return     mixed     array with user info or FALSE if no user found
  390.      */
  391.     function &findCurrentDpUser($cookieid$cookiepass)
  392.     {
  393.         $rval FALSE;
  394.  
  395.         foreach ($this->mDpUsers as $user_arr_key => &$u{
  396.             if ($u[_DPUSER_COOKIEID=== $cookieid
  397.                     && $u[_DPUSER_COOKIEPASS=== $cookiepass{
  398.                 $this->mCurrentDpUserKey $user_arr_key;
  399.                 return $u;
  400.             }
  401.         }
  402.  
  403.         return $rval;
  404.     }
  405.  
  406.     /**
  407.      * Checks if people left the site, throws them out of the universe
  408.      *
  409.      * @access     private
  410.      */
  411.     private function handleLinkdead()
  412.     {
  413.         $cur_time time();
  414.  
  415.         /* Time the user's browser should have done a page or AJAX request */
  416.         $linkdeath_time $cur_time DPUNIVERSE_LINKDEATH_KICKTIME;
  417.  
  418.         /*
  419.          * Currently, this function is triggered by a user http request. If
  420.          * there's one user and he leaves, then if the next user enters, say a
  421.          * minute later (this time is defined here), he should not see
  422.          * 'X leaves the site.'
  423.          */
  424.         $showmsg_time $linkdeath_time DPUNIVERSE_LINKDEATH_SHOWMSGTIME;
  425.  
  426.         /*
  427.          * Bots may be visible a bit longer, since they don't have Javacript and
  428.          * sometimes do a lot of requests. With a short 'kick' time, users would
  429.          * get a lot of 'Bot enters the site' and 'Bot leaves the site'
  430.          * messages.
  431.          */
  432.         $botkick_time $cur_time DPUNIVERSE_BOT_KICKTIME;
  433.  
  434.         $showbot_time $botkick_time DPUNIVERSE_LINKDEATH_SHOWBOTTIME;
  435.  
  436.         foreach ($this->mDpUsers as $i => &$u{
  437.             /*
  438.              * Throw out people who lost connection or browsed elsewhere. Need
  439.              * to think this one out (move them to a void, etc.), something
  440.              * simple for now.
  441.              */
  442.             $lastrequest_time $u[_DPUSER_TIME_LASTREQUEST];
  443.             $ajax_capable (isset($u[_DPUSER_OBJECT]->isAjaxCapable)
  444.                 && TRUE === $u[_DPUSER_OBJECT]->isAjaxCapable)
  445.                 || !empty($u[_DPUSER_OBJECT]->browseAvatarCustom);
  446.  
  447.             /* The "linkdeath" check */
  448.             if (($ajax_capable && $lastrequest_time $linkdeath_time
  449.                     && (empty($u[_DPUSER_OBJECT]->browseAvatarCustom)
  450.                     || $lastrequest_time $cur_time
  451.                     - DPSERVER_OBJECT_IMAGE_CUSTOM_MAX_BROWSETIME))
  452.                     || (!$ajax_capable && $lastrequest_time $botkick_time)) {
  453.                 /*
  454.                  * This method is called before an instance of
  455.                  * CurrentDpUserRequest is created and the current http request
  456.                  * is handled. However, the tell() functions operate on the
  457.                  * current request. Therefore, any sound made should be stored
  458.                  * for the next cycle, otherwise the people get wrong messages.
  459.                  * tell() in the User class checks for this variable:
  460.                  */
  461.                 $this->mNoDirectTell TRUE;
  462.  
  463.                 if (FALSE !== ($env =
  464.                         $u[_DPUSER_OBJECT]->getEnvironment())) {
  465.                     if (($ajax_capable && $lastrequest_time $showmsg_time)
  466.                             || (!$ajax_capable
  467.                             && $lastrequest_time $showbot_time)) {
  468.                         /* Drop stuff, tell people on the page the user left */
  469.                         $u[_DPUSER_OBJECT]->actionDrop(dp_text('drop'),
  470.                             dp_text('all'));
  471.                         $env->tell($left_msg sprintf(
  472.                             dp_text('%s left the site.<br />'),
  473.                             ucfirst($u[_DPUSER_OBJECT]->getTitle(
  474.                             DPUNIVERSE_TITLE_TYPE_DEFINITE))),
  475.                             $u[_DPUSER_OBJECT]);
  476.                         if (!$u[_DPUSER_OBJECT]->isKnownBot{
  477.                             $listeners get_current_dpuniverse()->
  478.                                 getAlertEvent('people_leaving');
  479.                             if (is_array($listeners)) {
  480.                                 $listener_msg ' ' sprintf(
  481.                                     dp_text("<span class=\"col2\">%s</span> %s left the site at %s.<br />"),
  482.                                     strftime(dp_text('%H:%M')),
  483.                                     ucfirst($u[_DPUSER_OBJECT]->getTitle(
  484.                                     DPUNIVERSE_TITLE_TYPE_DEFINITE)),
  485.                                     $env->title);
  486.                                 foreach ($listeners as &$listener{
  487.                                     if ($listener->getEnvironment(!== $env{
  488.                                         $listener->tell($listener_msg);
  489.                                     }
  490.                                 }
  491.                             }
  492.                         }
  493.                     else {
  494.                         /* Drop all silently */
  495.                         $u[_DPUSER_OBJECT]->actionDrop(dp_text('drop'),
  496.                             dp_text('all')TRUE);
  497.                     }
  498.                 }
  499.  
  500.                 /* Keeps track of all unique user agents */
  501.                 $this->saveUserAgent($u[_DPUSER_OBJECT]);
  502.  
  503.                 /* Remove the object */
  504.                 $this->mDpUsers[$i][_DPUSER_OBJECT]->removeDpObject();
  505.  
  506.                 $this->mNoDirectTell FALSE;
  507.             }
  508.         }
  509.     }
  510.  
  511.     /**
  512.      * Calls '__reset' in each object every DPUNIVERSE_RESET_CYCLE seconds
  513.      *
  514.      * @access     private
  515.      */
  516.     private function handleReset()
  517.     {
  518.         /* Perform a limited number of resets per cycle */
  519.         $max_resets DPUNIVERSE_MAX_RESETS;
  520.         $max_loop 100;
  521.  
  522.         reset($this->mDpObjectResets);
  523.         /* Pick up where we were in the reset array */
  524.         while (($ob current($this->mDpObjectResets)) && $max_resets--
  525.                  && $max_loop--{
  526.             /* Checks if the current object ready to reset */
  527.             if ($ob->resetTime time()) {
  528.                 $this->mNextResetTime $ob->resetTime;
  529.                 return;
  530.             }
  531.             /* Resets the object, sets next reset time */
  532.             $ob->__reset();
  533.             $ob->resetTime time(DPUNIVERSE_RESET_CYCLE;
  534.             $this->mDpObjectResets[$ob;
  535.             array_splice($this->mDpObjectResets01);
  536.             reset($this->mDpObjectResets);
  537.             $this->mNextResetTime current($this->mDpObjectResets)->resetTime;
  538.         }
  539.     }
  540.  
  541.     /**
  542.      * Optionally uses experimental PHP runkit module to catch errors in code
  543.      */
  544.      /*
  545.     function handleRunkit()
  546.     {
  547.         if (FALSE !== DPUNIVERSE_RUNKIT) {
  548.             if (FALSE === @runkit_lint_file(DPUNIVERSE_PREFIX_PATH
  549.                     . $this->__GET['location'])) {
  550.                 if ($this->mrUser->getEnvironment()) {
  551.                     $this->mrEnvironment = $this->mrUser->getEnvironment();
  552.                 }
  553.                 $this->__GET['location'] =
  554.                     FALSE === is_null($this->mrEnvironment)
  555.                     ? $this->mrEnvironment->location
  556.                     : DPUNIVERSE_PAGE_PATH . 'index.php';
  557.                 $this->mrUser->tell('<location>' . $__GET['location']
  558.                     . '</location>');
  559.                 $this->mMoveError = dp_text('You notice a disruptance.<br />');
  560.             }
  561.         }
  562.     }
  563.     */
  564.  
  565.     /**
  566.      * Handles delayed function calls requested by objects in the universe
  567.      *
  568.      * @access     private
  569.      */
  570.     private function handleTimeouts()
  571.     {
  572.         while (sizeof($this->mTimeouts)) {
  573.             foreach ($this->mTimeouts as $i => $to{
  574.                 if (isset($this->mTimeouts[$i][0]->isRemoved)
  575.                         && TRUE === $this->mTimeouts[$i][0]->isRemoved{
  576.                     unset($this->mTimeouts[$i][0]);
  577.                     unset($this->mTimeouts[$i]);
  578.                     break;
  579.                 }
  580.                 $cur_time time();
  581.                 if ($this->mTimeouts[$i][2<= $cur_time{
  582.                     $method $this->mTimeouts[$i][1];
  583.                     if (!isset($this->mTimeouts[$i][3])) {
  584.                         $this->mTimeouts[$i][0]->$method();
  585.                     else {
  586.                         call_user_func_array(array(&$this->mTimeouts[$i][0],
  587.                             $method)$this->mTimeouts[$i][3]);
  588.                     }
  589.                     unset($this->mTimeouts[$i][0]);
  590.                     unset($this->mTimeouts[$i]);
  591.                     break;
  592.                 }
  593.                 break 2;
  594.             }
  595.         }
  596.     }
  597.  
  598.     /**
  599.      * Handles removal of unused object instances
  600.      *
  601.      * @access     private
  602.      */
  603.     private function handleCleanUps()
  604.     {
  605.         echo "HandleCleanUps called\n";
  606.         foreach ($this->mDpObjects as $i => &$ob{
  607.             if (!$ob->getEnvironment()
  608.                     && $ob->lastEventTime time(DPUNIVERSE_RESET_CYCLE{
  609.                 echo "calling handleCleanUp in {$ob->title}\n";
  610.                 $ob->handleCleanUp();
  611.             }
  612.         }
  613.     }
  614.  
  615.     /**
  616.      * Stores user agent information in the database
  617.      *
  618.      * Experimental. Used to catch search bots.
  619.      *
  620.      * @access     private
  621.      * @param      string    &$user      user object
  622.      */
  623.     private function saveUserAgent(&$user)
  624.     {
  625.         $agent !isset($user->_SERVER['HTTP_USER_AGENT'])
  626.             || === dp_strlen($user->_SERVER['HTTP_USER_AGENT'])
  627.             ? '[Undefined]'
  628.             : $user->_SERVER['HTTP_USER_AGENT'];
  629.  
  630.         if (isset($user->isAjaxCapable&& TRUE === $user->isAjaxCapable{
  631.             $result dp_db_query('SELECT userAgentId from UserAgents '
  632.                 . 'WHERE userAgentString=' dp_db_quote($agent'text'));
  633.             if (FALSE === $result || !dp_db_num_rows($result)) {
  634.                 if ($next_id dp_db_next_id('UserAgents''userAgentId')) {
  635.                     dp_db_exec('INSERT INTO UserAgents '
  636.                         . '(userAgentId,userAgentString) VALUES ('
  637.                         . dp_db_quote($next_id'integer'','
  638.                         . dp_db_quote($agent'text'')');
  639.                 }
  640.             }
  641.             dp_db_free($result);
  642.         else {
  643.             $remote_address !isset($user->_SERVER['REMOTE_ADDR'])
  644.                 || === dp_strlen($user->_SERVER['REMOTE_ADDR'])
  645.                 ? '[Undefined]'
  646.                 : $user->_SERVER['REMOTE_ADDR'];
  647.             $result dp_db_query('SELECT userAgentId from UserAgents '
  648.                 . 'WHERE userAgentString=' dp_db_quote($agent'text')
  649.                 . ' AND userAgentRemoteAddress='
  650.                 . dp_db_quote($remote_address'text'));
  651.             if (FALSE === $result || !dp_db_num_rows($result)) {
  652.                 if ($next_id dp_db_next_id('UserAgents''userAgentId')) {
  653.                     dp_db_exec('INSERT INTO UserAgents '
  654.                         . '(userAgentId,userAgentString,userAgentRemoteAddress)'
  655.                         . ' VALUES (' dp_db_quote($next_id'integer'','
  656.                         . dp_db_quote($agent'text'','
  657.                         . dp_db_quote($remote_address'text'')');
  658.                 }
  659.             }
  660.             dp_db_free($result);
  661.         }
  662.     }
  663.  
  664.     /**
  665.      * Stores a message for a user while we wait for another http request
  666.      *
  667.      * Called from tell in DpUser.php
  668.      *
  669.      * :WARNING: This method should normally only be called the tell method in
  670.      * DpUser.php.
  671.      *
  672.      * @access     private
  673.      * @param      object    $user        recipient user of message
  674.      * @param      string    $data        message string
  675.      * @param      object    $binded_env  optional binded environment
  676.      * @see        DpObject::tell()
  677.      *
  678.      */
  679.     function storeTell(&$user$data&$binded_env NULL)
  680.     {
  681.         foreach ($this->mDpUsers as $i => &$u{
  682.             if ($u[_DPUSER_OBJECT=== $user{
  683.                 $this->mDpUsers[$i][1][array($data$binded_env);
  684.             }
  685.         }
  686.     }
  687.  
  688.     /**
  689.      * Tells something back to the currently connected user client
  690.      *
  691.      * :WARNING: This method should normally only be called from DpUser.php.
  692.      *
  693.      * @access     private
  694.      * @param      string    $talkback   XML string
  695.      */
  696.     function tellCurrentDpUserRequest($talkback)
  697.     {
  698.         // echo "Talkback: " . htmlentities($talkback) . "\n";
  699.         $this->mrDpServer->tellCurrentDpUserRequest($talkback);
  700.         $this->mrCurrentDpUserRequest->setToldSomething();
  701.     }
  702.  
  703.     /**
  704.      * Gets db row key of a random CAPTCHA code for the user registration page
  705.      *
  706.      * Used to seperate software robots from real people during registration.
  707.      * Codes aren't generated on the fly and as such not really random because
  708.      * the CPU time penalty is too high. A directory with pre-generated codes
  709.      * exists and a database table with info. A cronjob makes one every hour and
  710.      * replaces the oldest one in the database. Then we obtain a random entry
  711.      * here. This should do it for now, but your milleague might vary and the
  712.      * situation might change as spambots get smarter.
  713.      *
  714.      * @return     int       CAPTCHA database row key
  715.      */
  716.     function getRandCaptcha()
  717.     {
  718.         $result dp_db_query('SELECT captchaId FROM Captcha');
  719.  
  720.         if (FALSE === $result || !($num_rows dp_db_num_rows($result))) {
  721.             return FALSE;
  722.         }
  723.  
  724.         $rval dp_db_fetch_one($resultmt_rand(0$num_rows 1)0);
  725.         dp_db_free($result);
  726.         return $rval;
  727.     }
  728.  
  729.     /**
  730.      * Creates a new object in the universe
  731.      *
  732.      * You MUST call this function to create new objects in a DutchPIPE
  733.      * universe, don't use the 'new' construct directly.
  734.      *
  735.      * The object can have a unique location, given with $pathname, or just be
  736.      * based on $pathname, with a sublocation handling multiple objects. For
  737.      * example, the URL in uour browser contains the following bit for the
  738.      * DutchPIPE "about" page: location=/page/about.php
  739.      *
  740.      * It is a unique page with a unique location. The manual however is not
  741.      * based on many unique locations, but just one object which spawns pages
  742.      * based on the sublocation given in the URL:
  743.      * location=/page/manual.php&sublocation=index.html
  744.      *
  745.      * @param      string    $pathname     path to code from universe base path
  746.      * @param      string    $sublocation  optional sublocation
  747.      * @return     object    The newly created object
  748.      */
  749.     function &newDpObject($pathname$sublocation FALSE)
  750.     {
  751.         if (!$pathname{
  752.             $pathname DPUNIVERSE_PAGE_PATH 'index.php';
  753.         }
  754.  
  755.         echo "Making: $pathname$sublocation\n";
  756.  
  757.         if (dp_strlen($pathname>= && dp_substr($pathname07)
  758.                 == 'http://'{
  759.             if (($len dp_strlen(DPSERVER_HOST_URL)) >= dp_strlen($pathname)
  760.                     || DPSERVER_HOST_URL !== dp_substr($pathname0$len)) {
  761.                 echo dp_text("Illegal object requested!\n");
  762.                 $rval FALSE;
  763.                 return $rval;
  764.             }
  765.         }
  766.  
  767.         $unique_id $this->mUniqueDpObjectCnt;
  768.         $this->mUniqueDpObjectCnt++;
  769.  
  770.         if ($pathname && (dp_substr($pathname01!= '/'
  771.                 || ((FALSE === dp_strpos($pathname'://'))
  772.                 && (dp_strlen($pathname4
  773.                 || dp_substr($pathname4!= '.php')))) {
  774.             require_once(DPUNIVERSE_PREFIX_PATH DPUNIVERSE_STD_PATH
  775.                 . 'DpPage.php');
  776.             $ob new DpPage($unique_idtime(DPUNIVERSE_RESET_CYCLE,
  777.                 $pathnameFALSE);
  778.             $ob->setTitle($pathname);
  779.             $ob->isStandalone new_dp_property(TRUE);
  780.             if (FALSE === dp_strpos($pathname'://')) {
  781.                 $ob->setBody($pathname'file');
  782.                 $ob->setNavigationTrail(array(DPUNIVERSE_NAVLOGO'/'));
  783.             }
  784.         else {
  785.             require_once(DPUNIVERSE_PREFIX_PATH $pathname);
  786.             $classname =  explode("/"$pathname);
  787.             $classname ucfirst(!dp_strlen($classname[sizeof($classname1])
  788.                 ? 'index'
  789.                 : dp_substr($classname[sizeof($classname1]0-4));
  790.             $ob new $classname($unique_idtime(DPUNIVERSE_RESET_CYCLE,
  791.                 $pathname$sublocation);
  792.         }
  793.         if (empty($ob)) {
  794.             $rval FALSE;
  795.             return $rval;
  796.         }
  797.  
  798.         $this->__GET['location'$pathname;
  799.         if (FALSE !== $sublocation{
  800.             $this->__GET['sublocation'$sublocation;
  801.         }
  802.  
  803.         $this->mDpObjects[=$ob;
  804.         $this->mDpObjectResets[=$ob;
  805.         if (!isset($this->mNextResetTime)) {
  806.             $this->mNextResetTime $ob->resetTime;
  807.         }
  808.  
  809.         $ob->__construct2();
  810.  
  811.         echo sprintf(dp_text("Made new object %s\n")$pathname);
  812.  
  813.         return $ob;
  814.     }
  815.  
  816.     /**
  817.      * Moves the object to another environment
  818.      *
  819.      * This method only handles the internal storage of environments.
  820.      * Most functionality can be found in  moveDpObject in DpObject.php.
  821.      *
  822.      * :WARNING: This method should normally only be called from DpObject.php.
  823.      *
  824.      * @access     private
  825.      * @param      object  &$rItem      object to move
  826.      * @param      mixed   &$rDest      object to move into to
  827.      */
  828.     function moveDpObject(&$rItem&$rDest)
  829.     {
  830.         foreach ($this->mEnvironments as $i => &$pair{
  831.             if ($pair[0=== $rItem{
  832.                 unset($this->mEnvironments[$i]);
  833.                 break;
  834.                 $this->mEnvironments[$i][1=$rDest;
  835.                 return;
  836.             }
  837.         }
  838.  
  839.         $this->mEnvironments[array(&$rItem&$rDest);
  840.     }
  841.  
  842.     /**
  843.      * Removes this object
  844.      *
  845.      * The object is destroyed and no longer part of the universe.
  846.      * This method only handles the internal storage of objects.
  847.      * Most functionality can be found in removeDpObject in DpObject.php.
  848.      *
  849.      * :WARNING: This method should normally only be called from DpObject.php.
  850.      *
  851.      * @access     private
  852.      * @param      object  &$rTarget    object to remove
  853.      */
  854.     function removeDpObject(&$rTarget)
  855.     {
  856.         global $grCurrentDpObject;
  857.  
  858.         foreach ($this->mDpUsers as $i => &$u{
  859.             if ($u[_DPUSER_OBJECT=== $rTarget{
  860.                 $del_user $i;
  861.                 break;
  862.             }
  863.         }
  864.  
  865.         $del_envs array();
  866.         foreach ($this->mEnvironments as $i => &$env{
  867.             if ($env[0=== $rTarget{
  868.                 $del_env $i;
  869.             }
  870.             if ($env[1=== $rTarget{
  871.                 $del_envs[$i;
  872.             }
  873.         }
  874.  
  875.         foreach ($this->mDpObjects as $i => &$ob{
  876.             if ($ob === $rTarget{
  877.                 $del_obj $i;
  878.                 break;
  879.             }
  880.         }
  881.  
  882.         foreach ($this->mDpObjectResets as $i => &$ob{
  883.             if ($ob === $rTarget{
  884.                 $del_reset $i;
  885.                 break;
  886.             }
  887.         }
  888.  
  889.         $del_timeouts array();
  890.         foreach ($this->mTimeouts as $i => &$ob{
  891.             if ($ob[0=== $rTarget{
  892.                 $del_timeouts[$i;
  893.             }
  894.         }
  895.  
  896.         $del_events array();
  897.         foreach ($this->mAlertEvents as $event => &$listeners{
  898.             foreach ($listeners as $i => &$ob{
  899.                 if ($ob === $rTarget{
  900.                     $del_events[array($event$i);
  901.                 }
  902.             }
  903.         }
  904.         if (isset($del_user)) {
  905.             unset($this->mDpUsers[$del_user][_DPUSER_OBJECT]);
  906.             unset($this->mDpUsers[$del_user]);
  907.         }
  908.         if (isset($del_env)) {
  909.             unset($this->mEnvironments[$del_env][0]);
  910.             unset($this->mEnvironments[$del_env]);
  911.         }
  912.         foreach ($del_envs as $del_env{
  913.             unset($this->mEnvironments[$del_env][1]);
  914.             $this->mEnvironments[$del_env][0]->removeDpObject();
  915.         }
  916.         if (isset($del_obj)) {
  917.             unset($this->mDpObjects[$del_obj]);
  918.         }
  919.         if (isset($del_reset)) {
  920.             unset($this->mDpObjectResets[$del_reset]);
  921.         }
  922.         foreach ($del_timeouts as $del_timeout{
  923.             unset($this->mTimeouts[$del_timeout][0]);
  924.             unset($this->mTimeouts[$del_timeout]);
  925.         }
  926.         foreach ($del_events as $event => $i{
  927.             unset($this->mAlertEvents[$event][$i]);
  928.         }
  929.         unset($rTarget);
  930.     }
  931.  
  932.     /**
  933.      * Finds an object in the universe with the given unique id
  934.      *
  935.      * @param      string    $unique_id  the object's unique string id
  936.      * @return     mixed     Object reference if found, FALSE otherwise
  937.      */
  938.     function &findDpObject($unique_id)
  939.     {
  940.         $rval FALSE;
  941.  
  942.         foreach ($this->mDpObjects as $i => &$ob{
  943.             if ($unique_id === $ob->getUniqueId()) {
  944.                 return $ob;
  945.             }
  946.         }
  947.  
  948.         return $rval;
  949.     }
  950.  
  951.     /**
  952.      * Finds or makes an object in the universe with the given pathname
  953.      *
  954.      * If an object with the given pathname exists, a reference to that object
  955.      * is returned. Otherwise a new instance of the class found at $pathname
  956.      * is created and returned.
  957.      *
  958.      * The object can have a unique location, given with $pathname, or just be
  959.      * based on $pathname, with a sublocation handling multiple objects. For
  960.      * example, the URL in uour browser contains the following bit for the
  961.      * DutchPIPE "about" page: location=/page/about.php
  962.      *
  963.      * It is a unique page with a unique location. The manual however is not
  964.      * based on many unique locations, but just one object which spawns pages
  965.      * based on the sublocation given in the URL:
  966.      * location=/page/manual.php&sublocation=index.html
  967.      *
  968.      *
  969.      * @param      string    $pathname     a path within dpuniverse/
  970.      * @param      string    $sublocation  optional sublocation
  971.      * @return     object    Reference to instance of $pathname
  972.      * @see        newDpObject
  973.      */
  974.     function &getDpObject($pathname$sublocation FALSE)
  975.     {
  976.         if (!$pathname{
  977.             $pathname DPUNIVERSE_PAGE_PATH 'index.php';
  978.         }
  979.  
  980.         if (FALSE === $sublocation{
  981.             foreach ($this->mDpObjects as $i => &$ob{
  982.                 if ($pathname === $ob->location{
  983.                     //echo dp_text("getDpObject(): returning existing object with location %s, no sublocation\n",
  984.                     //    $pathname);
  985.                     return $ob;
  986.                 }
  987.             }
  988.         else {
  989.             foreach ($this->mDpObjects as $i => &$ob{
  990.                 if ($pathname === $ob->location
  991.                         && $sublocation === $ob->sublocation{
  992.                     //echo dp_text("getDpObject(): returning existing object with location %s, sublocation %s\n",
  993.                     //    $pathname, $sublocation);
  994.                     return $ob;
  995.                 }
  996.             }
  997.         }
  998.  
  999.         echo FALSE == $sublocation
  1000.             ? dp_text("getDpObject(): returning new object for location %s, no sublocation\n",
  1001.                 $pathname)
  1002.             : dp_text("getDpObject(): returning new object for location %s, sublocation %s\n",
  1003.                 $pathname$sublocation);
  1004.         return $this->newDpObject($pathname$sublocation);
  1005.     }
  1006.  
  1007.     /**
  1008.      * Gets the object reference to the environment of this object
  1009.      *
  1010.      * Don't call this method here, call it in objects in the universe instead,
  1011.      * for instance $user->getEnvironment().
  1012.      *
  1013.      * :WARNING: This method should normally only be called from DpObject.php.
  1014.      *
  1015.      * @access     private
  1016.      * @param      object    &$ob        object we want to know environment of
  1017.      * @return     mixed     object reference or FALSE for no environment
  1018.      */
  1019.     function &getEnvironment(&$ob)
  1020.     {
  1021.         $env FALSE;
  1022.  
  1023.         foreach ($this->mEnvironments as &$pair{
  1024.             if ($pair[0=== $ob{
  1025.                 return $pair[1];
  1026.             }
  1027.         }
  1028.  
  1029.         return $env;
  1030.     }
  1031.  
  1032.     /**
  1033.      * Gets an array with object references to all objects in our inventory
  1034.      *
  1035.      * If this object contains no other objects, an empty array is returned.
  1036.      *
  1037.      * :WARNING: This method should normally only be called from DpObject.php.
  1038.      *
  1039.      * @access     private
  1040.      * @param      object    &$ob        object we want to know inventory of
  1041.      * @return     array     object references to objects in our inventory
  1042.      */
  1043.     function &getInventory(&$ob)
  1044.     {
  1045.         $inv array();
  1046.  
  1047.         foreach ($this->mEnvironments as &$pair{
  1048.             if ($pair[1=== $ob{
  1049.                 $inv[=$pair[0];
  1050.             }
  1051.         }
  1052.  
  1053.         return $inv;
  1054.     }
  1055.  
  1056.     /**
  1057.      * Checks if an object is present
  1058.      *
  1059.      * Search in the inventory of an object, as specified in $where, for another
  1060.      * object, as specified in $what. If $what is a string the objects searched
  1061.      * are checked for returning TRUE on the call isId($what).
  1062.      *
  1063.      * :WARNING: This method should normally only be called from DpObject.php.
  1064.      *
  1065.      * @access      private
  1066.      * @param       string|object    $what   object to search for
  1067.      * @param       object          &$where object to search in
  1068.      * @return      object|boolean the found object or FALSE if not found
  1069.      * @see         DpObject::getEnvironment(), DpObject::getInventory()
  1070.      */
  1071.     function &isPresent($what&$where)
  1072.     {
  1073.         $inv $this->getInventory($where);
  1074.         $rval FALSE;
  1075.         if (sizeof($inv)) {
  1076.             if (is_string($what&& dp_strlen($what trim($what))) {
  1077.                 $what dp_strtolower($what);
  1078.                 $nr 1;
  1079.                 if (FALSE !== ($pos dp_strrpos($what' '))) {
  1080.                     $nr dp_substr($what$pos 1);
  1081.                     if (FALSE === is_whole_number($nr)) {
  1082.                         $nr 1;
  1083.                     }
  1084.                     else {
  1085.                         $nr = (int)$nr;
  1086.                         $what trim(dp_substr($what0$pos));
  1087.                     }
  1088.                 }
  1089.                 foreach ($inv as &$ob{
  1090.                     if ($ob->isId($what&& (=== --$nr)) {
  1091.                         return $ob;
  1092.                     }
  1093.                 }
  1094.             }
  1095.             elseif (is_object($what)) {
  1096.                 foreach ($inv as &$ob{
  1097.                     if ($ob === $what{
  1098.                         return $ob;
  1099.                     }
  1100.                 }
  1101.             }
  1102.         }
  1103.  
  1104.         return $rval;
  1105.     }
  1106.  
  1107.     /**
  1108.      * Gets the current user connected to the server
  1109.      *
  1110.      * If a user page or AJAX request caused the current chain of execution that
  1111.      * caused this function to be called, that user object is returned.
  1112.      * Otherwise FALSE is returned. For example, if the chain of execution if
  1113.      * caused by a setTimeout, this will return FALSE.
  1114.      *
  1115.      * :WARNING: Use the function get_current_dpuser() instead of calling this
  1116.      * method.
  1117.      *
  1118.      * @access     private
  1119.      * @return     object    Reference to user object, FALSE for no current user
  1120.      */
  1121.     function &getCurrentDpUser()
  1122.     {
  1123.         $rval !isset($this->mrCurrentDpUserRequestFALSE
  1124.             : $this->mrCurrentDpUserRequest->getUser();
  1125.  
  1126.         return $rval;
  1127.     }
  1128.  
  1129.     /**
  1130.      * Finds the user with the given user name or id.
  1131.      *
  1132.      * @param       string   $userName  user name or id of player
  1133.      * @return      object|boolean     the found player or FALSE if not found
  1134.      */
  1135.     function &findUser($userName)
  1136.     {
  1137.         $rval FALSE;
  1138.  
  1139.         foreach ($this->mDpUsers as &$u{
  1140.             if ($u[_DPUSER_OBJECT]->isId($userName)) {
  1141.                 return $u[_DPUSER_OBJECT];
  1142.             }
  1143.         }
  1144.  
  1145.         return $rval;
  1146.     }
  1147.  
  1148.     /**
  1149.      * Gets an array with user object references of all users on this site
  1150.      *
  1151.      * @return     array     user object references of all users
  1152.      */
  1153.     function &getUsers()
  1154.     {
  1155.         $users array();
  1156.  
  1157.         /*
  1158.          * :TODO: Since this will be used a lot, keep a seperate copy instead of
  1159.          * constructing this array each time
  1160.          */
  1161.         foreach ($this->mDpUsers as &$u{
  1162.             $users[=$u[_DPUSER_OBJECT];
  1163.         }
  1164.  
  1165.         return $users;
  1166.     }
  1167.  
  1168.     /**
  1169.      * Gets the number of users on this site
  1170.      *
  1171.      * @return     int       number of users on this site
  1172.      */
  1173.     function getNrOfUsers()
  1174.     {
  1175.         return sizeof($this->mDpUsers);
  1176.     }
  1177.  
  1178.  
  1179.     /**
  1180.      * Calls a given method in an object after the given number of seconds
  1181.      *
  1182.      * Use this to perform delayed method calls in the given object. Note that
  1183.      * functions such as get_current_dpuser can be totally different when the
  1184.      * method is called. Also note that the actual delay is not exact science.
  1185.      *
  1186.      * :WARNING: This method should normally only be called from DpObject.php.
  1187.      *
  1188.      * @access     private
  1189.      * @param      object    &$ob        reference to object to call method in
  1190.      * @param      string    $method     name of method to call
  1191.      * @param      mixed     $arg1, $arg2, ...  optional arguments for method
  1192.      * @param      int d     $secs       delay in seconds
  1193.      */
  1194.     function setTimeout(&$ob$method$secs)
  1195.     {
  1196.         if (is_object($ob&& method_exists($ob$method&& $secs 0{
  1197.             $timeout_info array(&$ob$methodtime($secs);
  1198.             if (func_num_args(3{
  1199.                 $args func_get_args();
  1200.                 $tmp array_slice($args3);
  1201.                 $timeout_info[$tmp;
  1202.             }
  1203.             $this->mTimeouts[=$timeout_info;
  1204.         }
  1205.     }
  1206.  
  1207.     /**
  1208.      * Gets an array with information about the universe
  1209.      *
  1210.      * The following array is returned:
  1211.      *
  1212.      * array(
  1213.      *     'memory_usage'       : <int Universe memory usage in bytes>
  1214.      *     'nr_of_objects'      : <int Number of objects in the universe>
  1215.      *     'nr_of_users'        : <int Number of users in the universe>
  1216.      *     'nr_of_environments' : <int Number of environments in the universe>
  1217.      *     'nr_of_timeouts'     : <int Number of "timeouts" in the universe>
  1218.      * );
  1219.      *
  1220.      * @return     array     universe information
  1221.      */
  1222.     function getUniverseInfo()
  1223.     {
  1224.         /*
  1225.         echo "Saving...\n";
  1226.         $serialized_universe = serialize($this);
  1227.         $fp = fopen('/tmp/serialized_universe', 'w');
  1228.         fwrite($fp, $serialized_universe);
  1229.         fclose($fp);
  1230.         */
  1231.         $arr array(
  1232.             'memory_usage' => memory_get_usage(),
  1233.             'nr_of_objects' => sizeof($this->mDpObjects),
  1234.             'nr_of_users' => sizeof($this->mDpUsers),
  1235.             'nr_of_environments' => sizeof($this->mEnvironments),
  1236.             'nr_of_timeouts' => sizeof($this->mTimeouts));
  1237.  
  1238.         return $arr;
  1239.     }
  1240.  
  1241.     /**
  1242.      * Attempts to login the given user object of a guest as a registered user
  1243.      *
  1244.      * @param      object    &$user      user to validate
  1245.      * @return     boolean   TRUE for succesful login, FALSE otherwise
  1246.      */
  1247.     function validateExisting(&$user)
  1248.     {
  1249.         $this->mLastNewUserErrors array();
  1250.         if (!isset($user->_GET['username'])
  1251.                 || === dp_strlen($user->_GET['username'])) {
  1252.             $this->mLastNewUserErrors['<li>'
  1253.                 . dp_text('No username was given''</li>';
  1254.         }
  1255.         if (=== sizeof($this->mLastNewUserErrors)
  1256.                 && $user->_GET['username'=== $user->getTitle()) {
  1257.             $this->mLastNewUserErrors['<li>'
  1258.                 . sprintf(dp_text('You are already logged in as %s'),
  1259.                 $user->getTitle()) '</li>';
  1260.         elseif (!isset($user->_GET['password'])
  1261.                 || === dp_strlen($user->_GET['password'])) {
  1262.             $this->mLastNewUserErrors['<li>'
  1263.                 . dp_text('No password was given''</li>';
  1264.         }
  1265.         if (=== sizeof($this->mLastNewUserErrors)) {
  1266.             $username dp_strtolower($user->_GET['username']);
  1267.             $result dp_db_query('SELECT userUsername, userPassword, '
  1268.                 . 'userCookieId, userCookiePassword FROM Users WHERE '
  1269.                 . 'userUsernameLower=' dp_db_quote($username'text'));
  1270.             if (FALSE === $result || !($row dp_db_fetch_row($result))) {
  1271.                 $this->mLastNewUserErrors[=
  1272.                     '<li>' dp_text('That username doesn\'t exist''</li>';
  1273.             else {
  1274.                 if ($row[1!== $user->_GET['password']{
  1275.                     $this->mLastNewUserErrors['<li>'
  1276.                         . dp_text('Invalid password''</li>';
  1277.                 }
  1278.             }
  1279.             dp_db_free($result);
  1280.         }
  1281.  
  1282.         if (sizeof($this->mLastNewUserErrors)) {
  1283.             $user->tell('<window styleclass="dpwindow_error"><h1>'
  1284.                 . dp_text('Invalid login''</h1><br /><ul>'
  1285.                 . implode(''$this->mLastNewUserErrors'</ul></window>');
  1286.             return FALSE;
  1287.         }
  1288.  
  1289.         $username $row[0];
  1290.         $cookie_id $row[2];
  1291.         $cookie_pass $row[3];
  1292.         $user->tell('<cookie>removeguest</cookie>');
  1293.         $user->_COOKIE[DPSERVER_COOKIE_NAME"$cookie_id;$cookie_pass";
  1294.         $user->tell('<cookie>' $user->_COOKIE[DPSERVER_COOKIE_NAME]
  1295.             . '</cookie>');
  1296.         $user->_GET['username'$username;
  1297.         $user->addId($user->_GET['username']);
  1298.         $user->addId(dp_strtolower($user->_GET['username']));
  1299.         $user->setTitle(ucfirst($user->_GET['username']));
  1300.         $user->isRegistered TRUE;
  1301.         if ($user === get_current_dpuser()) {
  1302.             $user->titleImgWidth NULL;
  1303.             $user->titleImgHeight NULL;
  1304.             $row $this->mrCurrentDpUserRequest->findAndInitRegisteredDpUser(
  1305.                 $cookie_id$cookie_pass);
  1306.             $this->mrCurrentDpUserRequest->initDpUser();
  1307.         }
  1308.  
  1309.         /* :TODO: Move admin flag to user table in db */
  1310.         if (in_array($user->_GET['username'],
  1311.                 explode('#'DPUNIVERSE_ADMINISTRATORS))) {
  1312.             $user->isAdmin TRUE;
  1313.         }
  1314.         foreach ($this->mDpUsers as $user_nr => &$u{
  1315.             if ($u[0=== $user{
  1316.                 $this->mDpUsers[$user_nr][2$user->_GET['username'];
  1317.                 $this->mDpUsers[$user_nr][3$cookie_id;
  1318.                 $this->mDpUsers[$user_nr][4$cookie_pass;
  1319.                 $this->mDpUsers[$user_nr][51;
  1320.             }
  1321.         }
  1322.         $user->tell('<changeDpElement id="username">'
  1323.             . $user->_GET['username''</changeDpElement>');
  1324.  
  1325.         $user->tell(array('abstract' => '<changeDpElement id="'
  1326.             . $user->getUniqueId('"><b>'
  1327.             . $user->getAppearance(1FALSE'</b></changeDpElement>',
  1328.             'graphical' => '<changeDpElement id="'
  1329.             . $user->getUniqueId('"><b>'
  1330.             . $user->getAppearance(1FALSE$user'graphical')
  1331.             . '</b></changeDpElement>'));
  1332.         $user->tell('<changeDpElement id="loginlink"><a href="'
  1333.             . DPSERVER_CLIENT_URL '?location=' DPUNIVERSE_PAGE_PATH
  1334.             . 'login.php&amp;act=logout" style="padding-left: 4px">'
  1335.             . dp_text('Logout''</a></changeDpElement>');
  1336.         $user->getEnvironment()->tell(array(
  1337.             'abstract' => '<changeDpElement id="' $user->getUniqueId('">'
  1338.             . $user->getAppearance(1FALSE'</changeDpElement>',
  1339.             'graphical' => '<changeDpElement id="'
  1340.             . $user->getUniqueId('">'
  1341.             . $user->getAppearance(1FALSE$user'graphical')
  1342.             . '</changeDpElement>')$user);
  1343.         $user->tell('<window><h1>' dp_text('Welcome back''</h1><br />'
  1344.             . sprintf(dp_text('You are now logged in as: <b>%s</b>'),
  1345.             $user->getTitle()) '</window>');
  1346.  
  1347.         return TRUE;
  1348.     }
  1349.  
  1350.     /**
  1351.      * Logs out a given registered user and turns the user into a guest
  1352.      *
  1353.      * @param      object    &$user      user to logout
  1354.      */
  1355.     function logoutUser(&$user)
  1356.     {
  1357.         $username sprintf(dp_text('Guest#%d')$this->getGuestCnt());
  1358.         $cookie_id make_random_id();
  1359.         $cookie_pass make_random_id();
  1360.         $oldtitle $user->getTitle();
  1361.         $user->tell('<cookie>removeregistered</cookie>');
  1362.         $user->_COOKIE[DPSERVER_COOKIE_NAME"$cookie_id;$cookie_pass";
  1363.         $this->tellCurrentDpUserRequest("Set-Login: "
  1364.             . $user->_COOKIE[DPSERVER_COOKIE_NAME]);
  1365.         $user->_GET['username'$username;
  1366.         $user->removeId($oldtitle);
  1367.         $user->addId($username);
  1368.         $user->setTitle(ucfirst($username));
  1369.         if ($user->avatarCustom{
  1370.             $user->avatarCustom NULL;
  1371.             $user->titleImgWidth NULL;
  1372.             $user->titleImgHeight NULL;
  1373.             $user->avatarNr $this->getRandAvatarNr();
  1374.             $user->titleImg DPUNIVERSE_AVATAR_STD_URL 'user'
  1375.                 . $user->avatarNr '.gif';
  1376.             $user->body '<img src="' DPUNIVERSE_AVATAR_STD_URL
  1377.                 . 'user' $user->avatarNr '_body.gif" border="0" '
  1378.                 . 'alt="" align="left" style="margin-right: 15px" />'
  1379.                 . dp_text('A user.''<br />';
  1380.         }
  1381.         $user->isRegistered FALSE;
  1382.         $user->isAdmin FALSE;
  1383.         if ($user === get_current_dpuser()) {
  1384.             $this->mrCurrentDpUserRequest->setUsername($username);
  1385.         }
  1386.  
  1387.         foreach ($this->mDpUsers as $user_nr => &$u{
  1388.             if ($u[0=== $user{
  1389.                 $this->mDpUsers[$user_nr][2$username;
  1390.                 $this->mDpUsers[$user_nr][3$cookie_id;
  1391.                 $this->mDpUsers[$user_nr][4$cookie_pass;
  1392.                 $this->mDpUsers[$user_nr][50;
  1393.             }
  1394.         }
  1395.         $this->mrCurrentDpUserRequest->setHasMoved();
  1396.         $this->mNoDirectTell TRUE;
  1397.         $user->tell('<window><h1>' sprintf(dp_text('Logged out %s'),
  1398.             $oldtitle'</h1><br />' dp_text('See you later!''<br />'
  1399.             . dp_text('You are now: <b>%s</b>'$user->getTitle())
  1400.             . '</b></window>');
  1401.         $this->mNoDirectTell FALSE;
  1402.         $user->tell('<location>' DPUNIVERSE_PAGE_PATH
  1403.             . 'login.php</location>');
  1404.  
  1405.         $user->getEnvironment()->tell(array(
  1406.             'abstract' => '<changeDpElement id="' $user->getUniqueId('">'
  1407.             . $user->getAppearance(1FALSE'</changeDpElement>',
  1408.             'graphical' => '<changeDpElement id="'
  1409.             . $user->getUniqueId('">'
  1410.             . $user->getAppearance(1FALSE$user'graphical')
  1411.             . '</changeDpElement>')$user);
  1412.     }
  1413.  
  1414.     /**
  1415.      * Attempts the first step in registering a new user, throws CAPTCHA
  1416.      *
  1417.      * @param      object    &$user      user to register
  1418.      * @return     boolean   TRUE to continue to CAPTCHA, FALSE for errors
  1419.      */
  1420.     function validateNewUser(&$user)
  1421.     {
  1422.         if (FALSE === $this->validLoginInfo($user->_GET['username'],
  1423.                 $user->_GET['password']$user->_GET['password2'])) {
  1424.             $user->tell('<window styleclass="dpwindow_error"><h1>'
  1425.                 . dp_text('Invalid registration''</h1><br />'
  1426.                 . dp_text('Please correct the following errors:''<ul>'
  1427.                 . implode(''$this->mLastNewUserErrors'</ul></window>');
  1428.             return FALSE;
  1429.         else {
  1430.             if (!isset($user->_GET['givencode'])) {
  1431.                 if (FALSE === ($captcha_id $this->getRandCaptcha())) {
  1432.                     return TRUE;
  1433.                 }
  1434.                 $user->tell('<window><form method="post" '
  1435.                     . 'onsubmit="send_captcha(' $captcha_id
  1436.                     . '); return false"><div align="center">'
  1437.                     . '<img id="captchaimage" src="' DPSERVER_CLIENT_DIR
  1438.                     . 'dpcaptcha.php?captcha_id='
  1439.                     . $captcha_id '" border="0" alt="" /></div>'
  1440.                     . '<br clear="all" />'
  1441.                     . dp_text('To complete registration, please enter the code you see above:')
  1442.                     . '<br /><br /><div align="center" '
  1443.                     . 'style="margin-bottom: 5px"><input id="givencode" '
  1444.                     . 'type="text" size="6" maxlength="6" value="" /> '
  1445.                     . '<input type="submit" value="'
  1446.                     . dp_text('OK''" /></div><br />'
  1447.                     . dp_text('This system is used to filter software robots
  1448. from registrations submitted by individuals. If you are unable to validate the
  1449. above code, please <a href="mailto:registration@dutchpipe.org">mail us</a>
  1450. to complete registration.''</form></window>');
  1451.                 return FALSE;
  1452.             }
  1453.             return TRUE;
  1454.         }
  1455.     }
  1456.  
  1457.     /**
  1458.      * Attempts the second step in registering a new user, validates CAPTCHA
  1459.      *
  1460.      * @param      object    &$user      user to register
  1461.      */
  1462.     function validateCaptcha(&$user)
  1463.     {
  1464.         if (FALSE === $this->validateNewUser($user)) {
  1465.             return;
  1466.         }
  1467.         if (!isset($user->_GET['captcha_id'])
  1468.                 || !isset($user->_GET['givencode']|| FALSE ===
  1469.                 $this->validateCaptcha2($user->_GET['captcha_id'],
  1470.                 $user->_GET['givencode'])) {
  1471.             if (NULL === ($captcha_attempts $user->captchaAttempts)
  1472.                     || $captcha_attempts 2{
  1473.                 $user->captchaAttempts new_dp_property(
  1474.                     NULL === $captcha_attempts $captcha_attempts 1);
  1475.                 return;
  1476.             }
  1477.             unset($user->captchaAttempts);
  1478.             $user->tell('<window styleclass="dpwindow_error"><h1>'
  1479.                 . dp_text('Failure validating code''</h1><br />'
  1480.                 . dp_text('Please try again.''</window>');
  1481.             return;
  1482.         }
  1483.         if ($next_id dp_db_next_id('Users''userId')) {
  1484.             $username $user->_GET['username'];
  1485.             $keys $vals array();
  1486.             $keys['userId';
  1487.             $vals[dp_db_quote($next_id);
  1488.             $keys['userUsername';
  1489.             $vals[dp_db_quote($user->_GET['username']);
  1490.             $keys['userUsernameLower';
  1491.             $vals[dp_db_quote(dp_strtolower($user->_GET['username']));
  1492.             $keys['userPassword';
  1493.             $vals[dp_db_quote($user->_GET['password']);
  1494.             $keys['userCookieId';
  1495.             $vals[dp_db_quote($cookie_id make_random_id());
  1496.             $keys['userCookiePassword';
  1497.             $vals[dp_db_quote($cookie_pass make_random_id());
  1498.             $keys implode(','$keys);
  1499.             $vals implode(','$vals);
  1500.  
  1501.             if (FALSE !==
  1502.                     dp_db_exec("INSERT INTO Users ($keys) VALUES ($vals)")) {
  1503.                 $user->tell('<cookie>removeguest</cookie>');
  1504.                 $user->_COOKIE[DPSERVER_COOKIE_NAME=
  1505.                     "$cookie_id;$cookie_pass";
  1506.                 $user->tell('<cookie>' $user->_COOKIE[DPSERVER_COOKIE_NAME]
  1507.                     . '</cookie>');
  1508.                 $user->addId($username);
  1509.                 $user->setTitle(ucfirst($username));
  1510.                 $user->isRegistered TRUE;
  1511.                 $user->isAdmin FALSE;
  1512.                 if ($user === get_current_dpuser()) {
  1513.                     $this->mrCurrentDpUserRequest->findAndInitRegisteredDpUser(
  1514.                         $cookie_id$cookie_pass);
  1515.                 }
  1516.  
  1517.                 foreach ($this->mDpUsers as $user_nr => &$u{
  1518.                     if ($u[0=== $user{
  1519.                         $this->mDpUsers[$user_nr][2$username;
  1520.                         $this->mDpUsers[$user_nr][3$cookie_id;
  1521.                         $this->mDpUsers[$user_nr][4$cookie_pass;
  1522.                         $this->mDpUsers[$user_nr][51;
  1523.                     }
  1524.                 }
  1525.                 $user->tell('<changeDpElement id="username">' $username
  1526.                     . '</changeDpElement>');
  1527.                 $user->tell(array('abstract' => '<changeDpElement id="'
  1528.                     . $user->getUniqueId('"><b>'
  1529.                     . $user->getAppearance(1FALSE'</b></changeDpElement>',
  1530.                     'graphical' => '<changeDpElement id="'
  1531.                     . $user->getUniqueId('"><b>'
  1532.                     . $user->getAppearance(1FALSE$user'graphical')
  1533.                     . '</b></changeDpElement>'));
  1534.                 $user->tell('<changeDpElement id="loginlink"><a href="'
  1535.                     . DPSERVER_CLIENT_URL '?location=' DPUNIVERSE_PAGE_PATH
  1536.                     . 'login.php&amp;act=logout" style="padding-left: 4px">'
  1537.                     . dp_text('Logout''</a></changeDpElement>');
  1538.                 if ($env $user->getEnvironment()) {
  1539.                     $env->tell(array('abstract' => '<changeDpElement id="'
  1540.                         . $user->getUniqueId('">'
  1541.                         . $user->getAppearance(1FALSE'</changeDpElement>',
  1542.                         'graphical' => '<changeDpElement id="'
  1543.                         . $user->getUniqueId('">'
  1544.                         . $user->getAppearance(1FALSE$user'graphical')
  1545.                         . '</changeDpElement>')$user);
  1546.                 }
  1547.                 $user->tell('<window><h1>'
  1548.                     . dp_text('Thank you for registering and welcome to DutchPIPE!')
  1549.                     . '</h1><br />' sprintf(
  1550.                     dp_text('You are now logged in as: <b>%s</b>')$username)
  1551.                     . '</window>');
  1552.                 return;
  1553.             }
  1554.         }
  1555.         $user->tell('<window>' .
  1556.             dp_text('There was a problem registering your new user. Registration failed.')
  1557.             . '</window>');
  1558.     }
  1559.  
  1560.     /**
  1561.      * Validates a given CAPTCHA code against the code in the database
  1562.      *
  1563.      * @param      string    $captchaId  Captcha id given by the validation form
  1564.      * @param      string    $captchaGivenCode  User input
  1565.      * @return     boolean   TRUE if the given code was valid, FALSE otherwise
  1566.      */
  1567.     function validateCaptcha2($captchaId$captchaGivenCode)
  1568.     {
  1569.         $captchaId addslashes($captchaId);
  1570.         $captchaGivenCode addslashes($captchaGivenCode);
  1571.  
  1572.         $result dp_db_query('SELECT captchaId FROM Captcha WHERE '
  1573.             . 'captchaId=' dp_db_quote($captchaId'integer')
  1574.             . ' AND captchaFile=' dp_db_quote($captchaGivenCode '.gif'));
  1575.  
  1576.         $rval $result && dp_db_num_rows($result);
  1577.         dp_db_free($result);
  1578.         return $rval;
  1579.     }
  1580.  
  1581.     /**
  1582.      * Is the given login info valid for a new user?
  1583.      *
  1584.      * In case of errors, fills array $this->mLastNewUserErrors with one or more
  1585.      * error strings.
  1586.      *
  1587.      * @param      string    $userName   given user name to check
  1588.      * @param      string    $password   given password
  1589.      * @param      string    $password2  given repeated pssword
  1590.      * @return     boolean   TRUE for valid login info, FALSE otherwise
  1591.      */
  1592.     private function validLoginInfo($userName$password$password2)
  1593.     {
  1594.         $this->mLastNewUserErrors array();
  1595.  
  1596.         $len dp_strlen($userName);
  1597.         if (=== $len{
  1598.             $this->mLastNewUserErrors['<li>'
  1599.                 . dp_text('No username was given''</li>';
  1600.         else {
  1601.             if ($len DPUNIVERSE_MIN_USERNAME_LEN{
  1602.                 $this->mLastNewUserErrors['<li>' sprintf(
  1603.                     dp_text('The username must be at least %d characters long'),
  1604.                     DPUNIVERSE_MIN_USERNAME_LEN'</li>';
  1605.             elseif ($len DPUNIVERSE_MAX_USERNAME_LEN{
  1606.                 $this->mLastNewUserErrors['<li>' sprintf(
  1607.                     dp_text('The username must be at most %d characters long'),
  1608.                     DPUNIVERSE_MAX_USERNAME_LEN'</li>';
  1609.             }
  1610.  
  1611.             /*if (FALSE !== ($words = file(DUTCHPIPE_FORBIDDEN_USERNAMES_FILE))
  1612.                     && count($words)) {
  1613.                 foreach ($words as $word) {
  1614.                     if (FALSE !== dp_strpos($userName, $word)) {
  1615.                         $this->lastUsernameError[] = '<li>' .
  1616.                         dp_text('This username is not allowed, please try again.')
  1617.                         . '</li>';
  1618.                         break;
  1619.                     }
  1620.                 }
  1621.             }*/
  1622.  
  1623.             $lower_user_name dp_strtolower($userName);
  1624.             if ($lower_user_name{0'a' || $lower_user_name{0'z'{
  1625.                 $this->mLastNewUserErrors['<li>'
  1626.                      . dp_text('Illegal character in username at position 1 (usernames must start with a letter, digits or other characters are not allowed)')
  1627.                      . '</li>';
  1628.             }
  1629.             for ($i 1$i $len$i++{
  1630.                 if (($lower_user_name{$i'a' || $lower_user_name{$i'z')
  1631.                         && ($lower_user_name{$i'0'
  1632.                         || $lower_user_name{$i'9')) {
  1633.                     $this->mLastNewUserErrors['<li>' sprintf(
  1634.                         dp_text('Illegal character in username at position %d (you can only use a-z and 0-9)'),
  1635.                         ($i 1)) '</li>';
  1636.                     break;
  1637.                 }
  1638.             }
  1639.  
  1640.             $result dp_db_query('SELECT userId FROM Users WHERE '
  1641.                 . 'userUsernameLower=' dp_db_quote(dp_strtolower($userName)));
  1642.             if ($result && dp_db_num_rows($result)) {
  1643.                 $this->mLastNewUserErrors['<li>'
  1644.                     . dp_text('That username is already in use''</li>';
  1645.             }
  1646.             dp_db_free($result);
  1647.         }
  1648.  
  1649.         if (!isset($password|| !dp_strlen($password)) {
  1650.             $this->mLastNewUserErrors['<li>'
  1651.                 . dp_text('No password was given''</li>';
  1652.         }
  1653.  
  1654.         if (=== sizeof($this->mLastNewUserErrors)) {
  1655.             if (dp_strlen($password6{
  1656.                 $this->mLastNewUserErrors['<li>'
  1657.                     . dp_text('Your password must be at least 6 characters long')
  1658.                     . '</li>';
  1659.             elseif (dp_strlen($password32{
  1660.                 $this->mLastNewUserErrors['<li>'
  1661.                     . dp_text('Your password must be at most 32 characters long')
  1662.                     . '</li>';
  1663.             elseif (!dp_strlen($password2)) {
  1664.                 $this->mLastNewUserErrors['<li>'
  1665.                     . dp_text('You didn\'t repeat your password''</li>';
  1666.             elseif ($password !== $password2{
  1667.                 $this->mLastNewUserErrors['<li>'
  1668.                     . dp_text('The repeated password was different''</li>';
  1669.             }
  1670.         }
  1671.  
  1672.         return === sizeof($this->mLastNewUserErrors);
  1673.     }
  1674.  
  1675.     /**
  1676.      * Gets a random avatar image number in order to give guests an avatar
  1677.      *
  1678.      * Checks the avatar image directory for images with the format:
  1679.      * public/avatar/user<number>.gif
  1680.      * for possible numbers.
  1681.      *
  1682.      * @return  int     random avatar image number
  1683.      * @see     getNrOfAvatars
  1684.      */
  1685.     function getRandAvatarNr()
  1686.     {
  1687.         $entries $this->getNrOfAvatars();
  1688.         if (=== $entries{
  1689.             return 1;
  1690.         }
  1691.         return (mt_rand(5150 $entries50);
  1692.     }
  1693.  
  1694.     /**
  1695.      * Gets the available number of avatars images
  1696.      *
  1697.      * Searches the DPUNIVERSE_AVATAR_STD_PATH directory for files ending with
  1698.      * "_body.gif".
  1699.      *
  1700.      * @return  int     the number of available avatar images
  1701.      * @see     getRandAvatarNr
  1702.      */
  1703.     function getNrOfAvatars()
  1704.     {
  1705.         $entries 0;
  1706.         $d dir(DPUNIVERSE_AVATAR_STD_PATH);
  1707.             while (false !== ($entry $d->read())) {
  1708.             if ($entry !== '.' && $entry !== '..' && dp_strlen($entry13
  1709.                     && dp_substr($entry-9== '_body.gif'{
  1710.                 $entries++;
  1711.             }
  1712.         }
  1713.         return $entries;
  1714.     }
  1715.  
  1716.     /**
  1717.      * Sets the user been told anything this request
  1718.      *
  1719.      * @access     private
  1720.      */
  1721.     function setToldSomething()
  1722.     {
  1723.         $this->mrCurrentDpUserRequest->setToldSomething();;
  1724.     }
  1725.  
  1726.     /**
  1727.      * Has the user been told anything this request?
  1728.      *
  1729.      * @access     private
  1730.      * @return     boolean TRUE if user was told something, FALSE otherwise
  1731.      */
  1732.     function isToldSomething()
  1733.     {
  1734.         return $this->mrCurrentDpUserRequest->isToldSomething();
  1735.     }
  1736.  
  1737.     /**
  1738.      * Do not tell anything to the current http request?
  1739.      *
  1740.      * @access     private
  1741.      * @return     boolean TRUE for no telling, FALSE otherwise
  1742.      */
  1743.     function isNoDirectTell()
  1744.     {
  1745.         return $this->mNoDirectTell;
  1746.     }
  1747.  
  1748.     /**
  1749.      * Adds a user to the listener list of the given event
  1750.      *
  1751.      * @param      string    $event      Name of the event
  1752.      * @param      string    &$who       User listening to event
  1753.      */
  1754.     function addAlertEvent($event&$who)
  1755.     {
  1756.         if (!isset($this->mAlertEvents[$event])) {
  1757.             $this->mAlertEvents[$eventarray();
  1758.         }
  1759.  
  1760.         if (FALSE === array_search($who$this->mAlertEvents[$event]TRUE)) {
  1761.             $this->mAlertEvents[$event][=$who;
  1762.         }
  1763.     }
  1764.  
  1765.     /**
  1766.      * Removes a user from the listener list of the given event
  1767.      *
  1768.      * @param      string    $event      Name of the event
  1769.      * @param      string    &$who       User listening to event
  1770.      */
  1771.     function removeAlertEvent($event&$who)
  1772.     {
  1773.         if (isset($this->mAlertEvents[$event]&& FALSE !==
  1774.             ($key array_search($who$this->mAlertEvents[$event]TRUE))) {
  1775.             unset($this->mAlertEvents[$event][$key]);
  1776.             if (=== count($this->mAlertEvents[$event])) {
  1777.                 unset($this->mAlertEvents[$event]);
  1778.             }
  1779.         }
  1780.     }
  1781.  
  1782.     /**
  1783.      * Gets list of listening users to the given event
  1784.      *
  1785.      * @param      string    $event      Name of the event
  1786.      * @return     array     Users listening to event
  1787.      */
  1788.     function &getAlertEvent($event)
  1789.     {
  1790.         if (!isset($this->mAlertEvents[$event])) {
  1791.             $rval FALSE;
  1792.         else {
  1793.             /* Clean up event listeners list */
  1794.             foreach ($this->mAlertEvents[$eventas $key => &$who{
  1795.                 if (!isset($who|| is_null($who|| $who->isRemoved{
  1796.                     unset($this->mAlertEvents[$event][$key]);
  1797.                 }
  1798.             }
  1799.  
  1800.             $rval $this->mAlertEvents[$event];
  1801.         }
  1802.  
  1803.         return $rval;
  1804.     }
  1805.  
  1806.     /**
  1807.      * Shows a line with memory and universe info
  1808.      */
  1809.     function showStatusMemoryGetUsage()
  1810.     {
  1811.         if (!function_exists('memory_get_usage')) {
  1812.             return;
  1813.         }
  1814.  
  1815.         $info $this->getUniverseInfo();
  1816.  
  1817.         printf("Memory: %dKB  #Objects: %d  #Users: %d  #Environments: %d  "
  1818.             . "#Timeouts: %d\n",
  1819.             round($info['memory_usage'1024),
  1820.             $info['nr_of_objects'],
  1821.             $info['nr_of_users'],
  1822.             $info['nr_of_environments'],
  1823.             $info['nr_of_timeouts']);
  1824.     }
  1825.  
  1826.     /**
  1827.      * Gets a list of all objects in this DutchPIPE universe
  1828.      *
  1829.      * @return     array     A list of all objects in this DutchPIPE universe
  1830.      * @see        DpUser::actionOblist()
  1831.      * @since      DutchPIPE 0.4.0
  1832.      */
  1833.     function getObjectList()
  1834.     {
  1835.         $rval '<table border="0" cellspacing="2" cellpadding="2" '
  1836.             . 'class="dpoblist sortable"><thead><tr>'
  1837.             . '<th nowrap="nowrap" style="white-space: nowrap">'
  1838.                 . '<div style="float: left">' dp_text('Unique Id')
  1839.             . '</div></th>'
  1840.             . '<th>' dp_text('Title''</th>'
  1841.             . '<th>' dp_text('Location''</th>'
  1842.             . '<th>' dp_text('Environment''</th>'
  1843.             . '<th class="align_c">' dp_text('User''</th>'
  1844.             . '<th class="align_c">' dp_text('Adm''</th>'
  1845.             . '<th class="align_c">' dp_text('NPC''</th>'
  1846.             . '<th class="align_c">' dp_text('Page''</th>'
  1847.             . '<th>' dp_text('Created''</th>'
  1848.             . '<th>' dp_text('Reset''</th>'
  1849.             . '</tr></thead><tbody>';
  1850.         $checked '<img src="' DPUNIVERSE_IMAGE_URL 'checked.gif'
  1851.             . '" width="7" height="7" border="0" alt="*" title="*" />';
  1852.  
  1853.         $ob_nr 1;
  1854.         $ob_sz count($this->mDpObjects);
  1855.         foreach ($this->mDpObjects as &$ob{
  1856.             $rval .= '<tr>'
  1857.                 . '<td sorttable_customkey="' $ob_nr '">'
  1858.                     . $ob->uniqueId
  1859.                 . '</td>'
  1860.                 . '<td><div>' ucfirst($ob->title'</div></td>'
  1861.                 . '<td><div>' $ob->location '</div></td>'
  1862.                 . '<td><div>'
  1863.                     . (!($env $ob->getEnvironment()) '&nbsp;'
  1864.                     : '<a href="' (!$env->isStandalone DPSERVER_CLIENT_URL
  1865.                     . '?location=' ''$env->location '">'
  1866.                     . ucfirst($env->title)
  1867.                     . '</a>')
  1868.                 . '</div></td>'
  1869.                 . '<td class="align_c"' (!$ob->isUser
  1870.                     ? ' sorttable_customkey="' $ob_sz '">&nbsp;'
  1871.                     : '">' $checked)
  1872.                 . '</td>'
  1873.                 . '<td class="align_c"' (!$ob->isAdmin
  1874.                     ? ' sorttable_customkey="' $ob_sz '">&nbsp;'
  1875.                     : '">' $checked)
  1876.                 . '</td>'
  1877.                 . '<td class="align_c"' (!$ob->isNpc
  1878.                     ? ' sorttable_customkey="' $ob_sz '">&nbsp;'
  1879.                     : '">' $checked)
  1880.                 . '</td>'
  1881.                 . '<td class="align_c"' (!$ob->isPage
  1882.                     ? ' sorttable_customkey="' $ob_sz '">&nbsp;'
  1883.                     : '">' $checked)
  1884.                 . '</td>'
  1885.                 . '<td><div>'
  1886.                     . strftime('%d %b %H:%M'$ob->creationTime)
  1887.                 . '</div></td>'
  1888.                 . '<td><div>'
  1889.                     . strftime('%H:%M'$ob->resetTime)
  1890.                 . '</div></td>'
  1891.                 . '</tr>';
  1892.             $ob_nr++;
  1893.         }
  1894.  
  1895.         return $rval '</tbody></table>';
  1896.     }
  1897. }
  1898. ?>

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

Click me!
Guest#217
 
 
 
  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.