From 23eb03275915b5434df9b9ee3b33701f58bdf912 Mon Sep 17 00:00:00 2001 From: Exodus4D Date: Fri, 16 Sep 2016 21:57:04 +0200 Subject: [PATCH] - fixed multi character support location tracking, closed #314 --- app/main/controller/api/map.php | 3 +- app/main/controller/api/user.php | 28 +----------- app/main/controller/controller.php | 68 +++++++++------------------- app/main/model/characterlogmodel.php | 23 ++++++---- app/main/model/charactermodel.php | 27 ++++++++++- app/main/model/usermodel.php | 57 ++++++++++++++++++++++- 6 files changed, 121 insertions(+), 85 deletions(-) diff --git a/app/main/controller/api/map.php b/app/main/controller/api/map.php index 69d9b9d9..170e6051 100644 --- a/app/main/controller/api/map.php +++ b/app/main/controller/api/map.php @@ -779,7 +779,8 @@ class Map extends Controller\AccessController { $systemPosX = 0; $systemPosY = 30; - $sourceSystemId = (int)$this->getF3()->get(User::SESSION_KEY_CHARACTERS_PREV_SYSTEM_ID); + $sessionCharacter = $this->getSessionCharacterData(); + $sourceSystemId = (int)$sessionCharacter['PREV_SYSTEM_ID']; $targetSystemId = (int)$log->systemId; if($sourceSystemId){ diff --git a/app/main/controller/api/user.php b/app/main/controller/api/user.php index 2b4a3c97..67d67246 100644 --- a/app/main/controller/api/user.php +++ b/app/main/controller/api/user.php @@ -43,29 +43,6 @@ class User extends Controller\Controller{ */ private static $captchaReason = [self::SESSION_CAPTCHA_ACCOUNT_UPDATE, self::SESSION_CAPTCHA_ACCOUNT_DELETE]; - /** - * merges two multidimensional characterSession arrays by checking characterID - * @param array $characterDataBase - * @param array $characterData - * @return array - */ - private function mergeSessionCharacterData($characterDataBase = [], $characterData = []){ - $addData = []; - foreach($characterDataBase as $i => $baseData){ - foreach($characterData as $data){ - if((int)$baseData['ID'] === (int)$data['ID']){ - // overwrite changes - $characterDataBase[$i]['NAME'] = $data['NAME']; - $characterDataBase[$i]['TIME'] = $data['TIME']; - }else{ - $addData[] = $data; - } - } - } - - return array_merge($characterDataBase, $addData); - } - /** * login a valid character * @param Model\CharacterModel $characterModel @@ -99,10 +76,7 @@ class User extends Controller\Controller{ ]); }else{ // user has NOT changed ----------------------------------------------------------- - // -> get current session characters - $currentSessionCharacters = (array)$this->f3->get(self::SESSION_KEY_CHARACTERS); - - $sessionCharacters = $this->mergeSessionCharacterData($sessionCharacters, $currentSessionCharacters); + $sessionCharacters = $characterModel::mergeSessionCharacterData($sessionCharacters); } $this->f3->set(self::SESSION_KEY_CHARACTERS, $sessionCharacters); diff --git a/app/main/controller/controller.php b/app/main/controller/controller.php index 940ae319..7239d747 100644 --- a/app/main/controller/controller.php +++ b/app/main/controller/controller.php @@ -319,62 +319,38 @@ class Controller { /** * get current character data from session + * -> * @return array */ - protected function getSessionCharacterData(){ + public function getSessionCharacterData(){ $data = []; - $currentSessionCharacters = (array)$this->getF3()->get(Api\User::SESSION_KEY_CHARACTERS); - $requestedCharacterId = 0; - // get all characterData from currently active characters - if($this->getF3()->get('AJAX')){ - // Ajax request -> get characterId from Header (if already available!) - $header = $this->getRequestHeaders(); - $requestedCharacterId = (int)$header['Pf-Character']; + if($user = $this->getUser()){ + $requestedCharacterId = 0; - if( - $requestedCharacterId > 0 && - (int)$this->getF3()->get(Api\User::SESSION_KEY_TEMP_CHARACTER_ID) === $requestedCharacterId - ){ - // characterId is available in Javascript - // -> clear temp characterId for next character login/switch - $this->getF3()->clear(Api\User::SESSION_KEY_TEMP_CHARACTER_ID); - } - } + // get all characterData from currently active characters + if($this->getF3()->get('AJAX')){ + // Ajax request -> get characterId from Header (if already available!) + $header = $this->getRequestHeaders(); + $requestedCharacterId = (int)$header['Pf-Character']; - if($requestedCharacterId <= 0){ - // Ajax BUT characterID not yet set as HTTP header - // OR non Ajax -> get characterId from temp session (e.g. from HTTP redirect) - $requestedCharacterId = (int)$this->getF3()->get(Api\User::SESSION_KEY_TEMP_CHARACTER_ID); - } - - if($requestedCharacterId > 0){ - // search for session character data - foreach($currentSessionCharacters as $characterData){ - if($requestedCharacterId === (int)$characterData['ID']){ - $data = $characterData; - break; + if( + $requestedCharacterId > 0 && + (int)$this->getF3()->get(Api\User::SESSION_KEY_TEMP_CHARACTER_ID) === $requestedCharacterId + ){ + // requested characterId is "now" available on the client (Javascript) + // -> clear temp characterId for next character login/switch + $this->getF3()->clear(Api\User::SESSION_KEY_TEMP_CHARACTER_ID); } } - }elseif( !empty($currentSessionCharacters) ){ - // no character was requested ($requestedCharacterId = 0) AND session characters were found - // -> get first matched character (e.g. user open browser tab) - $data = $currentSessionCharacters[0]; - } - if( !empty($data) ){ - // check if character still exists on DB (e.g. was manually removed in the meantime) - // -> This should NEVER happen just for security and "local development" - $character = Model\BasicModel::getNew('CharacterModel'); - $character->getById( (int)$data['ID']); - - if( - $character->dry() || - !$character->hasUserCharacter() - ){ - // character data is invalid! - $data = []; + if($requestedCharacterId <= 0){ + // Ajax BUT characterID not yet set as HTTP header + // OR non Ajax -> get characterId from temp session (e.g. from HTTP redirect) + $requestedCharacterId = (int)$this->getF3()->get(Api\User::SESSION_KEY_TEMP_CHARACTER_ID); } + + $data = $user->getSessionCharacterData($requestedCharacterId); } return $data; diff --git a/app/main/model/characterlogmodel.php b/app/main/model/characterlogmodel.php index 781f8373..d54be720 100644 --- a/app/main/model/characterlogmodel.php +++ b/app/main/model/characterlogmodel.php @@ -8,8 +8,8 @@ namespace Model; -use Controller\Api\User; -use Controller\Controller; +use Controller\Api\User as User; +use Controller\Controller as Controller; use DB\SQL\Schema; class CharacterLogModel extends BasicModel { @@ -192,6 +192,10 @@ class CharacterLogModel extends BasicModel { return $logData; } + /** + * @param int $systemId + * @return int + */ public function set_systemId($systemId){ if($systemId > 0){ $this->updateCharacterSessionLocation($systemId); @@ -205,20 +209,21 @@ class CharacterLogModel extends BasicModel { */ protected function updateCharacterSessionLocation($systemId){ $controller = new Controller(); - $f3 = $this->getF3(); - $systemId = (int)$systemId; if( - ( $activeCharacter = $controller->getCharacter() ) && - ( $activeCharacter->_id === $this->characterId->_id ) + !empty($sessionCharacter = $controller->getSessionCharacterData()) && + $sessionCharacter['ID'] === $this->get('characterId', true) ){ - $prevSystemId = (int)$f3->get( User::SESSION_KEY_CHARACTERS_PREV_SYSTEM_ID); + $prevSystemId = (int)$sessionCharacter['PREV_SYSTEM_ID']; if($prevSystemId === 0){ - $f3->set( User::SESSION_KEY_CHARACTERS_PREV_SYSTEM_ID, $systemId); + $sessionCharacter['PREV_SYSTEM_ID'] = (int)$systemId; }else{ - $f3->set( User::SESSION_KEY_CHARACTERS_PREV_SYSTEM_ID, (int)$this->systemId); + $sessionCharacter['PREV_SYSTEM_ID'] = $this->systemId; } + + $sessionCharacters = CharacterModel::mergeSessionCharacterData([$sessionCharacter]); + $this->getF3()->set(User::SESSION_KEY_CHARACTERS, $sessionCharacters); } } diff --git a/app/main/model/charactermodel.php b/app/main/model/charactermodel.php index 7629f52f..93d0ac4d 100644 --- a/app/main/model/charactermodel.php +++ b/app/main/model/charactermodel.php @@ -10,8 +10,8 @@ namespace Model; use Controller; use Controller\Ccp\Sso as Sso; +use Controller\Api\User as User; use DB\SQL\Schema; -use Data\Mapper as Mapper; class CharacterModel extends BasicModel { @@ -527,4 +527,29 @@ class CharacterModel extends BasicModel { } } + /** + * merges two multidimensional characterSession arrays by checking characterID + * @param array $characterDataBase + * @return array + */ + static function mergeSessionCharacterData(array $characterDataBase = []){ + $addData = []; + // get current session characters to be merged with + $characterData = (array)self::getF3()->get(User::SESSION_KEY_CHARACTERS); + + foreach($characterDataBase as $i => $baseData){ + foreach($characterData as $data){ + if((int)$baseData['ID'] === (int)$data['ID']){ + // overwrite static data -> should NEVER change on merge! + $characterDataBase[$i]['NAME'] = $data['NAME']; + $characterDataBase[$i]['TIME'] = $data['TIME']; + }else{ + $addData[] = $data; + } + } + } + + return array_merge($characterDataBase, $addData); + } + } \ No newline at end of file diff --git a/app/main/model/usermodel.php b/app/main/model/usermodel.php index fe4a65e9..1b0b0866 100644 --- a/app/main/model/usermodel.php +++ b/app/main/model/usermodel.php @@ -10,7 +10,7 @@ namespace Model; use DB\SQL\Schema; use Controller; -use Controller\Api; +use Controller\Api\User as User; use Exception; class UserModel extends BasicModel { @@ -152,6 +152,61 @@ class UserModel extends BasicModel { return $this->getByForeignKey('name', $name, [], 0); } + /** + * get current character data from session + * -> if §characterID == 0 -> get first character data (random) + * @param int $characterId + * @param bool $objectCheck + * @return array + */ + public function getSessionCharacterData($characterId = 0, $objectCheck = true){ + $data = []; + $characterId = (int)$characterId; + $currentSessionUser = (array)$this->getF3()->get(User::SESSION_KEY_USER); + + if($this->_id === $currentSessionUser['ID']){ + // user matches session data + $sessionCharacters = (array)$this->getF3()->get(User::SESSION_KEY_CHARACTERS); + + if($characterId > 0){ + // search for specific characterData + foreach($sessionCharacters as $characterData){ + if($characterId === (int)$characterData['ID']){ + $data = $characterData; + break; + } + } + }elseif( !empty($sessionCharacters) ){ + // no character was requested ($requestedCharacterId = 0) AND session characters were found + // -> get first matched character (e.g. user open browser tab) + $data = $sessionCharacters[0]; + } + } + + if( + $objectCheck === true && + !empty($data) + ){ + // check if character still exists on DB (e.g. was manually removed in the meantime) + // -> This should NEVER happen just for security and "local development" + /** + * @var $character CharacterModel + */ + $character = BasicModel::getNew('CharacterModel'); + $character->getById( (int)$data['ID']); + + if( + $character->dry() || + !$character->hasUserCharacter() + ){ + // character data is invalid! + $data = []; + } + } + + return $data; + } + /** * get all userCharacters models for a user * characters will be checked/updated on login by CCP API call