diff --git a/src/containers/file.class.php b/src/containers/file.class.php index c238d366..23cf26f3 100644 --- a/src/containers/file.class.php +++ b/src/containers/file.class.php @@ -1,6 +1,6 @@ * @@ -36,17 +36,13 @@ class pfcContainer_File extends pfcContainer function pfcContainer_File(&$config) { pfcContainer::pfcContainer($config); - // $this->loadPaths(); } function loadPaths() { $c =& $this->c; - $c->container_cfg_chat_dir = $c->data_private_path."/chat"; - $c->container_cfg_server_dir = $c->container_cfg_chat_dir."/s_".$c->serverid; - $c->container_cfg_server_nickname_dir = $c->container_cfg_server_dir."/nicknames"; - $c->container_cfg_meta_dir = $c->container_cfg_server_dir."/metadata"; - $c->container_cfg_channel_dir = $c->container_cfg_server_dir."/channels"; + $c->container_cfg_chat_dir = $c->data_private_path."/chat"; + $c->container_cfg_server_dir = $c->container_cfg_chat_dir."/s_".$c->serverid; } function getDefaultConfig() @@ -54,11 +50,8 @@ function getDefaultConfig() $c =& $this->c; $cfg = array(); - $cfg["chat_dir"] = ""; // will be generated from the other parameters into the init step - $cfg["server_dir"] = ""; // will be generated from the other parameters into the init step - $cfg["server_nickname_dir"] = ""; // will be generated from the other parameters into the init step - $cfg["meta_dir"] = ""; // will be generated from the other parameters into the init step - $cfg["channel_dir"] = ""; // will be generated from the other parameters into the init step + $cfg["chat_dir"] = ''; // will be generated from the other parameters into the init step + $cfg["server_dir"] = ''; // will be generated from the other parameters into the init step return $cfg; } @@ -72,415 +65,18 @@ function init() $c->container_cfg_chat_dir = $c->data_private_path."/chat"; $this->loadPaths(); - $errors = array_merge($errors, @test_writable_dir($c->container_cfg_chat_dir, "container_cfg_chat_dir")); - $errors = array_merge($errors, @test_writable_dir($c->container_cfg_server_dir, "container_cfg_chat_dir/serverid")); - $errors = array_merge($errors, @test_writable_dir($c->container_cfg_server_nickname_dir, "container_cfg_chat_dir/nicknames")); - $errors = array_merge($errors, @test_writable_dir($c->container_cfg_meta_dir, "container_cfg_chat_dir/metadata")); - $errors = array_merge($errors, @test_writable_dir($c->container_cfg_channel_dir, "container_cfg_chat_dir/channels")); + $errors = array_merge($errors, @test_writable_dir($c->container_cfg_chat_dir, "container_cfg_chat_dir")); + $errors = array_merge($errors, @test_writable_dir($c->container_cfg_server_dir, "container_cfg_chat_dir/serverid")); return $errors; } - /** - * Create (connect/join) the nickname into the server or the channel locations - * Notice: the caller must take care to update all channels the users joined (use stored channel list into metadata) - * @param $chan if NULL then create the user on the server (connect), otherwise create the user on the given channel (join) - * @param $nick the nickname to create - * @param $nickid is the corresponding nickname id (taken from session) - */ - function createNick($chan, $nick, $nickid) - { - $c =& $this->c; - - if ($chan == NULL) $chan = 'SERVER'; - - $this->setMeta2("nickid-to-metadata", $nickid, 'nick', $nick); - $this->setMeta2("metadata-to-nickid", 'nick', $this->_encode($nick), $nickid); - - $this->setMeta2("nickid-to-channelid", $nickid, $this->_encode($chan)); - $this->setMeta2("channelid-to-nickid", $this->_encode($chan), $nickid); - - // update the SERVER channel - if ($chan != 'SERVER') $this->updateNick($nickid); - - return true; - } - - /** - * Remove (disconnect/quit) the nickname from the server or from a channel - * Notice: The caller must take care to update all joined channels. - * @param $chan if NULL then remove the user on the server (disconnect), otherwise just remove the user from the given channel (quit) - * @param $nick the nickname to remove - * @return true if the nickname was correctly removed - */ - function removeNick($chan, $nickid) - { - if ($chan == NULL) $chan = 'SERVER'; - - $timestamp = $this->getMeta2("channelid-to-nickid", $this->_encode('SERVER'), $nickid); - $timestamp = $timestamp["timestamp"][0]; - - $deleted_user = array(); - $deleted_user["nick"][] = $this->getNickname($nickid); - $deleted_user["nickid"][] = $nickid; - $deleted_user["timestamp"][] = $timestamp; - - // remove the nickid from the channel list - $this->rmMeta2('channelid-to-nickid', $this->_encode($chan), $nickid); - $this->rmMeta2('nickid-to-channelid', $nickid, $this->_encode($chan)); - - // get the current user's channels list - $channels = $this->getMeta2("nickid-to-channelid",$nickid); - $channels = $channels["value"]; - // no more joined channel, just remove the user's metadata - if (count($channels) == 0) - { - // remove the nickname to nickid correspondance - $this->rmMeta2('metadata-to-nickid', 'nick', $this->_encode($this->getNickname($nickid))); - // remove disconnected nickname metadata - $this->rmMeta2('nickid-to-metadata', $nickid); - } - - return $deleted_user; - } - - /** - * Store/update the alive user status somewhere - * The default File container will just touch (update the date) the nickname file. - * @param $chan where to update the nick, if null then update the server nick - * @param $nick nickname to update (raw nickname) - */ - function updateNick($nickid) - { - $c =& $this->c; - - $chan = 'SERVER'; - - $this->setMeta2("nickid-to-channelid", $nickid, $this->_encode($chan)); - $this->setMeta2("channelid-to-nickid", $this->_encode($chan), $nickid); - return true; - } - - /** - * Change the user' nickname - * Notice: the caller will just call this function one time, this function must take care to update if necessary all channels the user joined - * @param $newnick - * @param $oldnick - * @return true on success, false on failure - */ - function changeNick($newnick, $oldnick) - { - $c =& $this->c; - - $oldnickid = $this->getNickId($oldnick); - $newnickid = $this->getNickId($newnick); - if ($oldnickid == "") return false; // the oldnick must be connected - if ($newnickid != "") return false; // the newnick must not be inuse - - // remove the oldnick to oldnickid correspondance - $this->rmMeta2("metadata-to-nickid", 'nick', $this->_encode($oldnick)); - - // update the nickname - $this->setMeta2("nickid-to-metadata", $oldnickid, 'nick', $newnick); - $this->setMeta2("metadata-to-nickid", 'nick', $this->_encode($newnick), $oldnickid); - return true; - } - - /** - * Returns the nickid corresponding to the given nickname - * The nickid is a unique id used to identify a user (generated from the browser sessionid) - * @param $nick - * @return string the nick id - */ - function getNickId($nick) - { - $nickid = $this->getMeta2("metadata-to-nickid", 'nick', $this->_encode($nick), true); - $nickid = isset($nickid["value"][0]) ? $nickid["value"][0] : ""; - return $nickid; - } - - /** - * Returns the nickname corresponding the the given nickid - * @param $nickid - * @return string the corresponding nickname - */ - function getNickname($nickid) - { - $nick = $this->getMeta2("nickid-to-metadata", $nickid, 'nick', true); - $nick = isset($nick["value"][0]) ? $this->_decode($nick["value"][0]) : ""; - return $nick; - } - /** - * Remove (disconnect/quit) the timeouted nickname from the server or from a channel - * Notice: this function must remove all nicknames which are not uptodate from the given channel or from the server - * @param $chan if NULL then check obsolete nick on the server, otherwise just check obsolete nick on the given channel - * @param $timeout - * @return array("nickid"=>array("nickid1", ...),"timestamp"=>array(timestamp1, ...)) contains all disconnected nickids and there timestamp - */ - function removeObsoleteNick($timeout) - { - $c =& $this->c; - - $chan = 'SERVER'; - - $deleted_user = array('nick'=>array(), - 'nickid'=>array(), - 'timestamp'=>array(), - 'channels'=>array()); - $ret = $this->getMeta2("channelid-to-nickid", $this->_encode($chan)); - for($i = 0; $i ($timestamp+$timeout/1000) ) // user will be disconnected after 'timeout' secondes of inactivity - { - // get the current user's channels list - $channels = array(); - $ret2 = $this->getMeta2("nickid-to-channelid",$nickid); - foreach($ret2["value"] as $userchan) - { - // disconnect the user from each joined channels - $du = $this->removeNick($this->_decode($userchan), $nickid); - $channels[] = $this->_decode($userchan); - } - $deleted_user["nick"] = array_merge($deleted_user["nick"], $du["nick"]); - $deleted_user["nickid"] = array_merge($deleted_user["nickid"], $du["nickid"]); - $deleted_user["timestamp"] = array_merge($deleted_user["timestamp"], $du["timestamp"]); - $deleted_user["channels"] = array_merge($deleted_user["channels"], array($channels)); - } - } - - return $deleted_user; - } - - /** - * Returns the nickname list on the given channel or on the whole server - * @param $chan if NULL then returns all connected user, otherwise just returns the channel nicknames - * @return array("nickid"=>array("nickid1", ...),"timestamp"=>array(timestamp1, ...)) contains the nickid list with the associated timestamp (laste update time) - */ - function getOnlineNick($chan) - { - $c =& $this->c; - - if ($chan == NULL) $chan = 'SERVER'; - - $online_user = array(); - $ret = $this->getMeta2("channelid-to-nickid", $this->_encode($chan)); - for($i = 0; $igetMeta2("channelid-to-nickid", $this->_encode('SERVER'), $nickid); - $timestamp = $timestamp['timestamp'][0]; - - $online_user["nick"][] = $this->getNickname($nickid); - $online_user["nickid"][] = $nickid; - $online_user["timestamp"][] = $timestamp; - } - return $online_user; - } - - /** - * Returns returns a positive number if the nick is online - * @param $chan if NULL then check if the user is online on the server, otherwise check if the user has joined the channel - * @return -1 if the user is off line, a positive (>=0) if the user is online - */ - function isNickOnline($chan, $nickid) - { - if ($chan == NULL) $chan = 'SERVER'; - - $ret = $this->getMeta2("channelid-to-nickid", $this->_encode($chan)); - for($i = 0; $ic; - if ($chan == NULL) $chan = 'SERVER'; - - $msgid = $this->_requestMsgId($chan); - - // format message - $data = "\n"; - $data .= $msgid."\t"; - $data .= date("d/m/Y")."\t"; - $data .= date("H:i:s")."\t"; - $data .= $nick."\t"; - $data .= $cmd."\t"; - $data .= $param; - - // write message - $this->setMeta2("channelid-to-msg", $this->_encode($chan), $msgid, $data); - - // delete the obsolete message - $old_msgid = $msgid - $c->max_msg - 20; - if ($old_msgid > 0) - $this->rmMeta2("channelid-to-msg", $this->_encode($chan), $old_msgid); - - return $msgid; - } - - /** - * Read the last posted commands from a channel or from the server - * Notice: the returned array must be ordered by id - * @param $chan if NULL then read from the server, otherwise read from the given channel - * @param $from_id read all message with a greater id - * @return array() contains the command list - */ - function read($chan, $from_id) - { - $c =& $this->c; - if ($chan == NULL) $chan = 'SERVER'; - - // read new messages id - $new_msgid_list = array(); - $new_from_id = $from_id; - $msgid_list = $this->getMeta2("channelid-to-msg", $this->_encode($chan)); - for($i = 0; $i $from_id) - { - if ($msgidtmp > $new_from_id) $new_from_id = $msgidtmp; - $new_msgid_list[] = $msgidtmp; - } - } - - // read messages content and parse content - $datalist = array(); - foreach ( $new_msgid_list as $mid ) - { - $line = $this->getMeta2("channelid-to-msg", $this->_encode($chan), $mid, true); - $line = $line["value"][0]; - if ($line != "" && $line != "\n") - { - $formated_line = explode( "\t", $line ); - $data = array(); - $data["id"] = trim($formated_line[0]); - $data["date"] = $formated_line[1]; - $data["time"] = $formated_line[2]; - $data["sender"]= $formated_line[3]; - $data["cmd"] = $formated_line[4]; - $data["param"] = $formated_line[5]; - $datalist[$data["id"]] = $data; - } - } - ksort($datalist); - - return array("data" => $datalist, - "new_from_id" => $new_from_id ); - } - - /** - * Returns the last message id - * Notice: the default file container just returns the messages.index file content - * @param $chan if NULL then read if from the server, otherwise read if from the given channel - * @return int is the last posted message id - */ - function getLastId($chan) - { - if ($chan == NULL) $chan = 'SERVER'; - - $lastmsgid = $this->getMeta2("channelid-to-msgid", $this->_encode($chan), 'lastmsgid', true); - if (count($lastmsgid["value"]) == 0) - $lastmsgid = 0; - else - $lastmsgid = $lastmsgid["value"][0]; - return $lastmsgid; - } - - - /** - * Remove all created data for this server (identified by serverid) - * Notice: for the default File container, it's just a recursive directory remove - */ - function clear() - { - $c =& $this->c; - // remove the created files and directories - $dir = $c->container_cfg_server_dir; - @rm_r($dir); - // empty the cache - // $this->_meta = array(); - // $this->_users = array("nickid" => array(), - // "timestamp" => array()); - } - - - /** - * Return a unique id. Each time this function is called, the last id is incremented. - * used internaly - * @private - */ - function _requestMsgId($chan) - { - if ($chan == NULL) $chan = 'SERVER'; - - $lastmsgid = $this->getLastId($chan); - $lastmsgid++; - $this->setMeta2("channelid-to-msgid", $this->_encode($chan), 'lastmsgid', $lastmsgid); - - return $lastmsgid; - } - - /** - * Used to encode UTF8 strings to ASCII filenames - * @private - */ - function _encode($str) - { - return urlencode($str); - return base64_encode(urlencode($str)); - } - - /** - * Used to decode ASCII filenames to UTF8 strings - * @private - */ - function _decode($str) - { - return urldecode($str); - return urldecode(base64_decode($str)); - } - - - - - - - - - - - - - - /** - * Write a meta data value identified by a group / subgroup / leaf [with a value] - * @return 1 if the leaf allready existed, 0 if the leaf has been created - */ - function setMeta2($group, $subgroup, $leaf, $leafvalue = NULL) - // value, $key, $type, $subtype = NULL) + function setMeta($group, $subgroup, $leaf, $leafvalue = NULL) { // create directories $c =& $this->c; - $dir_base = $c->container_cfg_meta_dir; + $dir_base = $c->container_cfg_server_dir; $dir = $dir_base.'/'.$group.'/'.$subgroup; if (!is_dir($dir)) mkdir_r($dir); @@ -509,18 +105,14 @@ function setMeta2($group, $subgroup, $leaf, $leafvalue = NULL) } - /** - * Read meta data identified by a group [/ subgroup [/ leaf]] - * @return ... - */ - function getMeta2($group, $subgroup = null, $leaf = null, $withleafvalue = false) + function getMeta($group, $subgroup = null, $leaf = null, $withleafvalue = false) { // read data from metadata file $ret = array(); $ret["timestamp"] = array(); $ret["value"] = array(); $c =& $this->c; - $dir_base = $c->container_cfg_meta_dir; + $dir_base = $c->container_cfg_server_dir; $dir = $dir_base.'/'.$group; @@ -568,23 +160,18 @@ function getMeta2($group, $subgroup = null, $leaf = null, $withleafvalue = false return $ret; } - - /** - * Remove a meta data - * @return ... - */ - function rmMeta2($group, $subgroup = null, $leaf = null) - //($key, $type, $subtype = NULL) + function rmMeta($group, $subgroup = null, $leaf = null) { $c =& $this->c; + $dir = $c->container_cfg_server_dir; + if ($group == NULL) + { + rm_r($dir); + return true; + } - - // read data from metadata file - $c =& $this->c; - $dir_base = $c->container_cfg_meta_dir; - - $dir = $dir_base.'/'.$group; + $dir .= '/'.$group; if ($subgroup == NULL) { @@ -600,7 +187,7 @@ function rmMeta2($group, $subgroup = null, $leaf = null) return true; } - $leaffilename = $dir."/".$leaf; + $leaffilename = $dir.'/'.$leaf; if (!file_exists($leaffilename)) return false; unlink($leaffilename); @@ -608,28 +195,20 @@ function rmMeta2($group, $subgroup = null, $leaf = null) } - function getUserMeta($nickid, $key) - { - $ret = $this->getMeta2("nickid-to-metadata", $nickid, $key, true); - return isset($ret['value'][0]) ? $ret['value'][0] : NULL; - } - - function setUserMeta($nickid, $key, $value) - { - $ret = $this->setMeta2("nickid-to-metadata", $nickid, $key, $value); - return $ret; - } - - function getChanMeta($chan, $key) + /** + * Used to encode UTF8 strings to ASCII filenames + */ + function encode($str) { - $ret = $this->getMeta2("channelid-to-metadata", $this->_encode($chan), $key, true); - return isset($ret['value'][0]) ? $ret['value'][0] : NULL; + return urlencode($str); } - - function setChanMeta($chan, $key, $value) + + /** + * Used to decode ASCII filenames to UTF8 strings + */ + function decode($str) { - $ret = $this->setMeta2("channelid-to-metadata", $this->_encode($chan), $key, $value); - return $ret; + return urldecode($str); } } diff --git a/src/pfccontainer.class.php b/src/pfccontainer.class.php index b4b5a2cb..f5ce7bae 100644 --- a/src/pfccontainer.class.php +++ b/src/pfccontainer.class.php @@ -41,73 +41,217 @@ function init() { return array(); } * @param $nick the nickname to create * @param $nickid is the corresponding nickname id (taken from session) */ - function createNick($chan, $nickname, $nickid) - { die(_pfc("%s must be implemented", get_class($this)."::".__FUNCTION__)); } + function createNick($chan, $nick, $nickid) + { + $c =& $this->c; + + if ($chan == NULL) $chan = 'SERVER'; + + $this->setMeta("nickid-to-metadata", $nickid, 'nick', $nick); + $this->setMeta("metadata-to-nickid", 'nick', $this->encode($nick), $nickid); + + $this->setMeta("nickid-to-channelid", $nickid, $this->encode($chan)); + $this->setMeta("channelid-to-nickid", $this->encode($chan), $nickid); + + // update the SERVER channel + if ($chan != 'SERVER') $this->updateNick($nickid); + + return true; + } /** * Remove (disconnect/quit) the nickname from the server or from a channel - * Notice: The caller must take care to update all joined channels. - * @param $chan if NULL then remove the user on the server (disconnect), otherwise just remove the user from the given channel (quit) - * @param $nick the nickname to remove - * @return true if the nickname was correctly removed + * Notice: when a user quit, the caller must take care removeNick from each channels ('SERVER' included) + * This function takes care to remove all users metadata when he his disconnected from all channels + * @param $chan if NULL then remove the user from the 'SERVER' channel, otherwise just remove the user from the given channel (quit) + * @param $nickid the nickname id to remove + * @return array which contains removed user infos ('nickid', 'nick', 'timestamp') */ - function removeNick($chan, $nickname) - { die(_pfc("%s must be implemented", get_class($this)."::".__FUNCTION__)); } + function removeNick($chan, $nickid) + { + if ($chan == NULL) $chan = 'SERVER'; + + $timestamp = $this->getMeta("channelid-to-nickid", $this->encode('SERVER'), $nickid); + $timestamp = $timestamp["timestamp"][0]; + + $deleted_user = array(); + $deleted_user["nick"][] = $this->getNickname($nickid); + $deleted_user["nickid"][] = $nickid; + $deleted_user["timestamp"][] = $timestamp; + + // remove the nickid from the channel list + $this->rmMeta('channelid-to-nickid', $this->encode($chan), $nickid); + $this->rmMeta('nickid-to-channelid', $nickid, $this->encode($chan)); + + // get the current user's channels list + $channels = $this->getMeta("nickid-to-channelid",$nickid); + $channels = $channels["value"]; + // no more joined channel, just remove the user's metadata + if (count($channels) == 0) + { + // remove the nickname to nickid correspondance + $this->rmMeta('metadata-to-nickid', 'nick', $this->encode($this->getNickname($nickid))); + // remove disconnected nickname metadata + $this->rmMeta('nickid-to-metadata', $nickid); + } + + return $deleted_user; + } /** - * Store/update the alive user status somewhere - * The default File container will just touch (update the date) the nickname file. - * @param $chan where to update the nick, if null then update the server nick - * @param $nick nickname to update (raw nickname) + * Store/update the alive user status on the 'SERVER' channel + * The default File container will just touch (update the date) of the nickname file in the 'SERVER' channel. + * @param $nickid the nickname id to keep alive */ - function updateNick($chan, $nick) - { die(_pfc("%s must be implemented", get_class($this)."::".__FUNCTION__)); } + function updateNick($nickid) + { + $c =& $this->c; + + $chan = 'SERVER'; + $this->setMeta("nickid-to-channelid", $nickid, $this->encode($chan)); + $this->setMeta("channelid-to-nickid", $this->encode($chan), $nickid); + return true; + } /** - * Change the user' nickname - * Notice: this call must take care to update all channels the user joined - * @param $chan where to update the nick, if null then update the server nick + * Change the user's nickname + * As nickname value are stored in user's metadata, this function just update the 'nick' metadata * @param $newnick * @param $oldnick + * @return true on success, false on failure (if the oldnick doesn't exists) */ function changeNick($newnick, $oldnick) - { die(_pfc("%s must be implemented", get_class($this)."::".__FUNCTION__)); } - + { + $c =& $this->c; + + $oldnickid = $this->getNickId($oldnick); + $newnickid = $this->getNickId($newnick); + if ($oldnickid == "") return false; // the oldnick must be connected + if ($newnickid != "") return false; // the newnick must not be inuse + + // remove the oldnick to oldnickid correspondance + $this->rmMeta("metadata-to-nickid", 'nick', $this->encode($oldnick)); + + // update the nickname + $this->setMeta("nickid-to-metadata", $oldnickid, 'nick', $newnick); + $this->setMeta("metadata-to-nickid", 'nick', $this->encode($newnick), $oldnickid); + return true; + } + /** - * Returns the nickid, this is a unique id used to identify a user (taken from session) - * By default this nickid is just stored into the user' metadata, same as :->getNickMeta("nickid") + * Returns the nickid corresponding to the given nickname + * The nickid is a unique id used to identify a user (generated from the browser sessionid) + * The nickid is stored in the container when createNick is called. * @param $nick * @return string the nick id */ - function getNickId($nickname) - { die(_pfc("%s must be implemented", get_class($this)."::".__FUNCTION__)); } + function getNickId($nick) + { + $nickid = $this->getMeta("metadata-to-nickid", 'nick', $this->encode($nick), true); + $nickid = isset($nickid["value"][0]) ? $nickid["value"][0] : ""; + return $nickid; + } + + /** + * Returns the nickname corresponding the the given nickid + * @param $nickid + * @return string the corresponding nickname + */ + function getNickname($nickid) + { + $nick = $this->getMeta("nickid-to-metadata", $nickid, 'nick', true); + $nick = isset($nick["value"][0]) ? $this->decode($nick["value"][0]) : ""; + return $nick; + } /** * Remove (disconnect/quit) the timeouted nickname from the server or from a channel * Notice: this function must remove all nicknames which are not uptodate from the given channel or from the server * @param $chan if NULL then check obsolete nick on the server, otherwise just check obsolete nick on the given channel * @param $timeout - * @return array("nick"=>???, "timestamp"=>???) contains all disconnected nicknames and there timestamp + * @return array("nickid"=>array("nickid1", ...),"timestamp"=>array(timestamp1, ...)) contains all disconnected nickids and there timestamp */ - function removeObsoleteNick($chan, $timeout) - { die(_pfc("%s must be implemented", get_class($this)."::".__FUNCTION__)); } + function removeObsoleteNick($timeout) + { + $c =& $this->c; + + $chan = 'SERVER'; + + $deleted_user = array('nick'=>array(), + 'nickid'=>array(), + 'timestamp'=>array(), + 'channels'=>array()); + $ret = $this->getMeta("channelid-to-nickid", $this->encode($chan)); + for($i = 0; $i ($timestamp+$timeout/1000) ) // user will be disconnected after 'timeout' secondes of inactivity + { + // get the current user's channels list + $channels = array(); + $ret2 = $this->getMeta("nickid-to-channelid",$nickid); + foreach($ret2["value"] as $userchan) + { + // disconnect the user from each joined channels + $du = $this->removeNick($this->decode($userchan), $nickid); + $channels[] = $this->decode($userchan); + } + $deleted_user["nick"] = array_merge($deleted_user["nick"], $du["nick"]); + $deleted_user["nickid"] = array_merge($deleted_user["nickid"], $du["nickid"]); + $deleted_user["timestamp"] = array_merge($deleted_user["timestamp"], $du["timestamp"]); + $deleted_user["channels"] = array_merge($deleted_user["channels"], array($channels)); + } + } + + return $deleted_user; + } /** * Returns the nickname list on the given channel or on the whole server * @param $chan if NULL then returns all connected user, otherwise just returns the channel nicknames - * @return array(array("nick"=>???,"timestamp"=>???) contains the nickname list with the associated timestamp (laste update time) - */ + * @return array("nickid"=>array("nickid1", ...),"timestamp"=>array(timestamp1, ...)) contains the nickid list with the associated timestamp (laste update time) + */ function getOnlineNick($chan) - { die(_pfc("%s must be implemented", get_class($this)."::".__FUNCTION__)); } + { + $c =& $this->c; + + if ($chan == NULL) $chan = 'SERVER'; + + $online_user = array(); + $ret = $this->getMeta("channelid-to-nickid", $this->encode($chan)); + for($i = 0; $igetMeta("channelid-to-nickid", $this->encode('SERVER'), $nickid); + $timestamp = $timestamp['timestamp'][0]; + + $online_user["nick"][] = $this->getNickname($nickid); + $online_user["nickid"][] = $nickid; + $online_user["timestamp"][] = $timestamp; + } + return $online_user; + } + /** * Returns returns a positive number if the nick is online * @param $chan if NULL then check if the user is online on the server, otherwise check if the user has joined the channel * @return -1 if the user is off line, a positive (>=0) if the user is online */ - function isNickOnline($chan, $nick) - { die(_pfc("%s must be implemented", get_class($this)."::".__FUNCTION__)); } + function isNickOnline($chan, $nickid) + { + if ($chan == NULL) $chan = 'SERVER'; + + $ret = $this->getMeta("channelid-to-nickid", $this->encode($chan)); + for($i = 0; $ic; + if ($chan == NULL) $chan = 'SERVER'; + + $msgid = $this->_requestMsgId($chan); + + // format message + $data = "\n"; + $data .= $msgid."\t"; + $data .= date("d/m/Y")."\t"; + $data .= date("H:i:s")."\t"; + $data .= $nick."\t"; + $data .= $cmd."\t"; + $data .= $param; + + // write message + $this->setMeta("channelid-to-msg", $this->encode($chan), $msgid, $data); + + // delete the obsolete message + $old_msgid = $msgid - $c->max_msg - 20; + if ($old_msgid > 0) + $this->rmMeta("channelid-to-msg", $this->encode($chan), $old_msgid); + + return $msgid; + } /** * Read the last posted commands from a channel or from the server - * Notice: the returned array must be ordered by id + * Notice: the returned array is ordered by id * @param $chan if NULL then read from the server, otherwise read from the given channel * @param $from_id read all message with a greater id - * @return array() contains the command list + * @return array() contains the formated command list */ function read($chan, $from_id) - { die(_pfc("%s must be implemented", get_class($this)."::".__FUNCTION__)); } + { + $c =& $this->c; + if ($chan == NULL) $chan = 'SERVER'; + + // read new messages id + $new_msgid_list = array(); + $new_from_id = $from_id; + $msgid_list = $this->getMeta("channelid-to-msg", $this->encode($chan)); + for($i = 0; $i $from_id) + { + if ($msgidtmp > $new_from_id) $new_from_id = $msgidtmp; + $new_msgid_list[] = $msgidtmp; + } + } + + // read messages content and parse content + $datalist = array(); + foreach ( $new_msgid_list as $mid ) + { + $line = $this->getMeta("channelid-to-msg", $this->encode($chan), $mid, true); + $line = $line["value"][0]; + if ($line != "" && $line != "\n") + { + $formated_line = explode( "\t", $line ); + $data = array(); + $data["id"] = trim($formated_line[0]); + $data["date"] = $formated_line[1]; + $data["time"] = $formated_line[2]; + $data["sender"]= $formated_line[3]; + $data["cmd"] = $formated_line[4]; + $data["param"] = $formated_line[5]; + $datalist[$data["id"]] = $data; + } + } + ksort($datalist); + + return array("data" => $datalist, + "new_from_id" => $new_from_id ); + } /** * Returns the last message id @@ -138,48 +348,127 @@ function read($chan, $from_id) * @return int is the last posted message id */ function getLastId($chan) - { die(_pfc("%s must be implemented", get_class($this)."::".__FUNCTION__)); } + { + if ($chan == NULL) $chan = 'SERVER'; + + $lastmsgid = $this->getMeta("channelid-to-msgid", $this->encode($chan), 'lastmsgid', true); + if (count($lastmsgid["value"]) == 0) + $lastmsgid = 0; + else + $lastmsgid = $lastmsgid["value"][0]; + return $lastmsgid; + } + + + /** + * Return a unique id. Each time this function is called, the last id is incremented. + * used internaly + * @private + */ + function _requestMsgId($chan) + { + if ($chan == NULL) $chan = 'SERVER'; + + $lastmsgid = $this->getLastId($chan); + $lastmsgid++; + $this->setMeta("channelid-to-msgid", $this->encode($chan), 'lastmsgid', $lastmsgid); + + return $lastmsgid; + } + /** - * Read meta data identified by a key - * As an example the default file container store metadata into metadata/type/subtype/hash(key) - * @param $key is the index which identify a metadata - * @param $type is used to "group" some metadata - * @param $subtype is used to "group" precisely some metadata, use NULL to ignore it - * @return mixed the value assigned to the key, NULL if not found + * Remove all created data for this server (identified by serverid) + * Notice: for the default File container, it's just a recursive directory remove */ - function getMeta($key, $type, $subtype = NULL) - { die(_pfc("%s must be implemented", get_class($this)."::".__FUNCTION__)); } + function clear() + { + $this->rmMeta(NULL); + } /** - * Write a meta data value identified by a key - * As an example the default file container store metadata into metadata/type/subtype/hash(key) - * @param $key is the index which identify a metadata - * @param $value is the value associated to the key - * @param $type is used to "group" some metadata - * @param $subtype is used to "group" precisely some metadata, use NULL to ignore it - * @return true on success, false on error + * In the default File container: used to encode UTF8 strings to ASCII filenames + * This method can be overridden by the concrete container + */ + function encode($str) + { + return $str; + } + + /** + * In the default File container: used to decode ASCII filenames to UTF8 strings + * This method can be overridden by the concrete container + */ + function decode($str) + { + return $str; + } + + + function getUserMeta($nickid, $key) + { + $ret = $this->getMeta("nickid-to-metadata", $nickid, $key, true); + return isset($ret['value'][0]) ? $ret['value'][0] : NULL; + } + + function setUserMeta($nickid, $key, $value) + { + $ret = $this->setMeta("nickid-to-metadata", $nickid, $key, $value); + return $ret; + } + + function getChanMeta($chan, $key) + { + $ret = $this->getMeta("channelid-to-metadata", $this->encode($chan), $key, true); + return isset($ret['value'][0]) ? $ret['value'][0] : NULL; + } + + function setChanMeta($chan, $key, $value) + { + $ret = $this->setMeta("channelid-to-metadata", $this->encode($chan), $key, $value); + return $ret; + } + + /** + * Write a meta data value identified by a group / subgroup / leaf [with a value] + * As an example in the default file container this arborescent structure is modelised by simple directories + * group1/subgroup1/leaf1 + * /leaf2 + * /subgroup2/... + * Each leaf can contain or not a value. + * However each leaf and each group/subgroup must store the lastmodified time (timestamp). + * @param $group root arborescent element + * @param $subgroup is the root first child which contains leafs + * @param $leaf is the only element which can contain values + * @param $leafvalue NULL means the leaf will not contain any values + * @return 1 if the old leaf has been overwritten, 0 if a new leaf has been created */ - function setMeta($value, $key, $type, $subtype = NULL) + function setMeta($group, $subgroup, $leaf, $leafvalue = NULL) { die(_pfc("%s must be implemented", get_class($this)."::".__FUNCTION__)); } + /** - * Remove a meta data key/value couple - * Notice: if key is NULL then all the meta data must be removed - * @param $key is the key to delete, use NULL to delete all the metadata - * @param $type is used to "group" some metadata - * @param $subtype is used to "group" precisely some metadata, use NULL to ignore it - * @return true on success, false on error + * Read meta data identified by a group [/ subgroup [/ leaf]] + * @param $group is mandatory, it's the arborescence's root + * @param $subgroup if null then the subgroup list names are returned + * @param $leaf if null then the leaf names are returned + * @param $withleafvalue if set to true the leaf value will be returned + * @return array which contains two subarray 'timestamp' and 'value' */ - function rmMeta($key, $type, $subtype = NULL) + function getMeta($group, $subgroup = null, $leaf = null, $withleafvalue = false) { die(_pfc("%s must be implemented", get_class($this)."::".__FUNCTION__)); } + /** - * Remove all created data for this server (identified by serverid) - * Notice: for the default File container, it's just a recursive directory remove + * Remove a meta data or a group of metadata + * @param $group if null then it will remove all the possible groups (all the created metadata) + * @param $subgroup if null then it will remove the $group's childs (all the subgroup contained by $group) + * @param $leaf if null then it will remove all the $subgroup's childs (all the leafs contained by $subgroup) + * @return true on success, false on error */ - function clear() + function rmMeta($group, $subgroup = null, $leaf = null) { die(_pfc("%s must be implemented", get_class($this)."::".__FUNCTION__)); } + } -?> +?> \ No newline at end of file diff --git a/testcase/container_file.php b/testcase/container_file.php index 320511aa..68643e02 100644 --- a/testcase/container_file.php +++ b/testcase/container_file.php @@ -36,10 +36,10 @@ function test_setMeta_File_1() $group = $prefix."_nickid-to-channelid"; $subgroup = $prefix."_nickid1"; $leaf = $prefix."_channelid1"; - $ret = $ct->setMeta2($group, $subgroup, $leaf); + $ret = $ct->setMeta($group, $subgroup, $leaf); $this->assertEquals($ret, 0, "the leaf should be first time created"); - $f = $c->container_cfg_meta_dir.'/'.$group.'/'.$subgroup.'/'.$leaf; + $f = $c->container_cfg_server_dir.'/'.$group.'/'.$subgroup.'/'.$leaf; $ret = file_exists($f); $this->assertEquals($ret, true, "the leaf file should exists"); @@ -57,10 +57,10 @@ function test_setMeta_File_2() $subgroup = $prefix."_nickid1"; $leaf = $prefix."_channelid1"; $leafvalue = $prefix."_leafvalue1"; - $ret = $ct->setMeta2($group, $subgroup, $leaf, $leafvalue); + $ret = $ct->setMeta($group, $subgroup, $leaf, $leafvalue); $this->assertEquals($ret, 0, "the leaf should be first time created"); - $f = $c->container_cfg_meta_dir.'/'.$group.'/'.$subgroup.'/'.$leaf; + $f = $c->container_cfg_server_dir.'/'.$group.'/'.$subgroup.'/'.$leaf; $ret = file_exists($f); $this->assertEquals($ret, true, "the leaf file should exists"); @@ -79,14 +79,14 @@ function test_setMeta_File_3() $leaf = $prefix."_channelid1"; $leafvalue = $prefix."_leafvalue1"; - $ret = $ct->setMeta2($group, $subgroup, $leaf, $leafvalue); + $ret = $ct->setMeta($group, $subgroup, $leaf, $leafvalue); $this->assertEquals($ret, 0, "the leaf should be first time created"); $leafvalue = null; - $ret = $ct->setMeta2($group, $subgroup, $leaf, $leafvalue); + $ret = $ct->setMeta($group, $subgroup, $leaf, $leafvalue); $this->assertEquals($ret, 1, "the leaf should be overwritten"); - $f = $c->container_cfg_meta_dir.'/'.$group.'/'.$subgroup.'/'.$leaf; + $f = $c->container_cfg_server_dir.'/'.$group.'/'.$subgroup.'/'.$leaf; $ret = file_exists($f); $this->assertEquals($ret, true, "the leaf file should exists"); @@ -95,87 +95,6 @@ function test_setMeta_File_3() } - function test_getMeta_File_1() - { - $c =& $this->c; - $ct =& $this->ct; - - $prefix = __FUNCTION__; - $group = $prefix."_nickid-to-channelid"; - $subgroup = $prefix."_nickid1"; - $leaf = $prefix."_channelid1"; - $ct->setMeta2($group, $subgroup, $leaf); - $time = time(); - - $ret = $ct->getMeta2($group, $subgroup, $leaf); - $this->assertEquals(count($ret["timestamp"]), 1, "number of leaf is wrong"); - $this->assertEquals($ret["timestamp"][0], $time, "the leaf timestamp is wrong"); - $this->assertEquals($ret["value"][0], null, "the leaf value is wrong"); - - $ret = $ct->getMeta2($group, $subgroup); - $this->assertEquals(count($ret["timestamp"]), 1, "number of leaf is wrong"); - $this->assertEquals($ret["timestamp"][0], $time, "the leaf timestamp is wrong"); - $this->assertEquals($ret["value"][0], $leaf, "the leaf name is wrong"); - - $leafvalue = $prefix."_leafvalue"; - $ct->setMeta2($group, $subgroup, $leaf, $leafvalue); - $time = time(); - - $ret = $ct->getMeta2($group, $subgroup, $leaf, true); - $this->assertEquals(count($ret["timestamp"]), 1, "number of leaf is wrong"); - $this->assertEquals($ret["timestamp"][0], $time, "the leaf timestamp is wrong"); - $this->assertEquals($ret["value"][0], $leafvalue, "the leaf value is wrong"); - } - - function test_getMeta_File_2() - { - $c =& $this->c; - $ct =& $this->ct; - - $prefix = __FUNCTION__; - $group = $prefix."_nickid-to-channelid"; - $subgroup = $prefix."_nickid1"; - $leaf1 = $prefix."_channelid1"; - $leaf2 = $prefix."_channelid2"; - $ct->setMeta2($group, $subgroup, $leaf1); - $ct->setMeta2($group, $subgroup, $leaf2); - $time = time(); - - $ret = $ct->getMeta2($group, $subgroup); - asort($ret["value"]); - $this->assertEquals(count($ret["timestamp"]), 2, "number of leaf is wrong"); - $this->assertEquals($ret["timestamp"][0], $time, "the leaf timestamp is wrong"); - $this->assertEquals($ret["timestamp"][1], $time, "the leaf timestamp is wrong"); - $this->assertEquals($ret["value"][0], $leaf1, "the leaf name is wrong"); - $this->assertEquals($ret["value"][1], $leaf2, "the leaf name is wrong"); - } - - function test_getMeta_File_3() - { - $c =& $this->c; - $ct =& $this->ct; - - $prefix = __FUNCTION__; - $group = $prefix."_nickid-to-channelid"; - $subgroup1 = $prefix."_nickid1"; - $subgroup2 = $prefix."_nickid2"; - $leaf1 = $prefix."_channelid1"; - $leaf2 = $prefix."_channelid2"; - $ct->setMeta2($group, $subgroup1, $leaf1); - $ct->setMeta2($group, $subgroup1, $leaf2); - $ct->setMeta2($group, $subgroup2, $leaf1); - $ct->setMeta2($group, $subgroup2, $leaf2); - $time = time(); - - $ret = $ct->getMeta2($group); - asort($ret["value"]); - $this->assertEquals(count($ret["timestamp"]), 2, "number of subgroup is wrong"); - $this->assertEquals($ret["timestamp"][0], $time, "the subgroup timestamp is wrong"); - $this->assertEquals($ret["timestamp"][1], $time, "the subgroup timestamp is wrong"); - $this->assertEquals($ret["value"][0], $subgroup1, "the subgroup name is wrong"); - $this->assertEquals($ret["value"][1], $subgroup2, "the subgroup name is wrong"); - } - function test_rmMeta_File_1() { $c =& $this->c; @@ -185,12 +104,12 @@ function test_rmMeta_File_1() $group = $prefix."_nickid-to-channelid"; $subgroup = $prefix."_nickid1"; $leaf = $prefix."_channelid1"; - $ret = $ct->setMeta2($group, $subgroup, $leaf); + $ret = $ct->setMeta($group, $subgroup, $leaf); - $ret = $ct->rmMeta2($group, $subgroup, $leaf); + $ret = $ct->rmMeta($group, $subgroup, $leaf); $this->assertEquals($ret, true, "the returned value should be true (rm success)"); - $f = $c->container_cfg_meta_dir.'/'.$group.'/'.$subgroup.'/'.$leaf; + $f = $c->container_cfg_server_dir.'/'.$group.'/'.$subgroup.'/'.$leaf; $ret = file_exists($f); $this->assertEquals($ret, false, "the leaf file should not exists anymore"); } @@ -205,20 +124,20 @@ function test_rmMeta_File_2() $subgroup = $prefix."_nickid1"; $leaf1 = $prefix."_channelid1"; $leaf2 = $prefix."_channelid2"; - $ret = $ct->setMeta2($group, $subgroup, $leaf1); - $ret = $ct->setMeta2($group, $subgroup, $leaf2); + $ret = $ct->setMeta($group, $subgroup, $leaf1); + $ret = $ct->setMeta($group, $subgroup, $leaf2); - $ret = $ct->rmMeta2($group, $subgroup); + $ret = $ct->rmMeta($group, $subgroup); $this->assertEquals($ret, true, "the returned value should be true (rm success)"); - $f = $c->container_cfg_meta_dir.'/'.$group.'/'.$subgroup.'/'.$leaf1; + $f = $c->container_cfg_server_dir.'/'.$group.'/'.$subgroup.'/'.$leaf1; $ret = file_exists($f); $this->assertEquals($ret, false, "the leaf file should not exists anymore"); - $f = $c->container_cfg_meta_dir.'/'.$group.'/'.$subgroup.'/'.$leaf2; + $f = $c->container_cfg_server_dir.'/'.$group.'/'.$subgroup.'/'.$leaf2; $ret = file_exists($f); $this->assertEquals($ret, false, "the leaf file should not exists anymore"); - $d = $c->container_cfg_meta_dir.'/'.$group.'/'.$subgroup; + $d = $c->container_cfg_server_dir.'/'.$group.'/'.$subgroup; $ret = file_exists($f); $this->assertEquals($ret, false, "the subgroup directory should not exists anymore"); } @@ -233,48 +152,27 @@ function test_rmMeta_File_3() $subgroup = $prefix."_nickid1"; $leaf1 = $prefix."_channelid1"; $leaf2 = $prefix."_channelid2"; - $ret = $ct->setMeta2($group, $subgroup, $leaf1); - $ret = $ct->setMeta2($group, $subgroup, $leaf2); + $ret = $ct->setMeta($group, $subgroup, $leaf1); + $ret = $ct->setMeta($group, $subgroup, $leaf2); - $ret = $ct->rmMeta2($group); + $ret = $ct->rmMeta($group); $this->assertEquals($ret, true, "the returned value should be true (rm success)"); - $f = $c->container_cfg_meta_dir.'/'.$group.'/'.$subgroup.'/'.$leaf1; + $f = $c->container_cfg_server_dir.'/'.$group.'/'.$subgroup.'/'.$leaf1; $ret = file_exists($f); $this->assertEquals($ret, false, "the leaf file should not exists anymore"); - $f = $c->container_cfg_meta_dir.'/'.$group.'/'.$subgroup.'/'.$leaf2; + $f = $c->container_cfg_server_dir.'/'.$group.'/'.$subgroup.'/'.$leaf2; $ret = file_exists($f); $this->assertEquals($ret, false, "the leaf file should not exists anymore"); - $d = $c->container_cfg_meta_dir.'/'.$group.'/'.$subgroup; + $d = $c->container_cfg_server_dir.'/'.$group.'/'.$subgroup; $ret = file_exists($d); $this->assertEquals($ret, false, "the subgroup directory should not exists anymore"); - $d = $c->container_cfg_meta_dir.'/'.$group; + $d = $c->container_cfg_server_dir.'/'.$group; $ret = file_exists($d); $this->assertEquals($ret, false, "the group directory should not exists anymore"); } - - - function test_encodedecode_File_1() - { - $c =& $this->c; - $ct =& $this->ct; - - $string = "il était une fois C;h:!?§+ toto=}at是"; - - $prefix = __FUNCTION__; - $group = $prefix."_nickid-to-channelid"; - $subgroup = $prefix."_nickid1"; - $leaf = $prefix."_".$ct->_encode($string); - $leafvalue = $string; - $ct->setMeta2($group, $subgroup, $leaf, $leafvalue); - - $ret = $ct->getMeta2($group, $subgroup); - $this->assertEquals($ret['value'][0], $leaf, "the leaf name is wrong"); - $ret = $ct->getMeta2($group, $subgroup, $leaf, true); - $this->assertEquals($ret['value'][0], $leafvalue, "the leaf value is wrong"); - } } // on desactive le timeout car se script peut mettre bcp de temps a s'executer diff --git a/testcase/container_generic.php b/testcase/container_generic.php index f3c0adc0..4900df52 100644 --- a/testcase/container_generic.php +++ b/testcase/container_generic.php @@ -47,7 +47,7 @@ function tearDown() $this->c->destroyCache(); } - function testCreateNick_Generic() + function test_createNick_Generic() { $c =& $this->c; $ct =& $this->ct; @@ -68,7 +68,7 @@ function testCreateNick_Generic() $this->assertTrue($isonline, "nickname should be online on the server"); } - function testRemoveNick_Generic() + function test_removeNick_Generic() { $c =& $this->c; $ct =& $this->ct; @@ -90,7 +90,7 @@ function testRemoveNick_Generic() $this->assertFalse($isonline, "nickname shouldn't be online on the server"); } - function testGetNickId_Generic() + function test_getNickId_Generic() { $c =& $this->c; $ct =& $this->ct; @@ -104,7 +104,7 @@ function testGetNickId_Generic() $this->assertEquals($nickid, $ret, "created nickname doesn't have a correct nickid"); } - function testGetNickname_Generic() + function test_getNickname_Generic() { $c =& $this->c; $ct =& $this->ct; @@ -120,7 +120,7 @@ function testGetNickname_Generic() $this->assertEquals($nick, $ret, "nickname value is wrong"); } - function testGetOnlineNick_Generic() + function test_getOnlineNick_Generic() { $c =& $this->c; $ct =& $this->ct; @@ -143,7 +143,7 @@ function testGetOnlineNick_Generic() } - function testRemoveObsoleteNick_Generic() + function test_removeObsoleteNick_Generic() { $c =& $this->c; $ct =& $this->ct; @@ -161,7 +161,7 @@ function testRemoveObsoleteNick_Generic() $this->assertFalse($isonline, "nickname shouldn't be online anymore"); } - function testupdateNick_Generic() + function test_updateNick_Generic() { $c =& $this->c; $ct =& $this->ct; @@ -182,7 +182,7 @@ function testupdateNick_Generic() } - function testchangeNick_Generic() + function test_changeNick_Generic() { $c =& $this->c; $ct =& $this->ct; @@ -202,7 +202,7 @@ function testchangeNick_Generic() $this->assertTrue($isonline2, "nickname shouldn't be online"); } - function testgetLastId_Generic() + function test_getLastId_Generic() { $c =& $this->c; $ct =& $this->ct; @@ -224,7 +224,7 @@ function testgetLastId_Generic() $this->assertEquals(10, $msgid, "last msgid is not correct"); } - function testwrite_Generic() + function test_write_Generic() { $c =& $this->c; $ct =& $this->ct; @@ -245,7 +245,7 @@ function testwrite_Generic() $this->assertEquals(1, $res["new_from_id"],"new_from_id is not correct"); } - function testread_Generic() + function test_read_Generic() { $c =& $this->c; $ct =& $this->ct; @@ -276,6 +276,108 @@ function testread_Generic() $this->assertEquals($msg."9", $res["data"][10]["param"] ,"messages data is not the same as the sent one"); $this->assertEquals($res["new_from_id"], 10 ,"new_from_id is not correct"); } + + function test_encodedecode_Generic() + { + $c =& $this->c; + $ct =& $this->ct; + + $string = "il était une fois C;h:!?§+ toto=}at是"; + + $prefix = __FUNCTION__; + $group = $prefix."_nickid-to-channelid"; + $subgroup = $prefix."_nickid1"; + $leaf = $prefix."_".$ct->encode($string); + $leafvalue = $string; + $ct->setMeta($group, $subgroup, $leaf, $leafvalue); + + $ret = $ct->getMeta($group, $subgroup); + $this->assertEquals($ret['value'][0], $leaf, "the leaf name is wrong"); + $ret = $ct->getMeta($group, $subgroup, $leaf, true); + $this->assertEquals($ret['value'][0], $leafvalue, "the leaf value is wrong"); + } + + function test_getMeta_Generic_1() + { + $c =& $this->c; + $ct =& $this->ct; + + $prefix = __FUNCTION__; + $group = $prefix."_nickid-to-channelid"; + $subgroup = $prefix."_nickid1"; + $leaf = $prefix."_channelid1"; + $ct->setMeta($group, $subgroup, $leaf); + $time = time(); + + $ret = $ct->getMeta($group, $subgroup, $leaf); + $this->assertEquals(count($ret["timestamp"]), 1, "number of leaf is wrong"); + $this->assertEquals($ret["timestamp"][0], $time, "the leaf timestamp is wrong"); + $this->assertEquals($ret["value"][0], null, "the leaf value is wrong"); + + $ret = $ct->getMeta($group, $subgroup); + $this->assertEquals(count($ret["timestamp"]), 1, "number of leaf is wrong"); + $this->assertEquals($ret["timestamp"][0], $time, "the leaf timestamp is wrong"); + $this->assertEquals($ret["value"][0], $leaf, "the leaf name is wrong"); + + $leafvalue = $prefix."_leafvalue"; + $ct->setMeta($group, $subgroup, $leaf, $leafvalue); + $time = time(); + + $ret = $ct->getMeta($group, $subgroup, $leaf, true); + $this->assertEquals(count($ret["timestamp"]), 1, "number of leaf is wrong"); + $this->assertEquals($ret["timestamp"][0], $time, "the leaf timestamp is wrong"); + $this->assertEquals($ret["value"][0], $leafvalue, "the leaf value is wrong"); + } + + function test_getMeta_Generic_2() + { + $c =& $this->c; + $ct =& $this->ct; + + $prefix = __FUNCTION__; + $group = $prefix."_nickid-to-channelid"; + $subgroup = $prefix."_nickid1"; + $leaf1 = $prefix."_channelid1"; + $leaf2 = $prefix."_channelid2"; + $ct->setMeta($group, $subgroup, $leaf1); + $ct->setMeta($group, $subgroup, $leaf2); + $time = time(); + + $ret = $ct->getMeta($group, $subgroup); + asort($ret["value"]); + $this->assertEquals(count($ret["timestamp"]), 2, "number of leaf is wrong"); + $this->assertEquals($ret["timestamp"][0], $time, "the leaf timestamp is wrong"); + $this->assertEquals($ret["timestamp"][1], $time, "the leaf timestamp is wrong"); + $this->assertEquals($ret["value"][0], $leaf1, "the leaf name is wrong"); + $this->assertEquals($ret["value"][1], $leaf2, "the leaf name is wrong"); + } + + function test_getMeta_Generic_3() + { + $c =& $this->c; + $ct =& $this->ct; + + $prefix = __FUNCTION__; + $group = $prefix."_nickid-to-channelid"; + $subgroup1 = $prefix."_nickid1"; + $subgroup2 = $prefix."_nickid2"; + $leaf1 = $prefix."_channelid1"; + $leaf2 = $prefix."_channelid2"; + $ct->setMeta($group, $subgroup1, $leaf1); + $ct->setMeta($group, $subgroup1, $leaf2); + $ct->setMeta($group, $subgroup2, $leaf1); + $ct->setMeta($group, $subgroup2, $leaf2); + $time = time(); + + $ret = $ct->getMeta($group); + asort($ret["value"]); + $this->assertEquals(count($ret["timestamp"]), 2, "number of subgroup is wrong"); + $this->assertEquals($ret["timestamp"][0], $time, "the subgroup timestamp is wrong"); + $this->assertEquals($ret["timestamp"][1], $time, "the subgroup timestamp is wrong"); + $this->assertEquals($ret["value"][0], $subgroup1, "the subgroup name is wrong"); + $this->assertEquals($ret["value"][1], $subgroup2, "the subgroup name is wrong"); + } + } ?>