From c9a792083d74ad346593637ba10f4e4d882ecc03 Mon Sep 17 00:00:00 2001 From: Exodus4D Date: Sun, 28 Aug 2016 20:46:27 +0200 Subject: [PATCH] - added persistent system information, #184 - fixed some PHPDoc comments - fixed bug where system "status" change fails to update --- app/main/controller/api/system.php | 65 +++++++++++++------- app/main/model/basicmodel.php | 71 +++++++++++++++++----- app/main/model/mapmodel.php | 39 ++++-------- app/main/model/systemmodel.php | 96 ++++++++++++++++++++++++------ js/app/map/map.js | 16 ++--- public/js/v1.1.4/app/map/map.js | 16 ++--- 6 files changed, 204 insertions(+), 99 deletions(-) diff --git a/app/main/controller/api/system.php b/app/main/controller/api/system.php index 4c2934ef..49178a9a 100644 --- a/app/main/controller/api/system.php +++ b/app/main/controller/api/system.php @@ -190,23 +190,27 @@ class System extends \Controller\AccessController { */ public function save(\Base $f3){ $newSystemData = []; - $postData = (array)$f3->get('POST'); - // system to be saved - $systemModel = null; - if( isset($postData['systemData']) && isset($postData['mapData']) ){ $activeCharacter = $this->getCharacter(); - $systemData = (array)$postData['systemData']; $mapData = (array)$postData['mapData']; + $systemModel = null; + + if( isset($systemData['statusId']) ){ + if( (int)$systemData['statusId'] <= 0){ + unset($systemData['statusId']); + }else{ + $systemData['statusId'] = (int)$systemData['statusId']; + } + } if( isset($systemData['id']) ){ - // update existing system (e.g. changed system description) ------------------- + // update existing system (e.g. changed system description) ------------------------------------------- /** * @var $system Model\SystemModel @@ -220,7 +224,7 @@ class System extends \Controller\AccessController { } } }elseif( isset($mapData['id']) ){ - // save NEW system ------------------------------------------------------------ + // save NEW system ------------------------------------------------------------------------------------ /** * @var $map Model\MapModel @@ -233,24 +237,42 @@ class System extends \Controller\AccessController { ){ // make sure system is not already on map // --> (e.g. multiple simultaneously save() calls for the same system) - if( is_null( $systemModel = $map->getSystemByCCPId($systemData['systemId']) ) ){ + $systemModel = $map->getSystemByCCPId($systemData['systemId']); + if( is_null($systemModel) ){ // system not found on map -> get static system data (CCP DB) $systemModel = $map->getNewSystem($systemData['systemId']); $systemModel->createdCharacterId = $activeCharacter; + $systemModel->statusId = isset($systemData['statusId']) ? $systemData['statusId'] : 1; + }else{ + // system already exists (e.g. was inactive) + $systemModel->statusId = isset($systemData['statusId']) ? $systemData['statusId'] : $systemModel->statusId; } // map is not changeable for a system! (security) $systemData['mapId'] = $map; } } - } - if( !is_null($systemModel) ){ - // set/update system - $systemModel->setData($systemData); - $systemModel->updatedCharacterId = $activeCharacter; - $systemModel->save(); - $newSystemData = $systemModel->getData(); + if( !is_null($systemModel) ){ + // "statusId" was set above + unset($systemData['statusId']); + unset($systemData['mapId']); + unset($systemData['createdCharacterId']); + unset($systemData['updatedCharacterId']); + + // set/update system + $systemModel->setData($systemData); + // activate system (e.g. was inactive)) + $systemModel->setActive(true); + $systemModel->updatedCharacterId = $activeCharacter; + $systemModel->save(); + + // get data from "fresh" model (e.g. some relational data has changed: "statusId") + $newSystemModel = Model\BasicModel::getNew('SystemModel'); + $newSystemModel->getById( $systemModel->id, 0); + $newSystemModel->clearCacheData(); + $newSystemData = $newSystemModel->getData(); + } } echo json_encode($newSystemData); @@ -379,9 +401,9 @@ class System extends \Controller\AccessController { echo json_encode($return); } - /** - * delete systems and all its connections + * delete systems and all its connections from map + * -> set "active" flag * @param \Base $f3 */ public function delete(\Base $f3){ @@ -392,10 +414,13 @@ class System extends \Controller\AccessController { * @var Model\SystemModel $system */ $system = Model\BasicModel::getNew('SystemModel'); - foreach((array)$systemIds as $systemId){ + foreach($systemIds as $systemId){ $system->getById($systemId); - $system->delete($activeCharacter); - $system->reset(); + if( $system->hasAccess($activeCharacter) ){ + $system->setActive(false); + $system->save(); + $system->reset(); + } } echo json_encode([]); diff --git a/app/main/model/basicmodel.php b/app/main/model/basicmodel.php index 49d16451..69e270ab 100644 --- a/app/main/model/basicmodel.php +++ b/app/main/model/basicmodel.php @@ -48,6 +48,14 @@ abstract class BasicModel extends \DB\Cortex { */ protected $validate = []; + /** + * enables change for "active" column + * -> see setActive(); + * -> $this->active = false; will NOT work (prevent abuse)! + * @var bool + */ + protected $allowActiveChange = false; + /** * getData() cache key prefix * -> do not change, otherwise cached data is lost @@ -76,23 +84,30 @@ abstract class BasicModel extends \DB\Cortex { parent::__construct($db, $table, $fluid, $ttl); - // events ----------------------------------------- + // insert events ------------------------------------------------------------------------------------ + $this->beforeinsert( function($self, $pkeys){ + return $self->beforeInsertEvent($self, $pkeys); + }); + $this->afterinsert(function($self, $pkeys){ $self->afterInsertEvent($self, $pkeys); $self->clearCacheData(); }); + // update events ------------------------------------------------------------------------------------ + $this->beforeupdate( function($self, $pkeys){ + return $self->beforeUpdateEvent($self, $pkeys); + }); + $this->afterupdate( function($self, $pkeys){ $self->afterUpdateEvent($self, $pkeys); $self->clearCacheData(); }); - $this->beforeinsert( function($self, $pkeys){ - $self->beforeInsertEvent($self, $pkeys); - }); + // erase events ------------------------------------------------------------------------------------- $this->beforeerase( function($self, $pkeys){ - $self->beforeEraseEvent($self, $pkeys); + return $self->beforeEraseEvent($self, $pkeys); }); $this->aftererase( function($self, $pkeys){ @@ -100,7 +115,6 @@ abstract class BasicModel extends \DB\Cortex { }); } - /** * @param string $key * @param mixed $val @@ -109,11 +123,6 @@ abstract class BasicModel extends \DB\Cortex { */ public function set($key, $val){ - if($key == 'active'){ - // prevent abuse - return; - } - if( !$this->dry() && $key != 'updated' @@ -152,6 +161,24 @@ abstract class BasicModel extends \DB\Cortex { } } + /** + * setter for "active" status + * -> default: keep current "active" status + * -> can be overwritten + * @param bool $active + * @return mixed + */ + public function set_active($active){ + if( $this->allowActiveChange ){ + // allowed to set/change -> reset "allowed" property + $this->allowActiveChange = false; + }else{ + // not allowed to set/change -> keep current status + $active = $this->active; + } + return $active; + } + /** * extent the fieldConf Array with static fields for each table */ @@ -371,10 +398,14 @@ abstract class BasicModel extends \DB\Cortex { /** * set active state for a model - * @param $value + * -> do NOT use $this->active for status change! + * -> this will not work (prevent abuse) + * @param bool $active */ - public function setActive($value){ - $this->set('active', (int)$value); + public function setActive($active){ + // enables "active" change for this model + $this->allowActiveChange = true; + $this->active = $active; } /** @@ -430,6 +461,18 @@ abstract class BasicModel extends \DB\Cortex { public function afterInsertEvent($self, $pkeys){ } + /** + * Event "Hook" function + * can be overwritten + * return false will stop any further action + * @param self $self + * @param $pkeys + * @return bool + */ + public function beforeUpdateEvent($self, $pkeys){ + return true; + } + /** * Event "Hook" function * can be overwritten diff --git a/app/main/model/mapmodel.php b/app/main/model/mapmodel.php index 4eab5a9d..51649aa4 100644 --- a/app/main/model/mapmodel.php +++ b/app/main/model/mapmodel.php @@ -160,9 +160,6 @@ class MapModel extends BasicModel { $characters = $this->getCharacters(); $characterData = []; foreach($characters as $character){ - /** - * @var $character CharacterModel - */ $characterData[] = $character->getData(); } $mapData->access->character = $characterData; @@ -171,9 +168,6 @@ class MapModel extends BasicModel { $corporationData = []; foreach($corporations as $corporation){ - /** - * @var $corporation CorporationModel - */ $corporationData[] = $corporation->getData(); } $mapData->access->corporation = $corporationData; @@ -182,9 +176,6 @@ class MapModel extends BasicModel { $allianceData = []; foreach($alliances as $alliance){ - /** - * @var $alliance AllianceModel - */ $allianceData[] = $alliance->getData(); } $mapData->access->alliance = $allianceData; @@ -259,6 +250,8 @@ class MapModel extends BasicModel { /** * search for a system by CCPs systemId + * -> "active" column is NOT checked + * -> removed systems become "active" = 0 * @param int $systemId * @return null|SystemModel */ @@ -268,7 +261,7 @@ class MapModel extends BasicModel { */ $system = $this->rel('systems'); $result = $system->findone([ - 'active = 1 AND mapId = :mapId AND systemId = :systemId', + 'mapId = :mapId AND systemId = :systemId', ':mapId' => $this->id, ':systemId' => $systemId ]); @@ -296,7 +289,7 @@ class MapModel extends BasicModel { /** * get all system data for all systems in this map - * @return array + * @return \stdClass[] */ public function getSystemData(){ @@ -315,7 +308,7 @@ class MapModel extends BasicModel { /** * get all connections in this map - * @return array|mixed + * @return array */ public function getConnections(){ $this->filter('connections', [ @@ -333,7 +326,7 @@ class MapModel extends BasicModel { /** * get all connection data in this map - * @return array + * @return \stdClass[] */ public function getConnectionData(){ $connections = $this->getConnections(); @@ -472,7 +465,7 @@ class MapModel extends BasicModel { /** * get all (private) characters for this map - * @return CharacterModel array + * @return CharacterModel[] */ private function getCharacters(){ $characters = []; @@ -500,27 +493,18 @@ class MapModel extends BasicModel { // add active character for each user foreach($activeCharacters as $activeCharacter){ - /** - * @var UserModel $user - */ $characters[] = $activeCharacter; } }elseif($this->isCorporation()){ $corporations = $this->getCorporations(); foreach($corporations as $corporation){ - /** - * @var CorporationModel $corporation - */ $characters = array_merge($characters, $corporation->getCharacters()); } }elseif($this->isAlliance()){ $alliances = $this->getAlliances(); foreach($alliances as $alliance){ - /** - * @var AllianceModel $alliance - */ $characters = array_merge($characters, $alliance->getCharacters()); } } @@ -531,10 +515,9 @@ class MapModel extends BasicModel { /** * get data for all characters that are currently online "viewing" this map * -> the result of this function is cached! - * @return array + * @return \stdClass[] */ private function getCharactersData(){ - // check if there is cached data $charactersData = $this->getCacheData('CHARACTERS'); @@ -557,7 +540,7 @@ class MapModel extends BasicModel { /** * get all corporations that have access to this map - * @return array + * @return CorporationModel[] */ public function getCorporations(){ $corporations = []; @@ -577,7 +560,7 @@ class MapModel extends BasicModel { /** * get all alliances that have access to this map - * @return array + * @return AllianceModel[] */ public function getAlliances(){ $alliances = []; @@ -729,7 +712,7 @@ class MapModel extends BasicModel { /** * get all active characters (with active log) * grouped by systems - * @return object + * @return \stdClass */ public function getUserData(){ diff --git a/app/main/model/systemmodel.php b/app/main/model/systemmodel.php index 62be0624..1a37ba89 100644 --- a/app/main/model/systemmodel.php +++ b/app/main/model/systemmodel.php @@ -161,12 +161,18 @@ class SystemModel extends BasicModel { ], 'signatures' => [ 'has-many' => ['Model\SystemSignatureModel', 'systemId'] + ], + 'connectionsSource' => [ + 'has-many' => ['Model\ConnectionModel', 'source'] + ], + 'connectionsTarget' => [ + 'has-many' => ['Model\ConnectionModel', 'target'] ] ]; /** * set an array with all data for a system - * @param $systemData + * @param array $systemData */ public function setData($systemData){ @@ -202,7 +208,7 @@ class SystemModel extends BasicModel { /** * get map data as object - * @return object + * @return \stdClass * @throws \Exception */ public function getData(){ @@ -236,8 +242,8 @@ class SystemModel extends BasicModel { $systemData->type->name = $this->typeId->name; $systemData->status = (object) []; - $systemData->status->id = is_object($this->statusId) ? $this->statusId->id : 0; - $systemData->status->name = is_object($this->statusId) ? $this->statusId->name : ''; + $systemData->status->id = is_object($this->statusId) ? $this->statusId->id : 1; + $systemData->status->name = is_object($this->statusId) ? $this->statusId->name : 'unknown'; $systemData->locked = $this->locked; $systemData->rallyUpdated = strtotime($this->rallyUpdated); @@ -274,7 +280,7 @@ class SystemModel extends BasicModel { /** * setter for system security value - * @param $trueSec + * @param float $trueSec * @return float */ public function set_trueSec($trueSec){ @@ -294,8 +300,8 @@ class SystemModel extends BasicModel { /** * setter validation for x coordinate - * @param $posX - * @return int|number + * @param int $posX + * @return int */ public function set_posX($posX){ $posX = abs($posX); @@ -308,8 +314,8 @@ class SystemModel extends BasicModel { /** * setter validation for y coordinate - * @param $posY - * @return int|number + * @param int $posY + * @return int */ public function set_posY($posY){ $posY = abs($posY); @@ -322,7 +328,7 @@ class SystemModel extends BasicModel { /** * setter for system rally timestamp - * @param $rally + * @param int $rally * @return null|string */ public function set_rallyUpdated($rally){ @@ -346,6 +352,30 @@ class SystemModel extends BasicModel { return $rally; } + /** + * Event "Hook" function + * can be overwritten + * return false will stop any further action + * @param self $self + * @param $pkeys + * @return bool + */ + public function beforeUpdateEvent($self, $pkeys){ + if( !$self->isActive()){ + // system becomes inactive + // reset "rally point" fields + $self->rallyUpdated = 0; + $self->rallyPoke = false; + + // delete connections + $connections = $self->getConnections(); + foreach($connections as $connection){ + $connection->erase(); + } + } + return true; + } + /** * Event "Hook" function * return false will stop any further action @@ -365,7 +395,7 @@ class SystemModel extends BasicModel { /** * check object for model access * @param CharacterModel $characterModel - * @return mixed + * @return bool */ public function hasAccess(CharacterModel $characterModel){ return $this->mapId->hasAccess($characterModel); @@ -385,9 +415,41 @@ class SystemModel extends BasicModel { } } + /** + * get all connections of this system + * @return ConnectionModel[] + */ + public function getConnections(){ + $connections = []; + + $this->filter('connectionsTarget', [ + 'active = :active AND target = :targetId', + ':active' => 1, + ':targetId' => $this->_id + ]); + if($this->connectionsTarget){ + foreach($this->connectionsTarget as $connection){ + $connections[$connection->_id] = $connection; + } + } + + $this->filter('connectionsSource', [ + 'active = :active AND source = :sourceId', + ':active' => 1, + ':sourceId' => $this->_id + ]); + if($this->connectionsSource){ + foreach($this->connectionsSource as $connection){ + $connections[$connection->_id] = $connection; + } + } + + return $connections; + } + /** * get all signatures of this system - * @return SystemModel array + * @return SystemSignatureModel[] */ public function getSignatures(){ $this->filter('signatures', ['active = ?', 1], ['order' => 'name']); @@ -402,7 +464,7 @@ class SystemModel extends BasicModel { /** * get all data for all Signatures in this system - * @return array + * @return \stdClass[] */ public function getSignaturesData(){ $signatures = $this->getSignatures(); @@ -419,7 +481,7 @@ class SystemModel extends BasicModel { * get Signature by id and check for access * @param CharacterModel $characterModel * @param $id - * @return bool|null + * @return null|SystemSignatureModel */ public function getSignatureById(CharacterModel $characterModel, $id){ $signature = null; @@ -437,8 +499,8 @@ class SystemModel extends BasicModel { /** * get a signature by its "unique" 3-digit name * @param CharacterModel $characterModel - * @param $name - * @return mixed|null + * @param string $name + * @return null|SystemSignatureModel */ public function getSignatureByName(CharacterModel $characterModel, $name){ $signature = null; @@ -472,7 +534,7 @@ class SystemModel extends BasicModel { /** * get static WH data for this system * -> any WH system has at least one static WH - * @return array + * @return \stdClass[] * @throws \Exception */ protected function getStaticWormholeData(){ diff --git a/js/app/map/map.js b/js/app/map/map.js index b56597d6..ef8a4a5c 100644 --- a/js/app/map/map.js +++ b/js/app/map/map.js @@ -2473,30 +2473,26 @@ define([ * @param options */ var showNewSystemDialog = function(map, options){ - var mapContainer = $(map.getContainer()); // format system status for form select ------------------------------------------------------------- var systemStatus = {}; + // "default" selection (id = 0) prevents status from being overwritten + // -> e.g. keep status information if system was just inactive (active = 0) + systemStatus[0] = 'default'; + $.each(Init.systemStatus, function(status, statusData){ systemStatus[statusData.id] = statusData.label; }); // default system status -> first status entry - var tempKeys = []; - for(var k in Init.systemStatus){ - if (Init.systemStatus.hasOwnProperty(k)){ - tempKeys.push(k); - } - } - var defaultSystemStatus = Init.systemStatus[ tempKeys[0] ].id; - + var defaultSystemStatus = 0; // get current map data -> disable systems that are already on it ----------------------------------- var mapData = mapContainer.getMapDataFromClient({forceData: true}); var mapSystems = mapData.data.systems; var mapSystemIds = []; - for(var i = 0; i < mapSystems.length; i++ ){ + for(let i = 0; i < mapSystems.length; i++ ){ mapSystemIds.push( mapSystems[i].systemId ); } diff --git a/public/js/v1.1.4/app/map/map.js b/public/js/v1.1.4/app/map/map.js index b56597d6..ef8a4a5c 100644 --- a/public/js/v1.1.4/app/map/map.js +++ b/public/js/v1.1.4/app/map/map.js @@ -2473,30 +2473,26 @@ define([ * @param options */ var showNewSystemDialog = function(map, options){ - var mapContainer = $(map.getContainer()); // format system status for form select ------------------------------------------------------------- var systemStatus = {}; + // "default" selection (id = 0) prevents status from being overwritten + // -> e.g. keep status information if system was just inactive (active = 0) + systemStatus[0] = 'default'; + $.each(Init.systemStatus, function(status, statusData){ systemStatus[statusData.id] = statusData.label; }); // default system status -> first status entry - var tempKeys = []; - for(var k in Init.systemStatus){ - if (Init.systemStatus.hasOwnProperty(k)){ - tempKeys.push(k); - } - } - var defaultSystemStatus = Init.systemStatus[ tempKeys[0] ].id; - + var defaultSystemStatus = 0; // get current map data -> disable systems that are already on it ----------------------------------- var mapData = mapContainer.getMapDataFromClient({forceData: true}); var mapSystems = mapData.data.systems; var mapSystemIds = []; - for(var i = 0; i < mapSystems.length; i++ ){ + for(let i = 0; i < mapSystems.length; i++ ){ mapSystemIds.push( mapSystems[i].systemId ); }