Implement lint

This commit is contained in:
2026-08-27 12:45:30 +02:00
parent 171db88400
commit 17009b641f
41 changed files with 70402 additions and 580 deletions
+205 -217
View File
@@ -5,7 +5,6 @@ use Franzz\Objects\Db;
use Franzz\Objects\Main;
use Franzz\Objects\Translator;
use Franzz\Objects\ToolBox;
use Franzz\Objects\Mask;
use \Settings;
/* Timezones
@@ -32,27 +31,25 @@ use \Settings;
* - timezone: Site Timezone (stored user's timezone for emails)
*/
class Livetrail extends Main
{
class Livetrail extends Main {
//Database
const POST_TABLE = 'posts';
public const POST_TABLE = 'posts';
const FEED_CHUNK_SIZE = 15;
const MAIL_CHUNK_SIZE = 5;
private const FEED_CHUNK_SIZE = 15;
private const MAIL_CHUNK_SIZE = 5;
const DEFAULT_LANG = 'en';
const PROJECT_NAME = 'LiveTrail';
public const DEFAULT_LANG = 'en';
public const PROJECT_NAME = 'LiveTrail';
const MAIN_PAGE = 'index';
const VITE_APP = 'src/app.js';
private const MAIN_PAGE = 'index';
private const VITE_APP = 'src/app.js';
private Project $oProject;
private Media $oMedia;
private User $oUser;
private Map $oMap;
private Map $oMap;
public function __construct($sProcessPage, $sTimezone)
{
public function __construct($sProcessPage, $sTimezone) {
parent::__construct($sProcessPage, true, $sTimezone);
$this->oUser = new User($this->oDb);
@@ -65,116 +62,114 @@ class Livetrail extends Main
$this->oMap = new Map($this->oDb);
}
protected function install()
{
protected function install() {
//Install DB
$this->oDb->install();
//Add first user
$iUserId = $this->oDb->insertRow(User::USER_TABLE, array(
$iUserId = $this->oDb->insertRow(User::USER_TABLE, [
'name' => 'Admin',
'email' => 'admin@admin.com',
'language' => self::DEFAULT_LANG,
'timezone' => date_default_timezone_get(),
'subscribed'=> User::USER_SUBSCRIBED,
'clearance' => User::CLEARANCE_ADMIN
));
]);
$this->oUser->setUserId($iUserId);
}
protected function getSqlOptions()
{
return array
(
'tables' => array
(
Feed::MSG_TABLE => array('ref_msg_id', Db::getId(Feed::FEED_TABLE), 'type', 'latitude', 'longitude', 'iso_time', 'site_time', 'timezone', 'unix_time', 'content', 'battery_state', 'posted_on', 'weather_icon', 'weather_cond', 'weather_temp', 'display'),
Feed::FEED_TABLE => array('ref_feed_id', Db::getId(Feed::SPOT_TABLE), Db::getId(Project::PROJ_TABLE), 'name', 'description', 'status', 'last_update'),
Feed::SPOT_TABLE => array('ref_spot_id', 'name', 'model'),
Project::PROJ_TABLE => array('name', 'codename', 'active_from', 'active_to'),
self::POST_TABLE => array(Db::getId(Project::PROJ_TABLE), Db::getId(User::USER_TABLE), 'name', 'content', 'site_time', 'timezone'),
Media::MEDIA_TABLE => array(Db::getId(Project::PROJ_TABLE), 'filename', 'type', 'taken_on', 'posted_on', 'timezone', 'latitude', 'longitude', 'altitude', 'width', 'height', 'rotate', 'comment'),
User::USER_TABLE => array('name', 'email', 'password', 'token', 'token_exp', 'gravatar', 'language', 'timezone', 'subscribed', 'clearance'),
Map::MAP_TABLE => array('codename', 'pattern', 'token', 'tile_size', 'min_zoom', 'max_zoom', 'attribution'),
Map::MAPPING_TABLE => array(Db::getId(Map::MAP_TABLE) , Db::getId(Project::PROJ_TABLE))
),
'types' => array
(
'clearance' => "TINYINT(1) DEFAULT ".User::CLEARANCE_USER,
'active_from' => "TIMESTAMP DEFAULT 0",
'active_to' => "TIMESTAMP DEFAULT 0",
'battery_state' => "VARCHAR(10)",
'codename' => "VARCHAR(100)",
'content' => "LONGTEXT",
'comment' => "LONGTEXT",
'description' => "VARCHAR(100)",
'email' => "VARCHAR(320) NOT NULL",
'filename' => "VARCHAR(100) NOT NULL",
'iso_time' => "VARCHAR(24)",
'language' => "VARCHAR(2)",
'last_update' => "TIMESTAMP DEFAULT 0",
'latitude' => "DECIMAL(8,6)",
'longitude' => "DECIMAL(9,6)",
'altitude' => "SMALLINT",
'model' => "VARCHAR(20)",
'name' => "VARCHAR(100)",
'pattern' => "VARCHAR(200) NOT NULL",
protected function getSqlOptions() {
return
[
'tables' =>
[
Feed::MSG_TABLE => ['ref_msg_id', Db::getId(Feed::FEED_TABLE), 'type', 'latitude', 'longitude', 'iso_time', 'site_time', 'timezone', 'unix_time', 'content', 'battery_state', 'posted_on', 'weather_icon', 'weather_cond', 'weather_temp', 'display'],
Feed::FEED_TABLE => ['ref_feed_id', Db::getId(Feed::SPOT_TABLE), Db::getId(Project::PROJ_TABLE), 'name', 'description', 'status', 'last_update'],
Feed::SPOT_TABLE => ['ref_spot_id', 'name', 'model'],
Project::PROJ_TABLE => ['name', 'codename', 'active_from', 'active_to'],
self::POST_TABLE => [Db::getId(Project::PROJ_TABLE), Db::getId(User::USER_TABLE), 'name', 'content', 'site_time', 'timezone'],
Media::MEDIA_TABLE => [Db::getId(Project::PROJ_TABLE), 'filename', 'type', 'taken_on', 'posted_on', 'timezone', 'latitude', 'longitude', 'altitude', 'width', 'height', 'rotate', 'comment'],
User::USER_TABLE => ['name', 'email', 'password', 'token', 'token_exp', 'gravatar', 'language', 'timezone', 'subscribed', 'clearance'],
Map::MAP_TABLE => ['codename', 'pattern', 'token', 'tile_size', 'min_zoom', 'max_zoom', 'attribution'],
Map::MAPPING_TABLE => [Db::getId(Map::MAP_TABLE) , Db::getId(Project::PROJ_TABLE)]
],
'types' =>
[
'clearance' => 'TINYINT(1) DEFAULT '.User::CLEARANCE_USER,
'active_from' => 'TIMESTAMP DEFAULT 0',
'active_to' => 'TIMESTAMP DEFAULT 0',
'battery_state' => 'VARCHAR(10)',
'codename' => 'VARCHAR(100)',
'content' => 'LONGTEXT',
'comment' => 'LONGTEXT',
'description' => 'VARCHAR(100)',
'email' => 'VARCHAR(320) NOT NULL',
'filename' => 'VARCHAR(100) NOT NULL',
'iso_time' => 'VARCHAR(24)',
'language' => 'VARCHAR(2)',
'last_update' => 'TIMESTAMP DEFAULT 0',
'latitude' => 'DECIMAL(8,6)',
'longitude' => 'DECIMAL(9,6)',
'altitude' => 'SMALLINT',
'model' => 'VARCHAR(20)',
'name' => 'VARCHAR(100)',
'pattern' => 'VARCHAR(200) NOT NULL',
'password' => "VARCHAR(255) NOT NULL DEFAULT ''",
'posted_on' => "TIMESTAMP DEFAULT 0",
'ref_feed_id' => "VARCHAR(40)",
'ref_msg_id' => "VARCHAR(15)",
'ref_spot_id' => "VARCHAR(10)",
'rotate' => "SMALLINT",
'site_time' => "TIMESTAMP DEFAULT 0", //DEFAULT 0 removes auto-set to current time
'status' => "VARCHAR(10)",
'subscribed' => "BOOLEAN DEFAULT ".User::USER_UNSUBSCRIBED,
'taken_on' => "TIMESTAMP DEFAULT 0",
'timezone' => "CHAR(64) NOT NULL", //see mysql.time_zone_name
'token' => "VARCHAR(4096)",
'token_exp' => "TIMESTAMP DEFAULT 0",
'type' => "VARCHAR(20)",
'unix_time' => "INT",
'min_zoom' => "TINYINT UNSIGNED",
'max_zoom' => "TINYINT UNSIGNED",
'attribution' => "VARCHAR(100)",
'gravatar' => "LONGTEXT",
'weather_icon' => "VARCHAR(30)",
'weather_cond' => "VARCHAR(30)",
'weather_temp' => "DECIMAL(3,1)",
'tile_size' => "SMALLINT UNSIGNED DEFAULT 256",
'width' => "INT",
'height' => "INT",
'display' => "BOOLEAN DEFAULT ".Feed::MSG_DISPLAYED
),
'constraints' => array
(
Feed::MSG_TABLE => array("UNIQUE KEY `uni_ref_msg_id` (`ref_msg_id`)", "INDEX(`ref_msg_id`)"),
Feed::FEED_TABLE => array("UNIQUE KEY `uni_ref_feed_id` (`ref_feed_id`)", "INDEX(`ref_feed_id`)"),
Feed::SPOT_TABLE => array("UNIQUE KEY `uni_ref_spot_id` (`ref_spot_id`)", "INDEX(`ref_spot_id`)"),
Project::PROJ_TABLE => "UNIQUE KEY `uni_proj_name` (`codename`)",
Media::MEDIA_TABLE => "UNIQUE KEY `uni_file_name` (`filename`)",
User::USER_TABLE => "UNIQUE KEY `uni_email` (`email`)",
Map::MAP_TABLE => "UNIQUE KEY `uni_map_name` (`codename`)",
Map::MAPPING_TABLE => "default_on_generic_map_only CHECK (`default_map` = 0 OR `id_project` IS NULL)"
),
'cascading_delete' => array
(
Feed::SPOT_TABLE => array(Feed::FEED_TABLE),
Feed::FEED_TABLE => array(Feed::MSG_TABLE),
Project::PROJ_TABLE => array(Feed::FEED_TABLE, Media::MEDIA_TABLE, self::POST_TABLE, Map::MAPPING_TABLE),
Map::MAP_TABLE => array(Map::MAPPING_TABLE)
)
);
'posted_on' => 'TIMESTAMP DEFAULT 0',
'ref_feed_id' => 'VARCHAR(40)',
'ref_msg_id' => 'VARCHAR(15)',
'ref_spot_id' => 'VARCHAR(10)',
'rotate' => 'SMALLINT',
'site_time' => 'TIMESTAMP DEFAULT 0', //DEFAULT 0 removes auto-set to current time
'status' => 'VARCHAR(10)',
'subscribed' => 'BOOLEAN DEFAULT '.User::USER_UNSUBSCRIBED,
'taken_on' => 'TIMESTAMP DEFAULT 0',
'timezone' => 'CHAR(64) NOT NULL', //see mysql.time_zone_name
'token' => 'VARCHAR(4096)',
'token_exp' => 'TIMESTAMP DEFAULT 0',
'type' => 'VARCHAR(20)',
'unix_time' => 'INT',
'min_zoom' => 'TINYINT UNSIGNED',
'max_zoom' => 'TINYINT UNSIGNED',
'attribution' => 'VARCHAR(100)',
'gravatar' => 'LONGTEXT',
'weather_icon' => 'VARCHAR(30)',
'weather_cond' => 'VARCHAR(30)',
'weather_temp' => 'DECIMAL(3,1)',
'tile_size' => 'SMALLINT UNSIGNED DEFAULT 256',
'width' => 'INT',
'height' => 'INT',
'display' => 'BOOLEAN DEFAULT '.Feed::MSG_DISPLAYED
],
'constraints' =>
[
Feed::MSG_TABLE => ['UNIQUE KEY `uni_ref_msg_id` (`ref_msg_id`)', 'INDEX(`ref_msg_id`)'],
Feed::FEED_TABLE => ['UNIQUE KEY `uni_ref_feed_id` (`ref_feed_id`)', 'INDEX(`ref_feed_id`)'],
Feed::SPOT_TABLE => ['UNIQUE KEY `uni_ref_spot_id` (`ref_spot_id`)', 'INDEX(`ref_spot_id`)'],
Project::PROJ_TABLE => 'UNIQUE KEY `uni_proj_name` (`codename`)',
Media::MEDIA_TABLE => 'UNIQUE KEY `uni_file_name` (`filename`)',
User::USER_TABLE => 'UNIQUE KEY `uni_email` (`email`)',
Map::MAP_TABLE => 'UNIQUE KEY `uni_map_name` (`codename`)',
Map::MAPPING_TABLE => 'default_on_generic_map_only CHECK (`default_map` = 0 OR `id_project` IS NULL)'
],
'cascading_delete' =>
[
Feed::SPOT_TABLE => [Feed::FEED_TABLE],
Feed::FEED_TABLE => [Feed::MSG_TABLE],
Project::PROJ_TABLE => [Feed::FEED_TABLE, Media::MEDIA_TABLE, self::POST_TABLE, Map::MAPPING_TABLE],
Map::MAP_TABLE => [Map::MAPPING_TABLE]
]
];
}
public function getAppMainPage(string $sCsrfToken='') {
$asViteAssets = $this->getViteAssets();
return parent::getMainPage(
array(
[
'projects' => $this->oProject->getProjects(),
'user' => $this->oUser->getUserInfo(),
'consts' => array(
'consts' => [
'modes' => Project::MODES,
'clearances' => User::CLEARANCES,
'default_timezone' => Settings::TIMEZONE,
@@ -184,10 +179,10 @@ class Livetrail extends Main
'title' => self::PROJECT_NAME,
'default_page' => 'project',
'csrf_token' => $sCsrfToken
)
),
]
],
self::MAIN_PAGE,
array(
[
'tags' => [
'language' => $this->oLang->getLanguage(),
'title' => self::PROJECT_NAME,
@@ -197,7 +192,7 @@ class Livetrail extends Main
'css' => $asViteAssets['css'],
'module' => $asViteAssets['module']
]
)
]
);
}
@@ -206,31 +201,31 @@ class Livetrail extends Main
$asAppImport = $asManifest[self::VITE_APP];
//Recursive search for chunk imports
$asImports = array();
$asSeenImports = array(self::VITE_APP => true);
$asImports = [];
$asSeenImports = [self::VITE_APP => true];
$this->appendViteImportedChunks($asManifest, $asAppImport, $asSeenImports, $asImports);
//CSS
$asCssFiles = array();
foreach(array_merge(array($asAppImport), $asImports) as $asChunk) {
foreach($asChunk['css'] ?? array() as $sCssFile) $asCssFiles[] = $sCssFile;
$asCssFiles = [];
foreach(array_merge([$asAppImport], $asImports) as $asChunk) {
foreach($asChunk['css'] ?? [] as $sCssFile) $asCssFiles[] = $sCssFile;
}
//Modules
$asModuleFiles = array();
$asModuleFiles = [];
foreach($asImports as $asImport) {
if(str_ends_with($asImport['file'] ?? '', '.js')) $asModuleFiles[] = $asImport['file'];
}
return array(
return [
'app' => $asAppImport['file'],
'css' => $this->getViteAssetInstances($asCssFiles),
'module' => $this->getViteAssetInstances($asModuleFiles)
);
];
}
private function appendViteImportedChunks($asManifest, $asChunk, &$asSeenImports, &$asImports) {
foreach($asChunk['imports'] ?? array() as $sImport) {
foreach($asChunk['imports'] ?? [] as $sImport) {
if(isset($asSeenImports[$sImport]) || !isset($asManifest[$sImport])) continue;
$asSeenImports[$sImport] = true;
@@ -241,7 +236,7 @@ class Livetrail extends Main
private function getViteAssetInstances($asFilePaths) {
return array_map(
function($sFilePath) { return array('filename' => $sFilePath); },
function($sFilePath) { return ['filename' => $sFilePath]; },
$asFilePaths
);
}
@@ -283,7 +278,7 @@ class Livetrail extends Main
$oEmail->setDestInfo($this->oUser->getSubscribedUsersInfo());
//Add Position
$asSpotMessages = $this->getSpotMessages(array($this->oProject->getLastMessageId($this->getFeedConstraints(Feed::MSG_TABLE))));
$asSpotMessages = $this->getSpotMessages([$this->oProject->getLastMessageId($this->getFeedConstraints(Feed::MSG_TABLE))]);
$asLastMessage = array_shift($asSpotMessages);
$oEmail->oTemplate->setTags($asLastMessage);
$oEmail->oTemplate->setTag('date_time', 'time:'.$asLastMessage['unix_time'], 'd/m/Y, H:i');
@@ -294,11 +289,11 @@ class Livetrail extends Main
foreach($asNews as $asPost) {
if($asPost['type'] != 'message') {
$oEmail->oTemplate->newInstance('news');
$oEmail->oTemplate->setInstanceTags('news', array(
$oEmail->oTemplate->setInstanceTags('news', [
'local_server' => $this->asContext['serv_name'],
'project' => $this->oProject->getProjectCodeName(),
'type' => $asPost['type'],
'id' => $asPost['id_'.$asPost['type']])
'id' => $asPost['id_'.$asPost['type']]]
);
$oEmail->oTemplate->addInstance($asPost['type'], $asPost);
$oEmail->oTemplate->setInstanceTag($asPost['type'], 'local_server', $this->asContext['serv_name']);
@@ -310,8 +305,7 @@ class Livetrail extends Main
return $oEmail->send();
}
public function getMarkers($asMessageIds=array(), $asMediaIds=array(), $bInternal=false)
{
public function getMarkers($asMessageIds=[], $asMediaIds=[], $bInternal=false) {
//Get messages
$asMessages = $this->getSpotMessages($asMessageIds);
foreach($asMessages as &$asMessage) {
@@ -337,8 +331,8 @@ class Livetrail extends Main
//Assign medias to closest message
if(!empty($asMessages)) {
usort($asMessages, function($a, $b){return (int) $a['unix_time'] <=> (int) $b['unix_time'];});
usort($asMedias, function($a, $b){return (int) $a['unix_time'] <=> (int) $b['unix_time'];});
usort($asMessages, function($a, $b) {return (int) $a['unix_time'] <=> (int) $b['unix_time'];});
usort($asMedias, function($a, $b) {return (int) $a['unix_time'] <=> (int) $b['unix_time'];});
$iIndex = 0;
$iMaxIndex = count($asMessages) - 1;
@@ -359,18 +353,18 @@ class Livetrail extends Main
//Combine markers
$asMarkers = [...$asMessages, ...$asGeoMedias];
usort($asMarkers, function($a, $b){return (int) $a['unix_time'] <=> (int) $b['unix_time'];});
usort($asMarkers, function($a, $b) {return (int) $a['unix_time'] <=> (int) $b['unix_time'];});
$asResult = array(
$asResult = [
'markers' => $asMarkers,
'maps' => $this->oMap->getProjectMaps($this->oProject->getProjectId())
);
];
return $bInternal?$asResult:self::getJsonResult(true, '', $asResult);
}
public function getLastUpdate() {
$asLastUpdate = array();
$asLastUpdate = [];
$this->addTimeStamp($asLastUpdate, $this->oProject->getLastUpdate());
return self::getJsonResult(true, '', $asLastUpdate);
}
@@ -403,30 +397,28 @@ class Livetrail extends Main
return self::getJsonResult($asResult['result'], $asResult['desc_lang_id'], $this->oUser->getUserInfo(), $asResult['desc_lang_params']);
}
private function getSpotMessages($asMsgIds=array())
{
private function getSpotMessages($asMsgIds=[]) {
$asConstraints = $this->getFeedConstraints(Feed::MSG_TABLE);
if(!empty($asMsgIds)) {
$asConstraints['constraint'][Db::getId(Feed::MSG_TABLE)] = $asMsgIds;
$asConstraints['constOpe'][Db::getId(Feed::MSG_TABLE)] = 'IN';
}
$asCombinedMessages = array();
$asCombinedMessages = [];
//Get messages from all feeds belonging to the project
$asFeeds = $this->oProject->getFeedIds();
foreach($asFeeds as $iFeedId) {
$oFeed = new Feed($this->oDb, $iFeedId);
$asMessages = $oFeed->getMessages($asConstraints);
foreach($asMessages as $asMessage)
{
foreach($asMessages as $asMessage) {
$asMessage['latitude'] = floatval($asMessage['latitude']);
$asMessage['longitude'] = floatval($asMessage['longitude']);
$asMessage['lat_dms'] = self::decToDms($asMessage['latitude'], 'lat');
$asMessage['lon_dms'] = self::decToDms($asMessage['longitude'], 'lon');
$asMessage['displayed_id'] = $asMessage[Db::getId(Feed::MSG_TABLE)];
$asMessage['static_img_url'] = $this->oMap->getMapUrl('static', array('x'=>$asMessage['longitude'], 'y'=>$asMessage['latitude']));
$asMessage['marker_img_url'] = $this->oMap->getMapUrl('static_marker', array('x'=>$asMessage['longitude'], 'y'=>$asMessage['latitude']));
$asMessage['static_img_url'] = $this->oMap->getMapUrl('static', ['x'=>$asMessage['longitude'], 'y'=>$asMessage['latitude']]);
$asMessage['marker_img_url'] = $this->oMap->getMapUrl('static_marker', ['x'=>$asMessage['longitude'], 'y'=>$asMessage['latitude']]);
$this->addTimeStamp($asMessage, $asMessage['unix_time'], $asMessage['timezone']);
$asCombinedMessages[] = $asMessage;
@@ -443,8 +435,7 @@ class Livetrail extends Main
* @param String $sTimeRefField Field to calculate relative times: 'taken_on' or 'posted_on'
* @return Array Medias info
*/
private function getMedias($sTimeRefField, $asMediaIds=array(), $bOnlyGeoMedia=false)
{
private function getMedias($sTimeRefField, $asMediaIds=[], $bOnlyGeoMedia=false) {
//Constraints
$asConstraints = $this->getFeedConstraints(Media::MEDIA_TABLE, $sTimeRefField);
if(!empty($asMediaIds)) {
@@ -478,13 +469,12 @@ class Livetrail extends Main
return $asMedias;
}
private function getPosts($asPostIds=array())
{
$asInfo = array(
'select' => array(Db::getFullColumnName(self::POST_TABLE, '*'), 'gravatar'),
private function getPosts($asPostIds=[]) {
$asInfo = [
'select' => [Db::getFullColumnName(self::POST_TABLE, '*'), 'gravatar'],
'from' => self::POST_TABLE,
'join' => array(User::USER_TABLE => Db::getId(User::USER_TABLE))
);
'join' => [User::USER_TABLE => Db::getId(User::USER_TABLE)]
];
$asInfo = array_merge($asInfo, $this->getFeedConstraints(self::POST_TABLE));
if(!empty($asPostIds)) {
@@ -518,35 +508,35 @@ class Livetrail extends Main
}
private function getFeedConstraints($sType, $sTimeField='site_time', $sReturnFormat='array') {
$asConsArray = array();
$sConsSql = "";
$asConsArray = [];
$sConsSql = '';
$asActPeriod = $this->oProject->getActivePeriod();
//Filter on Project ID
$sConsSql = "WHERE ".Db::getId(Project::PROJ_TABLE)." = ".$this->oProject->getProjectId();
$asConsArray = array(
'constraint'=> array(Db::getId(Project::PROJ_TABLE) => $this->oProject->getProjectId()),
'constOpe' => array(Db::getId(Project::PROJ_TABLE) => "=")
);
$sConsSql = 'WHERE '.Db::getId(Project::PROJ_TABLE).' = '.$this->oProject->getProjectId();
$asConsArray = [
'constraint'=> [Db::getId(Project::PROJ_TABLE) => $this->oProject->getProjectId()],
'constOpe' => [Db::getId(Project::PROJ_TABLE) => '=']
];
//Time Filter
switch($sType) {
case Feed::MSG_TABLE:
$asConsArray['constraint'][$sTimeField] = $asActPeriod;
$asConsArray['constOpe'][$sTimeField] = "BETWEEN";
$asConsArray['constOpe'][$sTimeField] = 'BETWEEN';
$asConsArray['constraint']['display'] = Feed::MSG_DISPLAYED;
$asConsArray['constOpe']['display'] = "=";
$sConsSql .= " AND ".$sTimeField." BETWEEN '".$asActPeriod['from']."' AND '".$asActPeriod['to']."' AND display = ".Feed::MSG_DISPLAYED;
$asConsArray['constOpe']['display'] = '=';
$sConsSql .= ' AND '.$sTimeField." BETWEEN '".$asActPeriod['from']."' AND '".$asActPeriod['to']."' AND display = ".Feed::MSG_DISPLAYED;
break;
case Media::MEDIA_TABLE:
$asConsArray['constraint'][$sTimeField] = $asActPeriod['to'];
$asConsArray['constOpe'][$sTimeField] = "<=";
$sConsSql .= " AND ".$sTimeField." <= '".$asActPeriod['to']."'";
$asConsArray['constOpe'][$sTimeField] = '<=';
$sConsSql .= ' AND '.$sTimeField." <= '".$asActPeriod['to']."'";
break;
case self::POST_TABLE:
$asConsArray['constraint'][$sTimeField] = $asActPeriod['to'];
$asConsArray['constOpe'][$sTimeField] = "<=";
$sConsSql .= " AND ".$sTimeField." <= '".$asActPeriod['to']."'";
$asConsArray['constOpe'][$sTimeField] = '<=';
$sConsSql .= ' AND '.$sTimeField." <= '".$asActPeriod['to']."'";
break;
}
@@ -554,14 +544,14 @@ class Livetrail extends Main
}
public function getNewFeed($iRefIdFirst) {
$asResult = array();
$asResult = [];
$sLangId = '';
if($this->oProject->isEditable()) {
$asMessageIds = $asMediaIds = array();
$asMessageIds = $asMediaIds = [];
//New Feed Items
$asResult = $this->getFeed($iRefIdFirst, ">", "DESC");
$asResult = $this->getFeed($iRefIdFirst, '>', 'DESC');
foreach($asResult['feed'] as $asItem) {
switch($asItem['type']) {
case 'message':
@@ -575,8 +565,8 @@ class Livetrail extends Main
//New Markers
$asMarkers = $this->getMarkers(
empty($asMessageIds)?array(0):$asMessageIds,
empty($asMediaIds)?array(0):$asMediaIds,
empty($asMessageIds)?[0]:$asMessageIds,
empty($asMediaIds)?[0]:$asMediaIds,
true
);
@@ -589,12 +579,12 @@ class Livetrail extends Main
public function getNextFeed($iRefIdLast=0, $bInternal=false) {
if($this->oProject->getMode() == Project::MODE_HISTO) {
$sDirection = ">";
$sSort = "ASC";
$sDirection = '>';
$sSort = 'ASC';
}
else {
$sDirection = "<";
$sSort = "DESC";
$sDirection = '<';
$sSort = 'DESC';
}
$asResult = $this->getFeed($iRefIdLast, $sDirection, $sSort);
return $bInternal?$asResult['feed']:self::getJsonResult(true, '', $asResult);
@@ -610,26 +600,26 @@ class Livetrail extends Main
$sMediaIdField = Db::getId(Media::MEDIA_TABLE);
$sPostIdField = Db::getId(self::POST_TABLE);
$sFeedIdField = Db::getId(Feed::FEED_TABLE);
$sQuery = implode(" ", array(
"SELECT type, id, ref",
"FROM (",
$sQuery = implode(' ', [
'SELECT type, id, ref',
'FROM (',
"SELECT {$sProjectIdField}, {$sMsgIdField} AS id, 'message' AS type, CONCAT(UNIX_TIMESTAMP(site_time), '.0', {$sMsgIdField}) AS ref",
"FROM ".Feed::MSG_TABLE,
"INNER JOIN ".Feed::FEED_TABLE." USING({$sFeedIdField})",
'FROM '.Feed::MSG_TABLE,
'INNER JOIN '.Feed::FEED_TABLE." USING({$sFeedIdField})",
$this->getFeedConstraints(Feed::MSG_TABLE, 'site_time', 'sql'),
"UNION",
'UNION',
"SELECT {$sProjectIdField}, {$sMediaIdField} AS id, 'media' AS type, CONCAT(UNIX_TIMESTAMP(posted_on), '.1', {$sMediaIdField}) AS ref",
"FROM ".Media::MEDIA_TABLE,
'FROM '.Media::MEDIA_TABLE,
$this->getFeedConstraints(Media::MEDIA_TABLE, 'posted_on', 'sql'),
"UNION",
'UNION',
"SELECT {$sProjectIdField}, {$sPostIdField} AS id, 'post' AS type, CONCAT(UNIX_TIMESTAMP(site_time), '.2', {$sPostIdField}) AS ref",
"FROM ".self::POST_TABLE,
'FROM '.self::POST_TABLE,
$this->getFeedConstraints(self::POST_TABLE, 'site_time', 'sql'),
") AS items",
($sRefId !== '0')?("WHERE ref ".$sDirection." ".$sRefId):"",
"ORDER BY ref ".$sSort,
"LIMIT ".self::FEED_CHUNK_SIZE
));
') AS items',
($sRefId !== '0')?('WHERE ref '.$sDirection.' '.$sRefId):'',
'ORDER BY ref '.$sSort,
'LIMIT '.self::FEED_CHUNK_SIZE
]);
//Get new chunk
$asItems = $this->oDb->getArrayQuery($sQuery, true);
@@ -642,22 +632,22 @@ class Livetrail extends Main
}
//Sort Table IDs by type & Get attributes
$asFeedIds = array('message'=>array(), 'media'=>array(), 'post'=>array());
$asFeedIds = ['message'=>[], 'media'=>[], 'post'=>[]];
foreach($asItems as $asItem) {
$asFeedIds[$asItem['type']][$asItem['id']] = $asItem;
}
$asFeedAttrs = array(
'message' => empty($asFeedIds['message'])?array():$this->getSpotMessages(array_keys($asFeedIds['message'])),
'media' => empty($asFeedIds['media'])?array():$this->getMedias('posted_on', array_keys($asFeedIds['media'])),
'post' => empty($asFeedIds['post'])?array():$this->getPosts(array_keys($asFeedIds['post']))
);
$asFeedAttrs = [
'message' => empty($asFeedIds['message'])?[]:$this->getSpotMessages(array_keys($asFeedIds['message'])),
'media' => empty($asFeedIds['media'])?[]:$this->getMedias('posted_on', array_keys($asFeedIds['media'])),
'post' => empty($asFeedIds['post'])?[]:$this->getPosts(array_keys($asFeedIds['post']))
];
//Replace Array Key with Item ID
$asFeeds = array();
$asFeeds = [];
foreach($asFeedAttrs as $sType=>$asFeedAttr) {
foreach($asFeedAttr as $asFeed) {
$asFeeds[$sType][$asFeed['id_'.$sType]] = $asFeed;
}
}
}
//Assign
@@ -665,22 +655,21 @@ class Livetrail extends Main
$asItem = array_merge($asFeeds[$asItem['type']][$asItem['id']], $asItem);
}
return array('ref_id_last'=>$iRefIdLast, 'ref_id_first'=>$iRefIdFirst, 'sort'=>$sSort, 'feed'=>$asItems);
return ['ref_id_last'=>$iRefIdLast, 'ref_id_first'=>$iRefIdFirst, 'sort'=>$sSort, 'feed'=>$asItems];
}
public function addPost($sName, $sPost)
{
public function addPost($sName, $sPost) {
$iPostId = 0;
$sLangId = '';
if($this->oProject->isEditable()) {
$asData = array(
$asData = [
Db::getId(Project::PROJ_TABLE) => $this->oProject->getProjectId(),
'name' => mb_strtolower(trim($sName)),
'content' => trim($sPost),
'site_time' => date(Db::TIMESTAMP_FORMAT), //Now in Site Time
'timezone' => date_default_timezone_get() //Site Time Zone
);
];
if($this->oUser->getUserId() > 0) $asData[Db::getId(User::USER_TABLE)] = $this->oUser->getUserId();
$iPostId = $this->oDb->insertRow(self::POST_TABLE, $asData);
@@ -693,8 +682,7 @@ class Livetrail extends Main
return self::getJsonResult(($iPostId > 0), $sLangId);
}
public function upload()
{
public function upload() {
$oUploader = new Uploader($this->oMedia);
return $oUploader->sBody;
@@ -721,12 +709,12 @@ class Livetrail extends Main
public function getAdminSettings() {
$oFeed = new Feed($this->oDb);
$asData = array(
$asData = [
'project' => $this->oProject->getProjects(),
'feed' => $oFeed->getFeeds(),
'spot' => $oFeed->getSpots(),
'user' => $this->oUser->getSubscribedUsersInfo()
);
];
foreach($asData['project'] as &$asProject) {
$asProject['active_from'] = substr($asProject['active_from'], 0, 10);
@@ -739,10 +727,10 @@ class Livetrail extends Main
public function setAdminSettings($sType, $iId, $sField, $sValue) {
$bSuccess = false;
$sLangId = '';
$asLangParams = array();
$asResult = array();
$asLangParams = [];
$asResult = [];
if($this->oDb->isId($sField) && $sValue <= 0) return self::getJsonResult(false, 'error.impossible_value', array(), array($sValue, $sField));
if($this->oDb->isId($sField) && $sValue <= 0) return self::getJsonResult(false, 'error.impossible_value', [], [$sValue, $sField]);
switch($sType) {
case 'project':
@@ -763,7 +751,7 @@ class Livetrail extends Main
break;
default:
$sLangId = 'error.unknown_field';
$asLangParams = array($sField);
$asLangParams = [$sField];
}
//Identify missing GPX file
@@ -771,7 +759,7 @@ class Livetrail extends Main
if(!Converter::hasGpxFile($sProjectCodeName)) {
$bSuccess = true;
$sLangId = 'error.file_missing';
$asLangParams = array('GPX', $sProjectCodeName.Gpx::EXT);
$asLangParams = ['GPX', $sProjectCodeName.Gpx::EXT];
}
$asResult = $oProject->getProject();
@@ -792,7 +780,7 @@ class Livetrail extends Main
break;
default:
$sLangId = 'error.unknown_field';
$asLangParams = array($sField);
$asLangParams = [$sField];
}
$asResult = $oFeed->getFeed();
break;
@@ -806,20 +794,20 @@ class Livetrail extends Main
break;
default:
$sLangId = 'error.unknown_field';
$asLangParams = array($sField);
$asLangParams = [$sField];
}
$asResult = $this->oUser->getUserById($iId);
break;
}
if(!$bSuccess && $sLangId=='') $sLangId = 'error.commit_db';
return self::getJsonResult($bSuccess, $sLangId, array($sType=>array($asResult)), $asLangParams);
return self::getJsonResult($bSuccess, $sLangId, [$sType=>[$asResult]], $asLangParams);
}
public function createAdminSettings($sType) {
$bSuccess = false;
$sLangId = '';
$asResult = array();
$asResult = [];
switch($sType) {
case 'project':
@@ -830,18 +818,18 @@ class Livetrail extends Main
$oFeed->createFeedId($iNewProjectId);
$bSuccess = $iNewProjectId > 0;
$asResult = array(
'project' => array($oProject->getProject()),
'feed' => array($oFeed->getFeed())
);
$asResult = [
'project' => [$oProject->getProject()],
'feed' => [$oFeed->getFeed()]
];
break;
case 'feed':
$oFeed = new Feed($this->oDb);
$iNewFeedId = $oFeed->createFeedId($this->oProject->getProjectId());
$bSuccess = $iNewFeedId > 0;
$asResult = array(
'feed' => array($oFeed->getFeed())
);
$asResult = [
'feed' => [$oFeed->getFeed()]
];
break;
}
if(!$bSuccess && $sLangId=='') $sLangId = 'error.commit_db';
@@ -852,8 +840,8 @@ class Livetrail extends Main
public function deleteAdminSettings($sType, $iId) {
$bSuccess = false;
$sLangId = '';
$asLangParams = array();
$asResult = array();
$asLangParams = [];
$asResult = [];
switch($sType) {
case 'project':
@@ -865,7 +853,7 @@ class Livetrail extends Main
break;
case 'feed':
$oFeed = new Feed($this->oDb, $iId);
$asResult = array('feed' => array($oFeed->delete()));
$asResult = ['feed' => [$oFeed->delete()]];
$sLangId = $asResult['feed'][0]['desc_lang_id'];
$asLangParams = $asResult['feed'][0]['desc_lang_params'];
$bSuccess = $asResult['feed'][0]['result'];
@@ -900,8 +888,8 @@ class Livetrail extends Main
$sDirection;
}
public static function getNumberWithLeadingZeros($fValue, $iNbLeadingZeros, $iNbDigits){
$sDecimalSeparator = ".";
public static function getNumberWithLeadingZeros($fValue, $iNbLeadingZeros, $iNbDigits) {
$sDecimalSeparator = '.';
if($iNbDigits > 0) $iNbLeadingZeros += mb_strlen($sDecimalSeparator) + $iNbDigits;
$sPattern = '%0'.$iNbLeadingZeros.$sDecimalSeparator.$iNbDigits.'f';
return sprintf($sPattern, $fValue);
@@ -915,7 +903,7 @@ class Livetrail extends Main
$sDate = $oDate->format('d/m/Y');
$sTime = $oDate->format('H:i');
return $this->oLang->getTranslation('time.date_time', array($sDate, $sTime));
return $this->oLang->getTranslation('time.date_time', [$sDate, $sTime]);
}
public static function getTimeZoneDayOffset($iTime, $sLocalTimeZone) {