933 lines
27 KiB
PHP
933 lines
27 KiB
PHP
<?php
|
||
/**
|
||
* Created by PhpStorm.
|
||
* User: exodus4d
|
||
* Date: 23.02.15
|
||
* Time: 23:56
|
||
*/
|
||
|
||
namespace Exodus4D\Pathfinder\Model\Pathfinder;
|
||
|
||
use DB\SQL\Schema;
|
||
use Exodus4D\Pathfinder\Lib\Logging;
|
||
use Exodus4D\Pathfinder\Lib\PriorityCacheStore;
|
||
use Exodus4D\Pathfinder\Controller\Ccp\Universe;
|
||
use Exodus4D\Pathfinder\Exception;
|
||
|
||
class SystemModel extends AbstractMapTrackingModel {
|
||
|
||
/**
|
||
* system position x max
|
||
*/
|
||
const MAX_POS_X = 2440;
|
||
|
||
/**
|
||
* system position y max
|
||
*/
|
||
const MAX_POS_Y = 1480;
|
||
|
||
/**
|
||
* max count of history signature data in cache
|
||
*/
|
||
const MAX_SIGNATURES_HISTORY_DATA = 10;
|
||
|
||
/**
|
||
* TTL for history signature data
|
||
*/
|
||
const TTL_SIGNATURES_HISTORY = 7200;
|
||
|
||
/**
|
||
* cache key prefix for getData(); result WITH log data
|
||
*/
|
||
const DATA_CACHE_KEY_SIGNATURES_HISTORY = 'HISTORY_SIGNATURES';
|
||
|
||
/**
|
||
* @var PriorityCacheStore
|
||
*/
|
||
protected static $priorityCacheStore;
|
||
|
||
/**
|
||
* @var string
|
||
*/
|
||
protected $table = 'system';
|
||
|
||
/**
|
||
* @var array
|
||
*/
|
||
protected $fieldConf = [
|
||
'active' => [
|
||
'type' => Schema::DT_BOOL,
|
||
'nullable' => false,
|
||
'default' => 1,
|
||
'index' => true,
|
||
'activity-log' => true
|
||
],
|
||
'mapId' => [
|
||
'type' => Schema::DT_INT,
|
||
'index' => true,
|
||
'belongs-to-one' => 'Exodus4D\Pathfinder\Model\Pathfinder\MapModel',
|
||
'constraint' => [
|
||
[
|
||
'table' => 'map',
|
||
'on-delete' => 'CASCADE'
|
||
]
|
||
]
|
||
],
|
||
'systemId' => [
|
||
'type' => Schema::DT_INT,
|
||
'index' => true,
|
||
'validate' => true
|
||
],
|
||
'alias' => [
|
||
'type' => Schema::DT_VARCHAR128,
|
||
'nullable' => false,
|
||
'default' => '',
|
||
'activity-log' => true
|
||
],
|
||
'typeId' => [
|
||
'type' => Schema::DT_INT,
|
||
'index' => true,
|
||
'belongs-to-one' => 'Exodus4D\Pathfinder\Model\Pathfinder\SystemTypeModel',
|
||
'constraint' => [
|
||
[
|
||
'table' => 'system_type',
|
||
'on-delete' => 'CASCADE'
|
||
]
|
||
]
|
||
],
|
||
'statusId' => [
|
||
'type' => Schema::DT_INT,
|
||
'nullable' => false,
|
||
'default' => 1,
|
||
'index' => true,
|
||
'belongs-to-one' => 'Exodus4D\Pathfinder\Model\Pathfinder\SystemStatusModel',
|
||
'constraint' => [
|
||
[
|
||
'table' => 'system_status',
|
||
'on-delete' => 'CASCADE'
|
||
]
|
||
],
|
||
'validate' => true,
|
||
'activity-log' => true
|
||
],
|
||
'locked' => [
|
||
'type' => Schema::DT_BOOL,
|
||
'nullable' => false,
|
||
'default' => 0,
|
||
'activity-log' => true
|
||
],
|
||
'rallyUpdated' => [
|
||
'type' => Schema::DT_TIMESTAMP,
|
||
'default' => null
|
||
],
|
||
'rallyPoke' => [
|
||
'type' => Schema::DT_BOOL,
|
||
'nullable' => false,
|
||
'default' => 0,
|
||
'activity-log' => true
|
||
],
|
||
'description' => [
|
||
'type' => Schema::DT_TEXT,
|
||
'activity-log' => true,
|
||
'validate' => true
|
||
],
|
||
'posX' => [
|
||
'type' => Schema::DT_INT,
|
||
'nullable' => false,
|
||
'default' => 0
|
||
],
|
||
'posY' => [
|
||
'type' => Schema::DT_INT,
|
||
'nullable' => false,
|
||
'default' => 0
|
||
],
|
||
'signatures' => [
|
||
'has-many' => ['Exodus4D\Pathfinder\Model\Pathfinder\SystemSignatureModel', 'systemId']
|
||
],
|
||
'connectionsSource' => [
|
||
'has-many' => ['Exodus4D\Pathfinder\Model\Pathfinder\ConnectionModel', 'source']
|
||
],
|
||
'connectionsTarget' => [
|
||
'has-many' => ['Exodus4D\Pathfinder\Model\Pathfinder\ConnectionModel', 'target']
|
||
]
|
||
];
|
||
|
||
/**
|
||
* set data by associative array
|
||
* @param array $data
|
||
*/
|
||
public function setData(array $data){
|
||
$this->copyfrom($data, ['statusId', 'locked', 'rallyUpdated', 'position', 'description']);
|
||
}
|
||
|
||
/**
|
||
* get map data as object
|
||
* @return \stdClass
|
||
*/
|
||
public function getData(){
|
||
// check if there is cached data
|
||
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)){
|
||
$data->type = $this->typeId->getData();
|
||
}
|
||
|
||
if(is_object($this->statusId)){
|
||
$data->status = $this->statusId->getData();
|
||
}
|
||
|
||
$data->locked = $this->locked;
|
||
$data->drifter = $this->isDrifter();
|
||
$data->rallyUpdated = strtotime($this->rallyUpdated);
|
||
$data->rallyPoke = $this->rallyPoke;
|
||
$data->description = $this->description ? : '';
|
||
|
||
$data->position = (object) [];
|
||
$data->position->x = $this->posX;
|
||
$data->position->y = $this->posY;
|
||
|
||
$data->created = (object) [];
|
||
$data->created->created = strtotime($this->created);
|
||
if(is_object($this->createdCharacterId)){
|
||
$data->created->character = $this->createdCharacterId->getData();
|
||
}
|
||
|
||
$data->updated = (object) [];
|
||
$data->updated->updated = strtotime($this->updated);
|
||
if(is_object($this->updatedCharacterId)){
|
||
$data->updated->character = $this->updatedCharacterId->getData();
|
||
}
|
||
|
||
// static system data -------------------------------------------------------------------------------------
|
||
$data->name = $this->name;
|
||
$data->security = $this->security;
|
||
$data->trueSec = $this->trueSec;
|
||
|
||
$data->constellation = (object) [];
|
||
$data->constellation->id = $this->constellationId;
|
||
$data->constellation->name = $this->constellation;
|
||
|
||
$data->region = (object) [];
|
||
$data->region->id = $this->regionId;
|
||
$data->region->name = $this->region;
|
||
|
||
if($this->planets){
|
||
$data->planets = $this->planets;
|
||
}
|
||
|
||
if($this->statics){
|
||
$data->statics = $this->statics;
|
||
}
|
||
|
||
if($this->effect){
|
||
$data->effect = $this->effect;
|
||
}
|
||
|
||
if($this->shattered){
|
||
$data->shattered = $this->shattered;
|
||
}
|
||
|
||
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($data);
|
||
}
|
||
|
||
return $data;
|
||
}
|
||
|
||
/**
|
||
* get all static data
|
||
* @return mixed|null|\stdClass
|
||
* @throws \Exception
|
||
*/
|
||
private function getStaticSystemData(){
|
||
$staticData = null;
|
||
if(!is_object(self::$priorityCacheStore)){
|
||
self::$priorityCacheStore = new PriorityCacheStore();
|
||
}
|
||
|
||
if(self::$priorityCacheStore->exists($this->systemId)){
|
||
$staticData = self::$priorityCacheStore->get($this->systemId);
|
||
}else{
|
||
$staticData = (new Universe())->getSystemData($this->systemId);
|
||
if($staticData){
|
||
self::$priorityCacheStore->set($this->systemId, $staticData);
|
||
}
|
||
}
|
||
|
||
return $staticData;
|
||
}
|
||
|
||
/**
|
||
* get static system data by key
|
||
* @param string $key
|
||
* @return mixed|null
|
||
* @throws \Exception
|
||
*/
|
||
private function getStaticSystemValue(string $key){
|
||
$value = null;
|
||
if($staticData = $this->getStaticSystemData()){
|
||
if(isset($staticData->$key)){
|
||
$value = $staticData->$key;
|
||
}
|
||
}
|
||
return $value;
|
||
}
|
||
|
||
/**
|
||
* @param string $key
|
||
* @param int $val
|
||
* @return bool
|
||
* @throws \Exception
|
||
*/
|
||
protected function validate_systemId(string $key, int $val) : bool {
|
||
$valid = true;
|
||
// check if static system data exists for systemId = $val
|
||
if( !(bool)(new Universe())->getSystemData($val) ){
|
||
$valid = false;
|
||
$this->throwValidationException($key, 'Validation failed: "' . $key . '" = "' . $val . '"');
|
||
}
|
||
|
||
return $valid;
|
||
}
|
||
|
||
/**
|
||
* @param string $key
|
||
* @param int $val
|
||
* @return bool
|
||
* @throws Exception\ValidationException
|
||
*/
|
||
protected function validate_statusId(string $key, int $val) : bool {
|
||
$valid = true;
|
||
if( !$this->rel('statusId')::getStatusById($val) ){
|
||
$valid = false;
|
||
$this->throwValidationException($key, 'Validation failed: "' . $key . '" = "' . $val . '"');
|
||
}
|
||
|
||
return $valid;
|
||
}
|
||
|
||
/**
|
||
* @param string $key
|
||
* @param string $val
|
||
* @return bool
|
||
* @throws Exception\ValidationException
|
||
*/
|
||
protected function validate_description(string $key, string $val) : bool {
|
||
$valid = true;
|
||
if(mb_strlen($val) > 9000){
|
||
$valid = false;
|
||
$this->throwValidationException($key, 'Validation failed: "' . $key . '" too long');
|
||
}
|
||
return $valid;
|
||
}
|
||
|
||
/**
|
||
* setter for system alias
|
||
* @param string $alias
|
||
* @return string
|
||
*/
|
||
public function set_alias($alias){
|
||
$alias = trim($alias);
|
||
|
||
// we don´t need redundant data. "name" is always preferred if "alias" is empty
|
||
if($alias === $this->name){
|
||
$alias = '';
|
||
}
|
||
|
||
return $alias;
|
||
}
|
||
|
||
/**
|
||
* setter for statusId
|
||
* @param $status
|
||
*/
|
||
public function set_status($status){
|
||
if($statusId = (int)$status['id']){
|
||
$this->statusId = $statusId;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* setter for position array
|
||
* @param $position
|
||
* @return null
|
||
*/
|
||
public function set_position($position){
|
||
$position = (array)$position;
|
||
if(count($position) === 2){
|
||
$this->posX = $position['x'];
|
||
$this->posY = $position['y'];
|
||
}
|
||
return null;
|
||
}
|
||
|
||
/**
|
||
* setter for x coordinate
|
||
* @param int $posX
|
||
* @return int
|
||
*/
|
||
public function set_posX(int $posX) : int {
|
||
$posX = abs($posX);
|
||
if($posX > self::MAX_POS_X){
|
||
$posX = self::MAX_POS_X;
|
||
}
|
||
|
||
return $posX;
|
||
}
|
||
|
||
/**
|
||
* setter for y coordinate
|
||
* @param int $posY
|
||
* @return int
|
||
*/
|
||
public function set_posY(int $posY) : int{
|
||
$posY = abs($posY);
|
||
if($posY > self::MAX_POS_Y){
|
||
$posY = self::MAX_POS_Y;
|
||
}
|
||
|
||
return $posY;
|
||
}
|
||
|
||
/**
|
||
* setter for system rally timestamp
|
||
* @param int $rally
|
||
* @return null|string
|
||
*/
|
||
public function set_rallyUpdated($rally){
|
||
$rally = (int)$rally;
|
||
|
||
switch($rally){
|
||
case 0:
|
||
$rally = null;
|
||
break;
|
||
case 1:
|
||
// new rally point set
|
||
$rally = date('Y-m-d H:i:s', time());
|
||
break;
|
||
default:
|
||
$rally = date('Y-m-d H:i:s', $rally);
|
||
break;
|
||
}
|
||
|
||
return $rally;
|
||
}
|
||
|
||
public function get_name(){
|
||
return $this->getStaticSystemValue('name');
|
||
}
|
||
|
||
public function get_constellationId(){
|
||
$constellationData = $this->getStaticSystemValue('constellation');
|
||
return $constellationData ? $constellationData->id : null;
|
||
}
|
||
|
||
public function get_constellation(){
|
||
$constellationData = $this->getStaticSystemValue('constellation');
|
||
return $constellationData ? $constellationData->name : null;
|
||
}
|
||
|
||
public function get_regionId(){
|
||
$constellationData = $this->getStaticSystemValue('constellation');
|
||
return ($constellationData && $constellationData->region) ? $constellationData->region->id : null;
|
||
}
|
||
|
||
public function get_region(){
|
||
$constellationData = $this->getStaticSystemValue('constellation');
|
||
return ($constellationData && $constellationData->region) ? $constellationData->region->name : null;
|
||
}
|
||
|
||
public function get_security(){
|
||
return $this->getStaticSystemValue('security');
|
||
}
|
||
|
||
public function get_trueSec(){
|
||
return $this->getStaticSystemValue('trueSec');
|
||
}
|
||
|
||
public function get_effect(){
|
||
return $this->getStaticSystemValue('effect');
|
||
}
|
||
|
||
public function get_shattered(){
|
||
return $this->getStaticSystemValue('shattered');
|
||
}
|
||
|
||
public function get_statics(){
|
||
return $this->getStaticSystemValue('statics');
|
||
}
|
||
|
||
public function get_planets(){
|
||
return $this->getStaticSystemValue('planets');
|
||
}
|
||
|
||
public function get_stations(){
|
||
return $this->getStaticSystemValue('stations');
|
||
}
|
||
|
||
public function get_sovereignty(){
|
||
return $this->getStaticSystemValue('sovereignty');
|
||
}
|
||
|
||
public function get_factionWar(){
|
||
return $this->getStaticSystemValue('factionWar');
|
||
}
|
||
|
||
/**
|
||
* Event "Hook" function
|
||
* @param self $self
|
||
* @param $pkeys
|
||
*/
|
||
public function afterInsertEvent($self, $pkeys){
|
||
$self->clearCacheData();
|
||
$self->logActivity('systemCreate');
|
||
}
|
||
|
||
/**
|
||
* Event "Hook" function
|
||
* return false will stop any further action
|
||
* @param self $self
|
||
* @param $pkeys
|
||
* @return bool
|
||
*/
|
||
public function beforeUpdateEvent($self, $pkeys) : bool {
|
||
$status = parent::beforeUpdateEvent($self, $pkeys);
|
||
|
||
if($status && !$self->isActive()){
|
||
// reset "rally point" fields
|
||
$self->rallyUpdated = 0;
|
||
$self->rallyPoke = false;
|
||
|
||
// delete connections
|
||
foreach($self->getConnections() as $connection){
|
||
$connection->erase();
|
||
}
|
||
|
||
// delete signatures
|
||
if(!$self->getMap()->persistentSignatures){
|
||
foreach($self->getSignatures() as $signature){
|
||
$signature->erase();
|
||
}
|
||
}
|
||
}
|
||
|
||
return $status;
|
||
}
|
||
|
||
/**
|
||
* Event "Hook" function
|
||
* @param self $self
|
||
* @param $pkeys
|
||
*/
|
||
public function afterUpdateEvent($self, $pkeys){
|
||
$self->clearCacheData();
|
||
$activity = ($self->isActive()) ? 'systemUpdate' : 'systemDelete';
|
||
$self->logActivity($activity);
|
||
}
|
||
|
||
/**
|
||
* Event "Hook" function
|
||
* @param self $self
|
||
* @param $pkeys
|
||
*/
|
||
public function afterEraseEvent($self, $pkeys){
|
||
$self->clearCacheData();
|
||
$self->logActivity('systemDelete');
|
||
}
|
||
|
||
/**
|
||
* get blank signature model
|
||
* @return SystemSignatureModel
|
||
* @throws \Exception
|
||
*/
|
||
public function getNewSignature() : SystemSignatureModel {
|
||
/**
|
||
* @var $signature SystemSignatureModel
|
||
*/
|
||
$signature = self::getNew('SystemSignatureModel');
|
||
$signature->systemId = $this;
|
||
return $signature;
|
||
}
|
||
|
||
/**
|
||
* @param string $action
|
||
* @return Logging\LogInterface
|
||
* @throws Exception\ConfigException
|
||
*/
|
||
public function newLog(string $action = '') : Logging\LogInterface{
|
||
return $this->getMap()->newLog($action)->setTempData($this->getLogObjectData());
|
||
}
|
||
|
||
/**
|
||
* @return MapModel
|
||
*/
|
||
public function getMap() : MapModel {
|
||
return $this->get('mapId');
|
||
}
|
||
|
||
/**
|
||
* check object for model access
|
||
* @param CharacterModel $characterModel
|
||
* @return bool
|
||
*/
|
||
public function hasAccess(CharacterModel $characterModel) : bool {
|
||
return $this->mapId ? $this->mapId->hasAccess($characterModel) : false;
|
||
}
|
||
|
||
/**
|
||
* delete a system from a map
|
||
* hint: signatures and connections will be deleted on cascade
|
||
* @param CharacterModel $characterModel
|
||
* @return bool
|
||
*/
|
||
public function delete(CharacterModel $characterModel){
|
||
return ($this->valid() && $this->hasAccess($characterModel)) ? $this->erase() : false;
|
||
}
|
||
|
||
/**
|
||
* get all connections of this system
|
||
* @return ConnectionModel[]
|
||
*/
|
||
public function getConnections(){
|
||
$connections = [];
|
||
|
||
$this->filter('connectionsTarget', [
|
||
'active = :active AND target = :targetId',
|
||
':active' => 1,
|
||
':targetId' => $this->_id
|
||
]);
|
||
if($this->connectionsTarget){
|
||
foreach($this->connectionsTarget as $connection){
|
||
$connections[$connection->_id] = $connection;
|
||
}
|
||
}
|
||
|
||
$this->filter('connectionsSource', [
|
||
'active = :active AND source = :sourceId',
|
||
':active' => 1,
|
||
':sourceId' => $this->_id
|
||
]);
|
||
if($this->connectionsSource){
|
||
foreach($this->connectionsSource as $connection){
|
||
$connections[$connection->_id] = $connection;
|
||
}
|
||
}
|
||
|
||
return $connections;
|
||
}
|
||
|
||
/**
|
||
* get all signatures of this system
|
||
* -> might be filtered by active has() filter
|
||
* @return SystemSignatureModel[]
|
||
*/
|
||
public function getSignatures(){
|
||
return $this->signatures ? : [];
|
||
}
|
||
|
||
/**
|
||
* get data for all Signatures in this system
|
||
* @return \stdClass[]
|
||
*/
|
||
public function getSignaturesData() : array {
|
||
$signaturesData = [];
|
||
$signatures = $this->getSignatures();
|
||
foreach($signatures as $signature){
|
||
$signaturesData[] = $signature->getData();
|
||
}
|
||
|
||
return $signaturesData;
|
||
}
|
||
|
||
/**
|
||
* get Signature by id and check for access
|
||
* @param int $id
|
||
* @return SystemSignatureModel|null
|
||
*/
|
||
public function getSignatureById(int $id) : ?SystemSignatureModel {
|
||
return $this->relFindOne('signatures', self::getFilter('id', $id));
|
||
}
|
||
|
||
/**
|
||
* get a signature by its "unique" 3-digit name
|
||
* @param string $name
|
||
* @return SystemSignatureModel|null
|
||
*/
|
||
public function getSignatureByName(string $name) : ?SystemSignatureModel {
|
||
return $this->relFindOne('signatures', self::getFilter('name', $name));
|
||
}
|
||
|
||
/**
|
||
* get data for all structures in this system
|
||
* @return \stdClass[]
|
||
*/
|
||
public function getStructuresData() : array {
|
||
return $this->getMap()->getStructuresData($this->systemId);
|
||
}
|
||
|
||
/**
|
||
* get data for all stations in this system
|
||
* @return array
|
||
*/
|
||
public function getStationsData() : array {
|
||
return $this->stations ? : [];
|
||
}
|
||
|
||
/**
|
||
* check whether this system is in w-space
|
||
* @return bool
|
||
*/
|
||
public function isWormhole() : bool {
|
||
return ($this->typeId->id === 1);
|
||
}
|
||
|
||
/**
|
||
* check whether this system is in k-space
|
||
* @return bool
|
||
*/
|
||
public function isKspace() : bool {
|
||
return ($this->typeId->id === 2);
|
||
}
|
||
|
||
/**
|
||
* check whether this system is in a-space
|
||
* @return bool
|
||
*/
|
||
public function isAbyss() : bool {
|
||
return ($this->typeId->id === 3 && $this->security === 'A');
|
||
}
|
||
|
||
/**
|
||
* check whether this system is in drifter-space
|
||
* @return bool
|
||
*/
|
||
public function isDrifter() : bool {
|
||
return in_array($this->security, ['C14', 'C15', 'C16', 'C17', 'C18']);
|
||
}
|
||
|
||
/**
|
||
* send rally point poke to various "APIs"
|
||
* -> send to a Slack channel
|
||
* -> send to a Discord channel
|
||
* -> send to an Email
|
||
* @param array $rallyData
|
||
* @param CharacterModel $characterModel
|
||
* @throws Exception\ConfigException
|
||
* @throws \Exception
|
||
*/
|
||
public function sendRallyPoke(array $rallyData, CharacterModel $characterModel){
|
||
// rally log needs at least one handler to be valid
|
||
$isValidLog = false;
|
||
$log = new Logging\RallyLog('rallySet', $this->getMap()->getLogChannelData());
|
||
|
||
// Slack poke -----------------------------------------------------------------------------
|
||
$slackChannelKey = 'slackChannelRally';
|
||
if(
|
||
$rallyData['pokeSlack'] === true &&
|
||
$this->getMap()->isSlackChannelEnabled($slackChannelKey)
|
||
){
|
||
$isValidLog = true;
|
||
$log->addHandler('slackRally', null, $this->getMap()->getSlackWebHookConfig($slackChannelKey));
|
||
}
|
||
|
||
// Discord poke ---------------------------------------------------------------------------
|
||
$discordChannelKey = 'discordWebHookURLRally';
|
||
if(
|
||
$rallyData['pokeDiscord'] === true &&
|
||
$this->getMap()->isDiscordChannelEnabled($discordChannelKey)
|
||
){
|
||
$isValidLog = true;
|
||
|
||
$log->addHandler('discordRally', null, $this->getMap()->getDiscordWebHookConfig($discordChannelKey));
|
||
}
|
||
|
||
// Mail poke ------------------------------------------------------------------------------
|
||
$mailAddressKey = 'RALLY_SET';
|
||
if(
|
||
$rallyData['pokeMail'] === true &&
|
||
$this->getMap()->isMailSendEnabled('RALLY_SET')
|
||
){
|
||
$isValidLog = true;
|
||
$mailConf = $this->getMap()->getSMTPConfig($mailAddressKey, false);
|
||
$log->addHandler('mail', 'mail', $mailConf);
|
||
}
|
||
|
||
// Buffer log -----------------------------------------------------------------------------
|
||
if($isValidLog){
|
||
$log->setTempData($this->getLogObjectData(true));
|
||
$log->setCharacter($characterModel);
|
||
if( !empty($rallyData['message']) ){
|
||
$log->setData([
|
||
'message' => $rallyData['message']
|
||
]);
|
||
}
|
||
$log->buffer();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* set system type based on security
|
||
*/
|
||
public function setType(){
|
||
switch($this->security){
|
||
case 'H':
|
||
case 'L':
|
||
case '0.0':
|
||
case 'T':
|
||
$typeId = 2; // k-space
|
||
break;
|
||
case 'A':
|
||
$typeId = 3; // a-space
|
||
break;
|
||
default:
|
||
$typeId = 1; // w-space
|
||
}
|
||
|
||
/**
|
||
* @var $type MapTypeModel
|
||
*/
|
||
$type = $this->rel('typeId');
|
||
$type->getById($typeId);
|
||
$this->typeId = $type;
|
||
}
|
||
|
||
/**
|
||
* save signature for this system
|
||
* @param SystemSignatureModel $signature
|
||
* @param CharacterModel $character
|
||
* @return false|ConnectionModel
|
||
*/
|
||
public function saveSignature(SystemSignatureModel $signature, CharacterModel $character){
|
||
$signature->systemId = $this;
|
||
return $signature->save($character);
|
||
}
|
||
|
||
/**
|
||
* get object relevant data for model log
|
||
* @param bool $fullData
|
||
* @return array
|
||
*/
|
||
public function getLogObjectData($fullData = false) : array{
|
||
$objectData = [
|
||
'objId' => $this->_id,
|
||
'objName' => $this->name
|
||
];
|
||
|
||
if($fullData){
|
||
$objectData['objUrl'] = $this->getMap()->getDeeplinkUrl($this->_id);
|
||
$objectData['objAlias'] = $this->alias;
|
||
$objectData['objRegion'] = $this->region;
|
||
$objectData['objIsWormhole'] = $this->isWormhole();
|
||
$objectData['objEffect'] = $this->effect;
|
||
$objectData['objSecurity'] = $this->security;
|
||
$objectData['objTrueSec'] = $this->trueSec;
|
||
$objectData['objCountPlanets'] = count((array)$this->planets);
|
||
$objectData['objDescription'] = $this->description;
|
||
}
|
||
|
||
return $objectData;
|
||
}
|
||
|
||
/**
|
||
* @param string $stamp
|
||
* @return array|null
|
||
*/
|
||
public function getSignatureHistoryEntry(string $stamp) : ?array {
|
||
$signatureHistoryData = array_filter($this->getSignaturesHistory(), function($historyEntry) use ($stamp){
|
||
return md5($historyEntry['stamp']) == $stamp;
|
||
});
|
||
return empty($signatureHistoryData) ? null : reset($signatureHistoryData);
|
||
}
|
||
|
||
/**
|
||
* @return array
|
||
*/
|
||
public function getSignaturesHistory() : array {
|
||
if(!is_array($signaturesHistoryData = $this->getCacheData(self::DATA_CACHE_KEY_SIGNATURES_HISTORY))){
|
||
$signaturesHistoryData = [];
|
||
}
|
||
return $signaturesHistoryData;
|
||
}
|
||
|
||
/**
|
||
* Updates the signature history cache
|
||
* -> each (bulk) change to signatures of this system must result in a new signature history cache entry
|
||
* -> This method also clears the cache of this system, so that new signature data gets returned for in getData()
|
||
* @param CharacterModel $character
|
||
* @param string $action
|
||
* @throws \Exception
|
||
*/
|
||
public function updateSignaturesHistory(CharacterModel $character, string $action = 'edit') : void {
|
||
if(!$this->dry()){
|
||
$signaturesHistoryData = $this->getSignaturesHistory();
|
||
$historyEntry = [
|
||
'stamp' => microtime(true),
|
||
'character' => $character->getBasicData(),
|
||
'action' => $action,
|
||
'signatures' => $this->getSignaturesData()
|
||
];
|
||
|
||
array_unshift($signaturesHistoryData, $historyEntry);
|
||
|
||
// limit max history data
|
||
array_splice($signaturesHistoryData, self::MAX_SIGNATURES_HISTORY_DATA);
|
||
|
||
$this->updateCacheData($signaturesHistoryData, self::DATA_CACHE_KEY_SIGNATURES_HISTORY, self::TTL_SIGNATURES_HISTORY);
|
||
|
||
// clear system cache here
|
||
// -> Signature model updates should NOT update the system cache on change
|
||
// because a "bulk" change to signatures would clear the system cache multiple times
|
||
$this->clearCacheData();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @see parent
|
||
*/
|
||
public function clearCacheData(){
|
||
parent::clearCacheData();
|
||
|
||
// clear map cache as well
|
||
$this->mapId->clearCacheData();
|
||
}
|
||
|
||
/**
|
||
* @see parent
|
||
*/
|
||
public function filterRel() : void {
|
||
$this->filter('signatures', self::getFilter('active', true), ['order' => 'name']);
|
||
$this->filter('connectionsTarget', self::getFilter('active', true));
|
||
$this->filter('connectionsSource', self::getFilter('active', true));
|
||
}
|
||
|
||
/**
|
||
* @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(['mapId', 'systemId'], true);
|
||
}
|
||
|
||
return $status;
|
||
}
|
||
|
||
}
|