714 lines
27 KiB
PHP
714 lines
27 KiB
PHP
<?php
|
|
/**
|
|
* Created by PhpStorm.
|
|
* User: exodus4d
|
|
* Date: 16.02.15
|
|
* Time: 20:23
|
|
*/
|
|
|
|
namespace Controller\Api;
|
|
use Model;
|
|
|
|
/**
|
|
* Map controller
|
|
* Class Map
|
|
* @package Controller\Api
|
|
*/
|
|
class Map extends \Controller\AccessController {
|
|
|
|
/**
|
|
* event handler
|
|
* @param $f3
|
|
*/
|
|
function beforeroute($f3) {
|
|
|
|
// set header for all routes
|
|
header('Content-type: application/json');
|
|
|
|
parent::beforeroute($f3);
|
|
}
|
|
|
|
/**
|
|
* Get all required static config data for program initialization
|
|
* @param $f3
|
|
*/
|
|
public function init($f3){
|
|
|
|
// expire time in seconds
|
|
$expireTimeHead = 60 * 60 * 12;
|
|
$expireTimeSQL = 60 * 60 * 12;
|
|
|
|
$f3->expire($expireTimeHead);
|
|
|
|
$initData = [];
|
|
|
|
// static program data ------------------------------------------------
|
|
$initData['timer'] = $f3->get('PATHFINDER.TIMER');
|
|
|
|
// get all available map types ----------------------------------------
|
|
$mapType = Model\BasicModel::getNew('MapTypeModel');
|
|
$rows = $mapType->find('active = 1', null, $expireTimeSQL);
|
|
|
|
$mapTypeData = [];
|
|
foreach((array)$rows as $rowData){
|
|
$data = [
|
|
'id' => $rowData->id,
|
|
'label' => $rowData->label,
|
|
'class' => $rowData->class,
|
|
'classTab' => $rowData->classTab
|
|
];
|
|
$mapTypeData[$rowData->name] = $data;
|
|
|
|
}
|
|
$initData['mapTypes'] = $mapTypeData;
|
|
|
|
// get all available map scopes ---------------------------------------
|
|
$mapScope = Model\BasicModel::getNew('MapScopeModel');
|
|
$rows = $mapScope->find('active = 1', null, $expireTimeSQL);
|
|
$mapScopeData = [];
|
|
foreach((array)$rows as $rowData){
|
|
$data = [
|
|
'id' => $rowData->id,
|
|
'label' => $rowData->label
|
|
];
|
|
$mapScopeData[$rowData->name] = $data;
|
|
}
|
|
$initData['mapScopes'] = $mapScopeData;
|
|
|
|
// get all available system status ------------------------------------
|
|
$systemStatus = Model\BasicModel::getNew('SystemStatusModel');
|
|
$rows = $systemStatus->find('active = 1', null, $expireTimeSQL);
|
|
$systemScopeData = [];
|
|
foreach((array)$rows as $rowData){
|
|
$data = [
|
|
'id' => $rowData->id,
|
|
'label' => $rowData->label,
|
|
'class' => $rowData->class
|
|
];
|
|
$systemScopeData[$rowData->name] = $data;
|
|
}
|
|
$initData['systemStatus'] = $systemScopeData;
|
|
|
|
// get all available system types -------------------------------------
|
|
$systemType = Model\BasicModel::getNew('SystemTypeModel');
|
|
$rows = $systemType->find('active = 1', null, $expireTimeSQL);
|
|
$systemTypeData = [];
|
|
foreach((array)$rows as $rowData){
|
|
$data = [
|
|
'id' => $rowData->id,
|
|
'name' => $rowData->name
|
|
];
|
|
$systemTypeData[$rowData->name] = $data;
|
|
}
|
|
$initData['systemType'] = $systemTypeData;
|
|
|
|
// get available connection scopes ------------------------------------
|
|
$connectionScope = Model\BasicModel::getNew('ConnectionScopeModel');
|
|
$rows = $connectionScope->find('active = 1', null, $expireTimeSQL);
|
|
$connectionScopeData = [];
|
|
foreach((array)$rows as $rowData){
|
|
$data = [
|
|
'id' => $rowData->id,
|
|
'label' => $rowData->label,
|
|
'connectorDefinition' => $rowData->connectorDefinition
|
|
];
|
|
$connectionScopeData[$rowData->name] = $data;
|
|
}
|
|
$initData['connectionScopes'] = $connectionScopeData;
|
|
|
|
// get available character status -------------------------------------
|
|
$characterStatus = Model\BasicModel::getNew('CharacterStatusModel');
|
|
$rows = $characterStatus->find('active = 1', null, $expireTimeSQL);
|
|
$characterStatusData = [];
|
|
foreach((array)$rows as $rowData){
|
|
$data = [
|
|
'id' => $rowData->id,
|
|
'name' => $rowData->name,
|
|
'class' => $rowData->class
|
|
];
|
|
$characterStatusData[$rowData->name] = $data;
|
|
}
|
|
$initData['characterStatus'] = $characterStatusData;
|
|
|
|
// get max number of shared entities per map --------------------------
|
|
$maxSharedCount = [
|
|
'user' => $f3->get('PATHFINDER.MAX_SHARED_USER'),
|
|
'corporation' => $f3->get('PATHFINDER.MAX_SHARED_CORPORATION'),
|
|
'alliance' => $f3->get('PATHFINDER.MAX_SHARED_ALLIANCE'),
|
|
];
|
|
$initData['maxSharedCount'] = $maxSharedCount;
|
|
|
|
echo json_encode($initData);
|
|
}
|
|
|
|
/**
|
|
* import new map data
|
|
* @param $f3
|
|
*/
|
|
public function import($f3){
|
|
$importData = (array)$f3->get('POST');
|
|
|
|
$return = (object) [];
|
|
$return->error = [];
|
|
|
|
if(
|
|
isset($importData['typeId']) &&
|
|
count($importData['mapData']) > 0
|
|
){
|
|
$user = $this->_getUser();
|
|
|
|
if($user){
|
|
$activeCharacter = $user->getActiveUserCharacter();
|
|
|
|
$map = Model\BasicModel::getNew('MapModel');
|
|
$system = Model\BasicModel::getNew('SystemModel');
|
|
$connection = Model\BasicModel::getNew('ConnectionModel');
|
|
|
|
foreach($importData['mapData'] as $mapData){
|
|
if(
|
|
isset($mapData['config']) &&
|
|
isset($mapData['data'])
|
|
){
|
|
|
|
|
|
if(
|
|
isset($mapData['data']['systems']) &&
|
|
isset($mapData['data']['connections'])
|
|
){
|
|
if(isset($mapData['config']['id'])){
|
|
unset($mapData['config']['id']);
|
|
}
|
|
|
|
$map->setData($mapData['config']);
|
|
$map->typeId = (int)$importData['typeId'];
|
|
$map->save();
|
|
|
|
// new system IDs will be generated
|
|
// therefore we need to temp store a mapping between IDs
|
|
$tempSystemIdMapping = [];
|
|
|
|
foreach($mapData['data']['systems'] as $systemData){
|
|
if(isset($systemData['id'])){
|
|
$oldId = (int)$systemData['id'];
|
|
unset($systemData['id']);
|
|
|
|
$system->setData($systemData);
|
|
$system->mapId = $map;
|
|
$system->createdCharacterId = $activeCharacter->characterId;
|
|
$system->updatedCharacterId = $activeCharacter->characterId;
|
|
$system->save();
|
|
|
|
$tempSystemIdMapping[$oldId] = $system->id;
|
|
$system->reset();
|
|
}
|
|
}
|
|
|
|
|
|
foreach($mapData['data']['connections'] as $connectionData){
|
|
// check if source and target IDs match with new system ID
|
|
if(
|
|
isset( $tempSystemIdMapping[$connectionData['source']] ) &&
|
|
isset( $tempSystemIdMapping[$connectionData['target']] )
|
|
){
|
|
if(isset($connectionData['id'])){
|
|
unset($connectionData['id']);
|
|
}
|
|
|
|
$connection->setData($connectionData);
|
|
$connection->mapId = $map;
|
|
$connection->source = $tempSystemIdMapping[$connectionData['source']];
|
|
$connection->target = $tempSystemIdMapping[$connectionData['target']];
|
|
$connection->save();
|
|
|
|
$connection->reset();
|
|
}
|
|
}
|
|
|
|
// map access info should not automatically imported
|
|
if($map->isPrivate()){
|
|
$map->setAccess($user);
|
|
}elseif($map->isCorporation()){
|
|
$corporation = $activeCharacter->getCharacter()->getCorporation();
|
|
if($corporation){
|
|
$map->setAccess($corporation);
|
|
}
|
|
}elseif($map->isAlliance()){
|
|
$alliance = $activeCharacter->getCharacter()->getAlliance();
|
|
if($alliance){
|
|
$map->setAccess($alliance);
|
|
}
|
|
}
|
|
|
|
}else{
|
|
// systems || connections missing
|
|
$missingConfigError = (object) [];
|
|
$missingConfigError->type = 'error';
|
|
$missingConfigError->message = 'Map data not valid (systems || connections) missing';
|
|
$return->error[] = $missingConfigError;
|
|
}
|
|
|
|
}else{
|
|
// map config || systems/connections missing
|
|
$missingConfigError = (object) [];
|
|
$missingConfigError->type = 'error';
|
|
$missingConfigError->message = 'Map data not valid (config || data) missing';
|
|
$return->error[] = $missingConfigError;
|
|
}
|
|
|
|
|
|
$map->reset();
|
|
}
|
|
}else{
|
|
// user not found
|
|
$return->error[] = $this->getUserLoggedOffError();
|
|
}
|
|
}else{
|
|
// map data missing
|
|
$missingDataError = (object) [];
|
|
$missingDataError->type = 'error';
|
|
$missingDataError->message = 'Map data missing';
|
|
$return->error[] = $missingDataError;
|
|
}
|
|
|
|
|
|
echo json_encode($return);
|
|
}
|
|
|
|
/**
|
|
* save a new map or update an existing map
|
|
* @param $f3
|
|
*/
|
|
public function save($f3){
|
|
$formData = (array)$f3->get('POST.formData');
|
|
|
|
$return = (object) [];
|
|
$return->error = [];
|
|
|
|
if( isset($formData['id']) ){
|
|
|
|
$user = $this->_getUser(0);
|
|
|
|
if($user){
|
|
$map = Model\BasicModel::getNew('MapModel');
|
|
$map->getById( (int)$formData['id'] );
|
|
|
|
if(
|
|
$map->dry() ||
|
|
$map->hasAccess($user)
|
|
){
|
|
// new map
|
|
$map->setData($formData);
|
|
$map = $map->save();
|
|
|
|
// save global map access. Depends on map "type"
|
|
if($map->isPrivate()){
|
|
|
|
// share map between users -> set access
|
|
if(isset($formData['mapUsers'])){
|
|
// avoid abuse -> respect share limits
|
|
$accessUsers = array_slice( $formData['mapUsers'], 0, $f3->get('PATHFINDER.MAX_SHARED_USER') );
|
|
|
|
// clear map access. In case something has removed from access list
|
|
$map->clearAccess();
|
|
|
|
$tempUser = Model\BasicModel::getNew('UserModel');
|
|
|
|
foreach($accessUsers as $userId){
|
|
$tempUser->getById( (int)$userId );
|
|
|
|
if(
|
|
!$tempUser->dry() &&
|
|
$tempUser->sharing == 1 // check if map sharing is enabled
|
|
){
|
|
$map->setAccess($tempUser);
|
|
}
|
|
|
|
$tempUser->reset();
|
|
}
|
|
}
|
|
|
|
// the current user itself should always have access
|
|
// just in case he removed himself :)
|
|
$map->setAccess($user);
|
|
}elseif($map->isCorporation()){
|
|
$activeCharacter = $user->getActiveUserCharacter();
|
|
|
|
if($activeCharacter){
|
|
$corporation = $activeCharacter->getCharacter()->getCorporation();
|
|
|
|
if($corporation){
|
|
// the current user has to have a corporation when
|
|
// working on corporation maps!
|
|
|
|
// share map between corporations -> set access
|
|
if(isset($formData['mapCorporations'])){
|
|
// avoid abuse -> respect share limits
|
|
$accessCorporations = array_slice( $formData['mapCorporations'], 0, $f3->get('PATHFINDER.MAX_SHARED_CORPORATION') );
|
|
|
|
// clear map access. In case something has removed from access list
|
|
$map->clearAccess();
|
|
|
|
$tempCorporation = Model\BasicModel::getNew('CorporationModel');
|
|
|
|
foreach($accessCorporations as $corporationId){
|
|
$tempCorporation->getById( (int)$corporationId );
|
|
|
|
if(
|
|
!$tempCorporation->dry() &&
|
|
$tempCorporation->sharing == 1 // check if map sharing is enabled
|
|
){
|
|
$map->setAccess($tempCorporation);
|
|
}
|
|
|
|
$tempCorporation->reset();
|
|
}
|
|
}
|
|
|
|
// the corporation of the current user should always have access
|
|
$map->setAccess($corporation);
|
|
}
|
|
}
|
|
}elseif($map->isAlliance()){
|
|
$activeCharacter = $user->getActiveUserCharacter();
|
|
|
|
if($activeCharacter){
|
|
$alliance = $activeCharacter->getCharacter()->getAlliance();
|
|
|
|
if($alliance){
|
|
// the current user has to have a alliance when
|
|
// working on alliance maps!
|
|
|
|
// share map between alliances -> set access
|
|
if(isset($formData['mapAlliances'])){
|
|
// avoid abuse -> respect share limits
|
|
$accessAlliances = array_slice( $formData['mapAlliances'], 0, $f3->get('PATHFINDER.MAX_SHARED_ALLIANCE') );
|
|
|
|
// clear map access. In case something has removed from access list
|
|
$map->clearAccess();
|
|
|
|
$tempAlliance = Model\BasicModel::getNew('AllianceModel');
|
|
|
|
foreach($accessAlliances as $allianceId){
|
|
$tempAlliance->getById( (int)$allianceId );
|
|
|
|
if(
|
|
!$tempAlliance->dry() &&
|
|
$tempAlliance->sharing == 1 // check if map sharing is enabled
|
|
){
|
|
$map->setAccess($tempAlliance);
|
|
}
|
|
|
|
$tempAlliance->reset();
|
|
}
|
|
|
|
}
|
|
|
|
// the alliance of the current user should always have access
|
|
$map->setAccess($alliance);
|
|
}
|
|
}
|
|
}
|
|
// reload the same map model (refresh)
|
|
// this makes sure all data is up2date
|
|
$map->getById( $map->id, 0 );
|
|
|
|
|
|
$return->mapData = $map->getData();
|
|
|
|
}else{
|
|
// map access denied
|
|
$captchaError = (object) [];
|
|
$captchaError->type = 'error';
|
|
$captchaError->message = 'Access denied';
|
|
$return->error[] = $captchaError;
|
|
}
|
|
}
|
|
|
|
}else{
|
|
// map id field missing
|
|
$idError = (object) [];
|
|
$idError->type = 'error';
|
|
$idError->message = 'Map id missing';
|
|
$return->error[] = $idError;
|
|
}
|
|
|
|
echo json_encode($return);
|
|
}
|
|
|
|
/**
|
|
* delete a map and all dependencies
|
|
* @param $f3
|
|
*/
|
|
public function delete($f3){
|
|
$mapData = (array)$f3->get('POST.mapData');
|
|
|
|
$user = $this->_getUser();
|
|
|
|
if($user){
|
|
$map = Model\BasicModel::getNew('MapModel');
|
|
$map->getById($mapData['id']);
|
|
$map->delete($user);
|
|
}
|
|
|
|
echo json_encode([]);
|
|
}
|
|
|
|
/**
|
|
* update map data
|
|
* function is called continuously
|
|
* @param $f3
|
|
*/
|
|
public function updateData($f3){
|
|
|
|
// cache time(s) per user should be equal or less than this function is called
|
|
// prevent request flooding
|
|
$responseTTL = $f3->get('PATHFINDER.TIMER.UPDATE_SERVER_MAP.DELAY') / 1000;
|
|
$mapData = (array)$f3->get('POST.mapData');
|
|
|
|
$user = $this->_getUser(0);
|
|
$return = (object) [];
|
|
$return->error = [];
|
|
|
|
if($user){
|
|
// -> get active character
|
|
$activeCharacter = $user->getActiveUserCharacter();
|
|
|
|
$cacheKey = 'user_map_data_' . $activeCharacter->id;
|
|
|
|
// if there is any system/connection change data submitted -> save new data
|
|
if(
|
|
$f3->exists($cacheKey) === false ||
|
|
!empty($mapData)
|
|
){
|
|
|
|
// get current map data ========================================================
|
|
$maps = $user->getMaps();
|
|
|
|
// loop all submitted map data that should be saved
|
|
// -> currently there will only be ONE map data change submitted -> single loop
|
|
foreach($mapData as $data){
|
|
|
|
$systems = [];
|
|
$connections = [];
|
|
|
|
// check whether system data and/or connection data is send
|
|
// empty arrays are not included in ajax requests
|
|
if( isset($data['data']['systems']) ){
|
|
$systems = (array)$data['data']['systems'];
|
|
}
|
|
|
|
if( isset($data['data']['connections']) ){
|
|
$connections = (array)$data['data']['connections'];
|
|
}
|
|
|
|
// check if system data or connection data is send
|
|
if(
|
|
count($systems) > 0 ||
|
|
count($connections) > 0
|
|
){
|
|
|
|
// map changes expected =============================================
|
|
|
|
// loop current user maps and check for changes
|
|
foreach($maps as $map){
|
|
|
|
// update system data -----------------------------------------------
|
|
foreach($systems as $i => $systemData){
|
|
|
|
// check if current system belongs to the current map
|
|
$map->filter('systems', ['id = ?', $systemData['id'] ]);
|
|
$filteredMap = $map->find(
|
|
['id = ?', $map->id ],
|
|
['limit' => 1]
|
|
);
|
|
|
|
// this should never fail
|
|
if(is_object($filteredMap)){
|
|
$filteredMap = $filteredMap->current();
|
|
|
|
// system belongs to the current map
|
|
if(is_object($filteredMap->systems)){
|
|
// update
|
|
unset($systemData['updated']);
|
|
$system = $filteredMap->systems->current();
|
|
$system->setData($systemData);
|
|
$system->updatedCharacterId = $activeCharacter->characterId;
|
|
$system->save();
|
|
|
|
// a system belongs to ONE map -> speed up for multiple maps
|
|
unset($systemData[$i]);
|
|
}
|
|
}
|
|
}
|
|
|
|
// update connection data -------------------------------------------
|
|
foreach($connections as $i => $connectionData){
|
|
|
|
// check if the current connection belongs to the current map
|
|
$map->filter('connections', ['id = ?', $connectionData['id'] ]);
|
|
$filteredMap = $map->find(
|
|
['id = ?', $map->id ],
|
|
['limit' => 1]
|
|
);
|
|
|
|
// this should never fail
|
|
if(is_object($filteredMap)){
|
|
$filteredMap = $filteredMap->current();
|
|
|
|
// connection belongs to the current map
|
|
if(is_object($filteredMap->connections)){
|
|
// update
|
|
unset($connectionData['updated']);
|
|
$connection = $filteredMap->connections->current();
|
|
$connection->setData($connectionData);
|
|
$connection->save($user);
|
|
|
|
// a connection belongs to ONE map -> speed up for multiple maps
|
|
unset($connectionData[$i]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// format map Data for return
|
|
$return->mapData = self::getFormattedMapData($maps);
|
|
$f3->set($cacheKey, $return, $responseTTL);
|
|
}else{
|
|
// get from cache
|
|
$return = $f3->get($cacheKey);
|
|
}
|
|
|
|
}else{
|
|
// user logged off
|
|
$return->error[] = $this->getUserLoggedOffError();
|
|
}
|
|
|
|
echo json_encode( $return );
|
|
}
|
|
|
|
/**
|
|
* @param $mapModels
|
|
* @return Model\MapModel[]
|
|
*/
|
|
public static function getFormattedMapData($mapModels){
|
|
|
|
$mapData = [];
|
|
foreach($mapModels as $mapModel){
|
|
|
|
$allMapData = $mapModel->getData();
|
|
|
|
$mapData[] = [
|
|
'config' => $allMapData->mapData,
|
|
'data' => [
|
|
'systems' => $allMapData->systems,
|
|
'connections' => $allMapData->connections,
|
|
]
|
|
];
|
|
}
|
|
|
|
return $mapData;
|
|
}
|
|
|
|
/**
|
|
* update map data api
|
|
* function is called continuously
|
|
* @param $f3
|
|
*/
|
|
public function updateUserData($f3){
|
|
|
|
// cache time(s) should be equal or less than request trigger time
|
|
// prevent request flooding
|
|
$responseTTL = $f3->get('PATHFINDER.TIMER.UPDATE_SERVER_USER_DATA.DELAY') / 1000;
|
|
|
|
// if the cache key will be set -> cache request
|
|
$cacheKey = null;
|
|
|
|
$return = (object) [];
|
|
$return->error = [];
|
|
|
|
$user = $this->_getUser(0);
|
|
|
|
if($user){
|
|
|
|
if( !empty($f3->get('POST.mapIds')) ){
|
|
$mapIds = (array)$f3->get('POST.mapIds');
|
|
// check if data for specific system is requested
|
|
$systemData = (array)$f3->get('POST.systemData');
|
|
|
|
|
|
// update current location (IGB data)
|
|
$user->updateCharacterLog(60 * 5);
|
|
|
|
// if data is requested extend the cache key in order to get new data
|
|
$requestSystemData = (object) [];
|
|
$requestSystemData->mapId = isset($systemData['mapId']) ? (int) $systemData['mapId'] : 0;
|
|
$requestSystemData->systemId = isset($systemData['systemData']['id']) ? (int) $systemData['systemData']['id'] : 0;
|
|
|
|
// IMPORTANT for now -> just update a single map (save performance)
|
|
$mapIds = array_slice($mapIds, 0, 1);
|
|
|
|
// the userMasData is cached per map (this must be changed if multiple maps
|
|
// will be allowed in future...
|
|
$tempId = (int)$mapIds[0];
|
|
$cacheKey = 'user_data_' . $tempId . '_' . $requestSystemData->systemId;
|
|
|
|
if( $f3->exists($cacheKey) === false ){
|
|
foreach($mapIds as $mapId){
|
|
$map = $user->getMap($mapId);
|
|
|
|
if( !is_null($map) ){
|
|
$return->mapUserData[] = $map->getUserData();
|
|
|
|
// request signature data for a system if user has map access!
|
|
if( $map->id === $requestSystemData->mapId ){
|
|
$system = $map->getSystem( $requestSystemData->systemId );
|
|
|
|
if( !is_null($system) ){
|
|
// data for the current selected system
|
|
$return->system = $system->getData();
|
|
$return->system->signatures = $system->getSignaturesData();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// cache response
|
|
$f3->set($cacheKey, $return, $responseTTL);
|
|
}else{
|
|
// get from cache
|
|
// this should happen if a user has multiple program instances running
|
|
// with the same main char
|
|
$return = $f3->get($cacheKey);
|
|
}
|
|
}
|
|
|
|
// get current user data -> this should not be cached because each user has different personal data
|
|
// even if they have multiple characters using the same map!
|
|
$return->userData = $user->getData();
|
|
|
|
}else{
|
|
// user logged off
|
|
$return->error[] = $this->getUserLoggedOffError();
|
|
}
|
|
|
|
|
|
echo json_encode( $return );
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|