- New "Sovereignty" and "Faction warfare" data added, closed #853
- New ESI data import for wormhole type data from _ESI_, closed #852 - New ESI data import static wormholes, closed #852 - Improved performance for character authorization (PHP). Reduced number of _SQL_ queries. - Improved HTTP cache header for `api/map/initData`, 'api/user/getEveServerStatus' ajax requests
This commit is contained in:
@@ -61,6 +61,7 @@ truncateMapHistoryLogFiles = Cron\MapHistory->truncateFiles, @halfHou
|
||||
|
||||
; updates small amount of static system data from CCP API
|
||||
;updateUniverseSystems = Cron\Universe->updateUniverseSystems, @instant
|
||||
;updateSovereigntyData = Cron\Universe->updateSovereigntyData, @instant
|
||||
|
||||
; setup universe DB with static data from ESI
|
||||
;setup = Cron\Universe->setup, @instant
|
||||
@@ -213,7 +213,7 @@ class Cortex extends Cursor {
|
||||
} else
|
||||
$this->whitelist=$fields;
|
||||
$id=$this->dbsType=='sql'?$this->primary:'_id';
|
||||
if (!in_array($id,$this->whitelist))
|
||||
if (!in_array($id,$this->whitelist) && !($exclude && in_array($id,$fields)))
|
||||
$this->whitelist[]=$id;
|
||||
$this->applyWhitelist();
|
||||
return $this->whitelist;
|
||||
@@ -595,7 +595,7 @@ class Cortex extends Cursor {
|
||||
* @param array|null $filter
|
||||
* @param array|null $options
|
||||
* @param int $ttl
|
||||
* @return CortexCollection
|
||||
* @return CortexCollection|false
|
||||
*/
|
||||
public function find($filter = NULL, array $options = NULL, $ttl = 0) {
|
||||
$sort=false;
|
||||
@@ -731,12 +731,12 @@ class Cortex extends Cursor {
|
||||
$addToFilter = array($id.' IN ?', $result);
|
||||
}
|
||||
// *-to-one
|
||||
elseif ($this->dbsType == 'sql') {
|
||||
elseif (!$deep && $this->dbsType == 'sql') {
|
||||
// use sub-query inclusion
|
||||
$has_filter=$this->mergeFilter([$has_filter,
|
||||
[$this->rel($key)->getTable().'.'.$fromConf[1].'='.$this->getTable().'.'.$id]]);
|
||||
$result = $this->_refSubQuery($key,$has_filter,$has_options);
|
||||
$addToFilter = ['exists('.$result[0].')']+$result[1];
|
||||
$addToFilter = array_merge(['exists('.$result[0].')'],$result[1]);
|
||||
}
|
||||
elseif ($result = $this->_hasRefsIn($key,$has_filter,$has_options,$ttl))
|
||||
$addToFilter = array($id.' IN ?', $result);
|
||||
@@ -781,11 +781,11 @@ class Cortex extends Cursor {
|
||||
$options['order'] = preg_replace('/\h+DESC(?=\s*(?:$|,))/i',' DESC NULLS LAST',$options['order']);
|
||||
// assemble full sql query for joined queries
|
||||
if ($hasJoin) {
|
||||
$adhoc=[];
|
||||
// when in count-mode and grouping is active, wrap the query later
|
||||
// otherwise add a an adhoc counter field here
|
||||
if (!($subquery_mode=($options && !empty($options['group']))) && $count)
|
||||
$this->adhoc['_rows']=['expr'=>'COUNT(*)','value'=>NULL];
|
||||
$adhoc=[];
|
||||
$adhoc[]='(COUNT(*)) as _rows';
|
||||
if (!$count)
|
||||
// add bind parameters for filters in adhoc fields
|
||||
if ($this->preBinds) {
|
||||
@@ -1224,7 +1224,7 @@ class Cortex extends Cursor {
|
||||
// m:m save cascade
|
||||
if (!empty($this->saveCsd)) {
|
||||
foreach($this->saveCsd as $key => $val) {
|
||||
if($fields[$key]['relType'] == 'has-many') {
|
||||
if ($fields[$key]['relType'] == 'has-many') {
|
||||
$relConf = $fields[$key]['has-many'];
|
||||
if ($relConf['hasRel'] == 'has-many') {
|
||||
$mmTable = $this->mmTable($relConf,$key);
|
||||
@@ -1236,12 +1236,12 @@ class Cortex extends Cursor {
|
||||
$filter[] = $id;
|
||||
}
|
||||
// delete all refs
|
||||
if (is_null($val))
|
||||
if (empty($val))
|
||||
$mm->erase($filter);
|
||||
// update refs
|
||||
elseif (is_array($val)) {
|
||||
$mm->erase($filter);
|
||||
foreach($val as $v) {
|
||||
foreach(array_unique($val) as $v) {
|
||||
if ($relConf['isSelf'] && $v==$id)
|
||||
continue;
|
||||
$mm->set($key,$v);
|
||||
@@ -1256,7 +1256,7 @@ class Cortex extends Cursor {
|
||||
$rel = $this->getRelInstance($relConf[0],$relConf,$key);
|
||||
// find existing relations
|
||||
$refs = $rel->find([$relConf[1].' = ?',$this->getRaw($relConf['relField'])]);
|
||||
if (is_null($val)) {
|
||||
if (empty($val)) {
|
||||
foreach ($refs?:[] as $model) {
|
||||
$model->set($relConf[1],NULL);
|
||||
$model->save();
|
||||
@@ -1470,7 +1470,7 @@ class Cortex extends Cursor {
|
||||
// handle relations
|
||||
if (isset($fields[$key]['belongs-to-one'])) {
|
||||
// one-to-many, one-to-one
|
||||
if (is_null($val))
|
||||
if (empty($val))
|
||||
$val = NULL;
|
||||
elseif (is_object($val) &&
|
||||
!($this->dbsType=='mongo' && (
|
||||
@@ -1489,7 +1489,7 @@ class Cortex extends Cursor {
|
||||
$val = $this->db->legacy() ? new \MongoId($val) : new \MongoDB\BSON\ObjectId($val);
|
||||
} elseif (isset($fields[$key]['has-one'])){
|
||||
$relConf = $fields[$key]['has-one'];
|
||||
if (is_null($val)) {
|
||||
if (empty($val)) {
|
||||
$val = $this->get($key);
|
||||
$val->set($relConf[1],NULL);
|
||||
} else {
|
||||
@@ -2554,7 +2554,7 @@ class CortexQueryParser extends \Prefab {
|
||||
function($match) use($db) {
|
||||
if (!isset($match[1]))
|
||||
return $match[0];
|
||||
if (preg_match('/\b(AND|OR|IN|LIKE|NOT)\b/i',$match[1]))
|
||||
if (preg_match('/\b(AND|OR|IN|LIKE|NOT|HAVING|SELECT|FROM|WHERE)\b/i',$match[1]))
|
||||
return $match[1];
|
||||
return $db->quotekey($match[1]);
|
||||
}, $cond);
|
||||
@@ -2576,7 +2576,7 @@ class CortexQueryParser extends \Prefab {
|
||||
function($match) use($table) {
|
||||
if (!isset($match[3]))
|
||||
return $match[1];
|
||||
if (preg_match('/\b(AND|OR|IN|LIKE|NOT)\b/i',$match[3]))
|
||||
if (preg_match('/\b(AND|OR|IN|LIKE|NOT|HAVING|SELECT|FROM|WHERE)\b/i',$match[3]))
|
||||
return $match[0];
|
||||
return $match[2].$table.'.'.$match[3];
|
||||
}, $cond);
|
||||
|
||||
@@ -36,14 +36,15 @@ class AccessController extends Controller {
|
||||
}
|
||||
|
||||
/**
|
||||
* get current character and check if it is a valid character
|
||||
* check login status and look or a valid character
|
||||
* @param \Base $f3
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function isLoggedIn(\Base $f3) : string {
|
||||
$loginStatus = 'UNKNOWN';
|
||||
if($character = $this->getCharacter()){
|
||||
// disable ttl cache time here. Further getCharacter() calls should use a short ttl
|
||||
if($character = $this->getCharacter(0)){
|
||||
if($character->checkLoginTimer()){
|
||||
if(( $authStatus = $character->isAuthorized()) === 'OK'){
|
||||
$loginStatus = 'OK';
|
||||
|
||||
@@ -89,7 +89,7 @@ class Admin extends Controller{
|
||||
protected function getAdminCharacter(\Base $f3){
|
||||
$adminCharacter = null;
|
||||
if( !$f3->exists(Sso::SESSION_KEY_SSO_ERROR) ){
|
||||
if( $character = $this->getCharacter() ){
|
||||
if( $character = $this->getCharacter(0) ){
|
||||
if(in_array($character->roleId->name, ['SUPER', 'CORPORATION'], true)){
|
||||
// current character is admin
|
||||
$adminCharacter = $character;
|
||||
@@ -288,7 +288,7 @@ class Admin extends Controller{
|
||||
$characters = [];
|
||||
// check if kickCharacters belong to same Corp as admin character
|
||||
// -> remove admin char from valid characters...
|
||||
if( !empty($characterIds = array_diff( [$characterId], [$character->_id])) ){
|
||||
if( !empty($characterIds = array_diff([$characterId], [$character->_id])) ){
|
||||
if($character->roleId->name === 'SUPER'){
|
||||
if($filterCharacters = CharacterModel::getAll($characterIds)){
|
||||
$characters = $filterCharacters;
|
||||
@@ -337,7 +337,7 @@ class Admin extends Controller{
|
||||
$maps = $filterMaps;
|
||||
}
|
||||
}else{
|
||||
$maps = $character->getCorporation()->getMaps([$mapId], ['addInactive' => true, 'ignoreMapCount' => true]);
|
||||
$maps = $character->getCorporation()->getMaps($mapId, ['addInactive' => true, 'ignoreMapCount' => true]);
|
||||
}
|
||||
|
||||
return $maps;
|
||||
@@ -404,7 +404,7 @@ class Admin extends Controller{
|
||||
$corporations = $this->getAccessibleCorporations($character);
|
||||
|
||||
foreach($corporations as $corporation){
|
||||
if($maps = $corporation->getMaps([], ['addInactive' => true, 'ignoreMapCount' => true])){
|
||||
if($maps = $corporation->getMaps(null, ['addInactive' => true, 'ignoreMapCount' => true])){
|
||||
$data->corpMaps[$corporation->name] = $maps;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,13 +52,10 @@ class Map extends Controller\AccessController {
|
||||
* @throws Exception
|
||||
*/
|
||||
public function initData(\Base $f3){
|
||||
// expire time in seconds
|
||||
$expireTimeCache = 60 * 60;
|
||||
|
||||
if(!$f3->exists(self::CACHE_KEY_INIT, $return)){
|
||||
// response should not be cached if invalid -> e.g. missing static data
|
||||
$validInitData = true;
|
||||
$validInitData = true;
|
||||
$ttl = 60 * 60;
|
||||
|
||||
if(!$exists = $f3->exists(self::CACHE_KEY_INIT, $return)){
|
||||
$return = (object) [];
|
||||
$return->error = [];
|
||||
|
||||
@@ -199,29 +196,33 @@ class Map extends Controller\AccessController {
|
||||
|
||||
// structure status ---------------------------------------------------------------------------------------
|
||||
$structureStatus = Pathfinder\StructureStatusModel::getAll();
|
||||
$structureData = [];
|
||||
$structureStatusData = [];
|
||||
foreach($structureStatus as $status){
|
||||
$structureData[$status->_id] = $status->getData();
|
||||
$structureStatusData[$status->_id] = $status->getData();
|
||||
}
|
||||
$return->structureStatus = $structureData;
|
||||
$return->structureStatus = $structureStatusData;
|
||||
|
||||
$validInitData = $validInitData ? !empty($structureData) : $validInitData;
|
||||
$validInitData = $validInitData ? !empty($structureStatusData) : $validInitData;
|
||||
|
||||
// get available wormhole types ---------------------------------------------------------------------------
|
||||
/**
|
||||
* @var $wormhole Universe\WormholeModel
|
||||
* @var $groupUniverseModel Universe\GroupModel
|
||||
*/
|
||||
$wormhole = Universe\AbstractUniverseModel::getNew('WormholeModel');
|
||||
$groupUniverseModel = Universe\AbstractUniverseModel::getNew('GroupModel');
|
||||
$groupUniverseModel->getById(Config::ESI_GROUP_WORMHOLE_ID);
|
||||
$wormholesData = [];
|
||||
if($rows = $wormhole->find(null, ['order' => 'name asc'])){
|
||||
foreach($rows as $rowData){
|
||||
$wormholesData[$rowData->name] = $rowData->getData();
|
||||
/**
|
||||
* @var $typeModel Universe\TypeModel
|
||||
*/
|
||||
foreach($types = $groupUniverseModel->getTypes(false) as $typeModel){
|
||||
if(
|
||||
($wormholeData = $typeModel->getWormholeData()) &&
|
||||
mb_strlen((string)$wormholeData->name) === 4
|
||||
){
|
||||
$wormholesData[$wormholeData->name] = $wormholeData;
|
||||
}
|
||||
|
||||
$wormhole->reset();
|
||||
$wormhole->name = 'K162';
|
||||
$wormholesData[$wormhole->name] = $wormhole->getData();
|
||||
}
|
||||
ksort($wormholesData);
|
||||
$return->wormholes = $wormholesData;
|
||||
|
||||
$validInitData = $validInitData ? !empty($wormholesData) : $validInitData;
|
||||
@@ -231,20 +232,20 @@ class Map extends Controller\AccessController {
|
||||
* @var $categoryUniverseModel Universe\CategoryModel
|
||||
*/
|
||||
$categoryUniverseModel = Universe\AbstractUniverseModel::getNew('CategoryModel');
|
||||
$categoryUniverseModel->getById(6);
|
||||
$shipData = $categoryUniverseModel->getData(['mass']);
|
||||
$categoryUniverseModel->getById(65);
|
||||
$structureData = $categoryUniverseModel->getData();
|
||||
|
||||
$return->universeCategories = [
|
||||
6 => $shipData,
|
||||
65 => $structureData
|
||||
Config::ESI_CATEGORY_SHIP_ID =>
|
||||
($categoryUniverseModel->getById(Config::ESI_CATEGORY_SHIP_ID) && $categoryUniverseModel->valid()) ? $categoryUniverseModel->getData(['mass']) : null,
|
||||
Config::ESI_CATEGORY_STRUCTURE_ID =>
|
||||
($categoryUniverseModel->getById(Config::ESI_CATEGORY_STRUCTURE_ID) && $categoryUniverseModel->valid()) ? $categoryUniverseModel->getData() : null,
|
||||
];
|
||||
|
||||
$validInitData = $validInitData ? !empty($return->universeCategories[65]) : $validInitData;
|
||||
$validInitData = $validInitData ? !count(array_filter($return->universeCategories, function($v){
|
||||
return empty(array_filter((array)$v->groups));
|
||||
})) : $validInitData;
|
||||
|
||||
// response should not be cached if invalid -> e.g. missing static data
|
||||
if($validInitData){
|
||||
$f3->set(self::CACHE_KEY_INIT, $return, $expireTimeCache );
|
||||
$f3->set(self::CACHE_KEY_INIT, $return, $ttl);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -257,6 +258,9 @@ class Map extends Controller\AccessController {
|
||||
$ssoError->message = $message;
|
||||
$return->error[] = $ssoError;
|
||||
$f3->clear(Controller\Ccp\Sso::SESSION_KEY_SSO_ERROR);
|
||||
}elseif($validInitData){
|
||||
// no errors and valid data -> send Cache header
|
||||
$f3->expire(Config::ttlLeft($exists, $ttl));
|
||||
}
|
||||
|
||||
echo json_encode($return);
|
||||
@@ -906,14 +910,13 @@ class Map extends Controller\AccessController {
|
||||
// systemData -----------------------------------------------------------------------------------------
|
||||
if(
|
||||
$mapId === (int)$systemData['mapId'] &&
|
||||
!is_null($system = $map->getSystemById((int)$systemData['systemData']['id']))
|
||||
!is_null($system = $map->getSystemById((int)$systemData['id']))
|
||||
){
|
||||
// data for currently selected system
|
||||
$return->system = $system->getData();
|
||||
$return->system->signatures = $system->getSignaturesData();
|
||||
$return->system->sigHistory = $system->getSignaturesHistory();
|
||||
$return->system->structures = $system->getStructuresData();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,14 +91,16 @@ class Route extends Controller\AccessController {
|
||||
* -> this data is equal for EACH route search (does not depend on map data)
|
||||
*/
|
||||
private function setStaticJumpData(){
|
||||
$query = "SELECT * FROM system_neighbour";
|
||||
$rows = $this->getDB()->exec($query, null, $this->staticJumpDataCacheTime);
|
||||
if($universeDB = $this->getDB('UNIVERSE')){
|
||||
$query = "SELECT * FROM system_neighbour";
|
||||
$rows = $universeDB->exec($query, null, $this->staticJumpDataCacheTime);
|
||||
|
||||
if(count($rows) > 0){
|
||||
array_walk($rows, function(&$row){
|
||||
$row['jumpNodes'] = array_map('intval', explode(':', $row['jumpNodes']));
|
||||
});
|
||||
$this->updateJumpData($rows);
|
||||
if(count($rows) > 0){
|
||||
array_walk($rows, function(&$row){
|
||||
$row['jumpNodes'] = array_map('intval', explode(':', $row['jumpNodes']));
|
||||
});
|
||||
$this->updateJumpData($rows);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
namespace Controller\Api;
|
||||
|
||||
use Controller;
|
||||
use lib\Config;
|
||||
use Model;
|
||||
|
||||
class Setup extends Controller\Controller {
|
||||
@@ -23,6 +24,7 @@ class Setup extends Controller\Controller {
|
||||
public function buildIndex(\Base $f3){
|
||||
$postData = (array)$f3->get('POST');
|
||||
$type = (string)$postData['type'];
|
||||
$countAll = (int)$postData['countAll'];
|
||||
$count = (int)$postData['count'];
|
||||
$offset = (int)$postData['offset'];
|
||||
|
||||
@@ -31,7 +33,7 @@ class Setup extends Controller\Controller {
|
||||
$return->type = $type;
|
||||
$return->count = $count;
|
||||
$return->offset = $offset;
|
||||
$return->countAll = 0;
|
||||
$return->countAll = $countAll;
|
||||
$return->countBuild = 0;
|
||||
$return->countBuildAll = 0;
|
||||
$return->progress = 0;
|
||||
@@ -42,7 +44,7 @@ class Setup extends Controller\Controller {
|
||||
* @param int $value
|
||||
* @return int
|
||||
*/
|
||||
$sum = function(int $carry, int $value){
|
||||
$sum = function(int $carry, int $value) : int {
|
||||
$carry += $value;
|
||||
return $carry;
|
||||
};
|
||||
@@ -62,49 +64,72 @@ class Setup extends Controller\Controller {
|
||||
case 'Systems':
|
||||
$length = 100;
|
||||
$buildInfo = $controller->buildSystemsIndex($offset, $length);
|
||||
|
||||
$return->offset = $buildInfo['offset'];
|
||||
$return->countAll = $buildInfo['countAll'];
|
||||
$return->countBuild = $buildInfo['countBuild'];
|
||||
$return->countBuildAll = $offset;
|
||||
$return->progress = $percent($return->countAll, $offset);
|
||||
$return->countBuildAll = $return->offset;
|
||||
break;
|
||||
case 'Wormholes':
|
||||
$groupId = Config::ESI_GROUP_WORMHOLE_ID;
|
||||
$length = 10;
|
||||
$buildInfo = $controller->setupGroup($groupId, $offset, $length, true);
|
||||
|
||||
$return->offset = $buildInfo['offset'];
|
||||
$return->countAll = $buildInfo['countAll'];
|
||||
$return->countBuild = $buildInfo['count'];
|
||||
$return->countBuildAll = $return->offset;
|
||||
break;
|
||||
case 'Structures':
|
||||
$categoryId = 65;
|
||||
$length = 2;
|
||||
$offset = $count * $length;
|
||||
$categoryId = Config::ESI_CATEGORY_STRUCTURE_ID;
|
||||
$length = 1;
|
||||
$buildInfo = $controller->setupCategory($categoryId, $offset, $length);
|
||||
|
||||
$categoryUniverseModel = Model\Universe\AbstractUniverseModel::getNew('CategoryModel');
|
||||
$categoryUniverseModel->getById($categoryId, 0);
|
||||
$return->countAll = (int)$f3->get('REQUIREMENTS.DATA.STRUCTURES');
|
||||
$return->countBuild = array_reduce($buildInfo, $sum, 0);
|
||||
$return->countBuildAll = $categoryUniverseModel->getTypesCount(false);
|
||||
$return->progress = $percent($return->countAll, $return->countBuildAll);
|
||||
|
||||
$return->offset = $buildInfo['offset'];
|
||||
$return->countBuild = $buildInfo['count'];
|
||||
$return->countBuildAll = $return->offset;
|
||||
$return->subCount = [
|
||||
'countBuildAll' => $categoryUniverseModel->getTypesCount(false)
|
||||
];
|
||||
break;
|
||||
case 'Ships':
|
||||
$categoryId = 6;
|
||||
$categoryId = Config::ESI_CATEGORY_SHIP_ID;
|
||||
$length = 2;
|
||||
$offset = $count * $length;
|
||||
$buildInfo = $controller->setupCategory($categoryId, $offset, $length);
|
||||
|
||||
$categoryUniverseModel = Model\Universe\AbstractUniverseModel::getNew('CategoryModel');
|
||||
$categoryUniverseModel->getById($categoryId, 0);
|
||||
$return->countAll = (int)$f3->get('REQUIREMENTS.DATA.SHIPS');
|
||||
$return->countBuild = array_reduce($buildInfo, $sum, 0);
|
||||
$return->countBuildAll = $categoryUniverseModel->getTypesCount(false);
|
||||
$return->progress = $percent($return->countAll, $return->countBuildAll);
|
||||
|
||||
$return->offset = $buildInfo['offset'];
|
||||
$return->countBuild = $buildInfo['count'];
|
||||
$return->countBuildAll = $return->offset;
|
||||
$return->subCount = [
|
||||
'countBuildAll' => $categoryUniverseModel->getTypesCount(false)
|
||||
];
|
||||
break;
|
||||
case 'SystemStatic':
|
||||
$length = 300;
|
||||
$buildInfo = $this->setupSystemStaticTable($offset, $length);
|
||||
|
||||
$return->offset = $buildInfo['offset'];
|
||||
$return->countAll = $buildInfo['countAll'];
|
||||
$return->countBuild = $buildInfo['count'];
|
||||
$return->countBuildAll = $return->offset;
|
||||
break;
|
||||
case 'SystemNeighbour':
|
||||
// Becomes deprecated with new Universe DB!!!
|
||||
$this->setupSystemJumpTable();
|
||||
$length = 1500;
|
||||
$buildInfo = $this->setupSystemJumpTable($offset, $length);
|
||||
|
||||
$return->countAll = (int)$f3->get('REQUIREMENTS.DATA.NEIGHBOURS');
|
||||
$return->countBuild = $f3->DB->getDB('PF')->getRowCount('system_neighbour');
|
||||
$return->countBuildAll = $return->countBuild;
|
||||
$return->progress = $percent($return->countAll, $return->countBuildAll);
|
||||
$return->offset = $buildInfo['offset'];
|
||||
$return->countAll = $buildInfo['countAll'];
|
||||
$return->countBuild = $buildInfo['count'];
|
||||
$return->countBuildAll = $return->offset;
|
||||
break;
|
||||
}
|
||||
|
||||
$return->progress = $percent($return->countAll, $return->countBuildAll);
|
||||
|
||||
if($return->countBuildAll < $return->countAll){
|
||||
$return->count++;
|
||||
}
|
||||
@@ -135,21 +160,87 @@ class Setup extends Controller\Controller {
|
||||
case 'Systems':
|
||||
$controller->clearSystemsIndex();
|
||||
$systemUniverseModel = Model\Universe\AbstractUniverseModel::getNew('SystemModel');
|
||||
$return->countAll = $f3->DB->getDB('UNIVERSE')->getRowCount($systemUniverseModel->getTable());
|
||||
$return->countAll = $systemUniverseModel->getRowCount();
|
||||
break;
|
||||
case 'SystemNeighbour':
|
||||
$systemNeighbourModel = Model\Universe\AbstractUniverseModel::getNew('SystemNeighbourModel');
|
||||
$systemNeighbourModel->truncate();
|
||||
$return->countAll = (int)$f3->get('REQUIREMENTS.DATA.NEIGHBOURS');
|
||||
break;
|
||||
}
|
||||
|
||||
echo json_encode($return);
|
||||
}
|
||||
|
||||
/**
|
||||
* import static 'system_static` table data from *.csv
|
||||
* @param int $offset
|
||||
* @param int $length
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function setupSystemStaticTable(int $offset = 0, int $length = 0) : array {
|
||||
$info = ['countAll' => 0, 'countChunk' => 0, 'count' => 0, 'offset' => $offset];
|
||||
|
||||
/**
|
||||
* @var $systemStaticModel Model\Universe\SystemStaticModel
|
||||
*/
|
||||
$systemStaticModel = Model\Universe\AbstractUniverseModel::getNew('SystemStaticModel');
|
||||
if(!empty($csvData = $systemStaticModel::getCSVData($systemStaticModel->getTable()))){
|
||||
$info['countAll'] = count($csvData);
|
||||
if($length){
|
||||
$csvData = array_slice($csvData, $offset, $length);
|
||||
}
|
||||
$info['countChunk'] = count($csvData);
|
||||
$cols = ['typeId' => [], 'systemId' => []];
|
||||
foreach($csvData as $data){
|
||||
$validColCount = 0;
|
||||
$systemStaticModel->getById((int)$data['id'], 0);
|
||||
$systemStaticModel->id = (int)$data['id'];
|
||||
foreach($cols as $col => &$invalidIds){
|
||||
if($systemStaticModel->exists($col)){
|
||||
$colVal = (int)$data[$col];
|
||||
if(!in_array($colVal, $invalidIds)){
|
||||
$relModel = $systemStaticModel->rel($col);
|
||||
$relModel->getById($colVal, 0);
|
||||
if($relModel->valid()){
|
||||
$systemStaticModel->$col = $relModel;
|
||||
$validColCount++;
|
||||
}else{
|
||||
$invalidIds[] = $colVal;
|
||||
break;
|
||||
}
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($validColCount == count($cols)){
|
||||
$systemStaticModel->save();
|
||||
}
|
||||
$systemStaticModel->reset();
|
||||
|
||||
$info['count']++;
|
||||
$info['offset']++;
|
||||
}
|
||||
}
|
||||
|
||||
return $info;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is just for setting up the cache table 'system_neighbour' which is used
|
||||
* for system jump calculation. Call this function manually when CCP adds Systems/Stargates
|
||||
* @param int $offset
|
||||
* @param int $length
|
||||
* @return array
|
||||
*/
|
||||
protected function setupSystemJumpTable(){
|
||||
$universeDB = $this->getDB('UNIVERSE');
|
||||
protected function setupSystemJumpTable(int $offset = 0, int $length = 0) : array {
|
||||
$info = ['countAll' => 0, 'countChunk' => 0, 'count' => 0, 'offset' => $offset];
|
||||
$universeDB = $this->getDB('UNIVERSE');
|
||||
|
||||
$query = "SELECT
|
||||
$query = "SELECT SQL_CALC_FOUND_ROWS
|
||||
`system`.`id` `systemId`,
|
||||
`system`.`name` `systemName`,
|
||||
`system`.`constellationId` `constellationId`,
|
||||
@@ -178,58 +269,73 @@ class Setup extends Controller\Controller {
|
||||
`system`.`security` = :ls OR
|
||||
`system`.`security` = :hs
|
||||
)
|
||||
HAVING
|
||||
`jumpNodes` IS NOT NULL
|
||||
";
|
||||
|
||||
$rows = $universeDB->exec($query, [
|
||||
$args = [
|
||||
':regionIdJove1' => 10000017,
|
||||
':regionIdJove2' => 10000019,
|
||||
':regionIdJove3' => 10000004,
|
||||
':ns' => '0.0',
|
||||
':ls' => 'L',
|
||||
':hs' => 'H'
|
||||
]);
|
||||
];
|
||||
|
||||
if(count($rows)){
|
||||
$pfDB = $this->getDB('PF');
|
||||
if($length){
|
||||
$query .= ' LIMIT :limit';
|
||||
$args[':limit'] = $length;
|
||||
|
||||
// clear cache table
|
||||
$pfDB->exec("TRUNCATE system_neighbour");
|
||||
if($offset){
|
||||
$query .= ' OFFSET :offset';
|
||||
$args[':offset'] = $offset;
|
||||
}
|
||||
}
|
||||
|
||||
$rows = $universeDB->exec($query, $args);
|
||||
|
||||
if(!empty($countRes = $universeDB->exec("SELECT FOUND_ROWS() `count`")) && isset($countRes[0]['count'])){
|
||||
$info['countAll'] = (int)$countRes[0]['count'];
|
||||
}
|
||||
|
||||
if($info['countChunk'] = count($rows)){
|
||||
$placeholderStr = function(string $str) : string {
|
||||
return ':' . $str;
|
||||
};
|
||||
|
||||
$updateRule = function(string $str) : string {
|
||||
return $str . " = VALUES(" . $str . ")";
|
||||
};
|
||||
|
||||
$universeDB->begin();
|
||||
foreach($rows as $row){
|
||||
$info['count']++;
|
||||
$info['offset']++;
|
||||
|
||||
if(!$row['jumpNodes']){
|
||||
// should never happen!
|
||||
continue;
|
||||
}
|
||||
|
||||
$pfDB->exec("
|
||||
INSERT INTO
|
||||
system_neighbour(
|
||||
regionId,
|
||||
constellationId,
|
||||
systemName,
|
||||
systemId,
|
||||
jumpNodes,
|
||||
trueSec
|
||||
)
|
||||
VALUES(
|
||||
:regionId,
|
||||
:constellationId,
|
||||
:systemName,
|
||||
:systemId,
|
||||
:jumpNodes,
|
||||
:trueSec
|
||||
)",
|
||||
[
|
||||
':regionId' => $row['regionId'],
|
||||
':constellationId' => $row['constellationId'],
|
||||
':systemName' => $row['systemName'],
|
||||
':systemId' => $row['systemId'],
|
||||
':jumpNodes' => $row['jumpNodes'],
|
||||
':trueSec' => $row['trueSec']
|
||||
]
|
||||
);
|
||||
$columns = array_keys($row);
|
||||
$columnsQuoted = array_map($universeDB->quotekey, $columns);
|
||||
$placeholder = array_map($placeholderStr, $columns);
|
||||
$args = array_combine($placeholder, $row);
|
||||
|
||||
$updateSql = array_map($updateRule, $columns);
|
||||
|
||||
$sql = "INSERT INTO
|
||||
system_neighbour(" . implode(', ', $columnsQuoted) . ")
|
||||
VALUES(" . implode(', ', $placeholder) . ")
|
||||
ON DUPLICATE KEY UPDATE
|
||||
" . implode(', ', $updateSql);
|
||||
|
||||
$universeDB->exec($sql, $args);
|
||||
}
|
||||
$universeDB->commit();
|
||||
}
|
||||
|
||||
return $info;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -112,7 +112,7 @@ class Universe extends Controller\AccessController {
|
||||
|
||||
$constellation = Model\Universe\AbstractUniverseModel::getNew('ConstellationModel');
|
||||
$constellation->getById($constellationId);
|
||||
if( !$constellation->dry() && $constellation->systems){
|
||||
if($constellation->valid() && $constellation->systems){
|
||||
/**
|
||||
* @var Model\Universe\SystemModel $system
|
||||
*/
|
||||
|
||||
@@ -128,7 +128,7 @@ class User extends Controller\Controller{
|
||||
// character is valid and allowed to login
|
||||
$return->character = reset($characters)->getData();
|
||||
// get Session status for character
|
||||
if($activeCharacter = $this->getCharacter()){
|
||||
if($activeCharacter = $this->getCharacter(0)){
|
||||
if($activeUser = $activeCharacter->getUser()){
|
||||
if($sessionCharacterData = $activeUser->findSessionCharacterData($return->character->id)){
|
||||
$return->character->hasActiveSession = true;
|
||||
|
||||
@@ -81,7 +81,7 @@ class Sso extends Api\User{
|
||||
|
||||
// check if character is valid and exists
|
||||
if(
|
||||
!$character->dry() &&
|
||||
$character->valid() &&
|
||||
$character->hasUserCharacter() &&
|
||||
($activeCharacter->getUser()->_id === $character->getUser()->_id)
|
||||
){
|
||||
@@ -217,9 +217,9 @@ class Sso extends Api\User{
|
||||
$characterModel = $characterModel->updateLog();
|
||||
|
||||
// connect character with current user
|
||||
if( is_null($user = $this->getUser()) ){
|
||||
if(is_null($user = $this->getUser())){
|
||||
// connect character with existing user (no changes)
|
||||
if( is_null( $user = $characterModel->getUser()) ){
|
||||
if(is_null($user = $characterModel->getUser())){
|
||||
// no user found (new character) -> create new user and connect to character
|
||||
/**
|
||||
* @var $user Pathfinder\UserModel
|
||||
@@ -234,7 +234,7 @@ class Sso extends Api\User{
|
||||
* @var $userCharactersModel Pathfinder\UserCharacterModel
|
||||
*/
|
||||
if( is_null($userCharactersModel = $characterModel->userCharacter) ){
|
||||
$userCharactersModel = Pathfinder\AbstractPathfinderModel::getNew('UserCharacterModel');
|
||||
$userCharactersModel = $characterModel->rel('userCharacter');
|
||||
$userCharactersModel->characterId = $characterModel;
|
||||
}
|
||||
|
||||
|
||||
@@ -53,6 +53,25 @@ class Universe extends Controller {
|
||||
}
|
||||
}*/
|
||||
|
||||
/**
|
||||
* setup categories + all dependencies (e.g. groups, types)
|
||||
* id 2 -> Celestial (>100 groups -> >1000 types)
|
||||
* id 6 -> Ship (46 groups -> 4xx types)
|
||||
* id 65 -> Structure (10 groups -> 33 types)
|
||||
* @param array $categoriesWhitelist
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function setupCategories(array $categoriesWhitelist = []) : array {
|
||||
$info = [];
|
||||
$categoryIds = Model\Universe\CategoryModel::getUniverseCategories();
|
||||
$categoryIds = array_intersect($categoriesWhitelist, $categoryIds);
|
||||
foreach($categoryIds as $categoryId){
|
||||
$info[$categoryId] = $this->setupCategory($categoryId);
|
||||
}
|
||||
return $info;
|
||||
}
|
||||
|
||||
/**
|
||||
* setup category + all dependencies (e.g. groups, types)
|
||||
* -> $length = 0 -> setup all groups
|
||||
@@ -63,41 +82,18 @@ class Universe extends Controller {
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function setupCategory(int $categoryId, int $offset = 0, int $length = 0) : array {
|
||||
$return = [];
|
||||
$info = ['countAll' => 0, 'countChunk' => 0, 'count' => 0, 'offset' => $offset, 'groupTypes' => []];
|
||||
|
||||
if($categoryId){
|
||||
/**
|
||||
* @var $category Model\Universe\CategoryModel
|
||||
*/
|
||||
$category = Model\Universe\AbstractUniverseModel::getNew('CategoryModel');
|
||||
$category->loadById($categoryId);
|
||||
$groupIds = $category->loadGroupsData($offset, $length);
|
||||
foreach((array)$category->groups as $group){
|
||||
// only load types for changed groups (not all)
|
||||
if(in_array($group->_id, $groupIds)){
|
||||
$return[$group->_id] = $group->loadTypesData();
|
||||
}
|
||||
}
|
||||
$info = $category->loadGroupsData($offset, $length);
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* setup categories + all dependencies (e.g. groups, types)
|
||||
* id 2 -> Celestial (>100 groups -> >1000 types)
|
||||
* id 6 -> Ship (45 groups -> 490 types)
|
||||
* id 65 -> Structure (10 groups -> 33 types)
|
||||
* @param array $categoriesWhitelist
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function setupCategories(array $categoriesWhitelist = []) : array {
|
||||
$return = [];
|
||||
$categoryIds = $this->getF3()->ccpClient()->getUniverseCategories();
|
||||
$categoryIds = array_intersect($categoriesWhitelist, $categoryIds);
|
||||
foreach($categoryIds as $categoryId){
|
||||
$return[$categoryId] = $this->setupCategory($categoryId);
|
||||
}
|
||||
return $return;
|
||||
return $info;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -111,19 +107,38 @@ class Universe extends Controller {
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function setupGroups(array $groupsWhitelist = []) : array {
|
||||
$return = [];
|
||||
$groupIds = $this->getF3()->ccpClient()->getUniverseGroups();
|
||||
$info = [];
|
||||
$groupIds = Model\Universe\GroupModel::getUniverseGroups();
|
||||
$groupIds = array_intersect($groupsWhitelist, $groupIds);
|
||||
/**
|
||||
* @var $group Model\Universe\GroupModel
|
||||
*/
|
||||
$group = Model\Universe\AbstractUniverseModel::getNew('GroupModel');
|
||||
foreach($groupIds as $groupId){
|
||||
$group->loadById($groupId);
|
||||
$return[$group->_id] = $group->loadTypesData();
|
||||
$group->reset();
|
||||
$info[$groupId] = $this->setupGroup($groupId);
|
||||
}
|
||||
return $return;
|
||||
return $info;
|
||||
}
|
||||
|
||||
/**
|
||||
* setup group + all dependencies (e.g. types)
|
||||
* @param int $groupId
|
||||
* @param int $offset
|
||||
* @param int $length
|
||||
* @param bool $storeDogmaAttributes
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function setupGroup(int $groupId, int $offset = 0, int $length = 0, bool $storeDogmaAttributes = false) : array {
|
||||
$info = ['countAll' => 0, 'countChunk' => 0, 'count' => 0, 'offset' => $offset];
|
||||
|
||||
if($groupId){
|
||||
/**
|
||||
* @var $group Model\Universe\GroupModel
|
||||
*/
|
||||
$group = Model\Universe\AbstractUniverseModel::getNew('GroupModel');
|
||||
$group->storeDogmaAttributes = $storeDogmaAttributes;
|
||||
$group->loadById($groupId);
|
||||
$info = $group->loadTypesData($offset, $length);
|
||||
}
|
||||
|
||||
return $info;
|
||||
}
|
||||
|
||||
// system search index methods ====================================================================================
|
||||
@@ -150,6 +165,7 @@ class Universe extends Controller {
|
||||
if($hashKeyId = $system->getHashKey()){
|
||||
$indexData[$hashKeyId] = $system->getData();
|
||||
}
|
||||
$system->reset();
|
||||
// offset must increase otherwise we get a endless loop
|
||||
// -> see /setup ajax build loop function
|
||||
$offset++;
|
||||
@@ -165,12 +181,14 @@ class Universe extends Controller {
|
||||
|
||||
/**
|
||||
* get systemIds for all systems
|
||||
* @param bool $ignoreCache
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getSystemIds() : array {
|
||||
public function getSystemIds(bool $ignoreCache = false) : array {
|
||||
$f3 = $this->getF3();
|
||||
if( !$f3->exists(self::SESSION_KEY_SYSTEM_IDS, $systemIds) ){
|
||||
$systemIds = [];
|
||||
if($ignoreCache || !$f3->exists(self::SESSION_KEY_SYSTEM_IDS, $systemIds)){
|
||||
/**
|
||||
* @var $system Model\Universe\SystemModel
|
||||
*/
|
||||
@@ -184,7 +202,7 @@ class Universe extends Controller {
|
||||
}
|
||||
}
|
||||
|
||||
return (array)$systemIds;
|
||||
return $systemIds ? : [];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -225,20 +243,20 @@ class Universe extends Controller {
|
||||
* @return null|\stdClass
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getSystemData(int $systemId){
|
||||
public function getSystemData(int $systemId) : ?\stdClass {
|
||||
$data = null;
|
||||
if($systemId){
|
||||
// ...check index for data
|
||||
$cacheKeyRow = Model\Universe\AbstractUniverseModel::generateHashKeyRow('system', $systemId);
|
||||
$data = $this->get($cacheKeyRow);
|
||||
if(!$data){
|
||||
if(!$data = $this->get($cacheKeyRow)){
|
||||
// .. try to build index
|
||||
/**
|
||||
* @var $system Model\Universe\SystemModel
|
||||
*/
|
||||
$system = Model\Universe\AbstractUniverseModel::getNew('SystemModel');
|
||||
$system->getById($systemId);
|
||||
$data = $system->buildIndex();
|
||||
if($system->getById($systemId)){
|
||||
$data = $system->buildIndex();
|
||||
}
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
@@ -249,7 +267,7 @@ class Universe extends Controller {
|
||||
* @param string $cacheKey
|
||||
* @return null|\stdClass
|
||||
*/
|
||||
private function get(string $cacheKey){
|
||||
private function get(string $cacheKey) : ?\stdClass {
|
||||
$data = null;
|
||||
if($this->getF3()->exists($cacheKey,$value)) {
|
||||
if(is_string($value) && strpos($value, Model\Universe\AbstractUniverseModel::CACHE_KEY_PREFIX) === 0) {
|
||||
|
||||
@@ -16,6 +16,7 @@ use lib\db\SQL;
|
||||
use lib\Resource;
|
||||
use lib\Monolog;
|
||||
use lib\Util;
|
||||
use Model\AbstractModel;
|
||||
use Model\Pathfinder;
|
||||
use DB;
|
||||
|
||||
@@ -381,13 +382,14 @@ class Controller {
|
||||
}
|
||||
|
||||
/**
|
||||
* get current character data from session
|
||||
* @return array
|
||||
* get current character from session data
|
||||
* @param int $ttl
|
||||
* @return Pathfinder\CharacterModel|null
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getSessionCharacterData() : array {
|
||||
$data = [];
|
||||
if($user = $this->getUser()){
|
||||
protected function getSessionCharacter(int $ttl = AbstractModel::DEFAULT_SQL_TTL) : ?Pathfinder\CharacterModel {
|
||||
$character = null;
|
||||
if($user = $this->getUser($ttl)){
|
||||
$header = self::getRequestHeaders();
|
||||
$requestedCharacterId = (int)$header['Pf-Character'];
|
||||
if( !$this->getF3()->get('AJAX') ){
|
||||
@@ -400,10 +402,10 @@ class Controller {
|
||||
}
|
||||
}
|
||||
|
||||
$data = $user->getSessionCharacterData($requestedCharacterId);
|
||||
$character = $user->getSessionCharacter($requestedCharacterId, $ttl);
|
||||
}
|
||||
|
||||
return $data;
|
||||
return $character;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -412,24 +414,8 @@ class Controller {
|
||||
* @return Pathfinder\CharacterModel|null
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getCharacter(int $ttl = 0) : ?Pathfinder\CharacterModel {
|
||||
$character = null;
|
||||
|
||||
if(!empty($characterData = $this->getSessionCharacterData())){
|
||||
/**
|
||||
* @var $characterModel Pathfinder\CharacterModel
|
||||
*/
|
||||
$characterModel = Pathfinder\AbstractPathfinderModel::getNew('CharacterModel');
|
||||
$characterModel->getById((int)$characterData['ID'], $ttl);
|
||||
if(
|
||||
!$characterModel->dry() &&
|
||||
$characterModel->hasUserCharacter()
|
||||
){
|
||||
$character = &$characterModel;
|
||||
}
|
||||
}
|
||||
|
||||
return $character;
|
||||
public function getCharacter(int $ttl = AbstractModel::DEFAULT_SQL_TTL) : ?Pathfinder\CharacterModel {
|
||||
return $this->getSessionCharacter($ttl);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -438,7 +424,7 @@ class Controller {
|
||||
* @return Pathfinder\UserModel|null
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getUser($ttl = 0) : ?Pathfinder\UserModel {
|
||||
public function getUser($ttl = AbstractModel::DEFAULT_SQL_TTL) : ?Pathfinder\UserModel {
|
||||
$user = null;
|
||||
|
||||
if($this->getF3()->exists(Api\User::SESSION_KEY_USER_ID, $userId)){
|
||||
@@ -452,7 +438,7 @@ class Controller {
|
||||
!$userModel->dry() &&
|
||||
$userModel->hasUserCharacters()
|
||||
){
|
||||
$user = &$userModel;
|
||||
$user = $userModel;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -534,10 +520,11 @@ class Controller {
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getEveServerStatus(\Base $f3){
|
||||
$ttl = 60;
|
||||
$esiStatusVersion = 'latest';
|
||||
$cacheKey = 'eve_server_status';
|
||||
|
||||
if( !$f3->exists($cacheKey, $return) ){
|
||||
if(!$exists = $f3->exists($cacheKey, $return)){
|
||||
$return = (object) [];
|
||||
$return->error = [];
|
||||
|
||||
@@ -593,10 +580,10 @@ class Controller {
|
||||
// find top status
|
||||
$status = 'OK';
|
||||
$color = 'green';
|
||||
foreach($apiStatus['status'] as $statusData){
|
||||
foreach($apiStatus['status'] as &$statusData){
|
||||
if('red' == $statusData['status']){
|
||||
$status = 'unstable';
|
||||
$color = $statusData['status'];
|
||||
$color = $statusData['status'] = 'orange'; // red is already in use for fatal API errors (e.g. no response at all, or offline)
|
||||
break;
|
||||
}
|
||||
if('yellow' == $statusData['status']){
|
||||
@@ -613,11 +600,15 @@ class Controller {
|
||||
}
|
||||
|
||||
if(empty($return->error)){
|
||||
$f3->set($cacheKey, $return, 60);
|
||||
$f3->set($cacheKey, $return, $ttl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(empty($return->error)){
|
||||
$f3->expire(Config::ttlLeft($exists, $ttl));
|
||||
}
|
||||
|
||||
echo json_encode($return);
|
||||
}
|
||||
|
||||
|
||||
@@ -118,13 +118,13 @@ class LogController extends \Prefab {
|
||||
$updateSql = array_map($updateRule, $columnsForUpdate);
|
||||
|
||||
$sql = "INSERT DELAYED INTO
|
||||
activity_log (" . implode(', ', $columnsQuoted) . ") values(
|
||||
" . implode(', ', $placeholder) . "
|
||||
)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
updated = NOW(),
|
||||
" . implode(', ', $updateSql) . "
|
||||
";
|
||||
activity_log (" . implode(', ', $columnsQuoted) . ") VALUES(
|
||||
" . implode(', ', $placeholder) . "
|
||||
)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
updated = NOW(),
|
||||
" . implode(', ', $updateSql) . "
|
||||
";
|
||||
|
||||
$db->exec($sql, $args);
|
||||
}
|
||||
|
||||
@@ -67,7 +67,6 @@ class Setup extends Controller {
|
||||
'Model\Pathfinder\MapTypeModel',
|
||||
'Model\Pathfinder\SystemTypeModel',
|
||||
'Model\Pathfinder\SystemStatusModel',
|
||||
'Model\Pathfinder\SystemNeighbourModel',
|
||||
'Model\Pathfinder\RightModel',
|
||||
'Model\Pathfinder\RoleModel',
|
||||
'Model\Pathfinder\StructureModel',
|
||||
@@ -105,19 +104,25 @@ class Setup extends Controller {
|
||||
'UNIVERSE' => [
|
||||
'info' => [],
|
||||
'models' => [
|
||||
'Model\Universe\DogmaAttributeModel',
|
||||
'Model\Universe\TypeAttributeModel',
|
||||
'Model\Universe\TypeModel',
|
||||
'Model\Universe\GroupModel',
|
||||
'Model\Universe\CategoryModel',
|
||||
'Model\Universe\FactionModel',
|
||||
'Model\Universe\AllianceModel',
|
||||
'Model\Universe\CorporationModel',
|
||||
'Model\Universe\StructureModel',
|
||||
'Model\Universe\WormholeModel',
|
||||
'Model\Universe\StargateModel',
|
||||
'Model\Universe\StarModel',
|
||||
'Model\Universe\PlanetModel',
|
||||
'Model\Universe\SystemModel',
|
||||
'Model\Universe\ConstellationModel',
|
||||
'Model\Universe\RegionModel',
|
||||
'Model\Universe\SystemStaticModel'
|
||||
'Model\Universe\SystemNeighbourModel',
|
||||
'Model\Universe\SystemStaticModel',
|
||||
'Model\Universe\SovereigntyMapModel',
|
||||
'Model\Universe\FactionWarSystemModel'
|
||||
]
|
||||
]
|
||||
];
|
||||
@@ -1665,18 +1670,111 @@ class Setup extends Controller {
|
||||
* @var $categoryUniverseModel Universe\CategoryModel
|
||||
*/
|
||||
$categoryUniverseModel = Universe\AbstractUniverseModel::getNew('CategoryModel');
|
||||
$categoryUniverseModel->getById(65, 0);
|
||||
$structureCount = $categoryUniverseModel->getTypesCount(false);
|
||||
$categoryUniverseModel->getById(Config::ESI_CATEGORY_STRUCTURE_ID, 0);
|
||||
$groupsCountStructure = $categoryUniverseModel->getGroupsCount(false);
|
||||
$typesCountStructure = $categoryUniverseModel->getTypesCount(false);
|
||||
|
||||
$categoryUniverseModel->getById(6, 0);
|
||||
$shipCount = $categoryUniverseModel->getTypesCount(false);
|
||||
$categoryUniverseModel->getById(Config::ESI_CATEGORY_SHIP_ID, 0);
|
||||
$groupsCountShip = $categoryUniverseModel->getGroupsCount(false);
|
||||
$typesCountShip = $categoryUniverseModel->getTypesCount(false);
|
||||
|
||||
/**
|
||||
* @var $systemNeighbourModel Pathfinder\SystemNeighbourModel
|
||||
* @var $groupUniverseModel Universe\GroupModel
|
||||
*/
|
||||
$systemNeighbourModel = Pathfinder\AbstractPathfinderModel::getNew('SystemNeighbourModel');
|
||||
|
||||
$groupUniverseModel = Universe\AbstractUniverseModel::getNew('GroupModel');
|
||||
$groupUniverseModel->getById(Config::ESI_GROUP_WORMHOLE_ID, 0);
|
||||
$wormholeCount = $groupUniverseModel->getTypesCount(false);
|
||||
|
||||
/**
|
||||
* @var $systemNeighbourModel Universe\SystemNeighbourModel
|
||||
*/
|
||||
$systemNeighbourModel = Universe\AbstractUniverseModel::getNew('SystemNeighbourModel');
|
||||
|
||||
/**
|
||||
* @var $systemStaticModel Universe\SystemStaticModel
|
||||
*/
|
||||
$systemStaticModel = Universe\AbstractUniverseModel::getNew('SystemStaticModel');
|
||||
|
||||
if(empty($systemCountAll = count(($universeController = new UniverseController())->getSystemIds(true)))){
|
||||
// no systems found in 'universe' DB. Clear potential existing system cache
|
||||
$universeController->clearSystemsIndex();
|
||||
}
|
||||
|
||||
$sum = function(int $carry, int $value) : int {
|
||||
return $carry + $value;
|
||||
};
|
||||
|
||||
$indexInfo = [
|
||||
'Wormholes' => [
|
||||
'task' => [
|
||||
[
|
||||
'action' => 'buildIndex',
|
||||
'label' => 'Import',
|
||||
'icon' => 'fa-sync',
|
||||
'btn' => 'btn-primary'
|
||||
]
|
||||
],
|
||||
'label' => 'Wormholes data',
|
||||
'countBuild' => $wormholeCount,
|
||||
'countAll' => count(Universe\GroupModel::getUniverseGroupTypes(Config::ESI_GROUP_WORMHOLE_ID)),
|
||||
'tooltip' => 'import all wormhole types (e.g. L031) from ESI. Runtime: ~25s'
|
||||
],
|
||||
'Structures' => [
|
||||
'task' => [
|
||||
[
|
||||
'action' => 'buildIndex',
|
||||
'label' => 'Import',
|
||||
'icon' => 'fa-sync',
|
||||
'btn' => 'btn-primary'
|
||||
]
|
||||
],
|
||||
'label' => 'Structures data',
|
||||
'countBuild' => $groupsCountStructure,
|
||||
'countAll' => count(Universe\CategoryModel::getUniverseCategoryGroups(Config::ESI_CATEGORY_STRUCTURE_ID)),
|
||||
'tooltip' => 'import all structure types (e.g. Citadels) from ESI. Runtime: ~15s',
|
||||
'subCount' => [
|
||||
'countBuild' => $typesCountStructure,
|
||||
'countAll' => array_reduce(array_map('count', Universe\CategoryModel::getUniverseCategoryTypes(Config::ESI_CATEGORY_STRUCTURE_ID)), $sum, 0),
|
||||
]
|
||||
],
|
||||
'Ships' => [
|
||||
'task' => [
|
||||
[
|
||||
'action' => 'buildIndex',
|
||||
'label' => 'Import',
|
||||
'icon' => 'fa-sync',
|
||||
'btn' => 'btn-primary'
|
||||
]
|
||||
],
|
||||
'label' => 'Ships data',
|
||||
'countBuild' => $groupsCountShip,
|
||||
'countAll' => count(Universe\CategoryModel::getUniverseCategoryGroups(Config::ESI_CATEGORY_SHIP_ID)),
|
||||
'tooltip' => 'import all ships from ESI. Runtime: ~2min',
|
||||
'subCount' => [
|
||||
'countBuild' => $typesCountShip,
|
||||
'countAll' => array_reduce(array_map('count', Universe\CategoryModel::getUniverseCategoryTypes(Config::ESI_CATEGORY_SHIP_ID)), $sum, 0),
|
||||
]
|
||||
],
|
||||
'SystemStatic' => [
|
||||
'task' => [
|
||||
[
|
||||
'action' => 'buildIndex',
|
||||
'label' => 'Import',
|
||||
'icon' => 'fa-sync',
|
||||
'btn' => 'btn-primary'
|
||||
]
|
||||
],
|
||||
'label' => 'Wormhole statics data',
|
||||
'countBuild' => $systemStaticModel->getRowCount(),
|
||||
'countAll' => 3772,
|
||||
'tooltip' => 'import all static wormholes for systems. Runtime: ~25s'
|
||||
],
|
||||
[
|
||||
'label' => 'Build search index',
|
||||
'icon' => 'fa-search',
|
||||
'tooltip' => 'Search indexes are build from static EVE universe data (e.g. systems, stargate connections,…). Re-build if underlying data was updated.'
|
||||
],
|
||||
'Systems' => [
|
||||
'task' => [
|
||||
[
|
||||
@@ -1691,81 +1789,36 @@ class Setup extends Controller {
|
||||
'btn' => 'btn-primary'
|
||||
]
|
||||
],
|
||||
'label' => 'build systems index',
|
||||
'countBuild' => count((new UniverseController())->getSystemsIndex()),
|
||||
'countAll' => count((new UniverseController())->getSystemIds()),
|
||||
'tooltip' => 'build up a static search index over all systems found on DB. Do not refresh page until import is complete (check progress)! Runtime: ~5min'
|
||||
],
|
||||
'Structures' => [
|
||||
'task' => [
|
||||
[
|
||||
'action' => 'buildIndex',
|
||||
'label' => 'Import',
|
||||
'icon' => 'fa-sync',
|
||||
'btn' => 'btn-primary'
|
||||
]
|
||||
],
|
||||
'label' => 'import structures data',
|
||||
'countBuild' => $structureCount,
|
||||
'countAll' => (int)$f3->get('REQUIREMENTS.DATA.STRUCTURES'),
|
||||
'tooltip' => 'import all structure types (e.g. Citadels) from ESI. Runtime: ~15s'
|
||||
],
|
||||
'Ships' => [
|
||||
'task' => [
|
||||
[
|
||||
'action' => 'buildIndex',
|
||||
'label' => 'Import',
|
||||
'icon' => 'fa-sync',
|
||||
'btn' => 'btn-primary'
|
||||
]
|
||||
],
|
||||
'label' => 'import ships data',
|
||||
'countBuild' => $shipCount,
|
||||
'countAll' => (int)$f3->get('REQUIREMENTS.DATA.SHIPS'),
|
||||
'tooltip' => 'import all ships types from ESI. Runtime: ~2min'
|
||||
'label' => 'Systems data index',
|
||||
'countBuild' => count($universeController->getSystemsIndex()),
|
||||
'countAll' => $systemCountAll,
|
||||
'tooltip' => 'Build up a static search index over all systems, found on DB. Runtime: ~5min'
|
||||
],
|
||||
'SystemNeighbour' => [
|
||||
'task' => [
|
||||
[
|
||||
'action' => 'clearIndex',
|
||||
'label' => 'Clear',
|
||||
'icon' => 'fa-trash',
|
||||
'btn' => 'btn-danger'
|
||||
],[
|
||||
'action' => 'buildIndex',
|
||||
'label' => 'Build',
|
||||
'icon' => 'fa-sync',
|
||||
'btn' => 'btn-primary'
|
||||
]
|
||||
],
|
||||
'label' => 'build neighbour index',
|
||||
'countBuild' => $f3->DB->getDB('PF')->getRowCount($systemNeighbourModel->getTable()),
|
||||
'label' => 'Systems neighbour index',
|
||||
'countBuild' => $systemNeighbourModel->getRowCount(),
|
||||
'countAll' => (int)$f3->get('REQUIREMENTS.DATA.NEIGHBOURS'),
|
||||
'tooltip' => 'build up a static search index for route search. This is used as fallback in case ESI is down. Runtime: ~30s'
|
||||
|
||||
],
|
||||
// All following rows become deprecated
|
||||
/*
|
||||
'WormholeModel' => [
|
||||
'task' => [
|
||||
[
|
||||
'action' => 'exportTable',
|
||||
'label' => 'Export',
|
||||
'icon' => 'fa-download',
|
||||
'btn' => 'btn-default'
|
||||
],[
|
||||
'action' => 'importTable',
|
||||
'label' => 'Import',
|
||||
'icon' => 'fa-upload',
|
||||
'btn' => 'btn-primary'
|
||||
]
|
||||
],
|
||||
'label' => 'wormhole',
|
||||
'countBuild' => $f3->DB->getDB('PF')->getRowCount($wormholeModel->getTable()),
|
||||
'countAll' => 89
|
||||
'tooltip' => 'Build up a static search index for route search. This is used as fallback in case ESI is down. Runtime: ~10s'
|
||||
]
|
||||
*/
|
||||
];
|
||||
}else{
|
||||
$indexInfo = [
|
||||
'SystemNeighbour' => [
|
||||
'task' => [],
|
||||
'label' => 'Fix database errors first!'
|
||||
[
|
||||
'label' => 'Fix database errors first!',
|
||||
'class' => 'txt-color-danger text-center'
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
@@ -193,12 +193,39 @@ class Universe extends AbstractCron {
|
||||
$model->loadStargatesData();
|
||||
};
|
||||
break;
|
||||
case 'sovereignty':
|
||||
// load sovereignty map data. Systems must be present first!
|
||||
$sovData = $f3->ccpClient()->getSovereigntyMap();
|
||||
$ids = !empty($sovData = $sovData['map']) ? array_keys($sovData): [];
|
||||
$modelClass = 'SystemModel';
|
||||
$setupModel = function(Model\Universe\SystemModel &$model, int $id) use ($sovData) {
|
||||
if($model->getById($id)){
|
||||
$model->updateSovereigntyData($sovData[$id]);
|
||||
}else{
|
||||
echo 'NOT VALID ' . $id . PHP_EOL;
|
||||
die();
|
||||
}
|
||||
};
|
||||
break;
|
||||
case 'faction_war_systems':
|
||||
$fwSystems = $f3->ccpClient()->getFactionWarSystems();
|
||||
$ids = !empty($fwSystems = $fwSystems['systems']) ? array_keys($fwSystems): [];
|
||||
$modelClass = 'SystemModel';
|
||||
$setupModel = function(Model\Universe\SystemModel &$model, int $id) use ($fwSystems) {
|
||||
if($model->getById($id)){
|
||||
$model->updateFactionWarData($fwSystems[$id]);
|
||||
}else{
|
||||
echo 'NOT VALID ' . $id . PHP_EOL;
|
||||
die();
|
||||
}
|
||||
};
|
||||
break;
|
||||
case 'index_system':
|
||||
// setup system index, Systems must be present first!
|
||||
$ids = $f3->ccpClient()->getUniverseSystems();
|
||||
$modelClass = 'SystemModel';
|
||||
$setupModel = function(Model\Universe\SystemModel &$model, int $id){
|
||||
$model->getById($id); // no loadById() here! would take "forever" when system not exists and build up first...
|
||||
$model->getById($id); // no loadById() here! would take "forever" when system not exists and must be build up first...
|
||||
$model->buildIndex();
|
||||
};
|
||||
break;
|
||||
@@ -242,6 +269,34 @@ class Universe extends AbstractCron {
|
||||
$this->formatSeconds(microtime(true) - $timeTotalStart), $msg) );
|
||||
}
|
||||
|
||||
/**
|
||||
* update Sovereignty system data from ESI
|
||||
* -> this updates Faction warfare data as well
|
||||
* >> php index.php "/cron/updateSovereigntyData"
|
||||
* @param \Base $f3
|
||||
* @throws \Exception
|
||||
*/
|
||||
function updateSovereigntyData(\Base $f3){
|
||||
$this->setMaxExecutionTime();
|
||||
$system = Model\Universe\AbstractUniverseModel::getNew('SystemModel');
|
||||
|
||||
$sovData = $f3->ccpClient()->getSovereigntyMap();
|
||||
$fwSystems = $f3->ccpClient()->getFactionWarSystems();
|
||||
$fwSystems = $fwSystems['systems'];
|
||||
$ids = !empty($sovData = $sovData['map']) ? array_keys($sovData): [];
|
||||
|
||||
foreach($ids as $id){
|
||||
if($system->getById($id)){
|
||||
$system->updateSovereigntyData($sovData[$id]);
|
||||
|
||||
if(is_array($fwSystems[$id])){
|
||||
$system->updateFactionWarData($fwSystems[$id]);
|
||||
}
|
||||
$system->reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* update static universe system data from ESI
|
||||
* -> updates small chunk of systems at once
|
||||
@@ -251,9 +306,12 @@ class Universe extends AbstractCron {
|
||||
*/
|
||||
function updateUniverseSystems(\Base $f3){
|
||||
$this->setMaxExecutionTime();
|
||||
|
||||
$system = Model\Universe\AbstractUniverseModel::getNew('SystemModel');
|
||||
$systems = $system->find( null, ['order' => 'updated', 'limit' => 2]);
|
||||
/**
|
||||
* @var $systemModel Model\Universe\SystemModel
|
||||
* @var $system Model\Universe\SystemModel
|
||||
*/
|
||||
$systemModel = Model\Universe\AbstractUniverseModel::getNew('SystemModel');
|
||||
$systems = $systemModel->find( null, ['order' => 'updated', 'limit' => 2]);
|
||||
if($systems){
|
||||
foreach ($systems as $system){
|
||||
$system->updateModel();
|
||||
|
||||
@@ -82,6 +82,30 @@ class Config extends \Prefab {
|
||||
*/
|
||||
const DOWNTIME_BUFFER = 1;
|
||||
|
||||
// ================================================================================================================
|
||||
// ESI API id´s
|
||||
// ================================================================================================================
|
||||
|
||||
/**
|
||||
* ESI categoryId or 'Structure's
|
||||
*/
|
||||
const ESI_CATEGORY_STRUCTURE_ID = 65;
|
||||
|
||||
/**
|
||||
* ESI categoryId or 'Ship's
|
||||
*/
|
||||
const ESI_CATEGORY_SHIP_ID = 6;
|
||||
|
||||
/**
|
||||
* ESI groupId or 'Wormhole's
|
||||
*/
|
||||
const ESI_GROUP_WORMHOLE_ID = 988;
|
||||
|
||||
/**
|
||||
* ESI dogmaAttributeId for 'scanWormholeStrength's
|
||||
*/
|
||||
const ESI_DOGMA_ATTRIBUTE_SCANWHSTRENGTH_ID = 1908;
|
||||
|
||||
/**
|
||||
* error message for missing Composer dependency class
|
||||
*/
|
||||
@@ -166,7 +190,7 @@ class Config extends \Prefab {
|
||||
* @return array|null
|
||||
*/
|
||||
protected function getAllEnvironmentData(\Base $f3){
|
||||
if( !$f3->exists(self::HIVE_KEY_ENVIRONMENT, $environmentData) ){
|
||||
if(!$f3->exists(self::HIVE_KEY_ENVIRONMENT, $environmentData)){
|
||||
$environmentData = $this->setAllEnvironmentData($f3);
|
||||
}
|
||||
|
||||
@@ -616,4 +640,18 @@ class Config extends \Prefab {
|
||||
return $format;
|
||||
}
|
||||
|
||||
static function ttlLeft($fromExists, int $ttlMax) : int {
|
||||
$ttlMax = max($ttlMax, 0);
|
||||
if($fromExists){
|
||||
// == true || array
|
||||
if(is_array($fromExists)){
|
||||
return max(min((int)ceil(round(array_sum($fromExists) - microtime(true), 4)), $ttlMax), 0);
|
||||
}else{
|
||||
return 0;
|
||||
}
|
||||
}else{
|
||||
// == false
|
||||
return $ttlMax;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -51,6 +51,24 @@ class Util {
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* transforms array with assoc. arrays as values
|
||||
* into assoc. array where $key column data is used for its key
|
||||
* @param array $array
|
||||
* @param string $key
|
||||
* @param bool $unsetKey
|
||||
* @return array
|
||||
*/
|
||||
static function arrayGetBy(array $array, string $key, bool $unsetKey = true) : array {
|
||||
// we can remove $key from nested arrays
|
||||
return array_map(function($val) use ($key, $unsetKey) : array {
|
||||
if($unsetKey){
|
||||
unset($val[$key]);
|
||||
}
|
||||
return $val;
|
||||
}, array_column($array, null, $key));
|
||||
}
|
||||
|
||||
/**
|
||||
* checks whether an array is associative or not (sequential)
|
||||
* @param mixed $array
|
||||
|
||||
@@ -11,6 +11,7 @@ namespace Model;
|
||||
use DB\Cortex;
|
||||
use DB\CortexCollection;
|
||||
use DB\SQL\Schema;
|
||||
use lib\Util;
|
||||
use lib\logging;
|
||||
use Controller;
|
||||
use Exception\ValidationException;
|
||||
@@ -44,6 +45,14 @@ abstract class AbstractModel extends Cortex {
|
||||
*/
|
||||
protected $addStaticFields = true;
|
||||
|
||||
/**
|
||||
* enables table truncate
|
||||
* -> see truncate();
|
||||
* -> CAUTION! if set to true truncate() will clear ALL rows!
|
||||
* @var bool
|
||||
*/
|
||||
protected $allowTruncate = false;
|
||||
|
||||
/**
|
||||
* enables change for "active" column
|
||||
* -> see setActive();
|
||||
@@ -89,6 +98,23 @@ abstract class AbstractModel extends Cortex {
|
||||
*/
|
||||
const DEFAULT_CACHE_TTL = 120;
|
||||
|
||||
/**
|
||||
* default TTL or temp table data read from *.csv file
|
||||
* -> used during data import
|
||||
*/
|
||||
const DEFAULT_CACHE_CSV_TTL = 120;
|
||||
|
||||
/**
|
||||
* cache key prefix name for "full table" indexing
|
||||
* -> used e.g. for a "search" index; or "import" index for *.csv imports
|
||||
*/
|
||||
const CACHE_KEY_PREFIX = 'INDEX';
|
||||
|
||||
/**
|
||||
* cache key name for temp data import from *.csv files per table
|
||||
*/
|
||||
const CACHE_KEY_CSV_PREFIX = 'CSV';
|
||||
|
||||
/**
|
||||
* default TTL for SQL query cache
|
||||
*/
|
||||
@@ -658,6 +684,24 @@ abstract class AbstractModel extends Cortex {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* get row count in this table
|
||||
* @return int
|
||||
*/
|
||||
public function getRowCount() : int {
|
||||
return is_object($this->db) ? $this->db->getRowCount($this->getTable()) : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* truncate all table rows
|
||||
* -> Use with Caution!!!
|
||||
*/
|
||||
public function truncate(){
|
||||
if($this->allowTruncate && is_object($this->db)){
|
||||
$this->db->exec("TRUNCATE " . $this->getTable());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* format dateTime column
|
||||
* @param $column
|
||||
@@ -716,43 +760,78 @@ abstract class AbstractModel extends Cortex {
|
||||
}
|
||||
|
||||
/**
|
||||
* import table data from a *.csv file
|
||||
* @return array|bool
|
||||
* read *.csv file for a $table name
|
||||
* -> 'group' by $getByKey column name and return array
|
||||
* @param string $table
|
||||
* @param string $getByKey
|
||||
* @return array
|
||||
*/
|
||||
public function importData(){
|
||||
$status = false;
|
||||
public static function getCSVData(string $table, string $getByKey = 'id') : array {
|
||||
$hashKeyTableCSV = static::generateHashKeyTable($table, static::CACHE_KEY_PREFIX . '_' . self::CACHE_KEY_CSV_PREFIX);
|
||||
|
||||
if(
|
||||
!self::getF3()->exists($hashKeyTableCSV, $tableData) &&
|
||||
!empty($tableData = Util::arrayGetBy(self::loadCSV($table), $getByKey, false))
|
||||
){
|
||||
self::getF3()->set($hashKeyTableCSV, $tableData, self::DEFAULT_CACHE_CSV_TTL);
|
||||
}
|
||||
|
||||
return $tableData;
|
||||
}
|
||||
|
||||
/**
|
||||
* load data from *.csv file
|
||||
* @param string $fileName
|
||||
* @return array
|
||||
*/
|
||||
protected static function loadCSV(string $fileName) : array {
|
||||
$tableData = [];
|
||||
|
||||
// rtrim(); for arrays (removes empty values) from the end
|
||||
$rtrim = function($array = [], $lengthMin = false){
|
||||
$rtrim = function($array = [], $lengthMin = false) : array {
|
||||
$length = key(array_reverse(array_diff($array, ['']), 1))+1;
|
||||
$length = $length < $lengthMin ? $lengthMin : $length;
|
||||
return array_slice($array, 0, $length);
|
||||
};
|
||||
|
||||
if(static::$enableDataImport){
|
||||
$filePath = $this->getF3()->get('EXPORT') . 'csv/' . $this->getTable() . '.csv';
|
||||
|
||||
if($fileName){
|
||||
$filePath = self::getF3()->get('EXPORT') . 'csv/' . $fileName . '.csv';
|
||||
if(is_file($filePath)){
|
||||
$handle = @fopen($filePath, 'r');
|
||||
$keys = array_map('lcfirst', fgetcsv($handle, 0, ';'));
|
||||
$keys = $rtrim($keys);
|
||||
|
||||
if(count($keys) > 0){
|
||||
$tableData = [];
|
||||
while (!feof($handle)) {
|
||||
$tableData[] = array_combine($keys, $rtrim(fgetcsv($handle, 0, ';'), count($keys)));
|
||||
}
|
||||
// import row data
|
||||
$status = $this->importStaticData($tableData);
|
||||
$this->getF3()->status(202);
|
||||
}else{
|
||||
$this->getF3()->error(500, 'File could not be read');
|
||||
self::getF3()->error(500, 'File could not be read');
|
||||
}
|
||||
}else{
|
||||
$this->getF3()->error(404, 'File not found: ' . $filePath);
|
||||
self::getF3()->error(404, 'File not found: ' . $filePath);
|
||||
}
|
||||
}
|
||||
|
||||
return $tableData;
|
||||
}
|
||||
|
||||
/**
|
||||
* import table data from a *.csv file
|
||||
* @return array|bool
|
||||
*/
|
||||
public function importData(){
|
||||
$status = false;
|
||||
|
||||
if(
|
||||
static::$enableDataImport &&
|
||||
!empty($tableData = self::loadCSV($this->getTable()))
|
||||
){
|
||||
// import row data
|
||||
$status = $this->importStaticData($tableData);
|
||||
$this->getF3()->status(202);
|
||||
}
|
||||
|
||||
return $status;
|
||||
}
|
||||
|
||||
@@ -1019,6 +1098,17 @@ abstract class AbstractModel extends Cortex {
|
||||
return $model;
|
||||
}
|
||||
|
||||
/**
|
||||
* generate hashKey for a complete table
|
||||
* -> should hold hashKeys for multiple rows
|
||||
* @param string $table
|
||||
* @param string $prefix
|
||||
* @return string
|
||||
*/
|
||||
public static function generateHashKeyTable(string $table, string $prefix = self::CACHE_KEY_PREFIX ) : string {
|
||||
return $prefix . '_' . strtolower($table);
|
||||
}
|
||||
|
||||
/**
|
||||
* overwrites parent
|
||||
* @param null $db
|
||||
|
||||
@@ -13,8 +13,14 @@ use lib\Config;
|
||||
|
||||
class AllianceModel extends AbstractPathfinderModel {
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'alliance';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $fieldConf = [
|
||||
'active' => [
|
||||
'type' => Schema::DT_BOOL,
|
||||
@@ -145,7 +151,7 @@ class AllianceModel extends AbstractPathfinderModel {
|
||||
if($this->isOutdated()){
|
||||
// request alliance data
|
||||
$allianceData = self::getF3()->ccpClient()->getAllianceData($id);
|
||||
if( !empty($allianceData) ){
|
||||
if(!empty($allianceData) && !isset($allianceData['error'])){
|
||||
$this->copyfrom($allianceData, ['id', 'name', 'ticker']);
|
||||
$this->save();
|
||||
}
|
||||
|
||||
@@ -499,14 +499,7 @@ class CharacterModel extends AbstractPathfinderModel {
|
||||
* @return UserModel|null
|
||||
*/
|
||||
public function getUser() : ?UserModel {
|
||||
$user = null;
|
||||
if($this->hasUserCharacter()){
|
||||
/**
|
||||
* @var $user UserModel
|
||||
*/
|
||||
$user = $this->userCharacter->userId;
|
||||
}
|
||||
return $user;
|
||||
return $this->hasUserCharacter() ? $this->userCharacter->userId : null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -14,8 +14,14 @@ use lib\logging;
|
||||
|
||||
class ConnectionModel extends AbstractMapTrackingModel {
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'connection';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $fieldConf = [
|
||||
'active' => [
|
||||
'type' => Schema::DT_BOOL,
|
||||
|
||||
@@ -13,6 +13,9 @@ use lib\Config;
|
||||
|
||||
class CorporationModel extends AbstractPathfinderModel {
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'corporation';
|
||||
|
||||
/**
|
||||
@@ -91,6 +94,9 @@ class CorporationModel extends AbstractPathfinderModel {
|
||||
'map_export'
|
||||
];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $fieldConf = [
|
||||
'active' => [
|
||||
'type' => Schema::DT_BOOL,
|
||||
@@ -181,17 +187,19 @@ class CorporationModel extends AbstractPathfinderModel {
|
||||
|
||||
/**
|
||||
* get all maps for this corporation
|
||||
* @param array $mapIds
|
||||
* @param int|null $mapId
|
||||
* @param array $options
|
||||
* @return array
|
||||
*/
|
||||
public function getMaps($mapIds = [], $options = []) : array {
|
||||
public function getMaps(?int $mapId = null, $options = []) : array {
|
||||
$maps = [];
|
||||
$this->filterRel();
|
||||
|
||||
if(!empty($mapIds)){
|
||||
$filters = [];
|
||||
$filters[] = ['mapId IN (:mapId)', ':mapId' => $mapIds];
|
||||
if($mapId){
|
||||
$filters = [
|
||||
self::getFilter('mapId', $mapId)
|
||||
];
|
||||
|
||||
$this->filter('mapCorporations', $this->mergeWithRelFilter('mapCorporations', $this->mergeFilter($filters)), $this->getRelFilterOption('mapCorporations'));
|
||||
}
|
||||
|
||||
@@ -217,7 +225,7 @@ class CorporationModel extends AbstractPathfinderModel {
|
||||
* @param array $options
|
||||
* @return CharacterModel[]
|
||||
*/
|
||||
public function getCharacters($characterIds = [], $options = []){
|
||||
public function getCharacters($characterIds = [], $options = []) : array {
|
||||
$characters = [];
|
||||
$filter = ['active = ?', 1];
|
||||
|
||||
@@ -244,30 +252,28 @@ class CorporationModel extends AbstractPathfinderModel {
|
||||
|
||||
/**
|
||||
* get all structure data for this corporation
|
||||
* @param array $systemIds
|
||||
* @param int $systemId
|
||||
* @return array
|
||||
*/
|
||||
public function getStructuresData(array $systemIds = []) : array {
|
||||
public function getStructuresData(int $systemId) : array {
|
||||
$structuresData = [];
|
||||
$structure = $this->rel('structures');
|
||||
|
||||
$this->filter('corporationStructures', ['active = ?', 1]);
|
||||
$this->has('corporationStructures.structureId', ['active = ?', 1]);
|
||||
$filters = [
|
||||
self::getFilter('corporationId', $this->id),
|
||||
self::getFilter('active', true)
|
||||
];
|
||||
|
||||
if($systemIds){
|
||||
if(count($systemIds) == 1){
|
||||
$filterSystems = 'systemId = ?';
|
||||
$filterSystemIds = reset($systemIds);
|
||||
}else{
|
||||
$filterSystems = 'systemId IN (?)';
|
||||
$filterSystemIds = $systemIds;
|
||||
}
|
||||
$structure->has('structureCorporations', $this->mergeFilter($filters));
|
||||
|
||||
$this->has('corporationStructures.structureId', [$filterSystems, $filterSystemIds]);
|
||||
}
|
||||
$filters = [
|
||||
self::getFilter('systemId', $systemId),
|
||||
self::getFilter('active', true)
|
||||
];
|
||||
|
||||
if($this->corporationStructures) {
|
||||
foreach($this->corporationStructures as $corporationStructure){
|
||||
$structuresData[] = $corporationStructure->structureId->getData();
|
||||
if($structures = $structure->find($this->mergeFilter($filters))){
|
||||
foreach($structures as $structure){
|
||||
$structuresData[] = $structure->getData();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -351,7 +357,7 @@ class CorporationModel extends AbstractPathfinderModel {
|
||||
if($this->isOutdated()){
|
||||
// request corporation data
|
||||
$corporationData = self::getF3()->ccpClient()->getCorporationData($id);
|
||||
if( !empty($corporationData) ){
|
||||
if(!empty($corporationData) && !isset($corporationData['error'])){
|
||||
// check for NPC corporation
|
||||
$corporationData['isNPC'] = self::getF3()->ccpClient()->isNpcCorporation($id);
|
||||
|
||||
|
||||
@@ -12,8 +12,14 @@ use DB\SQL\Schema;
|
||||
|
||||
class CorporationStructureModel extends AbstractPathfinderModel {
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'corporation_structure';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $fieldConf = [
|
||||
'active' => [
|
||||
'type' => Schema::DT_BOOL,
|
||||
|
||||
@@ -563,41 +563,37 @@ class MapModel extends AbstractMapTrackingModel {
|
||||
}
|
||||
|
||||
/**
|
||||
* get either all system models in this map
|
||||
* @return SystemModel[]
|
||||
* get systems in this map
|
||||
* @return CortexCollection|array
|
||||
*/
|
||||
protected function getSystems(){
|
||||
$systems = [];
|
||||
$filters = [
|
||||
self::getFilter('active', true)
|
||||
];
|
||||
|
||||
// orderBy x-Coordinate for smoother frontend animation (left to right)
|
||||
$this->filter('systems', ['active = 1'],
|
||||
['order' => 'posX']
|
||||
);
|
||||
|
||||
if($this->systems){
|
||||
$systems = $this->systems;
|
||||
}
|
||||
|
||||
return $systems;
|
||||
return $this->relFind('systems', $this->mergeFilter($filters)) ? : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* get all system data for all systems in this map
|
||||
* @return \stdClass[]
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getSystemsData() : array{
|
||||
$systemData = [];
|
||||
$systems = $this->getSystems();
|
||||
public function getSystemsData() : array {
|
||||
$systemsData = [];
|
||||
|
||||
foreach($systems as $system){
|
||||
foreach($this->getSystems() as $system){
|
||||
/**
|
||||
* @var $system SystemModel
|
||||
*/
|
||||
$systemData[] = $system->getData();
|
||||
$systemsData[] = $system->getData();
|
||||
}
|
||||
|
||||
return $systemData;
|
||||
// orderBy x-Coordinate for smoother frontend animation (left to right)
|
||||
usort($systemsData, function($sysDataA, $sysDataB){
|
||||
return $sysDataA->position->x <=> $sysDataB->position->x;
|
||||
});
|
||||
|
||||
return $systemsData;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -650,25 +646,24 @@ class MapModel extends AbstractMapTrackingModel {
|
||||
* @return \stdClass[]
|
||||
*/
|
||||
public function getConnectionsData() : array {
|
||||
$connectionData = [];
|
||||
$connections = $this->getConnections();
|
||||
$connectionsData = [];
|
||||
|
||||
foreach($connections as $connection){
|
||||
foreach($this->getConnections() as $connection){
|
||||
/**
|
||||
* @var $connection ConnectionModel
|
||||
*/
|
||||
$connectionData[] = $connection->getData(true);
|
||||
$connectionsData[] = $connection->getData(true);
|
||||
}
|
||||
|
||||
return $connectionData;
|
||||
return $connectionsData;
|
||||
}
|
||||
|
||||
/**
|
||||
* get all structures data for this map
|
||||
* @param array $systemIds
|
||||
* @param int $systemId
|
||||
* @return array
|
||||
*/
|
||||
public function getStructuresData(array $systemIds = []) : array {
|
||||
public function getStructuresData(int $systemId) : array {
|
||||
$structuresData = [];
|
||||
$corporations = $this->getAllCorporations();
|
||||
|
||||
@@ -676,7 +671,7 @@ class MapModel extends AbstractMapTrackingModel {
|
||||
// corporations should be unique
|
||||
if( !isset($structuresData[$corporation->_id]) ){
|
||||
// get all structures for current corporation
|
||||
$corporationStructuresData = $corporation->getStructuresData($systemIds);
|
||||
$corporationStructuresData = $corporation->getStructuresData($systemId);
|
||||
if( !empty($corporationStructuresData) ){
|
||||
// corporation has structures
|
||||
$structuresData[$corporation->_id] = [
|
||||
@@ -819,11 +814,6 @@ class MapModel extends AbstractMapTrackingModel {
|
||||
$characters = [];
|
||||
$filter = ['active = ?', 1];
|
||||
|
||||
if( !empty($characterIds) ){
|
||||
$filter[0] .= ' AND id IN (?)';
|
||||
$filter[] = $characterIds;
|
||||
}
|
||||
|
||||
$this->filter('mapCharacters', $filter);
|
||||
|
||||
if($this->mapCharacters){
|
||||
@@ -839,7 +829,7 @@ class MapModel extends AbstractMapTrackingModel {
|
||||
* get corporations that have access to this map
|
||||
* @return CorporationModel[]
|
||||
*/
|
||||
public function getCorporations() : array {
|
||||
private function getCorporations() : array {
|
||||
$corporations = [];
|
||||
|
||||
if($this->isCorporation()){
|
||||
@@ -847,7 +837,7 @@ class MapModel extends AbstractMapTrackingModel {
|
||||
|
||||
if($this->mapCorporations){
|
||||
foreach($this->mapCorporations as $mapCorporation){
|
||||
$corporations[] = $mapCorporation->corporationId;
|
||||
$corporations[$mapCorporation->corporationId->_id] = $mapCorporation->corporationId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,8 +12,14 @@ use DB\SQL\Schema;
|
||||
|
||||
class RightModel extends AbstractPathfinderModel {
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'right';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $fieldConf = [
|
||||
'active' => [
|
||||
'type' => Schema::DT_BOOL,
|
||||
@@ -24,7 +30,9 @@ class RightModel extends AbstractPathfinderModel {
|
||||
'name' => [
|
||||
'type' => Schema::DT_VARCHAR128,
|
||||
'nullable' => false,
|
||||
'default' => ''
|
||||
'default' => '',
|
||||
'index' => true,
|
||||
'unique' => true
|
||||
],
|
||||
'label' => [
|
||||
'type' => Schema::DT_VARCHAR128,
|
||||
@@ -41,6 +49,9 @@ class RightModel extends AbstractPathfinderModel {
|
||||
]
|
||||
];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected static $tableData = [
|
||||
[
|
||||
'id' => 1,
|
||||
|
||||
@@ -19,11 +19,6 @@ class StructureModel extends AbstractPathfinderModel {
|
||||
*/
|
||||
protected $table = 'structure';
|
||||
|
||||
/**
|
||||
* categoryId (from ESI) that holds all "groups" with structure "types"
|
||||
*/
|
||||
const CATEGORY_STRUCTURE_ID = 65;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
|
||||
@@ -161,80 +161,78 @@ class SystemModel extends AbstractMapTrackingModel {
|
||||
/**
|
||||
* get map data as object
|
||||
* @return \stdClass
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getData(){
|
||||
|
||||
// check if there is cached data
|
||||
$systemData = $this->getCacheData();
|
||||
|
||||
if(is_null($systemData)){
|
||||
// no cached system data found
|
||||
|
||||
$systemData = (object) [];
|
||||
$systemData->id = $this->_id;
|
||||
$systemData->mapId = is_object($this->mapId) ? $this->get('mapId', true) : 0;
|
||||
$systemData->systemId = $this->systemId;
|
||||
$systemData->alias = $this->alias;
|
||||
if(is_null($data = $this->getCacheData())){
|
||||
$data = (object) [];
|
||||
$data->id = $this->_id;
|
||||
$data->mapId = is_object($this->mapId) ? $this->get('mapId', true) : 0;
|
||||
$data->systemId = $this->systemId;
|
||||
$data->alias = $this->alias;
|
||||
|
||||
if(is_object($this->typeId)){
|
||||
$systemData->type = $this->typeId->getData();
|
||||
$data->type = $this->typeId->getData();
|
||||
}
|
||||
|
||||
if(is_object($this->statusId)){
|
||||
$systemData->status = $this->statusId->getData();
|
||||
$data->status = $this->statusId->getData();
|
||||
}
|
||||
|
||||
$systemData->locked = $this->locked;
|
||||
$systemData->rallyUpdated = strtotime($this->rallyUpdated);
|
||||
$systemData->rallyPoke = $this->rallyPoke;
|
||||
$systemData->description = $this->description ? : '';
|
||||
$data->locked = $this->locked;
|
||||
$data->rallyUpdated = strtotime($this->rallyUpdated);
|
||||
$data->rallyPoke = $this->rallyPoke;
|
||||
$data->description = $this->description ? : '';
|
||||
|
||||
$systemData->position = (object) [];
|
||||
$systemData->position->x = $this->posX;
|
||||
$systemData->position->y = $this->posY;
|
||||
$data->position = (object) [];
|
||||
$data->position->x = $this->posX;
|
||||
$data->position->y = $this->posY;
|
||||
|
||||
$systemData->created = (object) [];
|
||||
$systemData->created->created = strtotime($this->created);
|
||||
$data->created = (object) [];
|
||||
$data->created->created = strtotime($this->created);
|
||||
if(is_object($this->createdCharacterId)){
|
||||
$systemData->created->character = $this->createdCharacterId->getData();
|
||||
$data->created->character = $this->createdCharacterId->getData();
|
||||
}
|
||||
|
||||
$systemData->updated = (object) [];
|
||||
$systemData->updated->updated = strtotime($this->updated);
|
||||
$data->updated = (object) [];
|
||||
$data->updated->updated = strtotime($this->updated);
|
||||
if(is_object($this->updatedCharacterId)){
|
||||
$systemData->updated->character = $this->updatedCharacterId->getData();
|
||||
$data->updated->character = $this->updatedCharacterId->getData();
|
||||
}
|
||||
|
||||
// static system data -------------------------------------------------------------------------------------
|
||||
$systemData->name = $this->name;
|
||||
$systemData->security = $this->security;
|
||||
$systemData->trueSec = $this->trueSec;
|
||||
$systemData->effect = $this->effect;
|
||||
$systemData->shattered = $this->shattered;
|
||||
$data->name = $this->name;
|
||||
$data->security = $this->security;
|
||||
$data->trueSec = $this->trueSec;
|
||||
$data->effect = $this->effect;
|
||||
$data->shattered = $this->shattered;
|
||||
|
||||
$systemData->constellation = (object) [];
|
||||
$systemData->constellation->id = $this->constellationId;
|
||||
$systemData->constellation->name = $this->constellation;
|
||||
$data->constellation = (object) [];
|
||||
$data->constellation->id = $this->constellationId;
|
||||
$data->constellation->name = $this->constellation;
|
||||
|
||||
$systemData->region = (object) [];
|
||||
$systemData->region->id = $this->regionId;
|
||||
$systemData->region->name = $this->region;
|
||||
$data->region = (object) [];
|
||||
$data->region->id = $this->regionId;
|
||||
$data->region->name = $this->region;
|
||||
|
||||
$systemData->planets = $this->planets ? : [];
|
||||
$systemData->statics = $this->statics ? : [];
|
||||
$data->planets = $this->planets ? : [];
|
||||
$data->statics = $this->statics ? : [];
|
||||
|
||||
if(is_object($this->faction)){
|
||||
$systemData->faction = $this->faction;
|
||||
if(is_object($sovereignty = $this->sovereignty)){
|
||||
$data->sovereignty = $sovereignty;
|
||||
}
|
||||
|
||||
if(is_object($factionWar = $this->factionWar)){
|
||||
$data->factionWar = $factionWar;
|
||||
}
|
||||
|
||||
// max caching time for a system
|
||||
// the cached date has to be cleared manually on any change
|
||||
// this includes system, connection,... changes (all dependencies)
|
||||
$this->updateCacheData($systemData);
|
||||
$this->updateCacheData($data);
|
||||
}
|
||||
|
||||
return $systemData;
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -435,10 +433,6 @@ class SystemModel extends AbstractMapTrackingModel {
|
||||
return ($constellationData && $constellationData->region) ? $constellationData->region->name : null;
|
||||
}
|
||||
|
||||
public function get_faction(){
|
||||
return $this->getStaticSystemValue('faction');
|
||||
}
|
||||
|
||||
public function get_security(){
|
||||
return $this->getStaticSystemValue('security');
|
||||
}
|
||||
@@ -463,6 +457,14 @@ class SystemModel extends AbstractMapTrackingModel {
|
||||
return $this->getStaticSystemValue('planets');
|
||||
}
|
||||
|
||||
public function get_sovereignty(){
|
||||
return $this->getStaticSystemValue('sovereignty');
|
||||
}
|
||||
|
||||
public function get_factionWar(){
|
||||
return $this->getStaticSystemValue('factionWar');
|
||||
}
|
||||
|
||||
/**
|
||||
* Event "Hook" function
|
||||
* @param self $self
|
||||
@@ -652,7 +654,7 @@ class SystemModel extends AbstractMapTrackingModel {
|
||||
* @return \stdClass[]
|
||||
*/
|
||||
public function getStructuresData() : array {
|
||||
return $this->getMap()->getStructuresData([$this->systemId]);
|
||||
return $this->getMap()->getStructuresData($this->systemId);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: Exodus
|
||||
* Date: 24.12.2015
|
||||
* Time: 00:59
|
||||
*/
|
||||
|
||||
namespace Model\Pathfinder;
|
||||
|
||||
use DB\SQL\Schema;
|
||||
|
||||
class SystemNeighbourModel extends AbstractPathfinderModel {
|
||||
|
||||
protected $table = 'system_neighbour';
|
||||
|
||||
protected $fieldConf = [
|
||||
'regionId' => [
|
||||
'type' => Schema::DT_INT,
|
||||
'index' => true
|
||||
],
|
||||
'constellationId' => [
|
||||
'type' => Schema::DT_INT,
|
||||
'index' => true
|
||||
],
|
||||
'systemName' => [
|
||||
'type' => Schema::DT_VARCHAR128,
|
||||
'default' => ''
|
||||
],
|
||||
'systemId' => [
|
||||
'type' => Schema::DT_INT,
|
||||
'index' => true
|
||||
],
|
||||
'jumpNodes' => [
|
||||
'type' => Schema::DT_VARCHAR512,
|
||||
'default' => ''
|
||||
],
|
||||
'trueSec' => [
|
||||
'type' => Schema::DT_DECIMAL,
|
||||
'default' => 0
|
||||
]
|
||||
];
|
||||
|
||||
/**
|
||||
* No static columns added
|
||||
* @var bool
|
||||
*/
|
||||
protected $addStaticFields = false;
|
||||
}
|
||||
@@ -12,8 +12,14 @@ use DB\SQL\Schema;
|
||||
|
||||
class SystemTypeModel extends AbstractPathfinderModel {
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'system_type';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $fieldConf = [
|
||||
'active' => [
|
||||
'type' => Schema::DT_BOOL,
|
||||
@@ -28,6 +34,9 @@ class SystemTypeModel extends AbstractPathfinderModel {
|
||||
]
|
||||
];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected static $tableData = [
|
||||
[
|
||||
'id' => 1,
|
||||
|
||||
@@ -202,16 +202,15 @@ class UserModel extends AbstractPathfinderModel {
|
||||
}
|
||||
|
||||
/**
|
||||
* get current character data from session
|
||||
* get current character from session data
|
||||
* -> if $characterId == 0 -> get first character data (random)
|
||||
* @param int $characterId
|
||||
* @param bool $objectCheck
|
||||
* @return array
|
||||
* @param int $ttl
|
||||
* @return CharacterModel|null
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getSessionCharacterData($characterId = 0, $objectCheck = true) : array {
|
||||
public function getSessionCharacter(int $characterId = 0, int $ttl = self::DEFAULT_SQL_TTL) : ?CharacterModel {
|
||||
$data = [];
|
||||
$characterId = (int)$characterId;
|
||||
$currentSessionUser = (array)$this->getF3()->get(User::SESSION_KEY_USER);
|
||||
|
||||
if($this->_id === $currentSessionUser['ID']){
|
||||
@@ -228,28 +227,22 @@ class UserModel extends AbstractPathfinderModel {
|
||||
}
|
||||
}
|
||||
|
||||
if(
|
||||
$objectCheck === true &&
|
||||
!empty($data)
|
||||
){
|
||||
if($characterId = (int)$data['ID']){
|
||||
// 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 = AbstractPathfinderModel::getNew('CharacterModel');
|
||||
$character->getById((int)$data['ID']);
|
||||
$character->getById($characterId, $ttl);
|
||||
|
||||
if(
|
||||
$character->dry() ||
|
||||
!$character->hasUserCharacter()
|
||||
){
|
||||
// character data is invalid!
|
||||
$data = [];
|
||||
if($character->valid() && $character->hasUserCharacter()){
|
||||
// character data is valid!
|
||||
return $character;
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -259,10 +252,9 @@ class UserModel extends AbstractPathfinderModel {
|
||||
*/
|
||||
public function findSessionCharacterData(int $characterId) : array {
|
||||
$data = [];
|
||||
if($characterId){
|
||||
$sessionCharacters = (array)$this->getF3()->get(User::SESSION_KEY_CHARACTERS);
|
||||
if($characterId && $this->getF3()->exists(User::SESSION_KEY_CHARACTERS, $sessionCharacters)){
|
||||
// search for specific characterData
|
||||
foreach($sessionCharacters as $characterData){
|
||||
foreach((array)$sessionCharacters as $characterData){
|
||||
if($characterId === (int)$characterData['ID']){
|
||||
$data = $characterData;
|
||||
break;
|
||||
|
||||
@@ -20,7 +20,7 @@ abstract class AbstractUniverseModel extends AbstractModel {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const CACHE_KEY_PREFIX = 'index_universe_';
|
||||
const CACHE_KEY_PREFIX = parent::CACHE_KEY_PREFIX . '_' . self::DB_ALIAS;
|
||||
|
||||
/**
|
||||
* cache key for model data -> should "never" expire
|
||||
@@ -46,7 +46,7 @@ abstract class AbstractUniverseModel extends AbstractModel {
|
||||
public function beforeUpdateEvent($self, $pkeys) : bool {
|
||||
// if model changed, 'update' col needs to be updated as well
|
||||
// -> data no longer "outdated"
|
||||
$this->touch('updated');
|
||||
$self->touch('updated');
|
||||
|
||||
return parent::beforeUpdateEvent($self, $pkeys);
|
||||
}
|
||||
@@ -59,7 +59,7 @@ abstract class AbstractUniverseModel extends AbstractModel {
|
||||
*/
|
||||
public function getHashKey(string $column = '_id'){
|
||||
$key = false;
|
||||
if( !$this->dry() && $this->exists($column) ){
|
||||
if($this->valid() && $this->exists($column)){
|
||||
$key = self::generateHashKeyRow($this->getTable(), $this->$column);
|
||||
}
|
||||
return $key;
|
||||
@@ -110,21 +110,6 @@ abstract class AbstractUniverseModel extends AbstractModel {
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* add $rowKeys (hashKeys) to a search index that holds all rowKeys of a table
|
||||
* @param AbstractUniverseModel $model
|
||||
* @param array $rowKeys
|
||||
*/
|
||||
public static function buildTableIndex(AbstractUniverseModel $model, array $rowKeys = []){
|
||||
$hashKeyTable = self::generateHashKeyTable($model->getTable());
|
||||
if( !self::getF3()->exists($hashKeyTable, $cachedData) ){
|
||||
$cachedData = [];
|
||||
}
|
||||
$cachedData = array_unique(array_merge($cachedData, $rowKeys));
|
||||
|
||||
self::getF3()->set($hashKeyTable, $cachedData, self::CACHE_INDEX_EXPIRE_KEY);
|
||||
}
|
||||
|
||||
/**
|
||||
* get data from "search" index for this model
|
||||
* -> if data not found -> try to build up index for this model
|
||||
@@ -166,6 +151,45 @@ abstract class AbstractUniverseModel extends AbstractModel {
|
||||
*/
|
||||
abstract protected function loadData(int $id, string $accessToken = '', array $additionalOptions = []);
|
||||
|
||||
/**
|
||||
* convert CCPs ids for system security into Pathfinder security label
|
||||
* -> used e.g. in "Dogma Attributes" (wormholeTargetSystemClass) for wormhole types
|
||||
* @param int $id
|
||||
* @return string|null
|
||||
*/
|
||||
public static function getSystemSecurityFromId(int $id) : ?string {
|
||||
$security = null;
|
||||
if(
|
||||
($id >= 1 && $id <= 6) ||
|
||||
($id >= 12 && $id <= 18)
|
||||
){
|
||||
$security = 'C' . $id;
|
||||
}elseif($id == 7){
|
||||
$security = 'H';
|
||||
}elseif($id == 8){
|
||||
$security = 'L';
|
||||
}elseif($id == 9){
|
||||
$security = '0.0';
|
||||
}
|
||||
|
||||
return $security;
|
||||
}
|
||||
|
||||
/**
|
||||
* add $rowKeys (hashKeys) to a search index that holds all rowKeys of a table
|
||||
* @param AbstractUniverseModel $model
|
||||
* @param array $rowKeys
|
||||
*/
|
||||
public static function buildTableIndex(AbstractUniverseModel $model, array $rowKeys = []){
|
||||
$hashKeyTable = static::generateHashKeyTable($model->getTable());
|
||||
if( !self::getF3()->exists($hashKeyTable, $cachedData) ){
|
||||
$cachedData = [];
|
||||
}
|
||||
$cachedData = array_unique(array_merge($cachedData, $rowKeys));
|
||||
|
||||
self::getF3()->set($hashKeyTable, $cachedData, self::CACHE_INDEX_EXPIRE_KEY);
|
||||
}
|
||||
|
||||
/**
|
||||
* generate hashKey for a table row data for search index build
|
||||
* @param string $table
|
||||
@@ -173,16 +197,17 @@ abstract class AbstractUniverseModel extends AbstractModel {
|
||||
* @return string
|
||||
*/
|
||||
public static function generateHashKeyRow(string $table, $value) : string {
|
||||
return self::generateHashKeyTable($table) . '_' . md5(strtolower((string)$value));
|
||||
return static::generateHashKeyTable($table) . '_' . md5(strtolower((string)$value));
|
||||
}
|
||||
|
||||
/**
|
||||
* generate hashKey for a complete table
|
||||
* -> should hold hashKeys for multiple rows
|
||||
* @param string $table
|
||||
* @param string $prefix
|
||||
* @return string
|
||||
*/
|
||||
public static function generateHashKeyTable(string $table) : string {
|
||||
return self::CACHE_KEY_PREFIX . strtolower($table);
|
||||
public static function generateHashKeyTable(string $table, string $prefix = self::CACHE_KEY_PREFIX) : string {
|
||||
return parent::generateHashKeyTable($table, $prefix);
|
||||
}
|
||||
}
|
||||
87
app/main/model/universe/alliancemodel.php
Normal file
87
app/main/model/universe/alliancemodel.php
Normal file
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Model\Universe;
|
||||
|
||||
use DB\SQL\Schema;
|
||||
|
||||
class AllianceModel extends AbstractUniverseModel {
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'alliance';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $fieldConf = [
|
||||
'name' => [
|
||||
'type' => Schema::DT_VARCHAR128,
|
||||
'nullable' => false,
|
||||
'default' => ''
|
||||
],
|
||||
'ticker' => [
|
||||
'type' => Schema::DT_VARCHAR128,
|
||||
'nullable' => false,
|
||||
'default' => ''
|
||||
],
|
||||
'dateFounded' => [
|
||||
'type' => Schema::DT_DATETIME,
|
||||
'default' => null
|
||||
],
|
||||
'factionId' => [
|
||||
'type' => Schema::DT_INT,
|
||||
'index' => true,
|
||||
'belongs-to-one' => 'Model\Universe\FactionModel',
|
||||
'constraint' => [
|
||||
[
|
||||
'table' => 'faction',
|
||||
'on-delete' => 'SET NULL'
|
||||
]
|
||||
]
|
||||
],
|
||||
'corporations' => [
|
||||
'has-many' => ['Model\Universe\CorporationModel', 'allianceId']
|
||||
],
|
||||
'sovereigntySystems' => [
|
||||
'has-many' => ['Model\Universe\SovereigntyMapModel', 'allianceId']
|
||||
]
|
||||
];
|
||||
|
||||
/**
|
||||
* get data
|
||||
* @return \stdClass
|
||||
*/
|
||||
public function getData(){
|
||||
$data = (object) [];
|
||||
$data->id = $this->_id;
|
||||
$data->name = $this->name;
|
||||
$data->ticker = $this->ticker;
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* load alliance by Id either from DB or load data from API
|
||||
* @param int $id
|
||||
* @param string $accessToken
|
||||
* @param array $additionalOptions
|
||||
*/
|
||||
protected function loadData(int $id, string $accessToken = '', array $additionalOptions = []){
|
||||
$data = self::getF3()->ccpClient()->getAllianceData($id);
|
||||
if(!empty($data) && !isset($data['error'])){
|
||||
if($data['factionId']){
|
||||
/**
|
||||
* @var $faction FactionModel
|
||||
*/
|
||||
$faction = $this->rel('factionId');
|
||||
$faction->loadById($data['factionId'], $accessToken, $additionalOptions);
|
||||
$data['factionId'] = $faction;
|
||||
}
|
||||
|
||||
$this->copyfrom($data, ['id', 'name', 'ticker', 'dateFounded', 'factionId']);
|
||||
$this->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -38,7 +38,7 @@ class CategoryModel extends AbstractUniverseModel {
|
||||
*/
|
||||
public function getData(array $additionalData = []){
|
||||
$categoryData = (object) [];
|
||||
$categoryData->id = $this->id;
|
||||
$categoryData->id = $this->_id;
|
||||
$categoryData->name = $this->name;
|
||||
|
||||
if($groupsData = $this->getGroupsData($additionalData)){
|
||||
@@ -77,6 +77,9 @@ class CategoryModel extends AbstractUniverseModel {
|
||||
$groupsData = [];
|
||||
$groups = $this->getGroups();
|
||||
|
||||
/**
|
||||
* @var $group GroupModel
|
||||
*/
|
||||
foreach($groups as $group){
|
||||
$groupsData[] = $group->getData($additionalData);
|
||||
}
|
||||
@@ -84,6 +87,15 @@ class CategoryModel extends AbstractUniverseModel {
|
||||
return $groupsData;
|
||||
}
|
||||
|
||||
/**
|
||||
* get groups count
|
||||
* @param bool $published
|
||||
* @return int
|
||||
*/
|
||||
public function getGroupsCount(bool $published = true) : int {
|
||||
return $this->valid() ? count($this->getGroups($published)) : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* count all types that belong to groups in this category
|
||||
* @param bool $published
|
||||
@@ -91,7 +103,7 @@ class CategoryModel extends AbstractUniverseModel {
|
||||
*/
|
||||
public function getTypesCount(bool $published = true) : int {
|
||||
$count = 0;
|
||||
if( !$this->dry() ){
|
||||
if($this->valid()){
|
||||
/**
|
||||
* @var $group GroupModel
|
||||
*/
|
||||
@@ -109,8 +121,7 @@ class CategoryModel extends AbstractUniverseModel {
|
||||
* @param array $additionalOptions
|
||||
*/
|
||||
protected function loadData(int $id, string $accessToken = '', array $additionalOptions = []){
|
||||
$data = self::getF3()->ccpClient()->getUniverseCategoryData($id);
|
||||
if(!empty($data)){
|
||||
if(!empty($data = self::getUniverseCategoryData($id))){
|
||||
$this->copyfrom($data, ['id', 'name', 'published']);
|
||||
$this->save();
|
||||
}
|
||||
@@ -123,25 +134,71 @@ class CategoryModel extends AbstractUniverseModel {
|
||||
* @return array
|
||||
*/
|
||||
public function loadGroupsData(int $offset = 0, int $length = 0) : array {
|
||||
$groupIds = [];
|
||||
if( !$this->dry() ){
|
||||
$data = self::getF3()->ccpClient()->getUniverseCategoryData($this->_id);
|
||||
if(!empty($data)){
|
||||
array_multisort($data['groups'], SORT_ASC, SORT_NUMERIC);
|
||||
if($length){
|
||||
$data['groups'] = array_slice($data['groups'], $offset, $length);
|
||||
}
|
||||
foreach($data['groups'] as $groupId){
|
||||
/**
|
||||
* @var $group GroupModel
|
||||
*/
|
||||
$group = $this->rel('groups');
|
||||
$group->loadById($groupId);
|
||||
$groupIds[] = $groupId;
|
||||
$group->reset();
|
||||
}
|
||||
$info = ['countAll' => 0, 'countChunk' => 0, 'count' => 0, 'offset' => $offset, 'groupTypes' => []];
|
||||
|
||||
if(
|
||||
$this->valid() &&
|
||||
!empty($data = self::getUniverseCategoryData($this->_id))
|
||||
){
|
||||
$info['countAll'] = count($data['groups']);
|
||||
|
||||
array_multisort($data['groups'], SORT_ASC, SORT_NUMERIC);
|
||||
if($length){
|
||||
$data['groups'] = array_slice($data['groups'], $offset, $length);
|
||||
}
|
||||
|
||||
$info['countChunk'] = count($data['groups']);
|
||||
foreach($data['groups'] as $groupId){
|
||||
/**
|
||||
* @var $group GroupModel
|
||||
*/
|
||||
$group = $this->rel('groups');
|
||||
$group->loadById($groupId);
|
||||
|
||||
$info['groupTypes'][$groupId] = $group->loadTypesData();
|
||||
|
||||
$group->reset();
|
||||
|
||||
$info['count']++;
|
||||
$info['offset']++;
|
||||
}
|
||||
}
|
||||
return $groupIds;
|
||||
|
||||
return $info;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
* @return array
|
||||
*/
|
||||
public static function getUniverseCategoryData(int $id) : array {
|
||||
return self::getF3()->ccpClient()->getUniverseCategoryData($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function getUniverseCategories() : array {
|
||||
return self::getF3()->ccpClient()->getUniverseCategories();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
* @return array
|
||||
*/
|
||||
public static function getUniverseCategoryGroups(int $id) : array {
|
||||
return empty($data = self::getUniverseCategoryData($id)) ? [] : $data['groups'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
* @return array
|
||||
*/
|
||||
public static function getUniverseCategoryTypes(int $id) : array {
|
||||
$types = [];
|
||||
foreach($groupIds = self::getUniverseCategoryGroups($id) as $groupId){
|
||||
$types[$groupId] = GroupModel::getUniverseGroupTypes($groupId);
|
||||
}
|
||||
return $types;
|
||||
}
|
||||
}
|
||||
@@ -55,6 +55,9 @@ class ConstellationModel extends AbstractUniverseModel {
|
||||
],
|
||||
'systems' => [
|
||||
'has-many' => ['Model\Universe\SystemModel', 'constellationId']
|
||||
],
|
||||
'systemNeighbours' => [
|
||||
'has-many' => ['Model\Universe\SystemNeighbourModel', 'constellationId']
|
||||
]
|
||||
];
|
||||
|
||||
|
||||
116
app/main/model/universe/corporationmodel.php
Normal file
116
app/main/model/universe/corporationmodel.php
Normal file
@@ -0,0 +1,116 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Model\Universe;
|
||||
|
||||
use DB\SQL\Schema;
|
||||
|
||||
class CorporationModel extends AbstractUniverseModel {
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'corporation';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $fieldConf = [
|
||||
'name' => [
|
||||
'type' => Schema::DT_VARCHAR128,
|
||||
'nullable' => false,
|
||||
'default' => ''
|
||||
],
|
||||
'ticker' => [
|
||||
'type' => Schema::DT_VARCHAR128,
|
||||
'nullable' => false,
|
||||
'default' => ''
|
||||
],
|
||||
'dateFounded' => [
|
||||
'type' => Schema::DT_DATETIME,
|
||||
'default' => null
|
||||
],
|
||||
'memberCount' => [
|
||||
'type' => Schema::DT_INT,
|
||||
'nullable' => false,
|
||||
'default' => 0
|
||||
],
|
||||
'isNPC' => [
|
||||
'type' => Schema::DT_BOOL,
|
||||
'nullable' => false,
|
||||
'default' => 0
|
||||
],
|
||||
'factionId' => [
|
||||
'type' => Schema::DT_INT,
|
||||
'index' => true,
|
||||
'belongs-to-one' => 'Model\Universe\FactionModel',
|
||||
'constraint' => [
|
||||
[
|
||||
'table' => 'faction',
|
||||
'on-delete' => 'SET NULL'
|
||||
]
|
||||
]
|
||||
],
|
||||
'allianceId' => [
|
||||
'type' => Schema::DT_INT,
|
||||
'index' => true,
|
||||
'belongs-to-one' => 'Model\Universe\AllianceModel',
|
||||
'constraint' => [
|
||||
[
|
||||
'table' => 'alliance',
|
||||
'on-delete' => 'SET NULL'
|
||||
]
|
||||
]
|
||||
],
|
||||
'sovereigntySystems' => [
|
||||
'has-many' => ['Model\Universe\SovereigntyMapModel', 'corporationId']
|
||||
]
|
||||
];
|
||||
|
||||
/**
|
||||
* get data
|
||||
* @return \stdClass
|
||||
*/
|
||||
public function getData(){
|
||||
$data = (object) [];
|
||||
$data->id = $this->_id;
|
||||
$data->name = $this->name;
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* load corporation by Id either from DB or load data from API
|
||||
* @param int $id
|
||||
* @param string $accessToken
|
||||
* @param array $additionalOptions
|
||||
*/
|
||||
protected function loadData(int $id, string $accessToken = '', array $additionalOptions = []){
|
||||
$data = self::getF3()->ccpClient()->getCorporationData($id);
|
||||
if(!empty($data) && !isset($data['error'])){
|
||||
// check for NPC corporation
|
||||
$data['isNPC'] = self::getF3()->ccpClient()->isNpcCorporation($id);
|
||||
|
||||
if($data['factionId']){
|
||||
/**
|
||||
* @var $faction FactionModel
|
||||
*/
|
||||
$faction = $this->rel('factionId');
|
||||
$faction->loadById($data['factionId'], $accessToken, $additionalOptions);
|
||||
$data['factionId'] = $faction;
|
||||
}
|
||||
|
||||
if($data['allianceId']){
|
||||
/**
|
||||
* @var $faction AllianceModel
|
||||
*/
|
||||
$alliance = $this->rel('allianceId');
|
||||
$alliance->loadById($data['allianceId'], $accessToken, $additionalOptions);
|
||||
$data['allianceId'] = $alliance;
|
||||
}
|
||||
|
||||
$this->copyfrom($data, ['id', 'name', 'ticker', 'dateFounded', 'memberCount', 'isNPC', 'factionId', 'allianceId']);
|
||||
$this->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
97
app/main/model/universe/dogmaattributemodel.php
Normal file
97
app/main/model/universe/dogmaattributemodel.php
Normal file
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: Exodus4D
|
||||
* Date: 15.08.2019
|
||||
* Time: 22:00
|
||||
*/
|
||||
|
||||
namespace Model\Universe;
|
||||
|
||||
use DB\SQL\Schema;
|
||||
|
||||
class DogmaAttributeModel extends AbstractUniverseModel {
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'dogma_attribute';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $fieldConf = [
|
||||
'name' => [
|
||||
'type' => Schema::DT_VARCHAR128,
|
||||
'nullable' => false,
|
||||
'default' => ''
|
||||
],
|
||||
'displayName' => [
|
||||
'type' => Schema::DT_VARCHAR128,
|
||||
'nullable' => true,
|
||||
'default' => null
|
||||
],
|
||||
'description' => [
|
||||
'type' => Schema::DT_TEXT
|
||||
],
|
||||
'published' => [
|
||||
'type' => Schema::DT_BOOL,
|
||||
'nullable' => true,
|
||||
'default' => null
|
||||
],
|
||||
'stackable' => [
|
||||
'type' => Schema::DT_BOOL,
|
||||
'nullable' => true,
|
||||
'default' => null
|
||||
],
|
||||
'highIsGood' => [
|
||||
'type' => Schema::DT_BOOL,
|
||||
'nullable' => true,
|
||||
'default' => null
|
||||
],
|
||||
'defaultValue' => [
|
||||
'type' => Schema::DT_FLOAT,
|
||||
'nullable' => false,
|
||||
'default' => 0
|
||||
],
|
||||
'iconId' => [
|
||||
'type' => Schema::DT_INT,
|
||||
'nullable' => true,
|
||||
'default' => null
|
||||
],
|
||||
'unitId' => [
|
||||
'type' => Schema::DT_INT,
|
||||
'nullable' => true,
|
||||
'default' => null
|
||||
],
|
||||
'attributeTypes' => [
|
||||
'has-many' => ['Model\Universe\TypeAttributeModel', 'attributeId']
|
||||
]
|
||||
];
|
||||
|
||||
/**
|
||||
* get data
|
||||
* @return \stdClass
|
||||
*/
|
||||
public function getData(){
|
||||
$attributeData = (object) [];
|
||||
$attributeData->id = $this->_id;
|
||||
$attributeData->name = $this->name;
|
||||
$attributeData->description = $this->description;
|
||||
|
||||
return $attributeData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
* @param string $accessToken
|
||||
* @param array $additionalOptions
|
||||
*/
|
||||
protected function loadData(int $id, string $accessToken = '', array $additionalOptions = []){
|
||||
$data = self::getF3()->ccpClient()->getDogmaAttributeData($id);
|
||||
if(!empty($data)){
|
||||
$this->copyfrom($data, ['id', 'name', 'displayName', 'description', 'published', 'stackable', 'highIsGood', 'defaultValue', 'iconId', 'unitId']);
|
||||
$this->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -46,8 +46,20 @@ class FactionModel extends AbstractUniverseModel {
|
||||
'nullable' => false,
|
||||
'default' => 0
|
||||
],
|
||||
'systems' => [
|
||||
'has-many' => ['Model\Universe\SystemModel', 'factionId']
|
||||
'alliances' => [
|
||||
'has-many' => ['Model\Universe\AllianceModel', 'factionId']
|
||||
],
|
||||
'corporations' => [
|
||||
'has-many' => ['Model\Universe\CorporationModel', 'factionId']
|
||||
],
|
||||
'sovereigntySystems' => [
|
||||
'has-many' => ['Model\Universe\SovereigntyMapModel', 'factionId']
|
||||
],
|
||||
'factionWarSystemOwners' => [
|
||||
'has-many' => ['Model\Universe\FactionWarSystemModel', 'ownerFactionId']
|
||||
],
|
||||
'factionWarSystemOccupiers' => [
|
||||
'has-many' => ['Model\Universe\FactionWarSystemModel', 'occupierFactionId']
|
||||
]
|
||||
];
|
||||
|
||||
|
||||
120
app/main/model/universe/factionwarsystemmodel.php
Normal file
120
app/main/model/universe/factionwarsystemmodel.php
Normal file
@@ -0,0 +1,120 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Model\Universe;
|
||||
|
||||
use DB\SQL\Schema;
|
||||
|
||||
class FactionWarSystemModel extends AbstractUniverseModel {
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'faction_war_system';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $fieldConf = [
|
||||
'systemId' => [
|
||||
'type' => Schema::DT_INT,
|
||||
'index' => true,
|
||||
'unique' => true,
|
||||
'belongs-to-one' => 'Model\Universe\SystemModel',
|
||||
'constraint' => [
|
||||
[
|
||||
'table' => 'system',
|
||||
'on-delete' => 'CASCADE'
|
||||
]
|
||||
],
|
||||
'validate' => 'notDry'
|
||||
],
|
||||
'ownerFactionId' => [
|
||||
'type' => Schema::DT_INT,
|
||||
'index' => true,
|
||||
'belongs-to-one' => 'Model\Universe\FactionModel',
|
||||
'constraint' => [
|
||||
[
|
||||
'table' => 'faction',
|
||||
'on-delete' => 'CASCADE'
|
||||
]
|
||||
]
|
||||
],
|
||||
'occupierFactionId' => [
|
||||
'type' => Schema::DT_INT,
|
||||
'index' => true,
|
||||
'belongs-to-one' => 'Model\Universe\FactionModel',
|
||||
'constraint' => [
|
||||
[
|
||||
'table' => 'faction',
|
||||
'on-delete' => 'CASCADE'
|
||||
]
|
||||
]
|
||||
],
|
||||
'contested' => [
|
||||
'type' => Schema::DT_VARCHAR128,
|
||||
'nullable' => false,
|
||||
'default' => ''
|
||||
],
|
||||
'victoryPoints' => [
|
||||
'type' => Schema::DT_INT,
|
||||
'nullable' => false,
|
||||
'default' => 0
|
||||
],
|
||||
'victoryPointsThreshold' => [
|
||||
'type' => Schema::DT_INT,
|
||||
'nullable' => false,
|
||||
'default' => 0
|
||||
]
|
||||
];
|
||||
|
||||
/**
|
||||
* No static columns added
|
||||
* @var bool
|
||||
*/
|
||||
protected $addStaticFields = false;
|
||||
|
||||
/**
|
||||
* get data
|
||||
* @return \stdClass
|
||||
*/
|
||||
public function getData(){
|
||||
$data = (object) [];
|
||||
$data->contested = $this->contested;
|
||||
|
||||
if($this->ownerFactionId){
|
||||
$data->ownerFaction = $this->ownerFactionId->getData();
|
||||
$data->victoryPercentage = $this->getVictoryPercentage();
|
||||
|
||||
if(
|
||||
$this->occupierFactionId &&
|
||||
$this->get('occupierFactionId', true) !== $this->get('ownerFactionId', true)
|
||||
){
|
||||
$data->occupierFaction = $this->occupierFactionId->getData();
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* calculate victory progress in percent
|
||||
* @return int
|
||||
*/
|
||||
protected function getVictoryPercentage() : int {
|
||||
$percent = 0;
|
||||
|
||||
if($this->victoryPoints && $this->victoryPointsThreshold){
|
||||
$percent = floor((100 / $this->victoryPointsThreshold) * $this->victoryPoints);
|
||||
}
|
||||
|
||||
return $percent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
* @param string $accessToken
|
||||
* @param array $additionalOptions
|
||||
*/
|
||||
protected function loadData(int $id, string $accessToken = '', array $additionalOptions = []){}
|
||||
}
|
||||
@@ -12,8 +12,19 @@ use DB\SQL\Schema;
|
||||
|
||||
class GroupModel extends AbstractUniverseModel {
|
||||
|
||||
protected $table = 'group';
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'group';
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public $storeDogmaAttributes = TypeModel::DEFAULT_STORE_DOGMA_ATTRIBUTES;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $fieldConf = [
|
||||
'name' => [
|
||||
'type' => Schema::DT_VARCHAR128,
|
||||
@@ -50,7 +61,7 @@ class GroupModel extends AbstractUniverseModel {
|
||||
*/
|
||||
public function getData(array $additionalData = []){
|
||||
$groupData = (object) [];
|
||||
$groupData->id = $this->id;
|
||||
$groupData->id = $this->_id;
|
||||
$groupData->name = $this->name;
|
||||
|
||||
if($typesData = $this->getTypesData($additionalData)){
|
||||
@@ -65,7 +76,7 @@ class GroupModel extends AbstractUniverseModel {
|
||||
* @param bool $published
|
||||
* @return array|mixed
|
||||
*/
|
||||
protected function getTypes(bool $published = true){
|
||||
public function getTypes(bool $published = true){
|
||||
$types = [];
|
||||
if($published){
|
||||
$this->filter('types', [
|
||||
@@ -102,7 +113,7 @@ class GroupModel extends AbstractUniverseModel {
|
||||
* @return int
|
||||
*/
|
||||
public function getTypesCount(bool $published = true) : int {
|
||||
return $this->dry() ? 0 : count($this->getTypes($published));
|
||||
return $this->valid() ? count($this->getTypes($published)) : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -111,8 +122,7 @@ class GroupModel extends AbstractUniverseModel {
|
||||
* @param array $additionalOptions
|
||||
*/
|
||||
protected function loadData(int $id, string $accessToken = '', array $additionalOptions = []){
|
||||
$data = self::getF3()->ccpClient()->getUniverseGroupData($id);
|
||||
if(!empty($data)){
|
||||
if(!empty($data = self::getUniverseGroupData($id))){
|
||||
/**
|
||||
* @var $category CategoryModel
|
||||
*/
|
||||
@@ -127,24 +137,62 @@ class GroupModel extends AbstractUniverseModel {
|
||||
|
||||
/**
|
||||
* load types data for this group
|
||||
* @return int
|
||||
* @param int $offset
|
||||
* @param int $length 0 -> all types
|
||||
* @return array
|
||||
*/
|
||||
public function loadTypesData(){
|
||||
$count = 0;
|
||||
if( !$this->dry() ){
|
||||
$data = self::getF3()->ccpClient()->getUniverseGroupData($this->_id);
|
||||
if(!empty($data)){
|
||||
foreach((array)$data['types'] as $typeId){
|
||||
/**
|
||||
* @var $type TypeModel
|
||||
*/
|
||||
$type = $this->rel('types');
|
||||
$type->loadById($typeId);
|
||||
$type->reset();
|
||||
$count++;
|
||||
}
|
||||
public function loadTypesData(int $offset = 0, int $length = 0) : array {
|
||||
$info = ['countAll' => 0, 'countChunk' => 0, 'count' => 0, 'offset' => $offset];
|
||||
|
||||
if(
|
||||
$this->valid() &&
|
||||
!empty($data = self::getUniverseGroupData($this->_id))
|
||||
){
|
||||
$info['countAll'] = count($data['types']);
|
||||
|
||||
array_multisort($data['types'], SORT_ASC, SORT_NUMERIC);
|
||||
if($length){
|
||||
$data['types'] = array_slice($data['types'], $offset, $length);
|
||||
}
|
||||
|
||||
$info['countChunk'] = count($data['types']);
|
||||
foreach($data['types'] as $typeId){
|
||||
/**
|
||||
* @var $type TypeModel
|
||||
*/
|
||||
$type = $this->rel('types');
|
||||
$type->storeDogmaAttributes = $this->storeDogmaAttributes;
|
||||
$type->loadById($typeId);
|
||||
$type->reset();
|
||||
|
||||
$info['count']++;
|
||||
$info['offset']++;
|
||||
}
|
||||
}
|
||||
return $count;
|
||||
|
||||
return $info;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
* @return array
|
||||
*/
|
||||
public static function getUniverseGroupData(int $id) : array {
|
||||
return self::getF3()->ccpClient()->getUniverseGroupData($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function getUniverseGroups() : array {
|
||||
return self::getF3()->ccpClient()->getUniverseGroups();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
* @return array
|
||||
*/
|
||||
public static function getUniverseGroupTypes(int $id) : array {
|
||||
return empty($data = self::getUniverseGroupData($id)) ? [] : $data['types'];
|
||||
}
|
||||
}
|
||||
@@ -66,13 +66,13 @@ class PlanetModel extends AbstractUniverseModel {
|
||||
* @return \stdClass
|
||||
*/
|
||||
public function getData(){
|
||||
$planetData = (object) [];
|
||||
$planetData->name = $this->name;
|
||||
$data = (object) [];
|
||||
$data->name = $this->name;
|
||||
|
||||
$planetData->type = (object) [];
|
||||
$planetData->type->name = $this->typeId->name;
|
||||
$data->type = (object) [];
|
||||
$data->type->name = $this->typeId->name;
|
||||
|
||||
return $planetData;
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -32,6 +32,9 @@ class RegionModel extends AbstractUniverseModel {
|
||||
],
|
||||
'constellations' => [
|
||||
'has-many' => ['Model\Universe\ConstellationModel', 'regionId']
|
||||
],
|
||||
'systemNeighbours' => [
|
||||
'has-many' => ['Model\Universe\SystemNeighbourModel', 'regionId']
|
||||
]
|
||||
];
|
||||
|
||||
|
||||
101
app/main/model/universe/sovereigntymapmodel.php
Normal file
101
app/main/model/universe/sovereigntymapmodel.php
Normal file
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Model\Universe;
|
||||
|
||||
use DB\SQL\Schema;
|
||||
|
||||
class SovereigntyMapModel extends AbstractUniverseModel {
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'sovereignty_map';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $fieldConf = [
|
||||
'systemId' => [
|
||||
'type' => Schema::DT_INT,
|
||||
'index' => true,
|
||||
'unique' => true,
|
||||
'belongs-to-one' => 'Model\Universe\SystemModel',
|
||||
'constraint' => [
|
||||
[
|
||||
'table' => 'system',
|
||||
'on-delete' => 'CASCADE'
|
||||
]
|
||||
],
|
||||
'validate' => 'notDry'
|
||||
],
|
||||
'factionId' => [
|
||||
'type' => Schema::DT_INT,
|
||||
'index' => true,
|
||||
'belongs-to-one' => 'Model\Universe\FactionModel',
|
||||
'constraint' => [
|
||||
[
|
||||
'table' => 'faction',
|
||||
'on-delete' => 'CASCADE'
|
||||
]
|
||||
]
|
||||
],
|
||||
'allianceId' => [
|
||||
'type' => Schema::DT_INT,
|
||||
'index' => true,
|
||||
'belongs-to-one' => 'Model\Universe\AllianceModel',
|
||||
'constraint' => [
|
||||
[
|
||||
'table' => 'alliance',
|
||||
'on-delete' => 'CASCADE'
|
||||
]
|
||||
]
|
||||
],
|
||||
'corporationId' => [
|
||||
'type' => Schema::DT_INT,
|
||||
'index' => true,
|
||||
'belongs-to-one' => 'Model\Universe\CorporationModel',
|
||||
'constraint' => [
|
||||
[
|
||||
'table' => 'corporation',
|
||||
'on-delete' => 'CASCADE'
|
||||
]
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
/**
|
||||
* No static columns added
|
||||
* @var bool
|
||||
*/
|
||||
protected $addStaticFields = false;
|
||||
|
||||
/**
|
||||
* get data
|
||||
* @return \stdClass
|
||||
*/
|
||||
public function getData(){
|
||||
$data = (object) [];
|
||||
|
||||
if($this->factionId){
|
||||
$data->faction = $this->factionId->getData();
|
||||
}else{
|
||||
if($this->allianceId){
|
||||
$data->alliance = $this->allianceId->getData();
|
||||
}
|
||||
|
||||
if($this->corporationId){
|
||||
$data->corporation = $this->corporationId->getData();
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
* @param string $accessToken
|
||||
* @param array $additionalOptions
|
||||
*/
|
||||
protected function loadData(int $id, string $accessToken = '', array $additionalOptions = []){}
|
||||
}
|
||||
@@ -12,8 +12,14 @@ use DB\SQL\Schema;
|
||||
|
||||
class StarModel extends AbstractUniverseModel {
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'star';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $fieldConf = [
|
||||
'name' => [
|
||||
'type' => Schema::DT_VARCHAR128,
|
||||
|
||||
@@ -17,11 +17,6 @@ class SystemModel extends AbstractUniverseModel {
|
||||
*/
|
||||
protected $table = 'system';
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const ERROR_INVALID_WORMHOLE = 'Invalid wormhole name "%s" for system: "%s"';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
@@ -55,18 +50,6 @@ class SystemModel extends AbstractUniverseModel {
|
||||
],
|
||||
'validate' => 'notDry'
|
||||
],
|
||||
'factionId' => [
|
||||
'type' => Schema::DT_INT,
|
||||
'index' => true,
|
||||
'belongs-to-one' => 'Model\Universe\FactionModel',
|
||||
'constraint' => [
|
||||
[
|
||||
'table' => 'faction',
|
||||
'on-delete' => 'CASCADE'
|
||||
]
|
||||
],
|
||||
'validate' => 'notDry'
|
||||
],
|
||||
'security' => [
|
||||
'type' => Schema::DT_VARCHAR128
|
||||
],
|
||||
@@ -86,11 +69,6 @@ class SystemModel extends AbstractUniverseModel {
|
||||
'effect' => [
|
||||
'type' => Schema::DT_VARCHAR128
|
||||
],
|
||||
'shattered' => [
|
||||
'type' => Schema::DT_BOOL,
|
||||
'nullable' => false,
|
||||
'default' => 0
|
||||
],
|
||||
'x' => [
|
||||
'type' => Schema::DT_BIGINT,
|
||||
'nullable' => false,
|
||||
@@ -114,6 +92,18 @@ class SystemModel extends AbstractUniverseModel {
|
||||
],
|
||||
'stargates' => [
|
||||
'has-many' => ['Model\Universe\StargateModel', 'systemId']
|
||||
],
|
||||
'structures' => [
|
||||
'has-many' => ['Model\Universe\StructureModel', 'systemId']
|
||||
],
|
||||
'neighbour' => [
|
||||
'has-one' => ['Model\Universe\SystemNeighbourModel', 'systemId']
|
||||
],
|
||||
'sovereignty' => [
|
||||
'has-one' => ['Model\Universe\SovereigntyMapModel', 'systemId']
|
||||
],
|
||||
'factionWar' => [
|
||||
'has-one' => ['Model\Universe\FactionWarSystemModel', 'systemId']
|
||||
]
|
||||
];
|
||||
|
||||
@@ -123,37 +113,48 @@ class SystemModel extends AbstractUniverseModel {
|
||||
* @return \stdClass
|
||||
*/
|
||||
public function getData(){
|
||||
|
||||
$systemData = (object) [];
|
||||
$systemData->id = $this->_id;
|
||||
$systemData->name = $this->name;
|
||||
$systemData->constellation = $this->constellationId->getData();
|
||||
$systemData->security = $this->security;
|
||||
$systemData->trueSec = (float)$this->trueSec;
|
||||
$systemData->effect = $this->effect;
|
||||
$systemData->shattered = (bool)$this->shattered;
|
||||
$data = (object) [];
|
||||
$data->id = $this->_id;
|
||||
$data->name = $this->name;
|
||||
$data->constellation = $this->constellationId->getData();
|
||||
$data->security = $this->security;
|
||||
$data->trueSec = (float)$this->trueSec;
|
||||
$data->effect = $this->effect;
|
||||
$data->shattered = false;
|
||||
|
||||
if($this->starId){
|
||||
$systemData->star = $this->starId->getData();
|
||||
$data->star = $this->starId->getData();
|
||||
}
|
||||
|
||||
if($this->factionId){
|
||||
$systemData->faction = $this->factionId->getData();
|
||||
if($this->sovereignty){
|
||||
$data->sovereignty = $this->sovereignty->getData();
|
||||
}
|
||||
|
||||
if($this->factionWar){
|
||||
$data->factionWar = $this->factionWar->getData();
|
||||
}
|
||||
|
||||
if( !empty($planetsData = $this->getPlanetsData()) ){
|
||||
$systemData->planets = $planetsData;
|
||||
$data->planets = $planetsData;
|
||||
|
||||
// 'Shattered' systems have ONLY planets named with '(shattered)'
|
||||
// -> system 'Thera' has '(shattered)' AND other planets -> not shattered.
|
||||
// -> system 'J164104, 'J115422' - the only non-shattered wormholes which have a shattered planet -> not shattered.
|
||||
$data->shattered = count(array_filter($planetsData, function(object $planetData){
|
||||
return property_exists($planetData, 'type') &&
|
||||
(strpos(strtolower($planetData->type->name), '(shattered)') !== false);
|
||||
})) == count($planetsData);
|
||||
}
|
||||
|
||||
if( !empty($staticsData = $this->getStaticsData()) ){
|
||||
$systemData->statics = $staticsData;
|
||||
$data->statics = $staticsData;
|
||||
}
|
||||
|
||||
if( !empty($stargatesData = $this->getStargatesData()) ){
|
||||
$systemData->stargates = $stargatesData;
|
||||
$data->stargates = $stargatesData;
|
||||
}
|
||||
|
||||
return $systemData;
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -185,11 +186,18 @@ class SystemModel extends AbstractUniverseModel {
|
||||
}
|
||||
$this->trueSec = $trueSec;
|
||||
// set 'security' for NON wormhole systems! -> those get updated from csv import
|
||||
if(!preg_match('/^j\d+$/i', $this->name)){
|
||||
// check for "Abyssal" system
|
||||
if(
|
||||
$this->get('constellationId', true) >= 22000001 &&
|
||||
$this->get('constellationId', true) <= 22000025
|
||||
// 'J1226-0' is also a wormhole with a '-' in the name! (single system)
|
||||
if(
|
||||
!preg_match('/^j(\d{6}|\d{4}-\d)$/i', $this->name) &&
|
||||
$this->name != 'Thera'
|
||||
){
|
||||
$constellationId = (int)$this->get('constellationId', true);
|
||||
if($constellationId == 23000001){
|
||||
// "Pocket" system
|
||||
$security = 'P';
|
||||
}elseif(
|
||||
$constellationId >= 22000001 &&
|
||||
$constellationId <= 22000025
|
||||
){
|
||||
// "Abyssal" system
|
||||
$security = 'A';
|
||||
@@ -235,15 +243,120 @@ class SystemModel extends AbstractUniverseModel {
|
||||
}
|
||||
|
||||
/**
|
||||
* setter for static systems (wormholes)
|
||||
* -> comma separated string or array
|
||||
* @param $staticNames
|
||||
* @return null
|
||||
* @param array $sovData
|
||||
*/
|
||||
public function set_staticNames($staticNames){
|
||||
$staticNames = array_unique(is_string($staticNames) ? explode(',', $staticNames) : (array)$staticNames);
|
||||
$this->virtual('staticNames', array_map('strtoupper', $staticNames));
|
||||
return null;
|
||||
public function updateSovereigntyData(array $sovData = []){
|
||||
$systemId = (int)$sovData['systemId'];
|
||||
$factionId = (int)$sovData['factionId'];
|
||||
$allianceId = (int)$sovData['allianceId'];
|
||||
$corporationId = (int)$sovData['corporationId'];
|
||||
|
||||
if($this->valid()){
|
||||
if($systemId === $this->_id){
|
||||
// sov data belongs to this system
|
||||
$validSovData = (bool)max($factionId, $allianceId, $corporationId);
|
||||
if($validSovData){
|
||||
// at least one of these Ids must exist for a sovereignty relation
|
||||
/**
|
||||
* @var $sovereignty SovereigntyMapModel
|
||||
*/
|
||||
if( !($sovereignty = $this->sovereignty) ){
|
||||
// insert new sovereignty data
|
||||
$sovereignty = $this->rel('sovereignty');
|
||||
}
|
||||
|
||||
$sovData['systemId'] = $this;
|
||||
|
||||
if($factionId){
|
||||
// HS, L - systems have "faction war"
|
||||
$sovData['allianceId'] = null;
|
||||
$sovData['corporationId'] = null;
|
||||
|
||||
/**
|
||||
* @var $faction FactionModel
|
||||
*/
|
||||
$faction = $sovereignty->rel('factionId');
|
||||
$faction->loadById($factionId);
|
||||
$sovData['factionId'] = $faction;
|
||||
}else{
|
||||
// 0.0 - systems have sovereignty data by corp and/or ally
|
||||
$sovData['factionId'] = null;
|
||||
|
||||
/**
|
||||
* @var $alliance AllianceModel|null
|
||||
*/
|
||||
$alliance = null;
|
||||
if($allianceId){
|
||||
$alliance = $sovereignty->rel('allianceId');
|
||||
$alliance->loadById($allianceId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @var $corporation CorporationModel|null
|
||||
*/
|
||||
$corporation = null;
|
||||
if($corporationId){
|
||||
$corporation = $sovereignty->rel('corporationId');
|
||||
$corporation->loadById($corporationId);
|
||||
}
|
||||
|
||||
$sovData['allianceId'] = $alliance;
|
||||
$sovData['corporationId'] = $corporation;
|
||||
}
|
||||
|
||||
$sovereignty->copyfrom($sovData, ['systemId', 'factionId', 'allianceId', 'corporationId']);
|
||||
$sovereignty->save();
|
||||
}elseif($this->sovereignty){
|
||||
// delete existing sov data
|
||||
// -> hint: WH - systems never have sovereignty data
|
||||
$this->sovereignty->erase();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $fwData
|
||||
*/
|
||||
public function updateFactionWarData(array $fwData = []){
|
||||
$systemId = (int)$fwData['systemId'];
|
||||
$ownerFactionId = (int)$fwData['ownerFactionId'];
|
||||
$occupierFactionId = (int)$fwData['occupierFactionId'];
|
||||
|
||||
if($this->valid()){
|
||||
if($systemId === $this->_id){
|
||||
/**
|
||||
* @var $factionWar FactionWarSystemModel
|
||||
*/
|
||||
if( !($factionWar = $this->factionWar) ){
|
||||
// insert new faction war data
|
||||
$factionWar = $this->rel('factionWar');
|
||||
}
|
||||
|
||||
$fwData['systemId'] = $this;
|
||||
|
||||
if($ownerFactionId){
|
||||
/**
|
||||
* @var $ownerFaction FactionModel
|
||||
*/
|
||||
$ownerFaction = $factionWar->rel('ownerFactionId');
|
||||
$ownerFaction->loadById($ownerFactionId);
|
||||
$fwData['ownerFactionId'] = $ownerFaction;
|
||||
}
|
||||
|
||||
if($occupierFactionId){
|
||||
/**
|
||||
* @var $occupierFaction FactionModel
|
||||
*/
|
||||
$occupierFaction = $factionWar->rel('occupierFactionId');
|
||||
$occupierFaction->loadById($occupierFactionId);
|
||||
$fwData['occupierFactionId'] = $occupierFaction;
|
||||
}
|
||||
|
||||
$factionWar->copyfrom($fwData, ['systemId', 'ownerFactionId', 'occupierFactionId', 'contested', 'victoryPoints', 'victoryPointsThreshold']);
|
||||
$factionWar->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -253,38 +366,8 @@ class SystemModel extends AbstractUniverseModel {
|
||||
* @param $pkeys
|
||||
*/
|
||||
public function afterUpdateEvent($self, $pkeys){
|
||||
$staticNames = (array)$self->staticNames;
|
||||
|
||||
if(
|
||||
count($staticNames) > 0 && // make sure statics are set. In case a wh system get updated without statics are set
|
||||
preg_match('/^c\d+$/i', $self->security) // make sure it is a wormhole
|
||||
){
|
||||
foreach((array)$self->statics as $static){
|
||||
if(in_array($static->wormholeId->name, $staticNames)){
|
||||
unset($staticNames[array_search($static->wormholeId->name, $staticNames)]);
|
||||
}else{
|
||||
$static->erase();
|
||||
}
|
||||
}
|
||||
|
||||
// add new statics
|
||||
foreach($staticNames as $staticName){
|
||||
$static = $self->rel('statics');
|
||||
/**
|
||||
* @var $wormhole WormholeModel
|
||||
*/
|
||||
$wormhole = $static->rel('wormholeId')->getByForeignKey('name', $staticName, ['limit' => 1]);
|
||||
if( !$wormhole->dry() ){
|
||||
$static->systemId = $self;
|
||||
$static->wormholeId = $wormhole;
|
||||
$static->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// build search index
|
||||
$self->buildIndex();
|
||||
|
||||
return parent::afterUpdateEvent($self, $pkeys);
|
||||
}
|
||||
|
||||
@@ -292,7 +375,7 @@ class SystemModel extends AbstractUniverseModel {
|
||||
* get data from all planets
|
||||
* @return array
|
||||
*/
|
||||
protected function getPlanetsData(){
|
||||
protected function getPlanetsData() : array {
|
||||
$planetsData = [];
|
||||
|
||||
if($this->planets){
|
||||
@@ -310,7 +393,7 @@ class SystemModel extends AbstractUniverseModel {
|
||||
* get data from all static wormholes
|
||||
* @return array
|
||||
*/
|
||||
protected function getStaticsData(){
|
||||
protected function getStaticsData() : array {
|
||||
$staticsData = [];
|
||||
|
||||
if($this->statics){
|
||||
@@ -328,7 +411,7 @@ class SystemModel extends AbstractUniverseModel {
|
||||
* get data from all stargates
|
||||
* @return array
|
||||
*/
|
||||
protected function getStargatesData(){
|
||||
protected function getStargatesData() : array {
|
||||
$stargatesData = [];
|
||||
|
||||
if($this->stargates){
|
||||
@@ -346,7 +429,7 @@ class SystemModel extends AbstractUniverseModel {
|
||||
* update system from ESI
|
||||
*/
|
||||
public function updateModel(){
|
||||
if( !$this->dry() ){
|
||||
if($this->valid()){
|
||||
$this->loadData($this->_id);
|
||||
$this->loadPlanetsData();
|
||||
}
|
||||
@@ -387,7 +470,7 @@ class SystemModel extends AbstractUniverseModel {
|
||||
* load planets data for this system
|
||||
*/
|
||||
public function loadPlanetsData(){
|
||||
if( !$this->dry() ){
|
||||
if($this->valid()){
|
||||
$data = self::getF3()->ccpClient()->getUniverseSystemData($this->_id);
|
||||
if($data['planets']){
|
||||
// planets are optional since ESI v4 (e.g. Abyssal systems)
|
||||
@@ -408,9 +491,9 @@ class SystemModel extends AbstractUniverseModel {
|
||||
* -> stargates to destination system which is not in DB get ignored
|
||||
*/
|
||||
public function loadStargatesData(){
|
||||
if( !$this->dry() ){
|
||||
if($this->valid()){
|
||||
$data = self::getF3()->ccpClient()->getUniverseSystemData($this->_id);
|
||||
if(!empty($data)){
|
||||
if($data['stargates']){
|
||||
foreach((array)$data['stargates'] as $stargateId){
|
||||
/**
|
||||
* @var $stargate StargateModel
|
||||
|
||||
92
app/main/model/universe/systemneighbourmodel.php
Normal file
92
app/main/model/universe/systemneighbourmodel.php
Normal file
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Model\Universe;
|
||||
|
||||
use DB\SQL\Schema;
|
||||
|
||||
class SystemNeighbourModel extends AbstractUniverseModel {
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'system_neighbour';
|
||||
|
||||
/**
|
||||
* allow table truncate
|
||||
* -> used on /setup page or index build
|
||||
* @var bool
|
||||
*/
|
||||
protected $allowTruncate = true;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $fieldConf = [
|
||||
'regionId' => [
|
||||
'type' => Schema::DT_INT,
|
||||
'index' => true,
|
||||
'belongs-to-one' => 'Model\Universe\RegionModel',
|
||||
'constraint' => [
|
||||
[
|
||||
'table' => 'region',
|
||||
'on-delete' => 'CASCADE'
|
||||
]
|
||||
],
|
||||
'validate' => 'notDry'
|
||||
],
|
||||
'constellationId' => [
|
||||
'type' => Schema::DT_INT,
|
||||
'index' => true,
|
||||
'belongs-to-one' => 'Model\Universe\ConstellationModel',
|
||||
'constraint' => [
|
||||
[
|
||||
'table' => 'constellation',
|
||||
'on-delete' => 'CASCADE'
|
||||
]
|
||||
],
|
||||
'validate' => 'notDry'
|
||||
],
|
||||
'systemId' => [
|
||||
'type' => Schema::DT_INT,
|
||||
'index' => true,
|
||||
'unique' => true,
|
||||
'belongs-to-one' => 'Model\Universe\SystemModel',
|
||||
'constraint' => [
|
||||
[
|
||||
'table' => 'system',
|
||||
'on-delete' => 'CASCADE'
|
||||
]
|
||||
],
|
||||
'validate' => 'notDry'
|
||||
],
|
||||
'systemName' => [
|
||||
'type' => Schema::DT_VARCHAR128,
|
||||
'nullable' => false,
|
||||
'default' => ''
|
||||
],
|
||||
'jumpNodes' => [
|
||||
'type' => Schema::DT_VARCHAR512,
|
||||
'nullable' => false,
|
||||
'default' => ''
|
||||
],
|
||||
'trueSec' => [
|
||||
'type' => Schema::DT_DECIMAL,
|
||||
'nullable' => false,
|
||||
'default' => 0
|
||||
]
|
||||
];
|
||||
|
||||
/**
|
||||
* No static columns added
|
||||
* @var bool
|
||||
*/
|
||||
protected $addStaticFields = false;
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
* @param string $accessToken
|
||||
* @param array $additionalOptions
|
||||
*/
|
||||
protected function loadData(int $id, string $accessToken = '', array $additionalOptions = []){}
|
||||
}
|
||||
@@ -12,8 +12,14 @@ use DB\SQL\Schema;
|
||||
|
||||
class SystemStaticModel extends AbstractUniverseModel {
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'system_static';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $fieldConf = [
|
||||
'systemId' => [
|
||||
'type' => Schema::DT_INT,
|
||||
@@ -27,13 +33,13 @@ class SystemStaticModel extends AbstractUniverseModel {
|
||||
],
|
||||
'validate' => 'notDry'
|
||||
],
|
||||
'wormholeId' => [
|
||||
'typeId' => [
|
||||
'type' => Schema::DT_INT,
|
||||
'index' => true,
|
||||
'belongs-to-one' => 'Model\Universe\WormholeModel',
|
||||
'belongs-to-one' => 'Model\Universe\TypeModel',
|
||||
'constraint' => [
|
||||
[
|
||||
'table' => 'wormhole',
|
||||
'table' => 'type',
|
||||
'on-delete' => 'CASCADE'
|
||||
]
|
||||
],
|
||||
@@ -52,8 +58,14 @@ class SystemStaticModel extends AbstractUniverseModel {
|
||||
* @return null|string
|
||||
*/
|
||||
public function getData(){
|
||||
return $this->wormholeId ? $this->wormholeId->name : null;
|
||||
return $this->typeId ? $this->typeId->getWormholeName() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
* @param string $accessToken
|
||||
* @param array $additionalOptions
|
||||
*/
|
||||
protected function loadData(int $id, string $accessToken = '', array $additionalOptions = []){}
|
||||
|
||||
/**
|
||||
@@ -66,7 +78,7 @@ class SystemStaticModel extends AbstractUniverseModel {
|
||||
*/
|
||||
public static function setup($db = null, $table = null, $fields = null){
|
||||
if($status = parent::setup($db, $table, $fields)){
|
||||
$status = parent::setMultiColumnIndex(['systemId', 'wormholeId'], true);
|
||||
$status = parent::setMultiColumnIndex(['systemId', 'typeId'], true);
|
||||
}
|
||||
return $status;
|
||||
}
|
||||
|
||||
92
app/main/model/universe/typeattributemodel.php
Normal file
92
app/main/model/universe/typeattributemodel.php
Normal file
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: Exodus4D
|
||||
* Date: 15.08.2019
|
||||
* Time: 22:00
|
||||
*/
|
||||
|
||||
namespace Model\Universe;
|
||||
|
||||
use DB\SQL\Schema;
|
||||
|
||||
class TypeAttributeModel extends AbstractUniverseModel {
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'type_attribute';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $fieldConf = [
|
||||
'typeId' => [
|
||||
'type' => Schema::DT_INT,
|
||||
'index' => true,
|
||||
'belongs-to-one' => 'Model\Universe\TypeModel',
|
||||
'constraint' => [
|
||||
[
|
||||
'table' => 'type',
|
||||
'on-delete' => 'CASCADE'
|
||||
]
|
||||
],
|
||||
'validate' => 'notDry'
|
||||
],
|
||||
'attributeId' => [
|
||||
'type' => Schema::DT_INT,
|
||||
'index' => true,
|
||||
'belongs-to-one' => 'Model\Universe\DogmaAttributeModel',
|
||||
'constraint' => [
|
||||
[
|
||||
'table' => 'dogma_attribute',
|
||||
'on-delete' => 'CASCADE'
|
||||
]
|
||||
],
|
||||
'validate' => 'notDry'
|
||||
],
|
||||
'value' => [
|
||||
'type' => Schema::DT_FLOAT,
|
||||
'nullable' => false,
|
||||
'default' => 0
|
||||
]
|
||||
];
|
||||
|
||||
/**
|
||||
* No static columns added
|
||||
* @var bool
|
||||
*/
|
||||
protected $addStaticFields = false;
|
||||
|
||||
/**
|
||||
* @return \stdClass
|
||||
*/
|
||||
public function getData(){
|
||||
$typeAttributeData = $this->attributeId->getData();
|
||||
$typeAttributeData->value = (float)$this->value;
|
||||
|
||||
return $typeAttributeData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
* @param string $accessToken
|
||||
* @param array $additionalOptions
|
||||
*/
|
||||
protected function loadData(int $id, string $accessToken = '', array $additionalOptions = []){}
|
||||
|
||||
/**
|
||||
* overwrites parent
|
||||
* @param null $db
|
||||
* @param null $table
|
||||
* @param null $fields
|
||||
* @return bool
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function setup($db = null, $table = null, $fields = null){
|
||||
if($status = parent::setup($db, $table, $fields)){
|
||||
$status = parent::setMultiColumnIndex(['typeId', 'attributeId'], true);
|
||||
}
|
||||
return $status;
|
||||
}
|
||||
}
|
||||
@@ -9,11 +9,31 @@
|
||||
namespace Model\Universe;
|
||||
|
||||
use DB\SQL\Schema;
|
||||
use lib\Config;
|
||||
use lib\Util;
|
||||
|
||||
class TypeModel extends AbstractUniverseModel {
|
||||
|
||||
protected $table = 'type';
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'type';
|
||||
|
||||
/**
|
||||
* default store option for 'dogma' typeAttributes data
|
||||
* -> set to true will store all typeAttributes from ESI for a type
|
||||
* -> should be enabled for specific types, where data is used by Pathfinder
|
||||
*/
|
||||
const DEFAULT_STORE_DOGMA_ATTRIBUTES = false;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public $storeDogmaAttributes = self::DEFAULT_STORE_DOGMA_ATTRIBUTES;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $fieldConf = [
|
||||
'name' => [
|
||||
'type' => Schema::DT_VARCHAR128,
|
||||
@@ -92,11 +112,46 @@ class TypeModel extends AbstractUniverseModel {
|
||||
'stars' => [
|
||||
'has-many' => ['Model\Universe\StarModel', 'typeId']
|
||||
],
|
||||
'wormholes' => [
|
||||
'has-many' => ['Model\Universe\WormholeModel', 'typeId']
|
||||
'attributes' => [
|
||||
'has-many' => ['Model\Universe\TypeAttributeModel', 'typeId']
|
||||
],
|
||||
'stargates' => [
|
||||
'has-many' => ['Model\Universe\StargateModel', 'typeId']
|
||||
],
|
||||
'statics' => [
|
||||
'has-many' => ['Model\Universe\SystemStaticModel', 'typeId']
|
||||
]
|
||||
];
|
||||
|
||||
/**
|
||||
* set 'dogma_attributes' during ESI import process to a virtual field
|
||||
* -> 'dogma_attributes' get imported after type is saved
|
||||
* @see loadData()
|
||||
* @param $dogmaAttributesData
|
||||
* @return null
|
||||
*/
|
||||
public function set_dogma_attributes($dogmaAttributesData){
|
||||
$this->virtual('dogmaAttributes', (array)$dogmaAttributesData);
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* special getter for 'wormhole' types
|
||||
* @return string|null
|
||||
*/
|
||||
public function getWormholeName(){
|
||||
return self::formatWormholeName($this->name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $mapper
|
||||
* @return NULL|void
|
||||
*/
|
||||
public function reset($mapper = true){
|
||||
$this->clearVirtual('dogmaAttributes');
|
||||
parent::reset($mapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* get type data
|
||||
* @param array $additionalData
|
||||
@@ -104,16 +159,62 @@ class TypeModel extends AbstractUniverseModel {
|
||||
*/
|
||||
public function getData(array $additionalData = []){
|
||||
$typeData = (object) [];
|
||||
$typeData->id = $this->id;
|
||||
$typeData->id = $this->_id;
|
||||
$typeData->name = $this->name;
|
||||
|
||||
foreach($additionalData as $key){
|
||||
$typeData->$key = $this->$key;
|
||||
if($key == 'attributes'){
|
||||
// add 'dogma' typeAttributes data
|
||||
$typeData->$key = $this->getAttributesData();
|
||||
}elseif($this->exists($key)){
|
||||
$typeData->$key = $this->$key;
|
||||
}
|
||||
}
|
||||
|
||||
return $typeData;
|
||||
}
|
||||
|
||||
/**
|
||||
* get wormholeData from object
|
||||
* @return \stdClass
|
||||
*/
|
||||
public function getWormholeData() : \stdClass {
|
||||
$wormholeData = (object) [];
|
||||
if($this->valid()){
|
||||
$wormholeData->name = $this->getWormholeName();
|
||||
$wormholeData->static = $this->statics ? (bool)count($this->statics) : false;
|
||||
$wormholeData->security = '';
|
||||
$wormholeData->massTotal = null;
|
||||
$wormholeData->massIndividual = null;
|
||||
$wormholeData->maxStableTime = null;
|
||||
foreach($this->getAttributesData() as $id => $attributesData){
|
||||
switch($id){
|
||||
case 1381: // 'wormholeTargetSystemClass' -> 'security'
|
||||
$wormholeData->security = self::getSystemSecurityFromId((int)$attributesData['value']);
|
||||
break;
|
||||
case 1383: // 'wormholeMaxStableMass' -> 'massTotal'
|
||||
$wormholeData->massTotal = $attributesData['value'];
|
||||
break;
|
||||
case 1385: // 'wormholeMaxJumpMass' -> 'massIndividual'
|
||||
$wormholeData->massIndividual = $attributesData['value'];
|
||||
break;
|
||||
case 1384: // 'wormholeMassRegeneration' -> 'massRegeneration'
|
||||
if($attributesData['value']){
|
||||
$wormholeData->massRegeneration = $attributesData['value'];
|
||||
}
|
||||
break;
|
||||
case 1382: // 'wormholeMaxStableTime' -> 'maxStableTime'
|
||||
$wormholeData->maxStableTime = $attributesData['value'] / 60;
|
||||
break;
|
||||
case Config::ESI_DOGMA_ATTRIBUTE_SCANWHSTRENGTH_ID: // 'scanWormholeStrength' -> 'scanWormholeStrength'
|
||||
$wormholeData->scanWormholeStrength = $attributesData['value'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $wormholeData;
|
||||
}
|
||||
|
||||
/**
|
||||
* get shipData from object
|
||||
* -> more fields can be added in here if needed
|
||||
@@ -121,7 +222,7 @@ class TypeModel extends AbstractUniverseModel {
|
||||
*/
|
||||
public function getShipData(): \stdClass {
|
||||
$shipData = (object) [];
|
||||
if(!$this->dry()){
|
||||
if($this->valid()){
|
||||
$shipData->typeId = $this->_id;
|
||||
$shipData->typeName = $this->name;
|
||||
$shipData->mass = $this->mass;
|
||||
@@ -129,6 +230,118 @@ class TypeModel extends AbstractUniverseModel {
|
||||
return $shipData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function getAttributesData() : array {
|
||||
$attributesData = [];
|
||||
|
||||
if($this->attributes){
|
||||
foreach($this->attributes as $typeAttribute){
|
||||
/**
|
||||
* @var $typeAttribute TypeAttributeModel
|
||||
*/
|
||||
$attributesData[] = get_object_vars($typeAttribute->getData());
|
||||
}
|
||||
}
|
||||
return Util::arrayGetBy($attributesData, 'id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Event "Hook" function
|
||||
* return false will stop any further action
|
||||
* @param self $self
|
||||
* @param $pkeys
|
||||
*/
|
||||
public function afterInsertEvent($self, $pkeys){
|
||||
$self->syncDogmaAttributes();
|
||||
|
||||
return parent::afterInsertEvent($self, $pkeys);
|
||||
}
|
||||
|
||||
/**
|
||||
* Event "Hook" function
|
||||
* @param self $self
|
||||
* @param $pkeys
|
||||
*/
|
||||
public function afterUpdateEvent($self, $pkeys){
|
||||
$self->syncDogmaAttributes();
|
||||
|
||||
return parent::afterUpdateEvent($self, $pkeys);
|
||||
}
|
||||
|
||||
/**
|
||||
* sync existing 'dogma' typeAttributes data with "new/updated" typeAttributes
|
||||
* -> $this->dogmaAttributes must be set before calling this method
|
||||
*/
|
||||
protected function syncDogmaAttributes(){
|
||||
if(
|
||||
$this->storeDogmaAttributes &&
|
||||
!empty($dogmaAttributesData = (array)$this->dogmaAttributes)
|
||||
){
|
||||
foreach((array)$this->attributes as $typeAttribute){
|
||||
$key = array_search($typeAttribute->get('attributeId', true), array_column($dogmaAttributesData, 'attributeId'));
|
||||
if($key !== false){
|
||||
// attribute still belongs to this 'type' -> update value
|
||||
$typeAttribute->copyfrom($dogmaAttributesData[$key], ['value']);
|
||||
$typeAttribute->save();
|
||||
|
||||
unset($dogmaAttributesData[$key]);
|
||||
$dogmaAttributesData = array_values($dogmaAttributesData);
|
||||
}else{
|
||||
// attribute no longer belongs to this 'type'
|
||||
$typeAttribute->erase();
|
||||
}
|
||||
}
|
||||
|
||||
// add new dogmaTypes
|
||||
foreach($dogmaAttributesData as $dogmaAttributeData){
|
||||
/**
|
||||
* @var $typeAttribute TypeAttributeModel
|
||||
* @var $dogmaAttribute DogmaAttributeModel
|
||||
*/
|
||||
$typeAttribute = $this->rel('attributes');
|
||||
$dogmaAttribute = $typeAttribute->rel('attributeId');
|
||||
$dogmaAttribute->loadById($dogmaAttributeData['attributeId']);
|
||||
if($dogmaAttribute->valid()){
|
||||
$typeAttribute->typeId = $this;
|
||||
$typeAttribute->attributeId = $dogmaAttribute;
|
||||
$typeAttribute->value = $dogmaAttributeData['value'];
|
||||
$typeAttribute->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* manipulate 'dogma_attributes' array be reference
|
||||
* -> used to inject custom attributes (not available from ESI)
|
||||
* @param array $data
|
||||
*/
|
||||
private function manipulateDogmaAttributes(array &$data){
|
||||
if(!$this->storeDogmaAttributes){
|
||||
// attributes should not get saved
|
||||
unset($data['dogma_attributes']);
|
||||
}elseif(!empty($data['dogma_attributes'])){
|
||||
switch($data['groupId']){
|
||||
case Config::ESI_GROUP_WORMHOLE_ID:
|
||||
if(
|
||||
!empty($wormholesCSVData = static::getCSVData('wormhole', 'name')) &&
|
||||
!empty($wormholeCSVData = $wormholesCSVData[self::formatWormholeName($data['name'])])
|
||||
){
|
||||
// found relevant wormhole data in *.csv for current type
|
||||
if(!empty($scanWormholeStrength = (float)$wormholeCSVData['scanWormholeStrength'])){
|
||||
$data['dogma_attributes'][] = [
|
||||
'attributeId' => Config::ESI_DOGMA_ATTRIBUTE_SCANWHSTRENGTH_ID,
|
||||
'value' => $scanWormholeStrength
|
||||
];
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* load data from API into $this and save $this
|
||||
* @param int $id
|
||||
@@ -138,6 +351,8 @@ class TypeModel extends AbstractUniverseModel {
|
||||
protected function loadData(int $id, string $accessToken = '', array $additionalOptions = []){
|
||||
$data = self::getF3()->ccpClient()->getUniverseTypesData($id);
|
||||
if(!empty($data)){
|
||||
$this->manipulateDogmaAttributes($data);
|
||||
|
||||
/**
|
||||
* @var $group GroupModel
|
||||
*/
|
||||
@@ -149,4 +364,12 @@ class TypeModel extends AbstractUniverseModel {
|
||||
$this->save();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $name
|
||||
* @return string|null
|
||||
*/
|
||||
public static function formatWormholeName(?string $name) : ?string {
|
||||
return (!empty($name) && !empty($format = @end(explode(' ', $name)))) ? $format : null;
|
||||
}
|
||||
}
|
||||
@@ -1,192 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: Exodus 4D
|
||||
* Date: 13.05.2018
|
||||
* Time: 18:36
|
||||
*/
|
||||
|
||||
namespace Model\Universe;
|
||||
|
||||
use DB\SQL\Schema;
|
||||
|
||||
class WormholeModel extends AbstractUniverseModel {
|
||||
|
||||
protected $table = 'wormhole';
|
||||
|
||||
public static $enableDataExport = true;
|
||||
public static $enableDataImport = true;
|
||||
|
||||
protected $fieldConf = [
|
||||
'name' => [
|
||||
'type' => Schema::DT_VARCHAR128,
|
||||
'nullable' => false,
|
||||
'default' => '',
|
||||
'index' => true,
|
||||
'unique' => true
|
||||
],
|
||||
'typeId' => [
|
||||
'type' => Schema::DT_INT,
|
||||
'index' => true,
|
||||
'belongs-to-one' => 'Model\Universe\TypeModel',
|
||||
'constraint' => [
|
||||
[
|
||||
'table' => 'type',
|
||||
'on-delete' => 'SET NULL'
|
||||
]
|
||||
],
|
||||
'validate' => 'notDry'
|
||||
],
|
||||
'static' => [
|
||||
'type' => Schema::DT_BOOL,
|
||||
'nullable' => false,
|
||||
'default' => 0
|
||||
],
|
||||
'security' => [
|
||||
'type' => Schema::DT_VARCHAR128,
|
||||
'nullable' => false,
|
||||
'default' => ''
|
||||
],
|
||||
'massTotal' => [
|
||||
'type' => Schema::DT_BIGINT,
|
||||
'nullable' => true,
|
||||
'default' => null
|
||||
],
|
||||
'massIndividual' => [
|
||||
'type' => Schema::DT_BIGINT,
|
||||
'nullable' => true,
|
||||
'default' => null
|
||||
],
|
||||
'massRegeneration' => [
|
||||
'type' => Schema::DT_BIGINT,
|
||||
'nullable' => true,
|
||||
'default' => null
|
||||
],
|
||||
'maxStableTime' => [
|
||||
'type' => Schema::DT_TINYINT,
|
||||
'nullable' => true,
|
||||
'default' => null
|
||||
],
|
||||
'signatureStrength' => [
|
||||
'type' => Schema::DT_FLOAT,
|
||||
'nullable' => true,
|
||||
'default' => null
|
||||
],
|
||||
'systems' => [
|
||||
'has-many' => ['Model\Universe\SystemStaticModel', 'wormholeId']
|
||||
]
|
||||
];
|
||||
|
||||
/**
|
||||
* get wormhole data
|
||||
* @return \stdClass
|
||||
*/
|
||||
public function getData(){
|
||||
|
||||
$wormholeData = (object) [];
|
||||
$wormholeData->name = $this->name;
|
||||
$wormholeData->static = $this->static;
|
||||
$wormholeData->security = $this->security;
|
||||
$wormholeData->massTotal = $this->massTotal;
|
||||
$wormholeData->massIndividual = $this->massIndividual;
|
||||
|
||||
if($this->massRegeneration){
|
||||
$wormholeData->massRegeneration = $this->massRegeneration;
|
||||
}
|
||||
|
||||
$wormholeData->maxStableTime = $this->maxStableTime;
|
||||
|
||||
// signature strength as defined by http://wiki.eve-inspiracy.com/index.php?title=Wormhole_Signature_Strength_List
|
||||
if($this->signatureStrength){
|
||||
$wormholeData->signatureStrength = $this->signatureStrength;
|
||||
}
|
||||
|
||||
return $wormholeData;
|
||||
}
|
||||
|
||||
/**
|
||||
* setter for typeId
|
||||
* @param string $typeId
|
||||
* @return string|int|null
|
||||
*/
|
||||
public function set_typeId($typeId){
|
||||
if(!is_object($typeId)){
|
||||
/**
|
||||
* @var $type TypeModel
|
||||
*/
|
||||
$type = $this->rel('typeId');
|
||||
$type->loadById((int)$typeId);
|
||||
$typeId = $type->dry() ? null : $type->_id;
|
||||
}
|
||||
return $typeId;
|
||||
}
|
||||
|
||||
/**
|
||||
* setter for massTotal
|
||||
* @param string $mass
|
||||
* @return int|null
|
||||
*/
|
||||
public function set_massTotal($mass){
|
||||
$mass = (int)$mass;
|
||||
return $mass ? : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* setter for massIndividual
|
||||
* @param string $mass
|
||||
* @return string|null
|
||||
*/
|
||||
public function set_massIndividual($mass){
|
||||
$mass = (int)$mass;
|
||||
return $mass ? : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* setter for massRegeneration
|
||||
* @param $mass
|
||||
* @return int|null
|
||||
*/
|
||||
public function set_massRegeneration($mass){
|
||||
$mass = (int)$mass;
|
||||
return $mass ? : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* setter for maxStableTime
|
||||
* @param string $hours
|
||||
* @return int|null
|
||||
*/
|
||||
public function set_maxStableTime($hours){
|
||||
$hours = (int)$hours;
|
||||
return $hours ? : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* setter for signatureStrength
|
||||
* @param string $strength
|
||||
* @return float|null
|
||||
*/
|
||||
public function set_signatureStrength($strength){
|
||||
$strength = (float)$strength;
|
||||
return $strength ? : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $fields
|
||||
* @return bool
|
||||
*/
|
||||
public function exportData(array $fields = [
|
||||
'id', 'name', 'typeId', 'static', 'security', 'massTotal', 'massIndividual',
|
||||
'massRegeneration', 'maxStableTime', 'signatureStrength']
|
||||
) : bool {
|
||||
return parent::exportData($fields);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
* @param string $accessToken
|
||||
* @param array $additionalOptions
|
||||
*/
|
||||
protected function loadData(int $id, string $accessToken = '', array $additionalOptions = []){}
|
||||
|
||||
}
|
||||
@@ -80,6 +80,4 @@ NODE = 6.0
|
||||
NPM = 3.10.0
|
||||
|
||||
[REQUIREMENTS.DATA]
|
||||
STRUCTURES = 33
|
||||
SHIPS = 491
|
||||
NEIGHBOURS = 5201
|
||||
|
||||
3773
export/csv/system_static.csv
Normal file
3773
export/csv/system_static.csv
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,90 +1,90 @@
|
||||
"Id";"Name";"Security";"MassTotal";"MassIndividual";"MassRegeneration";"MaxStableTime";"SignatureStrength";
|
||||
"1";"A009";"C13";"500000000";"5000000";"3000000000";"16";;
|
||||
"2";"A239";"L";"2000000000";"300000000";;"24";"5";
|
||||
"3";"A641";"H";"2000000000";"1000000000";;"16";"10";
|
||||
"4";"A982";"C6";"3000000000";"300000000";;"24";"2.22";
|
||||
"5";"B041";"C6";"3000000000";"300000000";"500000000";"48";;
|
||||
"6";"B274";"H";"2000000000";"300000000";;"24";"10";
|
||||
"7";"B449";"H";"2000000000";"1000000000";;"16";"2.5";
|
||||
"8";"B520";"H";"3000000000";"300000000";"500000000";"24";;
|
||||
"9";"C008";"C5";"1000000000";"5000000";"3000000000";"16";;
|
||||
"10";"C125";"C2";"1000000000";"20000000";;"16";"6.67";
|
||||
"11";"C140";"L";"3000000000";"1350000000";;"24";"5";
|
||||
"12";"C247";"C3";"2000000000";"300000000";;"16";"10";
|
||||
"13";"C248";"0.0";"3000000000";"1350000000";"500000000";"24";;
|
||||
"14";"C391";"L";"3000000000";"1000000000";"500000000";"24";;
|
||||
"15";"D364";"C2";"1000000000";"300000000";;"16";"1.25";
|
||||
"16";"D382";"C2";"2000000000";"300000000";;"16";"6.67";
|
||||
"17";"D792";"H";"3000000000";"1000000000";;"24";"2.5";
|
||||
"18";"D845";"H";"5000000000";"300000000";"500000000";"24";"5";
|
||||
"19";"E004";"C1";"1000000000";"5000000";"3000000000";"16";;
|
||||
"20";"E175";"C4";"2000000000";"300000000";;"16";"5";
|
||||
"21";"E545";"0.0";"2000000000";"300000000";;"24";"2.5";
|
||||
"23";"G024";"C2";"2000000000";"300000000";;"16";"1.25";
|
||||
"24";"H121";"C1";"500000000";"20000000";;"16";"10";
|
||||
"25";"H296";"C5";"3000000000";"1350000000";;"24";"10";
|
||||
"26";"H900";"C5";"3000000000";"300000000";;"24";"2.5";
|
||||
"27";"I182";"C2";"2000000000";"300000000";;"16";"4";
|
||||
"28";"J244";"L";"1000000000";"20000000";;"24";"5";
|
||||
"29";"K329";"0.0";"5000000000";"1800000000";"500000000";"24";;
|
||||
"30";"K346";"0.0";"3000000000";"300000000";;"24";"2.5";
|
||||
"31";"L005";"C2";"1000000000";"5000000";"3000000000";"16";;
|
||||
"32";"L477";"C3";"2000000000";"300000000";;"16";"5";
|
||||
"33";"L614";"C5";"1000000000";"20000000";;"24";"2.5";
|
||||
"35";"M267";"C3";"1000000000";"300000000";;"16";"1.25";
|
||||
"36";"M555";"C5";"3000000000";"1000000000";;"24";"2.5";
|
||||
"37";"M609";"C4";"1000000000";"20000000";;"16";"4";
|
||||
"38";"N062";"C5";"3000000000";"300000000";;"24";"2.5";
|
||||
"39";"N110";"H";"1000000000";"20000000";;"24";"10";
|
||||
"40";"N290";"L";"3000000000";"1350000000";"500000000";"24";;
|
||||
"41";"N432";"C5";"3000000000";"1350000000";;"24";"10";
|
||||
"42";"N766";"C2";"2000000000";"300000000";;"16";"4";
|
||||
"43";"N770";"C5";"3000000000";"300000000";;"24";"2.5";
|
||||
"44";"N944";"L";"3000000000";"1350000000";;"24";"10";
|
||||
"45";"N968";"C3";"2000000000";"300000000";;"16";"10";
|
||||
"46";"O128";"C4";"1000000000";"300000000";"100000000";"24";;
|
||||
"47";"O477";"C3";"2000000000";"300000000";;"16";"5";
|
||||
"48";"O883";"C3";"1000000000";"20000000";;"16";"5";
|
||||
"49";"P060";"C1";"500000000";"20000000";;"16";"5";
|
||||
"50";"Q003";"0.0";"1000000000";"5000000";"3000000000";"16";;
|
||||
"51";"Q317";"C1";"500000000";"20000000";;"16";"2.5";
|
||||
"52";"R051";"L";"3000000000";"1000000000";;"16";"5";
|
||||
"53";"R474";"C6";"3000000000";"300000000";;"24";"2.22";
|
||||
"54";"R943";"C2";"750000000";"300000000";;"16";"6.67";
|
||||
"55";"S047";"H";"3000000000";"300000000";;"24";;
|
||||
"56";"S199";"0.0";"3000000000";"1350000000";;"24";"10";
|
||||
"57";"S804";"C6";"1000000000";"20000000";;"24";"1.25";
|
||||
"58";"T405";"C4";"2000000000";"300000000";;"16";"6.67";
|
||||
"59";"U210";"L";"3000000000";"300000000";;"24";"10";
|
||||
"60";"U319";"C6";"3000000000";"1350000000";"500000000";"48";;
|
||||
"61";"U574";"C6";"3000000000";"300000000";;"24";"1.25";
|
||||
"62";"V283";"0.0";"3000000000";"1000000000";;"24";"2.5";
|
||||
"63";"V301";"C1";"500000000";"20000000";;"16";"5";
|
||||
"64";"V753";"C6";"3000000000";"1350000000";;"24";"6.67";
|
||||
"65";"V911";"C5";"3000000000";"1350000000";;"24";"10";
|
||||
"66";"W237";"C6";"3000000000";"1350000000";;"24";"6.67";
|
||||
"67";"X702";"C3";"1000000000";"300000000";;"24";"10";
|
||||
"68";"X877";"C4";"2000000000";"300000000";;"16";"6.67";
|
||||
"69";"Y683";"C4";"2000000000";"300000000";;"16";"4";
|
||||
"70";"Y790";"C1";"500000000";"20000000";;"16";"2.5";
|
||||
"71";"Z006";"C3";"1000000000";"5000000";"3000000000";"16";;
|
||||
"72";"Z060";"0.0";"1000000000";"20000000";;"24";"2.5";
|
||||
"73";"Z142";"0.0";"3000000000";"1350000000";;"24";"10";
|
||||
"74";"Z457";"C4";"2000000000";"300000000";;"16";"4";
|
||||
"75";"Z647";"C1";"500000000";"20000000";;"16";"10";
|
||||
"76";"Z971";"C1";"100000000";"20000000";;"16";"10";
|
||||
"80";"M001";"C4";"1000000000";"5000000";"3000000000";"16";;
|
||||
"81";"E587";"0.0";"3000000000";"1000000000";;"16";;
|
||||
"82";"V898";"L";"2000000000";"300000000";;"16";;
|
||||
"83";"Q063";"H";"500000000";"20000000";;"16";;
|
||||
"84";"G008";"C6";"1000000000";"5000000";"3000000000";"16";;
|
||||
"85";"F353";"C12";"100000000";"20000000";;"16";;
|
||||
"86";"F135";"C12";"750000000";"300000000";;"16";;
|
||||
"87";"T458";"C12";"500000000";"20000000";;"16";;
|
||||
"88";"M164";"C12";"2000000000";"300000000";;"16";;
|
||||
"89";"L031";"C12";"3000000000";"1000000000";;"16";;
|
||||
"90";"S877";"C14";"750000000";"300000000";;"16";;
|
||||
"91";"B735";"C15";"750000000";"300000000";;"16";;
|
||||
"92";"V928";"C16";"750000000";"300000000";;"16";;
|
||||
"93";"C414";"C17";"750000000";"300000000";;"16";;
|
||||
"94";"R259";"C18";"750000000";"300000000";;"16";;
|
||||
Id;Name;scanWormholeStrength
|
||||
1;A009;
|
||||
2;A239;5
|
||||
3;A641;10
|
||||
4;A982;2.22
|
||||
5;B041;
|
||||
6;B274;10
|
||||
7;B449;2.5
|
||||
8;B520;
|
||||
9;C008;
|
||||
10;C125;6.67
|
||||
11;C140;5
|
||||
12;C247;10
|
||||
13;C248;
|
||||
14;C391;
|
||||
15;D364;1.25
|
||||
16;D382;6.67
|
||||
17;D792;2.5
|
||||
18;D845;5
|
||||
19;E004;
|
||||
20;E175;5
|
||||
21;E545;2.5
|
||||
23;G024;1.25
|
||||
24;H121;10
|
||||
25;H296;10
|
||||
26;H900;2.5
|
||||
27;I182;4
|
||||
28;J244;5
|
||||
29;K329;
|
||||
30;K346;2.5
|
||||
31;L005;
|
||||
32;L477;5
|
||||
33;L614;2.5
|
||||
35;M267;1.25
|
||||
36;M555;2.5
|
||||
37;M609;4
|
||||
38;N062;2.5
|
||||
39;N110;10
|
||||
40;N290;
|
||||
41;N432;10
|
||||
42;N766;4
|
||||
43;N770;2.5
|
||||
44;N944;10
|
||||
45;N968;10
|
||||
46;O128;
|
||||
47;O477;5
|
||||
48;O883;5
|
||||
49;P060;5
|
||||
50;Q003;
|
||||
51;Q317;2.5
|
||||
52;R051;5
|
||||
53;R474;2.22
|
||||
54;R943;6.67
|
||||
55;S047;
|
||||
56;S199;10
|
||||
57;S804;1.25
|
||||
58;T405;6.67
|
||||
59;U210;10
|
||||
60;U319;
|
||||
61;U574;1.25
|
||||
62;V283;2.5
|
||||
63;V301;5
|
||||
64;V753;6.67
|
||||
65;V911;10
|
||||
66;W237;6.67
|
||||
67;X702;10
|
||||
68;X877;6.67
|
||||
69;Y683;4
|
||||
70;Y790;2.5
|
||||
71;Z006;
|
||||
72;Z060;2.5
|
||||
73;Z142;10
|
||||
74;Z457;4
|
||||
75;Z647;10
|
||||
76;Z971;10
|
||||
80;M001;
|
||||
81;E587;
|
||||
82;V898;
|
||||
83;Q063;
|
||||
84;G008;
|
||||
85;F353;
|
||||
86;F135;
|
||||
87;T458;
|
||||
88;M164;
|
||||
89;L031;
|
||||
90;S877;
|
||||
91;B735;
|
||||
92;V928;
|
||||
93;C414;
|
||||
94;R259;
|
||||
|
Binary file not shown.
@@ -454,11 +454,18 @@ define([
|
||||
*/
|
||||
let initServerStatus = () => {
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
type: 'GET',
|
||||
url: Init.path.getServerStatus,
|
||||
dataType: 'json'
|
||||
}).done(function(responseData, textStatus, request){
|
||||
|
||||
let dateLastModified = new Date(request.getResponseHeader('Last-Modified') || Date.now());
|
||||
let dateExpires = new Date(request.getResponseHeader('Expires') || Date.now());
|
||||
|
||||
var options = { hour: '2-digit', minute: '2-digit', hour12: false, timeZone: 'UTC', timeZoneName: 'short' };
|
||||
responseData.api.cache = dateLastModified.toLocaleTimeString('en-US', options);
|
||||
responseData.api.cacheExpire = 'TTL ' + (dateExpires - dateLastModified) / 1000 + 's';
|
||||
|
||||
let data = {
|
||||
stickyPanelServerId: config.stickyPanelServerId,
|
||||
stickyPanelClass: config.stickyPanelClass,
|
||||
@@ -471,7 +478,8 @@ define([
|
||||
case 'online':
|
||||
case 'green': return 'txt-color-green';
|
||||
case 'vip':
|
||||
case 'yellow': return 'txt-color-orange';
|
||||
case 'yellow': return 'txt-color-yellow';
|
||||
case 'orange': return 'txt-color-orange';
|
||||
case 'offline':
|
||||
case 'red': return 'txt-color-red';
|
||||
default: return '';
|
||||
|
||||
@@ -422,7 +422,7 @@ define([
|
||||
_: (data, type, row, meta) => {
|
||||
let value = data.typeName;
|
||||
if(type === 'display'){
|
||||
value = '<img src="' + Init.url.ccpImageServer + '/Render/' + data.typeId + '_32.png"/>';
|
||||
value = '<img src="' + Util.eveImageUrl('render', data.typeId) + '_32.png"/>';
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -546,13 +546,15 @@ define([
|
||||
system.data('region', data.region.name);
|
||||
system.data('constellationId', parseInt(data.constellation.id));
|
||||
system.data('constellation', data.constellation.name);
|
||||
system.data('faction', data.faction);
|
||||
system.data('planets', data.planets);
|
||||
system.data('shattered', data.shattered);
|
||||
system.data('statics', data.statics);
|
||||
system.data('updated', parseInt(data.updated.updated));
|
||||
system.data('changed', false);
|
||||
system.attr('data-mapid', parseInt(mapContainer.data('id')));
|
||||
if(data.sovereignty){
|
||||
system.data('sovereignty', data.sovereignty);
|
||||
}
|
||||
|
||||
// locked system
|
||||
if( Boolean(system.data('locked')) !== data.locked ){
|
||||
@@ -3046,47 +3048,58 @@ define([
|
||||
*/
|
||||
$.fn.getSystemData = function(minimal = false){
|
||||
let system = $(this);
|
||||
let data = system.data();
|
||||
|
||||
let systemData = {
|
||||
id: parseInt(system.data('id')),
|
||||
id: parseInt(data.id),
|
||||
updated: {
|
||||
updated: parseInt(system.data('updated'))
|
||||
updated: parseInt(data.updated)
|
||||
}
|
||||
};
|
||||
|
||||
if(!minimal){
|
||||
systemData = Object.assign(systemData, {
|
||||
systemId: parseInt(system.data('systemId')),
|
||||
name: system.data('name'),
|
||||
let systemDataComplete = {
|
||||
systemId: parseInt(data.systemId),
|
||||
name: data.name,
|
||||
alias: system.getSystemInfo(['alias']),
|
||||
effect: system.data('effect'),
|
||||
effect: data.effect,
|
||||
type: {
|
||||
id: system.data('typeId')
|
||||
id: data.typeId
|
||||
},
|
||||
security: system.data('security'),
|
||||
trueSec: system.data('trueSec'),
|
||||
security: data.security,
|
||||
trueSec: data.trueSec,
|
||||
region: {
|
||||
id: system.data('regionId'),
|
||||
name: system.data('region')
|
||||
id: data.regionId,
|
||||
name: data.region
|
||||
},
|
||||
constellation: {
|
||||
id: system.data('constellationId'),
|
||||
name: system.data('constellation')
|
||||
id: data.constellationId,
|
||||
name: data.constellation
|
||||
},
|
||||
status: {
|
||||
id: system.data('statusId')
|
||||
id: data.statusId
|
||||
},
|
||||
locked: system.data('locked') ? 1 : 0,
|
||||
rallyUpdated: system.data('rallyUpdated') || 0,
|
||||
rallyPoke: system.data('rallyPoke') ? 1 : 0,
|
||||
currentUser: system.data('currentUser'), // if user is currently in this system
|
||||
faction: system.data('faction'),
|
||||
planets: system.data('planets'),
|
||||
shattered: system.data('shattered') ? 1 : 0,
|
||||
statics: system.data('statics'),
|
||||
userCount: (system.data('userCount') ? parseInt(system.data('userCount')) : 0),
|
||||
locked: data.locked ? 1 : 0,
|
||||
rallyUpdated: data.rallyUpdated || 0,
|
||||
rallyPoke: data.rallyPoke ? 1 : 0,
|
||||
currentUser: data.currentUser, // if user is currently in this system
|
||||
planets: data.planets,
|
||||
shattered: data.shattered ? 1 : 0,
|
||||
statics: data.statics,
|
||||
userCount: parseInt(data.userCount) || 0,
|
||||
position: MapUtil.getSystemPosition(system)
|
||||
});
|
||||
};
|
||||
|
||||
let optionalDataKeys = ['sovereignty'];
|
||||
|
||||
for(let dataKey of optionalDataKeys){
|
||||
let value = system.data(dataKey);
|
||||
if(value !== null && value !== undefined){
|
||||
systemDataComplete[dataKey] = value;
|
||||
}
|
||||
}
|
||||
|
||||
systemData = Object.assign(systemData, systemDataComplete);
|
||||
}
|
||||
|
||||
return systemData;
|
||||
|
||||
@@ -370,15 +370,16 @@ define([
|
||||
// init popover if not already exists
|
||||
if(!systemHead.data('bs.popover')){
|
||||
let system = systemHead.parent();
|
||||
let systemData = system.data();
|
||||
systemHead.popover({
|
||||
placement: 'right',
|
||||
placement: 'bottom',
|
||||
html: true,
|
||||
trigger: 'manual',
|
||||
container: mapElement,
|
||||
title: false,
|
||||
content: Util.getSystemRegionTable(
|
||||
system.data('region'),
|
||||
system.data('faction') || null
|
||||
Util.getObjVal(systemData, 'region'),
|
||||
Util.getObjVal(systemData, 'sovereignty')
|
||||
)
|
||||
});
|
||||
}
|
||||
|
||||
@@ -806,10 +806,9 @@ define([
|
||||
|
||||
// collect all required data from map module to update the info element
|
||||
// store them global and assessable for each module
|
||||
Util.setCurrentSystemData({
|
||||
systemData: system.getSystemData(),
|
||||
mapId: parseInt( system.attr('data-mapid') )
|
||||
});
|
||||
let systemData = system.getSystemData();
|
||||
systemData.mapId = parseInt(system.attr('data-mapid')) || 0;
|
||||
Util.setCurrentSystemData(systemData);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -1869,10 +1868,10 @@ define([
|
||||
if(tooltipData.maxStableTime){
|
||||
data.maxStableTime = tooltipData.maxStableTime + ' h';
|
||||
}
|
||||
if(tooltipData.signatureStrength){
|
||||
data.signatureStrength = parseFloat(tooltipData.signatureStrength).toLocaleString() + ' %';
|
||||
if(tooltipData.scanWormholeStrength){
|
||||
data.scanWormholeStrength = parseFloat(tooltipData.scanWormholeStrength).toLocaleString() + ' %';
|
||||
}else{
|
||||
data.signatureStrength = '<span class="txt-color txt-color-grayLight">unknown</span>';
|
||||
data.scanWormholeStrength = '<span class="txt-color txt-color-grayLight">unknown</span>';
|
||||
}
|
||||
|
||||
let title = tooltipData.name;
|
||||
|
||||
@@ -447,7 +447,7 @@ define([
|
||||
// start user update trigger after map loaded
|
||||
updateTimeouts.userUpdate = setTimeout(() => {
|
||||
triggerUserUpdatePing();
|
||||
}, 1000);
|
||||
}, 500);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -353,7 +353,7 @@ define([
|
||||
|
||||
// request "additional" system data (e.g. Structures, Description)
|
||||
// -> this is used to update some modules after initial draw
|
||||
let promiseRequestData = Util.request('GET', 'system', currentSystemData.systemData.id, {mapId: currentSystemData.mapId});
|
||||
let promiseRequestData = Util.request('GET', 'system', currentSystemData.id, {mapId: currentSystemData.mapId});
|
||||
|
||||
// draw modules -------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -361,22 +361,22 @@ define([
|
||||
let secondCell = tabContentElement.find('.' + config.mapTabContentCellSecond);
|
||||
|
||||
// draw system info module
|
||||
let promiseInfo = drawModule(firstCell, SystemInfoModule, currentSystemData.mapId, currentSystemData.systemData);
|
||||
let promiseInfo = drawModule(firstCell, SystemInfoModule, currentSystemData.mapId, currentSystemData);
|
||||
|
||||
// draw system graph module
|
||||
drawModule(firstCell, SystemGraphModule, currentSystemData.mapId, currentSystemData.systemData);
|
||||
drawModule(firstCell, SystemGraphModule, currentSystemData.mapId, currentSystemData);
|
||||
|
||||
// draw signature table module
|
||||
let promiseSignature = drawModule(firstCell, SystemSignatureModule, currentSystemData.mapId, currentSystemData.systemData);
|
||||
let promiseSignature = drawModule(firstCell, SystemSignatureModule, currentSystemData.mapId, currentSystemData);
|
||||
|
||||
// draw system routes module
|
||||
drawModule(secondCell, SystemRouteModule, currentSystemData.mapId, currentSystemData.systemData);
|
||||
drawModule(secondCell, SystemRouteModule, currentSystemData.mapId, currentSystemData);
|
||||
|
||||
// draw system intel module
|
||||
let promiseIntel = drawModule(secondCell, SystemIntelModule, currentSystemData.mapId, currentSystemData.systemData);
|
||||
let promiseIntel = drawModule(secondCell, SystemIntelModule, currentSystemData.mapId, currentSystemData);
|
||||
|
||||
// draw system killboard module
|
||||
drawModule(secondCell, SystemKillboardModule, currentSystemData.mapId, currentSystemData.systemData);
|
||||
drawModule(secondCell, SystemKillboardModule, currentSystemData.mapId, currentSystemData);
|
||||
|
||||
// update some modules ------------------------------------------------------------------------------------
|
||||
promiseDrawAll.push(promiseRequestData, promiseInfo, promiseSignature, promiseIntel);
|
||||
@@ -479,7 +479,7 @@ define([
|
||||
|
||||
if(
|
||||
currentSystemData &&
|
||||
systemData.id === currentSystemData.systemData.id
|
||||
systemData.id === currentSystemData.id
|
||||
){
|
||||
// trigger system update events
|
||||
let tabContentElement = $('#' + config.mapTabIdPrefix + systemData.mapId + '.' + config.mapTabContentClass);
|
||||
|
||||
@@ -11,7 +11,6 @@ define([
|
||||
'app/map/util',
|
||||
'app/map/contextmenu',
|
||||
'slidebars',
|
||||
'text!img/logo.svg!strip',
|
||||
'text!templates/layout/header_map.html',
|
||||
'text!templates/layout/footer_map.html',
|
||||
'dialog/notification',
|
||||
@@ -27,7 +26,7 @@ define([
|
||||
'dialog/credit',
|
||||
'xEditable',
|
||||
'app/module_map'
|
||||
], ($, Init, Util, Logging, Mustache, MapUtil, MapContextMenu, SlideBars, TplLogo, TplHead, TplFooter) => {
|
||||
], ($, Init, Util, Logging, Mustache, MapUtil, MapContextMenu, SlideBars, TplHead, TplFooter) => {
|
||||
|
||||
'use strict';
|
||||
|
||||
@@ -152,6 +151,7 @@ define([
|
||||
loadFooter(pageElement),
|
||||
loadLeftMenu(pageMenuLeftElement),
|
||||
loadRightMenu(pageMenuRightElement),
|
||||
loadSVGs()
|
||||
]).then(payload => Promise.all([
|
||||
setMenuObserver(payload[2].data),
|
||||
setMenuObserver(payload[3].data),
|
||||
@@ -413,6 +413,35 @@ define([
|
||||
return new Promise(executor);
|
||||
};
|
||||
|
||||
/**
|
||||
* load standalone <svg>´s into DOM
|
||||
* -> SVGs can be used by referencing its ID e.g.:
|
||||
* <svg width="12px" height="12px"><use xlink:href="#pf-svg-swords"/></svg>
|
||||
* @returns {Promise<any>}
|
||||
*/
|
||||
let loadSVGs = () => {
|
||||
|
||||
let executor = resolve => {
|
||||
let parentElement = $('body');
|
||||
|
||||
let svgPaths = [
|
||||
'img/svg/logo.svg',
|
||||
'img/svg/swords.svg'
|
||||
].map(path => 'text!' + path + '!strip');
|
||||
|
||||
requirejs(svgPaths, (...SVGs) => {
|
||||
parentElement.append.apply(parentElement, SVGs);
|
||||
|
||||
resolve({
|
||||
action: 'loadSVGs',
|
||||
data: {}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
return new Promise(executor);
|
||||
};
|
||||
|
||||
/**
|
||||
* load page header
|
||||
* @param pageElement
|
||||
@@ -423,7 +452,6 @@ define([
|
||||
let executor = resolve => {
|
||||
let moduleData = {
|
||||
id: config.pageHeaderId,
|
||||
logo: () => Mustache.render(TplLogo, {}),
|
||||
brandLogo: config.menuHeadMenuLogoClass,
|
||||
popoverTriggerClass: Util.config.popoverTriggerClass,
|
||||
userCharacterClass: config.headUserCharacterClass,
|
||||
@@ -1026,7 +1054,7 @@ define([
|
||||
if(changedCharacter){
|
||||
// current character changed
|
||||
userInfoElement.find('span').text(Util.getObjVal(userData, 'character.name'));
|
||||
userInfoElement.find('img').attr('src', Init.url.ccpImageServer + '/Character/' + Util.getObjVal(userData, 'character.id') + '_32.jpg');
|
||||
userInfoElement.find('img').attr('src', Util.eveImageUrl('character', Util.getObjVal(userData, 'character.id')));
|
||||
}
|
||||
// init "character switch" popover
|
||||
userInfoElement.initCharacterSwitchPopover(userData);
|
||||
@@ -1094,9 +1122,8 @@ define([
|
||||
|
||||
if(isCurrentLocation && shipTypeId){
|
||||
// show ship image
|
||||
let shipSrc = Init.url.ccpImageServer + '/Render/' + shipTypeId + '_32.png';
|
||||
breadcrumbHtml += '<img class="pf-head-image --right" ';
|
||||
breadcrumbHtml += 'src="' + shipSrc + '" ';
|
||||
breadcrumbHtml += 'src="' + Util.eveImageUrl('render', shipTypeId) + '" ';
|
||||
breadcrumbHtml += 'title="' + shipTypeName + '" ';
|
||||
breadcrumbHtml += '>';
|
||||
}
|
||||
|
||||
@@ -93,6 +93,7 @@ define([
|
||||
let url = '/api/setup/' + element.attr('data-action');
|
||||
sendRequest(url, {
|
||||
type: element.attr('data-type'),
|
||||
countAll: element.attr('data-countall'),
|
||||
count: 0,
|
||||
offset: 0
|
||||
}, {
|
||||
@@ -116,10 +117,10 @@ define([
|
||||
* @param responseData
|
||||
*/
|
||||
let updateIndexCount = (context, responseData) => {
|
||||
let countElement = context.target.closest('.row').children().eq(1).find('kbd');
|
||||
let countElement = context.target.closest('tr').children().eq(1).find('kbd');
|
||||
countElement.text(responseData.countBuildAll + '/' + responseData.countAll);
|
||||
countElement.removeClass('txt-color-success txt-color-danger txt-color-warning');
|
||||
if(responseData.countBuildAll >=responseData.countAll){
|
||||
if(responseData.countBuildAll >= responseData.countAll){
|
||||
countElement.addClass('txt-color-success');
|
||||
}else if(responseData.countBuildAll > 0){
|
||||
countElement.addClass('txt-color-warning');
|
||||
@@ -127,6 +128,12 @@ define([
|
||||
countElement.addClass('txt-color-danger');
|
||||
}
|
||||
|
||||
// update 'subCount' element (shows e.g. invType count)
|
||||
if(responseData.subCount){
|
||||
let subCountElement = context.target.closest('tr').children().eq(2).find('kbd');
|
||||
subCountElement.text(responseData.subCount.countBuildAll + '/' + subCountElement.attr('data-countall'));
|
||||
}
|
||||
|
||||
context.target.find('.btn-progress').html(' ' + responseData.progress + '%').css('width', responseData.progress + '%');
|
||||
|
||||
// send next chunk of rows -> import only
|
||||
@@ -136,6 +143,7 @@ define([
|
||||
){
|
||||
sendRequest(context.url, {
|
||||
type: responseData.type,
|
||||
countAll: responseData.countAll,
|
||||
count: responseData.count,
|
||||
offset: responseData.offset
|
||||
}, {
|
||||
|
||||
@@ -38,7 +38,8 @@ define([
|
||||
switch(render(val)){
|
||||
case 'green': return 'ok';
|
||||
case 'yellow': return 'degraded: Slow or potentially dropping requests';
|
||||
case 'red': return 'bad: Most requests are not succeeding and/or are very slow (5s+) on average';
|
||||
case 'orange': return 'bad: Most requests are not succeeding and/or are very slow (5s+) on average';
|
||||
case 'red': return 'error: Status data not available. Either offline or any other fatal error';
|
||||
default: return 'unknown';
|
||||
}
|
||||
};
|
||||
|
||||
@@ -225,7 +225,7 @@ define([
|
||||
paging: true,
|
||||
lengthMenu: [[5, 10, 20, 50, -1], [5, 10, 20, 50, 'All']],
|
||||
ordering: true,
|
||||
order: [14, 'desc'],
|
||||
order: [15, 'desc'],
|
||||
hover: false,
|
||||
data: mapData.data.systems,
|
||||
columnDefs: [],
|
||||
@@ -312,6 +312,22 @@ define([
|
||||
title: 'region',
|
||||
data: 'region.name',
|
||||
className: 'min-screen-l',
|
||||
},{
|
||||
name: 'sovereignty',
|
||||
title: 'sov.',
|
||||
width: 30,
|
||||
className: 'text-center',
|
||||
data: 'sovereignty.alliance.ticker',
|
||||
defaultContent: '',
|
||||
render: {
|
||||
display: (cellData, type, rowData, meta) => {
|
||||
let value = '';
|
||||
if(cellData){
|
||||
value = '<' + cellData + '>';
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
},{
|
||||
name: 'planets',
|
||||
title: '<i class="fas fa-circle" title="planets" data-toggle="tooltip"></i>',
|
||||
@@ -748,7 +764,7 @@ define([
|
||||
_: function(data, type, row, meta){
|
||||
let value = data;
|
||||
if(data && type === 'display'){
|
||||
value = '<img src="' + Init.url.ccpImageServer + '/Render/' + value.typeId + '_32.png" title="' + value.typeName + '" data-toggle="tooltip" />';
|
||||
value = '<img src="' + Util.eveImageUrl('render', value.typeId) + '" title="' + value.typeName + '" data-toggle="tooltip" />';
|
||||
}
|
||||
return value;
|
||||
}
|
||||
@@ -786,7 +802,7 @@ define([
|
||||
_: function(data, type, row, meta){
|
||||
let value = data;
|
||||
if(type === 'display'){
|
||||
value = '<img src="' + Init.url.ccpImageServer + '/Character/' + value + '_32.jpg" />';
|
||||
value = '<img src="' + Util.eveImageUrl('character', value) + '"/>';
|
||||
}
|
||||
return value;
|
||||
}
|
||||
@@ -826,7 +842,7 @@ define([
|
||||
_: function(data, type, row, meta){
|
||||
let value = data;
|
||||
if(type === 'display'){
|
||||
value = '<img src="' + Init.url.ccpImageServer + '/Corporation/' + value.id + '_32.png" />';
|
||||
value = '<img src="' + Util.eveImageUrl('corporation', value.id) + '"/>';
|
||||
}
|
||||
return value;
|
||||
}
|
||||
@@ -1109,7 +1125,7 @@ define([
|
||||
_: function(data, type, row, meta){
|
||||
let value = data;
|
||||
if(type === 'display'){
|
||||
value = '<img src="' + Init.url.ccpImageServer + '/Character/' + value + '_32.jpg" />';
|
||||
value = '<img src="' + Util.eveImageUrl('character', value) + '"/>';
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -130,7 +130,7 @@ define([
|
||||
data: 'character',
|
||||
render: {
|
||||
_: function(data, type, row, meta){
|
||||
return '<img src="' + Init.url.ccpImageServer + '/Character/' + data.id + '_32.jpg" />';
|
||||
return '<img src="' + Util.eveImageUrl('character', parseInt(data.id)) + '"/>';
|
||||
}
|
||||
}
|
||||
},{
|
||||
|
||||
@@ -38,19 +38,19 @@ define([
|
||||
|
||||
switch(data.categoryType){
|
||||
case 'character':
|
||||
imagePath = Init.url.ccpImageServer + '/Character/' + data.id + '_32.jpg';
|
||||
imagePath = Util.eveImageUrl('character', data.id);
|
||||
break;
|
||||
case 'corporation':
|
||||
imagePath = Init.url.ccpImageServer + '/Corporation/' + data.id + '_32.png';
|
||||
imagePath = Util.eveImageUrl('corporation', data.id);
|
||||
break;
|
||||
case 'alliance':
|
||||
imagePath = Init.url.ccpImageServer + '/Alliance/' + data.id + '_32.png';
|
||||
imagePath = Util.eveImageUrl('alliance', data.id);
|
||||
break;
|
||||
case 'inventoryType':
|
||||
imagePath = Init.url.ccpImageServer + '/Type/' + data.id + '_32.png';
|
||||
imagePath = Util.eveImageUrl('type', data.id);
|
||||
break;
|
||||
case 'render':
|
||||
imagePath = Init.url.ccpImageServer + '/Render/' + data.id + '_32.png';
|
||||
imagePath = Util.eveImageUrl('render', data.id);
|
||||
break;
|
||||
case 'station':
|
||||
iconName = 'fa-home';
|
||||
|
||||
@@ -774,7 +774,7 @@ define([
|
||||
_: function(data, type, row){
|
||||
let value = data.typeId;
|
||||
if(type === 'display'){
|
||||
value = '<img src="' + Init.url.ccpImageServer + '/Render/' + value + '_32.png" title="' + data.typeName + '" data-toggle="tooltip" />';
|
||||
value = '<img src="' + Util.eveImageUrl('render', value) + '" title="' + data.typeName + '" data-toggle="tooltip" />';
|
||||
}
|
||||
return value;
|
||||
}
|
||||
@@ -794,7 +794,7 @@ define([
|
||||
_: (cellData, type, rowData, meta) => {
|
||||
let value = cellData.name;
|
||||
if(type === 'display'){
|
||||
value = '<img src="' + Init.url.ccpImageServer + '/Character/' + cellData.id + '_32.jpg" title="' + value + '" data-toggle="tooltip" />';
|
||||
value = '<img src="' + Util.eveImageUrl('character', cellData.id) + '" title="' + value + '" data-toggle="tooltip" />';
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -265,7 +265,7 @@ define([
|
||||
for(let [graphKey, graphConfig] of Object.entries(config.systemGraphs)){
|
||||
rowElement.append(
|
||||
$('<div>', {
|
||||
class: ['col-xs-12', 'col-sm-6', 'col-md-4'].join(' ')
|
||||
class: ['col-xs-12', 'col-sm-4'].join(' ')
|
||||
}).append(
|
||||
$('<div>', {
|
||||
class: config.moduleHeadClass
|
||||
|
||||
@@ -27,7 +27,8 @@ define([
|
||||
typeLinkClass: 'pf-system-info-type', // class for "type" name
|
||||
urlLinkClass: 'pf-system-info-url', // class for "url" copy link
|
||||
|
||||
// info table
|
||||
// info col/table
|
||||
systemInfoSectionClass: 'pf-system-info-section', // class for system info section
|
||||
systemInfoTableClass: 'pf-module-table', // class for system info table
|
||||
systemInfoNameClass: 'pf-system-info-name', // class for "name" information element
|
||||
systemInfoEffectClass: 'pf-system-info-effect', // class for "effect" information element
|
||||
@@ -37,9 +38,21 @@ define([
|
||||
systemInfoWormholeClass: 'pf-system-info-wormhole-', // class prefix for static wormhole element
|
||||
|
||||
// description field
|
||||
descriptionAreaClass: 'pf-system-info-description-area', // class for "description" area
|
||||
descriptionSectionClass: 'pf-system-description-section', // class for system description section
|
||||
descriptionAreaClass: 'pf-system-info-description-area', // class for description area
|
||||
addDescriptionButtonClass: 'pf-system-info-description-button', // class for "add description" button
|
||||
descriptionTextareaElementClass: 'pf-system-info-description', // class for "description" textarea element (Summernote)
|
||||
descriptionTextareaElementClass: 'pf-system-info-description', // class for description textarea element (Summernote)
|
||||
|
||||
// sovereignty col/table
|
||||
systemSovSectionClass: 'pf-system-sov-section', // class for system sov. section
|
||||
systemSovTableClass: 'pf-module-table', // class for system sov. table
|
||||
systemSovFwContestedRowClass: 'pf-system-sov-fw-contested-row', // class for "contested" sov. table row
|
||||
systemSovFwOccupationRowClass: 'pf-system-sov-fw-occupation-row', // class for "-occupation" sov. table row
|
||||
systemSovFwContestedClass: 'pf-system-sov-fw-contested',
|
||||
systemSovFwPercentageClass: 'pf-system-sov-fw-percentage',
|
||||
systemSovFwOccupationClass: 'pf-system-sov-fw-occupation',
|
||||
systemSovFwOccupationImageClass: 'pf-system-sov-fw-occupation-image',
|
||||
systemSovFwStatusIconClass: 'pf-system-sov-fw-status-icon',
|
||||
|
||||
// fonts
|
||||
fontTriglivianClass: 'pf-triglivian', // class for "Triglivian" names (e.g. Abyssal systems)
|
||||
@@ -115,12 +128,64 @@ define([
|
||||
}
|
||||
}
|
||||
|
||||
// update faction warfare rows ----------------------------------------------------------------------------
|
||||
let fwContestedRow = moduleElement.find('.' + config.systemSovFwContestedRowClass);
|
||||
let fwOccupationRow = moduleElement.find('.' + config.systemSovFwOccupationRowClass);
|
||||
if(systemData.factionWar){
|
||||
let contested = String(Util.getObjVal(systemData.factionWar, 'contested') || '');
|
||||
let percentage = parseInt(Util.getObjVal(systemData.factionWar, 'victoryPercentage')) || 0;
|
||||
let occupierFaction = Util.getObjVal(systemData.factionWar, 'occupierFaction');
|
||||
|
||||
let statusColor = 'red';
|
||||
if(occupierFaction){
|
||||
// system is "occupied" by hostile "occupierFaction" (stable)
|
||||
// -> hide percent
|
||||
statusColor = '#d9534f';
|
||||
percentage += '%';
|
||||
}else if('uncontested' === contested){
|
||||
// system is "uncontested" and owned by default ownerFaction (stable)
|
||||
// -> hide percent
|
||||
statusColor = '#4f9e4f';
|
||||
percentage = 'stable';
|
||||
}else if('contested' === contested){
|
||||
// system is "contested", 0%-99% percentage
|
||||
statusColor = '#e28a0d';
|
||||
percentage += '%';
|
||||
}else if(
|
||||
'vulnerable' === contested ||
|
||||
'captured' === contested
|
||||
){
|
||||
// system is "vulnerable", 100% percentage
|
||||
// -> "captured" state is might be the same?!
|
||||
statusColor = '#d747d6';
|
||||
percentage = '100%';
|
||||
}
|
||||
|
||||
fwContestedRow.find('.' + config.systemSovFwStatusIconClass)[0].style.setProperty('--color', statusColor);
|
||||
fwContestedRow.find('.' + config.systemSovFwContestedClass).text(contested);
|
||||
fwContestedRow.find('.' + config.systemSovFwPercentageClass).text(percentage);
|
||||
fwContestedRow.show();
|
||||
|
||||
let occupierFactionImage = Util.eveImageUrl('alliance', (occupierFaction ? occupierFaction.id : 0), 64);
|
||||
let occupierFactionName = occupierFaction ? occupierFaction.name : '';
|
||||
|
||||
fwOccupationRow.find('.' + config.systemSovFwOccupationImageClass)[0].style.setProperty('--bg-image', 'url(\'' + occupierFactionImage + '\')');
|
||||
fwOccupationRow.find('.' + config.systemSovFwOccupationClass).text(occupierFactionName);
|
||||
if(occupierFaction){
|
||||
fwOccupationRow.show();
|
||||
}
|
||||
}else{
|
||||
fwContestedRow.hide();
|
||||
fwOccupationRow.hide();
|
||||
}
|
||||
|
||||
if(setUpdated){
|
||||
moduleElement.data('updated', systemData.updated.updated);
|
||||
}
|
||||
}
|
||||
|
||||
moduleElement.find('.' + config.descriptionAreaClass).hideLoadingAnimation();
|
||||
moduleElement.find('.' + config.systemSovSectionClass + ' .' + Util.config.dynamicAreaClass).hideLoadingAnimation();
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -135,6 +200,56 @@ define([
|
||||
// store systemId -> module can be updated with the correct data
|
||||
moduleElement.data('id', systemData.id);
|
||||
|
||||
// system "sovereignty" data
|
||||
// "primary" data is eigther "alliance" -> 0.0 space
|
||||
// or "faction" -> Empire Regions (LS, HS)
|
||||
let sovereigntyDefault = {
|
||||
row1Label: 'Sov.',
|
||||
row1Val: '???',
|
||||
row1Img: undefined,
|
||||
row1ImgTitle: undefined,
|
||||
row2Label: undefined,
|
||||
row2Val: undefined,
|
||||
row3Label: undefined,
|
||||
row3Val: undefined
|
||||
};
|
||||
|
||||
let sovereigntyPrimary;
|
||||
let sovereigntySecondary;
|
||||
|
||||
if(systemData.sovereignty){
|
||||
let sovDataFact = Util.getObjVal(systemData.sovereignty, 'faction');
|
||||
let sovDataAlly = Util.getObjVal(systemData.sovereignty, 'alliance');
|
||||
let sovDataCorp = Util.getObjVal(systemData.sovereignty, 'corporation');
|
||||
|
||||
if(sovDataFact){
|
||||
sovereigntyPrimary = {
|
||||
row1Val: 'Faction',
|
||||
row1Img: Util.eveImageUrl('alliance', sovDataFact.id, 64),
|
||||
row1ImgTitle: sovDataFact.name,
|
||||
row2Val: sovDataFact.name
|
||||
};
|
||||
}else{
|
||||
if(sovDataAlly){
|
||||
sovereigntyPrimary = {
|
||||
row1Val: 'Alliance',
|
||||
row1Img: Util.eveImageUrl('alliance', sovDataAlly.id, 64),
|
||||
row1ImgTitle: sovDataAlly.name,
|
||||
row2Val: '<' + sovDataAlly.ticker + '>',
|
||||
row3Label: 'Ally',
|
||||
row3Val: sovDataAlly.name
|
||||
};
|
||||
}
|
||||
if(sovDataCorp){
|
||||
sovereigntySecondary = {
|
||||
row1Label: 'Corp',
|
||||
row1Val: sovDataCorp.name,
|
||||
row1Img: Util.eveImageUrl('corporation', sovDataCorp.id, 64)
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// system "static" wh data
|
||||
let staticsData = [];
|
||||
if(
|
||||
@@ -152,9 +267,15 @@ define([
|
||||
|
||||
let data = {
|
||||
system: systemData,
|
||||
sovereigntyPrimary: sovereigntyPrimary ? Object.assign({}, sovereigntyDefault, sovereigntyPrimary) : undefined,
|
||||
sovereigntySecondary: sovereigntySecondary ? Object.assign({}, sovereigntyDefault, sovereigntySecondary) : undefined,
|
||||
static: staticsData,
|
||||
moduleHeadlineIconClass: config.moduleHeadlineIconClass,
|
||||
tableClass: config.systemInfoTableClass,
|
||||
infoSectionClass: config.systemInfoSectionClass,
|
||||
descriptionSectionClass: config.descriptionSectionClass,
|
||||
sovSectionClass: config.systemSovSectionClass,
|
||||
infoTableClass: config.systemInfoTableClass,
|
||||
sovTableClass: config.systemSovTableClass,
|
||||
nameInfoClass: config.systemInfoNameClass,
|
||||
effectInfoClass: config.systemInfoEffectClass,
|
||||
planetsInfoClass: config.systemInfoPlanetsClass,
|
||||
@@ -162,6 +283,15 @@ define([
|
||||
statusInfoClass: config.systemInfoStatusLabelClass,
|
||||
popoverTriggerClass: Util.config.popoverTriggerClass,
|
||||
|
||||
// sovereignty table
|
||||
sovFwContestedRowClass: config.systemSovFwContestedRowClass,
|
||||
sovFwOccupationRowClass: config.systemSovFwOccupationRowClass,
|
||||
sovFwContestedInfoClass: config.systemSovFwContestedClass,
|
||||
sovFwPercentageInfoClass: config.systemSovFwPercentageClass,
|
||||
sovFwOccupationInfoClass: config.systemSovFwOccupationClass,
|
||||
sovFwOccupationImageClass: config.systemSovFwOccupationImageClass,
|
||||
sovFwStatusIconClass: config.systemSovFwStatusIconClass,
|
||||
|
||||
systemUrl: MapUtil.getMapDeeplinkUrl(mapId, systemData.id),
|
||||
systemTypeName: MapUtil.getSystemTypeInfo(systemData.type.id, 'name'),
|
||||
systemIsWormhole: MapUtil.getSystemTypeInfo(systemData.type.id, 'name') === 'w-space',
|
||||
@@ -194,19 +324,22 @@ define([
|
||||
systemConstellationLinkClass: config.constellationLinkClass,
|
||||
systemRegionLinkClass: config.regionLinkClass,
|
||||
systemTypeLinkClass: config.typeLinkClass,
|
||||
systemUrlLinkClass: config.urlLinkClass
|
||||
systemUrlLinkClass: config.urlLinkClass,
|
||||
ccpImageServerUrl: Init.url.ccpImageServer,
|
||||
};
|
||||
|
||||
requirejs(['text!templates/modules/system_info.html', 'mustache', 'summernote.loader'], (template, Mustache, Summernote) => {
|
||||
let content = Mustache.render(template, data);
|
||||
moduleElement.append(content);
|
||||
|
||||
let sovSectionArea = moduleElement.find('.' + config.systemSovSectionClass + ' .' + Util.config.dynamicAreaClass);
|
||||
let descriptionArea = moduleElement.find('.' + config.descriptionAreaClass);
|
||||
let descriptionButton = moduleElement.find('.' + config.addDescriptionButtonClass);
|
||||
let descriptionTextareaElement = moduleElement.find('.' + config.descriptionTextareaElementClass);
|
||||
|
||||
// lock "description" field until first update
|
||||
descriptionArea.showLoadingAnimation();
|
||||
sovSectionArea.showLoadingAnimation();
|
||||
|
||||
// WYSIWYG init on button click ---------------------------------------------------------------------------
|
||||
descriptionButton.on('click', function(e){
|
||||
|
||||
@@ -452,7 +452,7 @@ define([
|
||||
_: function(data, type, row, meta){
|
||||
let value = data;
|
||||
if(type === 'display' && value){
|
||||
value = '<img src="' + Init.url.ccpImageServer + '/Type/' + value + '_32.png" />';
|
||||
value = '<img src="' + Util.eveImageUrl('type', value) +'"/>';
|
||||
}
|
||||
return value;
|
||||
}
|
||||
@@ -486,7 +486,7 @@ define([
|
||||
let value = data;
|
||||
if(type === 'display' && value){
|
||||
value = '<a href="https://zkillboard.com/corporation/' + data + '/" target="_blank" rel="noopener">';
|
||||
value += '<img src="' + Init.url.ccpImageServer + '/Corporation/' + data + '_32.png" />';
|
||||
value += '<img src="' + Util.eveImageUrl('corporation', data) + '"/>';
|
||||
value += '</a>';
|
||||
}
|
||||
return value;
|
||||
@@ -625,7 +625,7 @@ define([
|
||||
'<tr class="group">' +
|
||||
'<td></td>' +
|
||||
'<td class="' + config.tableCellImageClass + '">' +
|
||||
'<img src="' + Init.url.ccpImageServer + '/Corporation/' + group.id + '_32.png" />' +
|
||||
'<img src="' + Util.eveImageUrl('corporation', group.id) + '"/>' +
|
||||
'</td>' +
|
||||
'<td colspan="' + (columnCount - 2 ) + '">' + group.name + '</td>' +
|
||||
'</tr>'
|
||||
|
||||
@@ -552,7 +552,7 @@ define([
|
||||
userData: userData,
|
||||
otherCharacters: () => {
|
||||
return userData.characters.filter((character, i) => {
|
||||
let characterImage = Init.url.ccpImageServer + '/Character/' + character.id + '_32.jpg';
|
||||
let characterImage = eveImageUrl('character', character.id);
|
||||
// preload image (prevent UI flicker
|
||||
let img= new Image();
|
||||
img.src = characterImage;
|
||||
@@ -852,6 +852,23 @@ define([
|
||||
*/
|
||||
let showVersionInfo = () => Con.showVersionInfo(getVersion());
|
||||
|
||||
/**
|
||||
* get CCP image URLs for
|
||||
* @param type 'alliance'|'corporation'|'character'|'type'|'render'
|
||||
* @param id
|
||||
* @param size
|
||||
* @returns {boolean}
|
||||
*/
|
||||
let eveImageUrl = (type, id, size = 32) => {
|
||||
let url = false;
|
||||
if(typeof type === 'string' && typeof id === 'number' && typeof size === 'number'){
|
||||
type = type.capitalize();
|
||||
let format = type === 'Character' ? 'jpg' : 'png';
|
||||
url = Init.url.ccpImageServer + '/' + type + '/' + id + '_' + size + '.' + format;
|
||||
}
|
||||
return url;
|
||||
};
|
||||
|
||||
/**
|
||||
* polyfill for "passive" events
|
||||
* -> see https://github.com/zzarcon/default-passive-events
|
||||
@@ -2303,26 +2320,28 @@ define([
|
||||
* get a HTML table with universe region information
|
||||
* e.g. for popover
|
||||
* @param regionName
|
||||
* @param faction
|
||||
* @param sovereignty
|
||||
* @returns {string}
|
||||
*/
|
||||
let getSystemRegionTable = (regionName, faction) => {
|
||||
let getSystemRegionTable = (regionName, sovereignty) => {
|
||||
let data = [{label: 'Region', value: regionName}];
|
||||
if(sovereignty){
|
||||
if(sovereignty.faction){
|
||||
data.push({label: 'Sov. Faction', value: sovereignty.faction.name});
|
||||
}
|
||||
if(sovereignty.alliance){
|
||||
data.push({label: 'Sov. Ally', value: sovereignty.alliance.name});
|
||||
}
|
||||
}
|
||||
|
||||
let table = '<table>';
|
||||
table += '<tr>';
|
||||
table += '<td>';
|
||||
table += 'Region';
|
||||
table += '</td>';
|
||||
table += '<td class="text-right">';
|
||||
table += regionName;
|
||||
table += '</td>';
|
||||
table += '</tr>';
|
||||
table += '<tr>';
|
||||
if(faction){
|
||||
for(let rowData of data){
|
||||
table += '<tr>';
|
||||
table += '<td>';
|
||||
table += 'Faction';
|
||||
table += rowData.label;
|
||||
table += '</td>';
|
||||
table += '<td class="text-right">';
|
||||
table += faction.name;
|
||||
table += rowData.value;
|
||||
table += '</td>';
|
||||
table += '</tr>';
|
||||
}
|
||||
@@ -3425,6 +3444,7 @@ define([
|
||||
config: config,
|
||||
getVersion: getVersion,
|
||||
showVersionInfo: showVersionInfo,
|
||||
eveImageUrl: eveImageUrl,
|
||||
initPrototypes: initPrototypes,
|
||||
initDefaultBootboxConfig: initDefaultBootboxConfig,
|
||||
initDefaultConfirmationConfig: initDefaultConfirmationConfig,
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,11 +1,11 @@
|
||||
<svg id="pf-logo-wrapper" xmlns="http://www.w3.org/2000/svg" version="1.2" width="0" height="0" shape-rendering="geometricPrecision">
|
||||
<svg class="pf-logo-wrapper" xmlns="http://www.w3.org/2000/svg" version="1.2" width="0" height="0" shape-rendering="geometricPrecision">
|
||||
<filter id="LogoFilterShadow" width="150%" height="150%">
|
||||
<feOffset result="offOut" in="SourceAlpha" dx="-3" dy="3"/>
|
||||
<feGaussianBlur result="blurOut" in="offOut" stdDeviation="3"/>
|
||||
<feBlend in="SourceGraphic" in2="blurOut" mode="normal"/>
|
||||
</filter>
|
||||
|
||||
<symbol id="pf-logo" viewBox="0 0 355 370" >
|
||||
<symbol id="pf-svg-logo" viewBox="0 0 355 370" >
|
||||
<!-- comment this for filter within the use-tag -->
|
||||
<!-- <g filter="url(#LogoFilterShadow)"> -->
|
||||
<g>
|
||||
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
8
public/img/svg/swords.svg
Normal file
8
public/img/svg/swords.svg
Normal file
@@ -0,0 +1,8 @@
|
||||
<svg class="pf-logo-wrapper" xmlns="http://www.w3.org/2000/svg" version="1.2" width="0" height="0" shape-rendering="geometricPrecision">
|
||||
<symbol id="pf-svg-swords" viewBox="0 0 512 512">
|
||||
<g>
|
||||
<path fill="currentColor"
|
||||
d="M309.37 389.38l80-80L93.33 13.33 15.22.14C6.42-1.12-1.12 6.42.14 15.22l13.2 78.11 296.03 296.05zm197.94 72.68L448 402.75l31.64-59.03c3.33-6.22 2.2-13.88-2.79-18.87l-17.54-17.53c-6.25-6.25-16.38-6.25-22.63 0L307.31 436.69c-6.25 6.25-6.25 16.38 0 22.62l17.53 17.54a16 16 0 0 0 18.87 2.79L402.75 448l59.31 59.31c6.25 6.25 16.38 6.25 22.63 0l22.62-22.62c6.25-6.25 6.25-16.38 0-22.63zm-8.64-368.73l13.2-78.11c1.26-8.8-6.29-16.34-15.08-15.08l-78.11 13.2-140.05 140.03 80 80L498.67 93.33zm-345.3 185.3L100 332l-24.69-24.69c-6.25-6.25-16.38-6.25-22.62 0l-17.54 17.53a15.998 15.998 0 0 0-2.79 18.87L64 402.75 4.69 462.06c-6.25 6.25-6.25 16.38 0 22.63l22.62 22.62c6.25 6.25 16.38 6.25 22.63 0L109.25 448l59.03 31.64c6.22 3.33 13.88 2.2 18.87-2.79l17.53-17.54c6.25-6.25 6.25-16.38 0-22.62L180 412l53.37-53.37-80-80z"/>
|
||||
</g>
|
||||
</symbol>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -454,11 +454,18 @@ define([
|
||||
*/
|
||||
let initServerStatus = () => {
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
type: 'GET',
|
||||
url: Init.path.getServerStatus,
|
||||
dataType: 'json'
|
||||
}).done(function(responseData, textStatus, request){
|
||||
|
||||
let dateLastModified = new Date(request.getResponseHeader('Last-Modified') || Date.now());
|
||||
let dateExpires = new Date(request.getResponseHeader('Expires') || Date.now());
|
||||
|
||||
var options = { hour: '2-digit', minute: '2-digit', hour12: false, timeZone: 'UTC', timeZoneName: 'short' };
|
||||
responseData.api.cache = dateLastModified.toLocaleTimeString('en-US', options);
|
||||
responseData.api.cacheExpire = 'TTL ' + (dateExpires - dateLastModified) / 1000 + 's';
|
||||
|
||||
let data = {
|
||||
stickyPanelServerId: config.stickyPanelServerId,
|
||||
stickyPanelClass: config.stickyPanelClass,
|
||||
@@ -471,7 +478,8 @@ define([
|
||||
case 'online':
|
||||
case 'green': return 'txt-color-green';
|
||||
case 'vip':
|
||||
case 'yellow': return 'txt-color-orange';
|
||||
case 'yellow': return 'txt-color-yellow';
|
||||
case 'orange': return 'txt-color-orange';
|
||||
case 'offline':
|
||||
case 'red': return 'txt-color-red';
|
||||
default: return '';
|
||||
|
||||
@@ -422,7 +422,7 @@ define([
|
||||
_: (data, type, row, meta) => {
|
||||
let value = data.typeName;
|
||||
if(type === 'display'){
|
||||
value = '<img src="' + Init.url.ccpImageServer + '/Render/' + data.typeId + '_32.png"/>';
|
||||
value = '<img src="' + Util.eveImageUrl('render', data.typeId) + '_32.png"/>';
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -546,13 +546,15 @@ define([
|
||||
system.data('region', data.region.name);
|
||||
system.data('constellationId', parseInt(data.constellation.id));
|
||||
system.data('constellation', data.constellation.name);
|
||||
system.data('faction', data.faction);
|
||||
system.data('planets', data.planets);
|
||||
system.data('shattered', data.shattered);
|
||||
system.data('statics', data.statics);
|
||||
system.data('updated', parseInt(data.updated.updated));
|
||||
system.data('changed', false);
|
||||
system.attr('data-mapid', parseInt(mapContainer.data('id')));
|
||||
if(data.sovereignty){
|
||||
system.data('sovereignty', data.sovereignty);
|
||||
}
|
||||
|
||||
// locked system
|
||||
if( Boolean(system.data('locked')) !== data.locked ){
|
||||
@@ -3046,47 +3048,58 @@ define([
|
||||
*/
|
||||
$.fn.getSystemData = function(minimal = false){
|
||||
let system = $(this);
|
||||
let data = system.data();
|
||||
|
||||
let systemData = {
|
||||
id: parseInt(system.data('id')),
|
||||
id: parseInt(data.id),
|
||||
updated: {
|
||||
updated: parseInt(system.data('updated'))
|
||||
updated: parseInt(data.updated)
|
||||
}
|
||||
};
|
||||
|
||||
if(!minimal){
|
||||
systemData = Object.assign(systemData, {
|
||||
systemId: parseInt(system.data('systemId')),
|
||||
name: system.data('name'),
|
||||
let systemDataComplete = {
|
||||
systemId: parseInt(data.systemId),
|
||||
name: data.name,
|
||||
alias: system.getSystemInfo(['alias']),
|
||||
effect: system.data('effect'),
|
||||
effect: data.effect,
|
||||
type: {
|
||||
id: system.data('typeId')
|
||||
id: data.typeId
|
||||
},
|
||||
security: system.data('security'),
|
||||
trueSec: system.data('trueSec'),
|
||||
security: data.security,
|
||||
trueSec: data.trueSec,
|
||||
region: {
|
||||
id: system.data('regionId'),
|
||||
name: system.data('region')
|
||||
id: data.regionId,
|
||||
name: data.region
|
||||
},
|
||||
constellation: {
|
||||
id: system.data('constellationId'),
|
||||
name: system.data('constellation')
|
||||
id: data.constellationId,
|
||||
name: data.constellation
|
||||
},
|
||||
status: {
|
||||
id: system.data('statusId')
|
||||
id: data.statusId
|
||||
},
|
||||
locked: system.data('locked') ? 1 : 0,
|
||||
rallyUpdated: system.data('rallyUpdated') || 0,
|
||||
rallyPoke: system.data('rallyPoke') ? 1 : 0,
|
||||
currentUser: system.data('currentUser'), // if user is currently in this system
|
||||
faction: system.data('faction'),
|
||||
planets: system.data('planets'),
|
||||
shattered: system.data('shattered') ? 1 : 0,
|
||||
statics: system.data('statics'),
|
||||
userCount: (system.data('userCount') ? parseInt(system.data('userCount')) : 0),
|
||||
locked: data.locked ? 1 : 0,
|
||||
rallyUpdated: data.rallyUpdated || 0,
|
||||
rallyPoke: data.rallyPoke ? 1 : 0,
|
||||
currentUser: data.currentUser, // if user is currently in this system
|
||||
planets: data.planets,
|
||||
shattered: data.shattered ? 1 : 0,
|
||||
statics: data.statics,
|
||||
userCount: parseInt(data.userCount) || 0,
|
||||
position: MapUtil.getSystemPosition(system)
|
||||
});
|
||||
};
|
||||
|
||||
let optionalDataKeys = ['sovereignty'];
|
||||
|
||||
for(let dataKey of optionalDataKeys){
|
||||
let value = system.data(dataKey);
|
||||
if(value !== null && value !== undefined){
|
||||
systemDataComplete[dataKey] = value;
|
||||
}
|
||||
}
|
||||
|
||||
systemData = Object.assign(systemData, systemDataComplete);
|
||||
}
|
||||
|
||||
return systemData;
|
||||
|
||||
@@ -370,15 +370,16 @@ define([
|
||||
// init popover if not already exists
|
||||
if(!systemHead.data('bs.popover')){
|
||||
let system = systemHead.parent();
|
||||
let systemData = system.data();
|
||||
systemHead.popover({
|
||||
placement: 'right',
|
||||
placement: 'bottom',
|
||||
html: true,
|
||||
trigger: 'manual',
|
||||
container: mapElement,
|
||||
title: false,
|
||||
content: Util.getSystemRegionTable(
|
||||
system.data('region'),
|
||||
system.data('faction') || null
|
||||
Util.getObjVal(systemData, 'region'),
|
||||
Util.getObjVal(systemData, 'sovereignty')
|
||||
)
|
||||
});
|
||||
}
|
||||
|
||||
@@ -806,10 +806,9 @@ define([
|
||||
|
||||
// collect all required data from map module to update the info element
|
||||
// store them global and assessable for each module
|
||||
Util.setCurrentSystemData({
|
||||
systemData: system.getSystemData(),
|
||||
mapId: parseInt( system.attr('data-mapid') )
|
||||
});
|
||||
let systemData = system.getSystemData();
|
||||
systemData.mapId = parseInt(system.attr('data-mapid')) || 0;
|
||||
Util.setCurrentSystemData(systemData);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -1869,10 +1868,10 @@ define([
|
||||
if(tooltipData.maxStableTime){
|
||||
data.maxStableTime = tooltipData.maxStableTime + ' h';
|
||||
}
|
||||
if(tooltipData.signatureStrength){
|
||||
data.signatureStrength = parseFloat(tooltipData.signatureStrength).toLocaleString() + ' %';
|
||||
if(tooltipData.scanWormholeStrength){
|
||||
data.scanWormholeStrength = parseFloat(tooltipData.scanWormholeStrength).toLocaleString() + ' %';
|
||||
}else{
|
||||
data.signatureStrength = '<span class="txt-color txt-color-grayLight">unknown</span>';
|
||||
data.scanWormholeStrength = '<span class="txt-color txt-color-grayLight">unknown</span>';
|
||||
}
|
||||
|
||||
let title = tooltipData.name;
|
||||
|
||||
@@ -447,7 +447,7 @@ define([
|
||||
// start user update trigger after map loaded
|
||||
updateTimeouts.userUpdate = setTimeout(() => {
|
||||
triggerUserUpdatePing();
|
||||
}, 1000);
|
||||
}, 500);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -353,7 +353,7 @@ define([
|
||||
|
||||
// request "additional" system data (e.g. Structures, Description)
|
||||
// -> this is used to update some modules after initial draw
|
||||
let promiseRequestData = Util.request('GET', 'system', currentSystemData.systemData.id, {mapId: currentSystemData.mapId});
|
||||
let promiseRequestData = Util.request('GET', 'system', currentSystemData.id, {mapId: currentSystemData.mapId});
|
||||
|
||||
// draw modules -------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -361,22 +361,22 @@ define([
|
||||
let secondCell = tabContentElement.find('.' + config.mapTabContentCellSecond);
|
||||
|
||||
// draw system info module
|
||||
let promiseInfo = drawModule(firstCell, SystemInfoModule, currentSystemData.mapId, currentSystemData.systemData);
|
||||
let promiseInfo = drawModule(firstCell, SystemInfoModule, currentSystemData.mapId, currentSystemData);
|
||||
|
||||
// draw system graph module
|
||||
drawModule(firstCell, SystemGraphModule, currentSystemData.mapId, currentSystemData.systemData);
|
||||
drawModule(firstCell, SystemGraphModule, currentSystemData.mapId, currentSystemData);
|
||||
|
||||
// draw signature table module
|
||||
let promiseSignature = drawModule(firstCell, SystemSignatureModule, currentSystemData.mapId, currentSystemData.systemData);
|
||||
let promiseSignature = drawModule(firstCell, SystemSignatureModule, currentSystemData.mapId, currentSystemData);
|
||||
|
||||
// draw system routes module
|
||||
drawModule(secondCell, SystemRouteModule, currentSystemData.mapId, currentSystemData.systemData);
|
||||
drawModule(secondCell, SystemRouteModule, currentSystemData.mapId, currentSystemData);
|
||||
|
||||
// draw system intel module
|
||||
let promiseIntel = drawModule(secondCell, SystemIntelModule, currentSystemData.mapId, currentSystemData.systemData);
|
||||
let promiseIntel = drawModule(secondCell, SystemIntelModule, currentSystemData.mapId, currentSystemData);
|
||||
|
||||
// draw system killboard module
|
||||
drawModule(secondCell, SystemKillboardModule, currentSystemData.mapId, currentSystemData.systemData);
|
||||
drawModule(secondCell, SystemKillboardModule, currentSystemData.mapId, currentSystemData);
|
||||
|
||||
// update some modules ------------------------------------------------------------------------------------
|
||||
promiseDrawAll.push(promiseRequestData, promiseInfo, promiseSignature, promiseIntel);
|
||||
@@ -479,7 +479,7 @@ define([
|
||||
|
||||
if(
|
||||
currentSystemData &&
|
||||
systemData.id === currentSystemData.systemData.id
|
||||
systemData.id === currentSystemData.id
|
||||
){
|
||||
// trigger system update events
|
||||
let tabContentElement = $('#' + config.mapTabIdPrefix + systemData.mapId + '.' + config.mapTabContentClass);
|
||||
|
||||
@@ -11,7 +11,6 @@ define([
|
||||
'app/map/util',
|
||||
'app/map/contextmenu',
|
||||
'slidebars',
|
||||
'text!img/logo.svg!strip',
|
||||
'text!templates/layout/header_map.html',
|
||||
'text!templates/layout/footer_map.html',
|
||||
'dialog/notification',
|
||||
@@ -27,7 +26,7 @@ define([
|
||||
'dialog/credit',
|
||||
'xEditable',
|
||||
'app/module_map'
|
||||
], ($, Init, Util, Logging, Mustache, MapUtil, MapContextMenu, SlideBars, TplLogo, TplHead, TplFooter) => {
|
||||
], ($, Init, Util, Logging, Mustache, MapUtil, MapContextMenu, SlideBars, TplHead, TplFooter) => {
|
||||
|
||||
'use strict';
|
||||
|
||||
@@ -152,6 +151,7 @@ define([
|
||||
loadFooter(pageElement),
|
||||
loadLeftMenu(pageMenuLeftElement),
|
||||
loadRightMenu(pageMenuRightElement),
|
||||
loadSVGs()
|
||||
]).then(payload => Promise.all([
|
||||
setMenuObserver(payload[2].data),
|
||||
setMenuObserver(payload[3].data),
|
||||
@@ -413,6 +413,35 @@ define([
|
||||
return new Promise(executor);
|
||||
};
|
||||
|
||||
/**
|
||||
* load standalone <svg>´s into DOM
|
||||
* -> SVGs can be used by referencing its ID e.g.:
|
||||
* <svg width="12px" height="12px"><use xlink:href="#pf-svg-swords"/></svg>
|
||||
* @returns {Promise<any>}
|
||||
*/
|
||||
let loadSVGs = () => {
|
||||
|
||||
let executor = resolve => {
|
||||
let parentElement = $('body');
|
||||
|
||||
let svgPaths = [
|
||||
'img/svg/logo.svg',
|
||||
'img/svg/swords.svg'
|
||||
].map(path => 'text!' + path + '!strip');
|
||||
|
||||
requirejs(svgPaths, (...SVGs) => {
|
||||
parentElement.append.apply(parentElement, SVGs);
|
||||
|
||||
resolve({
|
||||
action: 'loadSVGs',
|
||||
data: {}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
return new Promise(executor);
|
||||
};
|
||||
|
||||
/**
|
||||
* load page header
|
||||
* @param pageElement
|
||||
@@ -423,7 +452,6 @@ define([
|
||||
let executor = resolve => {
|
||||
let moduleData = {
|
||||
id: config.pageHeaderId,
|
||||
logo: () => Mustache.render(TplLogo, {}),
|
||||
brandLogo: config.menuHeadMenuLogoClass,
|
||||
popoverTriggerClass: Util.config.popoverTriggerClass,
|
||||
userCharacterClass: config.headUserCharacterClass,
|
||||
@@ -1026,7 +1054,7 @@ define([
|
||||
if(changedCharacter){
|
||||
// current character changed
|
||||
userInfoElement.find('span').text(Util.getObjVal(userData, 'character.name'));
|
||||
userInfoElement.find('img').attr('src', Init.url.ccpImageServer + '/Character/' + Util.getObjVal(userData, 'character.id') + '_32.jpg');
|
||||
userInfoElement.find('img').attr('src', Util.eveImageUrl('character', Util.getObjVal(userData, 'character.id')));
|
||||
}
|
||||
// init "character switch" popover
|
||||
userInfoElement.initCharacterSwitchPopover(userData);
|
||||
@@ -1094,9 +1122,8 @@ define([
|
||||
|
||||
if(isCurrentLocation && shipTypeId){
|
||||
// show ship image
|
||||
let shipSrc = Init.url.ccpImageServer + '/Render/' + shipTypeId + '_32.png';
|
||||
breadcrumbHtml += '<img class="pf-head-image --right" ';
|
||||
breadcrumbHtml += 'src="' + shipSrc + '" ';
|
||||
breadcrumbHtml += 'src="' + Util.eveImageUrl('render', shipTypeId) + '" ';
|
||||
breadcrumbHtml += 'title="' + shipTypeName + '" ';
|
||||
breadcrumbHtml += '>';
|
||||
}
|
||||
|
||||
@@ -93,6 +93,7 @@ define([
|
||||
let url = '/api/setup/' + element.attr('data-action');
|
||||
sendRequest(url, {
|
||||
type: element.attr('data-type'),
|
||||
countAll: element.attr('data-countall'),
|
||||
count: 0,
|
||||
offset: 0
|
||||
}, {
|
||||
@@ -116,10 +117,10 @@ define([
|
||||
* @param responseData
|
||||
*/
|
||||
let updateIndexCount = (context, responseData) => {
|
||||
let countElement = context.target.closest('.row').children().eq(1).find('kbd');
|
||||
let countElement = context.target.closest('tr').children().eq(1).find('kbd');
|
||||
countElement.text(responseData.countBuildAll + '/' + responseData.countAll);
|
||||
countElement.removeClass('txt-color-success txt-color-danger txt-color-warning');
|
||||
if(responseData.countBuildAll >=responseData.countAll){
|
||||
if(responseData.countBuildAll >= responseData.countAll){
|
||||
countElement.addClass('txt-color-success');
|
||||
}else if(responseData.countBuildAll > 0){
|
||||
countElement.addClass('txt-color-warning');
|
||||
@@ -127,6 +128,12 @@ define([
|
||||
countElement.addClass('txt-color-danger');
|
||||
}
|
||||
|
||||
// update 'subCount' element (shows e.g. invType count)
|
||||
if(responseData.subCount){
|
||||
let subCountElement = context.target.closest('tr').children().eq(2).find('kbd');
|
||||
subCountElement.text(responseData.subCount.countBuildAll + '/' + subCountElement.attr('data-countall'));
|
||||
}
|
||||
|
||||
context.target.find('.btn-progress').html(' ' + responseData.progress + '%').css('width', responseData.progress + '%');
|
||||
|
||||
// send next chunk of rows -> import only
|
||||
@@ -136,6 +143,7 @@ define([
|
||||
){
|
||||
sendRequest(context.url, {
|
||||
type: responseData.type,
|
||||
countAll: responseData.countAll,
|
||||
count: responseData.count,
|
||||
offset: responseData.offset
|
||||
}, {
|
||||
|
||||
@@ -38,7 +38,8 @@ define([
|
||||
switch(render(val)){
|
||||
case 'green': return 'ok';
|
||||
case 'yellow': return 'degraded: Slow or potentially dropping requests';
|
||||
case 'red': return 'bad: Most requests are not succeeding and/or are very slow (5s+) on average';
|
||||
case 'orange': return 'bad: Most requests are not succeeding and/or are very slow (5s+) on average';
|
||||
case 'red': return 'error: Status data not available. Either offline or any other fatal error';
|
||||
default: return 'unknown';
|
||||
}
|
||||
};
|
||||
|
||||
@@ -225,7 +225,7 @@ define([
|
||||
paging: true,
|
||||
lengthMenu: [[5, 10, 20, 50, -1], [5, 10, 20, 50, 'All']],
|
||||
ordering: true,
|
||||
order: [14, 'desc'],
|
||||
order: [15, 'desc'],
|
||||
hover: false,
|
||||
data: mapData.data.systems,
|
||||
columnDefs: [],
|
||||
@@ -312,6 +312,22 @@ define([
|
||||
title: 'region',
|
||||
data: 'region.name',
|
||||
className: 'min-screen-l',
|
||||
},{
|
||||
name: 'sovereignty',
|
||||
title: 'sov.',
|
||||
width: 30,
|
||||
className: 'text-center',
|
||||
data: 'sovereignty.alliance.ticker',
|
||||
defaultContent: '',
|
||||
render: {
|
||||
display: (cellData, type, rowData, meta) => {
|
||||
let value = '';
|
||||
if(cellData){
|
||||
value = '<' + cellData + '>';
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
},{
|
||||
name: 'planets',
|
||||
title: '<i class="fas fa-circle" title="planets" data-toggle="tooltip"></i>',
|
||||
@@ -748,7 +764,7 @@ define([
|
||||
_: function(data, type, row, meta){
|
||||
let value = data;
|
||||
if(data && type === 'display'){
|
||||
value = '<img src="' + Init.url.ccpImageServer + '/Render/' + value.typeId + '_32.png" title="' + value.typeName + '" data-toggle="tooltip" />';
|
||||
value = '<img src="' + Util.eveImageUrl('render', value.typeId) + '" title="' + value.typeName + '" data-toggle="tooltip" />';
|
||||
}
|
||||
return value;
|
||||
}
|
||||
@@ -786,7 +802,7 @@ define([
|
||||
_: function(data, type, row, meta){
|
||||
let value = data;
|
||||
if(type === 'display'){
|
||||
value = '<img src="' + Init.url.ccpImageServer + '/Character/' + value + '_32.jpg" />';
|
||||
value = '<img src="' + Util.eveImageUrl('character', value) + '"/>';
|
||||
}
|
||||
return value;
|
||||
}
|
||||
@@ -826,7 +842,7 @@ define([
|
||||
_: function(data, type, row, meta){
|
||||
let value = data;
|
||||
if(type === 'display'){
|
||||
value = '<img src="' + Init.url.ccpImageServer + '/Corporation/' + value.id + '_32.png" />';
|
||||
value = '<img src="' + Util.eveImageUrl('corporation', value.id) + '"/>';
|
||||
}
|
||||
return value;
|
||||
}
|
||||
@@ -1109,7 +1125,7 @@ define([
|
||||
_: function(data, type, row, meta){
|
||||
let value = data;
|
||||
if(type === 'display'){
|
||||
value = '<img src="' + Init.url.ccpImageServer + '/Character/' + value + '_32.jpg" />';
|
||||
value = '<img src="' + Util.eveImageUrl('character', value) + '"/>';
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -130,7 +130,7 @@ define([
|
||||
data: 'character',
|
||||
render: {
|
||||
_: function(data, type, row, meta){
|
||||
return '<img src="' + Init.url.ccpImageServer + '/Character/' + data.id + '_32.jpg" />';
|
||||
return '<img src="' + Util.eveImageUrl('character', parseInt(data.id)) + '"/>';
|
||||
}
|
||||
}
|
||||
},{
|
||||
|
||||
@@ -38,19 +38,19 @@ define([
|
||||
|
||||
switch(data.categoryType){
|
||||
case 'character':
|
||||
imagePath = Init.url.ccpImageServer + '/Character/' + data.id + '_32.jpg';
|
||||
imagePath = Util.eveImageUrl('character', data.id);
|
||||
break;
|
||||
case 'corporation':
|
||||
imagePath = Init.url.ccpImageServer + '/Corporation/' + data.id + '_32.png';
|
||||
imagePath = Util.eveImageUrl('corporation', data.id);
|
||||
break;
|
||||
case 'alliance':
|
||||
imagePath = Init.url.ccpImageServer + '/Alliance/' + data.id + '_32.png';
|
||||
imagePath = Util.eveImageUrl('alliance', data.id);
|
||||
break;
|
||||
case 'inventoryType':
|
||||
imagePath = Init.url.ccpImageServer + '/Type/' + data.id + '_32.png';
|
||||
imagePath = Util.eveImageUrl('type', data.id);
|
||||
break;
|
||||
case 'render':
|
||||
imagePath = Init.url.ccpImageServer + '/Render/' + data.id + '_32.png';
|
||||
imagePath = Util.eveImageUrl('render', data.id);
|
||||
break;
|
||||
case 'station':
|
||||
iconName = 'fa-home';
|
||||
|
||||
@@ -774,7 +774,7 @@ define([
|
||||
_: function(data, type, row){
|
||||
let value = data.typeId;
|
||||
if(type === 'display'){
|
||||
value = '<img src="' + Init.url.ccpImageServer + '/Render/' + value + '_32.png" title="' + data.typeName + '" data-toggle="tooltip" />';
|
||||
value = '<img src="' + Util.eveImageUrl('render', value) + '" title="' + data.typeName + '" data-toggle="tooltip" />';
|
||||
}
|
||||
return value;
|
||||
}
|
||||
@@ -794,7 +794,7 @@ define([
|
||||
_: (cellData, type, rowData, meta) => {
|
||||
let value = cellData.name;
|
||||
if(type === 'display'){
|
||||
value = '<img src="' + Init.url.ccpImageServer + '/Character/' + cellData.id + '_32.jpg" title="' + value + '" data-toggle="tooltip" />';
|
||||
value = '<img src="' + Util.eveImageUrl('character', cellData.id) + '" title="' + value + '" data-toggle="tooltip" />';
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -265,7 +265,7 @@ define([
|
||||
for(let [graphKey, graphConfig] of Object.entries(config.systemGraphs)){
|
||||
rowElement.append(
|
||||
$('<div>', {
|
||||
class: ['col-xs-12', 'col-sm-6', 'col-md-4'].join(' ')
|
||||
class: ['col-xs-12', 'col-sm-4'].join(' ')
|
||||
}).append(
|
||||
$('<div>', {
|
||||
class: config.moduleHeadClass
|
||||
|
||||
@@ -27,7 +27,8 @@ define([
|
||||
typeLinkClass: 'pf-system-info-type', // class for "type" name
|
||||
urlLinkClass: 'pf-system-info-url', // class for "url" copy link
|
||||
|
||||
// info table
|
||||
// info col/table
|
||||
systemInfoSectionClass: 'pf-system-info-section', // class for system info section
|
||||
systemInfoTableClass: 'pf-module-table', // class for system info table
|
||||
systemInfoNameClass: 'pf-system-info-name', // class for "name" information element
|
||||
systemInfoEffectClass: 'pf-system-info-effect', // class for "effect" information element
|
||||
@@ -37,9 +38,21 @@ define([
|
||||
systemInfoWormholeClass: 'pf-system-info-wormhole-', // class prefix for static wormhole element
|
||||
|
||||
// description field
|
||||
descriptionAreaClass: 'pf-system-info-description-area', // class for "description" area
|
||||
descriptionSectionClass: 'pf-system-description-section', // class for system description section
|
||||
descriptionAreaClass: 'pf-system-info-description-area', // class for description area
|
||||
addDescriptionButtonClass: 'pf-system-info-description-button', // class for "add description" button
|
||||
descriptionTextareaElementClass: 'pf-system-info-description', // class for "description" textarea element (Summernote)
|
||||
descriptionTextareaElementClass: 'pf-system-info-description', // class for description textarea element (Summernote)
|
||||
|
||||
// sovereignty col/table
|
||||
systemSovSectionClass: 'pf-system-sov-section', // class for system sov. section
|
||||
systemSovTableClass: 'pf-module-table', // class for system sov. table
|
||||
systemSovFwContestedRowClass: 'pf-system-sov-fw-contested-row', // class for "contested" sov. table row
|
||||
systemSovFwOccupationRowClass: 'pf-system-sov-fw-occupation-row', // class for "-occupation" sov. table row
|
||||
systemSovFwContestedClass: 'pf-system-sov-fw-contested',
|
||||
systemSovFwPercentageClass: 'pf-system-sov-fw-percentage',
|
||||
systemSovFwOccupationClass: 'pf-system-sov-fw-occupation',
|
||||
systemSovFwOccupationImageClass: 'pf-system-sov-fw-occupation-image',
|
||||
systemSovFwStatusIconClass: 'pf-system-sov-fw-status-icon',
|
||||
|
||||
// fonts
|
||||
fontTriglivianClass: 'pf-triglivian', // class for "Triglivian" names (e.g. Abyssal systems)
|
||||
@@ -115,12 +128,64 @@ define([
|
||||
}
|
||||
}
|
||||
|
||||
// update faction warfare rows ----------------------------------------------------------------------------
|
||||
let fwContestedRow = moduleElement.find('.' + config.systemSovFwContestedRowClass);
|
||||
let fwOccupationRow = moduleElement.find('.' + config.systemSovFwOccupationRowClass);
|
||||
if(systemData.factionWar){
|
||||
let contested = String(Util.getObjVal(systemData.factionWar, 'contested') || '');
|
||||
let percentage = parseInt(Util.getObjVal(systemData.factionWar, 'victoryPercentage')) || 0;
|
||||
let occupierFaction = Util.getObjVal(systemData.factionWar, 'occupierFaction');
|
||||
|
||||
let statusColor = 'red';
|
||||
if(occupierFaction){
|
||||
// system is "occupied" by hostile "occupierFaction" (stable)
|
||||
// -> hide percent
|
||||
statusColor = '#d9534f';
|
||||
percentage += '%';
|
||||
}else if('uncontested' === contested){
|
||||
// system is "uncontested" and owned by default ownerFaction (stable)
|
||||
// -> hide percent
|
||||
statusColor = '#4f9e4f';
|
||||
percentage = 'stable';
|
||||
}else if('contested' === contested){
|
||||
// system is "contested", 0%-99% percentage
|
||||
statusColor = '#e28a0d';
|
||||
percentage += '%';
|
||||
}else if(
|
||||
'vulnerable' === contested ||
|
||||
'captured' === contested
|
||||
){
|
||||
// system is "vulnerable", 100% percentage
|
||||
// -> "captured" state is might be the same?!
|
||||
statusColor = '#d747d6';
|
||||
percentage = '100%';
|
||||
}
|
||||
|
||||
fwContestedRow.find('.' + config.systemSovFwStatusIconClass)[0].style.setProperty('--color', statusColor);
|
||||
fwContestedRow.find('.' + config.systemSovFwContestedClass).text(contested);
|
||||
fwContestedRow.find('.' + config.systemSovFwPercentageClass).text(percentage);
|
||||
fwContestedRow.show();
|
||||
|
||||
let occupierFactionImage = Util.eveImageUrl('alliance', (occupierFaction ? occupierFaction.id : 0), 64);
|
||||
let occupierFactionName = occupierFaction ? occupierFaction.name : '';
|
||||
|
||||
fwOccupationRow.find('.' + config.systemSovFwOccupationImageClass)[0].style.setProperty('--bg-image', 'url(\'' + occupierFactionImage + '\')');
|
||||
fwOccupationRow.find('.' + config.systemSovFwOccupationClass).text(occupierFactionName);
|
||||
if(occupierFaction){
|
||||
fwOccupationRow.show();
|
||||
}
|
||||
}else{
|
||||
fwContestedRow.hide();
|
||||
fwOccupationRow.hide();
|
||||
}
|
||||
|
||||
if(setUpdated){
|
||||
moduleElement.data('updated', systemData.updated.updated);
|
||||
}
|
||||
}
|
||||
|
||||
moduleElement.find('.' + config.descriptionAreaClass).hideLoadingAnimation();
|
||||
moduleElement.find('.' + config.systemSovSectionClass + ' .' + Util.config.dynamicAreaClass).hideLoadingAnimation();
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -135,6 +200,56 @@ define([
|
||||
// store systemId -> module can be updated with the correct data
|
||||
moduleElement.data('id', systemData.id);
|
||||
|
||||
// system "sovereignty" data
|
||||
// "primary" data is eigther "alliance" -> 0.0 space
|
||||
// or "faction" -> Empire Regions (LS, HS)
|
||||
let sovereigntyDefault = {
|
||||
row1Label: 'Sov.',
|
||||
row1Val: '???',
|
||||
row1Img: undefined,
|
||||
row1ImgTitle: undefined,
|
||||
row2Label: undefined,
|
||||
row2Val: undefined,
|
||||
row3Label: undefined,
|
||||
row3Val: undefined
|
||||
};
|
||||
|
||||
let sovereigntyPrimary;
|
||||
let sovereigntySecondary;
|
||||
|
||||
if(systemData.sovereignty){
|
||||
let sovDataFact = Util.getObjVal(systemData.sovereignty, 'faction');
|
||||
let sovDataAlly = Util.getObjVal(systemData.sovereignty, 'alliance');
|
||||
let sovDataCorp = Util.getObjVal(systemData.sovereignty, 'corporation');
|
||||
|
||||
if(sovDataFact){
|
||||
sovereigntyPrimary = {
|
||||
row1Val: 'Faction',
|
||||
row1Img: Util.eveImageUrl('alliance', sovDataFact.id, 64),
|
||||
row1ImgTitle: sovDataFact.name,
|
||||
row2Val: sovDataFact.name
|
||||
};
|
||||
}else{
|
||||
if(sovDataAlly){
|
||||
sovereigntyPrimary = {
|
||||
row1Val: 'Alliance',
|
||||
row1Img: Util.eveImageUrl('alliance', sovDataAlly.id, 64),
|
||||
row1ImgTitle: sovDataAlly.name,
|
||||
row2Val: '<' + sovDataAlly.ticker + '>',
|
||||
row3Label: 'Ally',
|
||||
row3Val: sovDataAlly.name
|
||||
};
|
||||
}
|
||||
if(sovDataCorp){
|
||||
sovereigntySecondary = {
|
||||
row1Label: 'Corp',
|
||||
row1Val: sovDataCorp.name,
|
||||
row1Img: Util.eveImageUrl('corporation', sovDataCorp.id, 64)
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// system "static" wh data
|
||||
let staticsData = [];
|
||||
if(
|
||||
@@ -152,9 +267,15 @@ define([
|
||||
|
||||
let data = {
|
||||
system: systemData,
|
||||
sovereigntyPrimary: sovereigntyPrimary ? Object.assign({}, sovereigntyDefault, sovereigntyPrimary) : undefined,
|
||||
sovereigntySecondary: sovereigntySecondary ? Object.assign({}, sovereigntyDefault, sovereigntySecondary) : undefined,
|
||||
static: staticsData,
|
||||
moduleHeadlineIconClass: config.moduleHeadlineIconClass,
|
||||
tableClass: config.systemInfoTableClass,
|
||||
infoSectionClass: config.systemInfoSectionClass,
|
||||
descriptionSectionClass: config.descriptionSectionClass,
|
||||
sovSectionClass: config.systemSovSectionClass,
|
||||
infoTableClass: config.systemInfoTableClass,
|
||||
sovTableClass: config.systemSovTableClass,
|
||||
nameInfoClass: config.systemInfoNameClass,
|
||||
effectInfoClass: config.systemInfoEffectClass,
|
||||
planetsInfoClass: config.systemInfoPlanetsClass,
|
||||
@@ -162,6 +283,15 @@ define([
|
||||
statusInfoClass: config.systemInfoStatusLabelClass,
|
||||
popoverTriggerClass: Util.config.popoverTriggerClass,
|
||||
|
||||
// sovereignty table
|
||||
sovFwContestedRowClass: config.systemSovFwContestedRowClass,
|
||||
sovFwOccupationRowClass: config.systemSovFwOccupationRowClass,
|
||||
sovFwContestedInfoClass: config.systemSovFwContestedClass,
|
||||
sovFwPercentageInfoClass: config.systemSovFwPercentageClass,
|
||||
sovFwOccupationInfoClass: config.systemSovFwOccupationClass,
|
||||
sovFwOccupationImageClass: config.systemSovFwOccupationImageClass,
|
||||
sovFwStatusIconClass: config.systemSovFwStatusIconClass,
|
||||
|
||||
systemUrl: MapUtil.getMapDeeplinkUrl(mapId, systemData.id),
|
||||
systemTypeName: MapUtil.getSystemTypeInfo(systemData.type.id, 'name'),
|
||||
systemIsWormhole: MapUtil.getSystemTypeInfo(systemData.type.id, 'name') === 'w-space',
|
||||
@@ -194,19 +324,22 @@ define([
|
||||
systemConstellationLinkClass: config.constellationLinkClass,
|
||||
systemRegionLinkClass: config.regionLinkClass,
|
||||
systemTypeLinkClass: config.typeLinkClass,
|
||||
systemUrlLinkClass: config.urlLinkClass
|
||||
systemUrlLinkClass: config.urlLinkClass,
|
||||
ccpImageServerUrl: Init.url.ccpImageServer,
|
||||
};
|
||||
|
||||
requirejs(['text!templates/modules/system_info.html', 'mustache', 'summernote.loader'], (template, Mustache, Summernote) => {
|
||||
let content = Mustache.render(template, data);
|
||||
moduleElement.append(content);
|
||||
|
||||
let sovSectionArea = moduleElement.find('.' + config.systemSovSectionClass + ' .' + Util.config.dynamicAreaClass);
|
||||
let descriptionArea = moduleElement.find('.' + config.descriptionAreaClass);
|
||||
let descriptionButton = moduleElement.find('.' + config.addDescriptionButtonClass);
|
||||
let descriptionTextareaElement = moduleElement.find('.' + config.descriptionTextareaElementClass);
|
||||
|
||||
// lock "description" field until first update
|
||||
descriptionArea.showLoadingAnimation();
|
||||
sovSectionArea.showLoadingAnimation();
|
||||
|
||||
// WYSIWYG init on button click ---------------------------------------------------------------------------
|
||||
descriptionButton.on('click', function(e){
|
||||
|
||||
@@ -452,7 +452,7 @@ define([
|
||||
_: function(data, type, row, meta){
|
||||
let value = data;
|
||||
if(type === 'display' && value){
|
||||
value = '<img src="' + Init.url.ccpImageServer + '/Type/' + value + '_32.png" />';
|
||||
value = '<img src="' + Util.eveImageUrl('type', value) +'"/>';
|
||||
}
|
||||
return value;
|
||||
}
|
||||
@@ -486,7 +486,7 @@ define([
|
||||
let value = data;
|
||||
if(type === 'display' && value){
|
||||
value = '<a href="https://zkillboard.com/corporation/' + data + '/" target="_blank" rel="noopener">';
|
||||
value += '<img src="' + Init.url.ccpImageServer + '/Corporation/' + data + '_32.png" />';
|
||||
value += '<img src="' + Util.eveImageUrl('corporation', data) + '"/>';
|
||||
value += '</a>';
|
||||
}
|
||||
return value;
|
||||
@@ -625,7 +625,7 @@ define([
|
||||
'<tr class="group">' +
|
||||
'<td></td>' +
|
||||
'<td class="' + config.tableCellImageClass + '">' +
|
||||
'<img src="' + Init.url.ccpImageServer + '/Corporation/' + group.id + '_32.png" />' +
|
||||
'<img src="' + Util.eveImageUrl('corporation', group.id) + '"/>' +
|
||||
'</td>' +
|
||||
'<td colspan="' + (columnCount - 2 ) + '">' + group.name + '</td>' +
|
||||
'</tr>'
|
||||
|
||||
@@ -552,7 +552,7 @@ define([
|
||||
userData: userData,
|
||||
otherCharacters: () => {
|
||||
return userData.characters.filter((character, i) => {
|
||||
let characterImage = Init.url.ccpImageServer + '/Character/' + character.id + '_32.jpg';
|
||||
let characterImage = eveImageUrl('character', character.id);
|
||||
// preload image (prevent UI flicker
|
||||
let img= new Image();
|
||||
img.src = characterImage;
|
||||
@@ -852,6 +852,23 @@ define([
|
||||
*/
|
||||
let showVersionInfo = () => Con.showVersionInfo(getVersion());
|
||||
|
||||
/**
|
||||
* get CCP image URLs for
|
||||
* @param type 'alliance'|'corporation'|'character'|'type'|'render'
|
||||
* @param id
|
||||
* @param size
|
||||
* @returns {boolean}
|
||||
*/
|
||||
let eveImageUrl = (type, id, size = 32) => {
|
||||
let url = false;
|
||||
if(typeof type === 'string' && typeof id === 'number' && typeof size === 'number'){
|
||||
type = type.capitalize();
|
||||
let format = type === 'Character' ? 'jpg' : 'png';
|
||||
url = Init.url.ccpImageServer + '/' + type + '/' + id + '_' + size + '.' + format;
|
||||
}
|
||||
return url;
|
||||
};
|
||||
|
||||
/**
|
||||
* polyfill for "passive" events
|
||||
* -> see https://github.com/zzarcon/default-passive-events
|
||||
@@ -2303,26 +2320,28 @@ define([
|
||||
* get a HTML table with universe region information
|
||||
* e.g. for popover
|
||||
* @param regionName
|
||||
* @param faction
|
||||
* @param sovereignty
|
||||
* @returns {string}
|
||||
*/
|
||||
let getSystemRegionTable = (regionName, faction) => {
|
||||
let getSystemRegionTable = (regionName, sovereignty) => {
|
||||
let data = [{label: 'Region', value: regionName}];
|
||||
if(sovereignty){
|
||||
if(sovereignty.faction){
|
||||
data.push({label: 'Sov. Faction', value: sovereignty.faction.name});
|
||||
}
|
||||
if(sovereignty.alliance){
|
||||
data.push({label: 'Sov. Ally', value: sovereignty.alliance.name});
|
||||
}
|
||||
}
|
||||
|
||||
let table = '<table>';
|
||||
table += '<tr>';
|
||||
table += '<td>';
|
||||
table += 'Region';
|
||||
table += '</td>';
|
||||
table += '<td class="text-right">';
|
||||
table += regionName;
|
||||
table += '</td>';
|
||||
table += '</tr>';
|
||||
table += '<tr>';
|
||||
if(faction){
|
||||
for(let rowData of data){
|
||||
table += '<tr>';
|
||||
table += '<td>';
|
||||
table += 'Faction';
|
||||
table += rowData.label;
|
||||
table += '</td>';
|
||||
table += '<td class="text-right">';
|
||||
table += faction.name;
|
||||
table += rowData.value;
|
||||
table += '</td>';
|
||||
table += '</tr>';
|
||||
}
|
||||
@@ -3425,6 +3444,7 @@ define([
|
||||
config: config,
|
||||
getVersion: getVersion,
|
||||
showVersionInfo: showVersionInfo,
|
||||
eveImageUrl: eveImageUrl,
|
||||
initPrototypes: initPrototypes,
|
||||
initDefaultBootboxConfig: initDefaultBootboxConfig,
|
||||
initDefaultConfirmationConfig: initDefaultConfirmationConfig,
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
<p>Shows status information for external used APIs. Provides a general health indicator per route and method.</p>
|
||||
|
||||
<h4 class="pf-dynamic-area">{{ apiData.name }}
|
||||
<span class="pull-right" title="{{#statusTitle}}{{ apiData.statusColor }}{{/statusTitle}}"><i class="fas fa-fw fa-circle txt-color txt-color-{{ apiData.statusColor }}"></i></span>
|
||||
<h4 class="pf-dynamic-area">
|
||||
<span class="pf-help-default" title="{{#statusTitle}}{{ apiData.statusColor }}{{/statusTitle}}">
|
||||
<i class="fas fa-fw fa-circle txt-color txt-color-{{ apiData.statusColor }}"></i>
|
||||
</span> {{ apiData.name }}
|
||||
<span class="pull-right pf-help-default" title="{{#apiData.cacheExpire}}{{ apiData.cacheExpire }}{{/apiData.cacheExpire}}">{{ apiData.cache }}</span>
|
||||
</h4>
|
||||
|
||||
<dl class="dl-horizontal" style="float: left;">
|
||||
@@ -42,7 +45,7 @@
|
||||
<tbody>
|
||||
{{#apiData.routes}}
|
||||
<tr>
|
||||
<td class="text-center txt-color txt-color-grayLight txt-color-{{ status }}" title="{{#statusTitle}}{{status}}{{/statusTitle}}">
|
||||
<td class="text-center pf-help-default txt-color txt-color-grayLight txt-color-{{ status }}" title="{{#statusTitle}}{{status}}{{/statusTitle}}">
|
||||
<i class="fas fa-fw fa-circle initialism"></i>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
|
||||
@@ -44,8 +44,8 @@
|
||||
<td class="text-right" data-order="{{massIndividual}}">{{#massValue}}{{massIndividual}}{{/massValue}}</td>
|
||||
<td class="text-right" data-order="{{massRegeneration}}">{{#massValue}}{{massRegeneration}}{{/massValue}}</td>
|
||||
<td class="text-right txt-color {{^maxStableTime}}txt-color-grayLight{{/maxStableTime}}" data-order="{{maxStableTime}}">{{#formatTime}}{{maxStableTime}}{{/formatTime}}</td>
|
||||
<td class="text-right txt-color {{^signatureStrength}}txt-color-grayLight{{/signatureStrength}}" data-order="{{signatureStrength}}">
|
||||
{{#sigStrengthValue}}{{signatureStrength}}{{/sigStrengthValue}}
|
||||
<td class="text-right txt-color {{^scanWormholeStrength}}txt-color-grayLight{{/scanWormholeStrength}}" data-order="{{scanWormholeStrength}}">
|
||||
{{#sigStrengthValue}}{{scanWormholeStrength}}{{/sigStrengthValue}}
|
||||
</td>
|
||||
</tr>
|
||||
{{/wormholes}}
|
||||
|
||||
@@ -1,13 +1,9 @@
|
||||
|
||||
{{! Render the *.svg logo. So it can be used through the "use" tag}}
|
||||
{{{logo}}}
|
||||
|
||||
<nav id="{{id}}" class="navbar navbar-default pf-head" role="navigation">
|
||||
<div class="container-fluid">
|
||||
<div class="navbar-header pull-left">
|
||||
<a class="navbar-brand pf-head-menu" href="">
|
||||
<svg class="{{brandLogo}}" width="24px" height="24px">
|
||||
<use xlink:href="#pf-logo"/>
|
||||
<use xlink:href="#pf-svg-logo"/>
|
||||
</svg>
|
||||
Menu
|
||||
</a>
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
</check>
|
||||
|
||||
<td
|
||||
class="{{ isset(@requirement.required) ? 'text-right col-md-3 text-right' : 'text-right col-md-6 text-right' }}"
|
||||
class="{{ isset(@requirement.required) ? 'text-right col-xs-2 col-md-3 text-right' : 'text-right col-xs-4 col-md-6 text-right' }}"
|
||||
colspan="{{ isset(@requirement.required) ? '1' : '2' }}"
|
||||
>
|
||||
<check if="{{ @requirement.check }}">
|
||||
@@ -55,7 +55,7 @@
|
||||
|
||||
<check if="{{ @requirement.task }}">
|
||||
<true>
|
||||
<td class="text-right col-md-2 no-padding text-right">
|
||||
<td class="text-right col-xs-{{ count(@requirement.task) * 2 }} col-md-{{ count(@requirement.task) * 2 }} no-padding text-right">
|
||||
<div class="btn-group btn-group-justified">
|
||||
<repeat group="{{ @requirement.task }}" key="{{ @taskKey }}" value="{{ @taskData }}">
|
||||
<a href="?{{ @taskData.action }}" class="btn btn-default {{ @taskData.btn }}" role="button">
|
||||
@@ -67,7 +67,7 @@
|
||||
</true>
|
||||
<false>
|
||||
{* no task data *}
|
||||
<td class="text-right col-md-1">
|
||||
<td class="text-right col-sm-1 col-md-1">
|
||||
<check if="{{ @requirement.check }}">
|
||||
<true>
|
||||
{* Check ok *}
|
||||
|
||||
@@ -35,30 +35,20 @@
|
||||
|
||||
<div class="row">
|
||||
|
||||
{{! info text ================================================================================================ }}
|
||||
<div class="col-xs-12 col-sm-9">
|
||||
<div class="pf-dynamic-area {{descriptionAreaClass}}">
|
||||
<div class="{{descriptionTextareaClass}} {{summernoteClass}}"></div>
|
||||
<i class="fas fa-fw fa-lg fa-pen pull-right {{moduleHeadlineIconClass}} {{descriptionButtonClass}}" data-toggle="tooltip" title="edit description"></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{! info table ================================================================================================ }}
|
||||
<div class="col-xs-12 col-sm-3">
|
||||
|
||||
{{! Info table ================================================================================================ }}
|
||||
<div class="col-xs-6 col-sm-3 {{infoSectionClass}}">
|
||||
<span data-toggle="tooltip" title="status" data-status="{{systemStatusId}}" class="label center-block {{statusInfoClass}} {{systemStatusClass}}">
|
||||
{{systemStatusLabel}}
|
||||
</span>
|
||||
|
||||
|
||||
<div class="pf-dynamic-area">
|
||||
<table class="table table-condensed pf-table-fixed {{tableClass}}">
|
||||
<table class="table table-condensed pf-table-fixed {{infoTableClass}}">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th class="text-right pf-system-info-name-cell">
|
||||
<th class="text-right pf-table-cell-ellipses-auto pf-system-info-name-cell">
|
||||
{{#system.shattered}}
|
||||
<i class="fas fa-fw fa-skull {{shatteredClass}}" data-toggle="tooltip" title="shattered"></i>
|
||||
<i class="fas fa-fw fa-skull {{shatteredClass}}" data-toggle="tooltip" title="shattered"></i>
|
||||
{{/system.shattered}}
|
||||
<span class="pf-help-default {{nameInfoClass}} {{#systemNameClass}}{{system.security}}{{/systemNameClass}}">{{system.name}}</span>
|
||||
</th>
|
||||
@@ -102,6 +92,77 @@
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{! Sovereignty table ========================================================================================= }}
|
||||
<div class="col-xs-6 col-sm-3 {{sovSectionClass}} {{^sovereigntyPrimary}}hidden{{/sovereigntyPrimary}}">
|
||||
<div class="pf-dynamic-area">
|
||||
<table class="table table-condensed pf-table-fixed {{sovTableClass}}">
|
||||
<colgroup>
|
||||
<col style="width: 40px;"/>
|
||||
<col/>
|
||||
<col style="width: 45px;"/>
|
||||
</colgroup>
|
||||
<thead>
|
||||
{{#sovereigntyPrimary}}
|
||||
<tr>
|
||||
<th>{{row1Label}}</th>
|
||||
<th class="text-right">{{row1Val}}</th>
|
||||
<th class="pf-table-cell-bg-image" rowspan="2">
|
||||
<div class="pf-table-cell-bg-image-wrapper pf-help-default" style="--bg-image: url('{{{row1Img}}}');" data-toggle="tooltip" title="{{row1ImgTitle}}"></div>
|
||||
</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>{{#row2Label}}{{row2Label}}{{/row2Label}}</th>
|
||||
<th class="text-right pf-table-cell-ellipses-auto">{{#row2Val}}{{row2Val}}{{/row2Val}}</th>
|
||||
</tr>
|
||||
{{/sovereigntyPrimary}}
|
||||
</thead>
|
||||
<tbody>
|
||||
{{#sovereigntyPrimary.row3Val}}
|
||||
<tr>
|
||||
<td>{{sovereigntyPrimary.row3Label}}</td>
|
||||
<td colspan="2" class="text-right pf-table-cell-ellipses-auto">{{sovereigntyPrimary.row3Val}}</td>
|
||||
</tr>
|
||||
{{/sovereigntyPrimary.row3Val}}
|
||||
{{#sovereigntySecondary}}
|
||||
<tr>
|
||||
<td>{{row1Label}}</td>
|
||||
<td colspan="2" class="text-right pf-table-cell-ellipses-auto">{{row1Val}}</td>
|
||||
</tr>
|
||||
{{/sovereigntySecondary}}
|
||||
<tr class="{{sovFwContestedRowClass}}">
|
||||
<td>
|
||||
<svg class="pf-system-info-svg pf-help-default" width="12px" height="12px" data-toggle="tooltip" title="Faction Warfare System">
|
||||
<use xlink:href="#pf-svg-swords"/>
|
||||
</svg>
|
||||
<i class="fas fa-flag {{sovFwStatusIconClass}}"></i>
|
||||
</td>
|
||||
<td class="text-right pf-table-cell-ellipses-auto {{sovFwContestedInfoClass}}"></td>
|
||||
<td class="text-right {{sovFwPercentageInfoClass}}"></td>
|
||||
</tr>
|
||||
<tr class="{{sovFwOccupationRowClass}}">
|
||||
<td></td>
|
||||
<td class="text-right pf-table-cell-ellipses-auto">occupied by</td>
|
||||
<td class="pf-table-cell-bg-image" rowspan="2">
|
||||
<div class="pf-table-cell-bg-image-wrapper pf-help-default {{sovFwOccupationImageClass}}"></div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="{{sovFwOccupationRowClass}}">
|
||||
<td colspan="2" class="text-right pf-table-cell-ellipses-auto {{sovFwOccupationInfoClass}}"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{! Description editor ======================================================================================== }}
|
||||
<div class="col-xs-12 col-sm-6 {{^sovereigntyPrimary}}col-sm-9{{/sovereigntyPrimary}} {{descriptionSectionClass}}">
|
||||
<div class="pf-dynamic-area {{descriptionAreaClass}}">
|
||||
<div class="{{descriptionTextareaClass}} {{summernoteClass}}"></div>
|
||||
<i class="fas fa-fw fa-lg fa-pen pull-right {{moduleHeadlineIconClass}} {{descriptionButtonClass}}" data-toggle="tooltip" title="edit description"></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@@ -23,11 +23,11 @@
|
||||
<td class="text-right">{{maxStableTime}}</td>
|
||||
</tr>
|
||||
{{/maxStableTime}}
|
||||
{{#signatureStrength}}
|
||||
{{#scanWormholeStrength}}
|
||||
<tr>
|
||||
<td>Sig strength</td>
|
||||
<td class="text-right">{{{signatureStrength}}}</td>
|
||||
<td class="text-right">{{{scanWormholeStrength}}}</td>
|
||||
</tr>
|
||||
{{/signatureStrength}}
|
||||
{{/scanWormholeStrength}}
|
||||
</table>
|
||||
|
||||
|
||||
@@ -17,10 +17,11 @@
|
||||
{{#api}}
|
||||
<h4>{{ name }}</h4>
|
||||
<ul class="fa-ul">
|
||||
<li><i class="fa-li fas fa-hdd"></i>{{cache}}</li>
|
||||
{{#status}}
|
||||
<li><i class="fa-li fas fa-server"></i><span class="txt-color {{#statusFormat}}{{statusColor}}{{/statusFormat}}">{{ status }}</span></li>
|
||||
{{/status}}
|
||||
<li><i class="fa-li fas fa-question"></i><a class="{{ apiStatusTriggerClass }}" href="#">info</a></li>
|
||||
<li><i class="fa-li fas fa-info"></i><a class="{{ apiStatusTriggerClass }}" href="#">info</a></li>
|
||||
</ul>
|
||||
{{/api}}
|
||||
</div>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user