Add Local Time Zone
This commit is contained in:
50
files/db/update_v12_to_v13.sql
Normal file
50
files/db/update_v12_to_v13.sql
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
ALTER TABLE medias ADD timezone CHAR(64) AFTER posted_on;
|
||||||
|
ALTER TABLE messages ADD timezone CHAR(64) AFTER site_time;
|
||||||
|
ALTER TABLE posts ADD timezone CHAR(64) AFTER site_time;
|
||||||
|
|
||||||
|
UPDATE messages
|
||||||
|
SET iso_time = DATE_FORMAT(CONVERT_TZ(iso_time,'+00:00','+02:00'), '%Y-%m-%dT%T+0200'),
|
||||||
|
led = led
|
||||||
|
WHERE id_feed = 2;
|
||||||
|
|
||||||
|
UPDATE messages
|
||||||
|
INNER JOIN feeds ON feeds.id_feed = messages.id_feed
|
||||||
|
INNER JOIN projects ON projects.id_project = feeds.id_project
|
||||||
|
SET messages.timezone = projects.timezone,
|
||||||
|
messages.led = messages.led;
|
||||||
|
|
||||||
|
UPDATE posts
|
||||||
|
SET timezone = 'Europe/Paris',
|
||||||
|
led = led;
|
||||||
|
|
||||||
|
UPDATE posts
|
||||||
|
INNER JOIN projects ON projects.id_project = posts.id_project
|
||||||
|
SET posts.id_user = 1,
|
||||||
|
posts.timezone = projects.timezone,
|
||||||
|
posts.led = posts.led
|
||||||
|
WHERE posts.name IN ('francois', 'françois','Francois', 'François', 'franzz');
|
||||||
|
|
||||||
|
UPDATE posts
|
||||||
|
SET timezone = 'Pacific/Auckland',
|
||||||
|
led = led
|
||||||
|
WHERE name = 'nz';
|
||||||
|
|
||||||
|
UPDATE posts
|
||||||
|
SET timezone = 'Atlantic/Madeira',
|
||||||
|
led = led
|
||||||
|
WHERE id_post IN (141, 142);
|
||||||
|
|
||||||
|
UPDATE medias
|
||||||
|
INNER JOIN projects ON projects.id_project = medias.id_project
|
||||||
|
SET medias.timezone = projects.timezone,
|
||||||
|
medias.led = medias.led;
|
||||||
|
|
||||||
|
UPDATE medias
|
||||||
|
SET timezone = 'Atlantic/Madeira',
|
||||||
|
taken_on = posted_on,
|
||||||
|
led = led
|
||||||
|
WHERE id_media IN (64, 65);
|
||||||
|
|
||||||
|
ALTER TABLE projects DROP COLUMN timezone;
|
||||||
|
|
||||||
|
UPDATE maps SET attribution = 'OpenTopoMap (CC-BY-SA)' WHERE id_map = 2;
|
||||||
@@ -8,44 +8,44 @@ require_once 'inc/PHPMailer/PHPMailer.php';
|
|||||||
require_once 'inc/PHPMailer/SMTP.php';
|
require_once 'inc/PHPMailer/SMTP.php';
|
||||||
|
|
||||||
class Email extends PhpObject {
|
class Email extends PhpObject {
|
||||||
|
|
||||||
private $sServName;
|
private $sServName;
|
||||||
private $sTemplateName;
|
private $sTemplateName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Email Template
|
* Email Template
|
||||||
* @var Mask
|
* @var Mask
|
||||||
*/
|
*/
|
||||||
public $oTemplate;
|
public $oTemplate;
|
||||||
|
|
||||||
private $asDests;
|
private $asDests;
|
||||||
|
|
||||||
public function __construct($sServName, $sTemplateName='') {
|
public function __construct($sServName, $sTemplateName='') {
|
||||||
$this->sServName = $sServName;
|
$this->sServName = $sServName;
|
||||||
$this->setTemplate($sTemplateName);
|
$this->setTemplate($sTemplateName);
|
||||||
$this->asDests = array();
|
$this->asDests = array();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setTemplate($sTemplateName) {
|
public function setTemplate($sTemplateName) {
|
||||||
$this->sTemplateName = $sTemplateName;
|
$this->sTemplateName = $sTemplateName;
|
||||||
$this->oTemplate = new Mask($this->sTemplateName);
|
$this->oTemplate = new Mask($this->sTemplateName);
|
||||||
$this->oTemplate->setTag('local_server', $this->sServName);
|
$this->oTemplate->setTag('local_server', $this->sServName);
|
||||||
$this->oTemplate->setTag('geo_server', Settings::GEO_SERVER);
|
$this->oTemplate->setTag('geo_server', Settings::GEO_SERVER);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set Target User Info
|
* Set Target User Info
|
||||||
* @param array $asDests Contains: id_user, name, email, language, active
|
* @param array $asDests Contains: id_user, name, email, language, timezone, active
|
||||||
*/
|
*/
|
||||||
public function setDestInfo($asDests) {
|
public function setDestInfo($asDests) {
|
||||||
if(array_key_exists('email', $asDests)) $asDests = array($asDests);
|
if(array_key_exists('email', $asDests)) $asDests = array($asDests);
|
||||||
$this->asDests = $asDests;
|
$this->asDests = $asDests;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function send() {
|
public function send() {
|
||||||
foreach($this->asDests as $asDest) {
|
foreach($this->asDests as $asDest) {
|
||||||
$oPHPMailer = new PHPMailer(true);
|
$oPHPMailer = new PHPMailer(true);
|
||||||
|
|
||||||
//Server settings
|
//Server settings
|
||||||
if(Settings::DEBUG) $oPHPMailer->SMTPDebug = SMTP::DEBUG_SERVER;//Enable verbose debug output
|
if(Settings::DEBUG) $oPHPMailer->SMTPDebug = SMTP::DEBUG_SERVER;//Enable verbose debug output
|
||||||
$oPHPMailer->isSMTP(); //Send using SMTP
|
$oPHPMailer->isSMTP(); //Send using SMTP
|
||||||
@@ -59,31 +59,31 @@ class Email extends PhpObject {
|
|||||||
$oPHPMailer->Port = 587; //TCP port to connect to, use 465 for `PHPMailer::ENCRYPTION_SMTPS` above
|
$oPHPMailer->Port = 587; //TCP port to connect to, use 465 for `PHPMailer::ENCRYPTION_SMTPS` above
|
||||||
$oPHPMailer->setFrom(Settings::MAIL_FROM, 'Spotty');
|
$oPHPMailer->setFrom(Settings::MAIL_FROM, 'Spotty');
|
||||||
$oPHPMailer->addReplyTo(Settings::MAIL_FROM, 'Spotty');
|
$oPHPMailer->addReplyTo(Settings::MAIL_FROM, 'Spotty');
|
||||||
|
|
||||||
//Message
|
//Message
|
||||||
$this->oTemplate->setLanguage($asDest['language'], Spot::DEFAULT_LANG);
|
$this->oTemplate->setLanguage($asDest['language'], Spot::DEFAULT_LANG);
|
||||||
$this->oTemplate->setTimezone($asDest['timezone']);
|
$this->oTemplate->setTimezone($asDest['timezone']);
|
||||||
|
|
||||||
//Unsubscribe Link
|
//Unsubscribe Link
|
||||||
$sUnsubLink = $this->sServName.'?a=unsubscribe_email&id='.$asDest['id_user'];
|
$sUnsubLink = $this->sServName.'?a=unsubscribe_email&id='.$asDest['id_user'];
|
||||||
$this->oTemplate->setTag('unsubscribe_link', htmlspecialchars($sUnsubLink));
|
$this->oTemplate->setTag('unsubscribe_link', htmlspecialchars($sUnsubLink));
|
||||||
$oPHPMailer->addCustomHeader('List-Unsubscribe','<mailto:'.Settings::MAIL_FROM.'?subject=unsubscribe>, <'.$sUnsubLink.'>');
|
$oPHPMailer->addCustomHeader('List-Unsubscribe','<mailto:'.Settings::MAIL_FROM.'?subject=unsubscribe>, <'.$sUnsubLink.'>');
|
||||||
$oPHPMailer->addCustomHeader('List-Unsubscribe-Post','List-Unsubscribe=One-Click');
|
$oPHPMailer->addCustomHeader('List-Unsubscribe-Post','List-Unsubscribe=One-Click');
|
||||||
|
|
||||||
//Email Content
|
//Email Content
|
||||||
$this->oTemplate->setTag('timezone', 'lang:city_time', self::getTimeZoneCity($asDest['timezone']));
|
$this->oTemplate->setTag('timezone', 'lang:city_time', self::getTimeZoneCity($asDest['timezone']));
|
||||||
$sHtmlMessage = $this->oTemplate->getMask();
|
$sHtmlMessage = $this->oTemplate->getMask();
|
||||||
$sPlainMessage = strip_tags(str_replace('<br />', "\n", $sHtmlMessage));
|
$sPlainMessage = strip_tags(str_replace('<br />', "\n", $sHtmlMessage));
|
||||||
|
|
||||||
//Recipients
|
//Recipients
|
||||||
$oPHPMailer->addAddress($asDest['email'], $asDest['name']);
|
$oPHPMailer->addAddress($asDest['email'], $asDest['name']);
|
||||||
|
|
||||||
//Content
|
//Content
|
||||||
$oPHPMailer->isHTML(true);
|
$oPHPMailer->isHTML(true);
|
||||||
$oPHPMailer->Subject = $this->oTemplate->getTranslator()->getTranslation($this->sTemplateName.'_subject');
|
$oPHPMailer->Subject = $this->oTemplate->getTranslator()->getTranslation($this->sTemplateName.'_subject');
|
||||||
$oPHPMailer->Body = $sHtmlMessage;
|
$oPHPMailer->Body = $sHtmlMessage;
|
||||||
$oPHPMailer->AltBody = $sPlainMessage;
|
$oPHPMailer->AltBody = $sPlainMessage;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$oPHPMailer->send();
|
$oPHPMailer->send();
|
||||||
}
|
}
|
||||||
@@ -92,8 +92,8 @@ class Email extends PhpObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function getTimeZoneCity($sTimeZone) {
|
private static function getTimeZoneCity($sTimeZone) {
|
||||||
return (strpos($sTimeZone, '/')!==false)?str_replace('_', ' ', explode('/', $sTimeZone)[1]):$sTimeZone;
|
return (strpos($sTimeZone, '/')!==false)?str_replace('_', ' ', explode('/', $sTimeZone)[1]):$sTimeZone;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
18
inc/feed.php
18
inc/feed.php
@@ -90,7 +90,7 @@ class Feed extends PhpObject {
|
|||||||
|
|
||||||
public function getMessages($asActivePeriod = array()) {
|
public function getMessages($asActivePeriod = array()) {
|
||||||
$asInfo = array(
|
$asInfo = array(
|
||||||
'select' => array('id_message', 'ref_msg_id', 'type', 'latitude', 'longitude', 'site_time', 'unix_time'),
|
'select' => array('id_message', 'ref_msg_id', 'type', 'latitude', 'longitude', 'site_time', 'timezone', 'unix_time'),
|
||||||
'from' => self::MSG_TABLE,
|
'from' => self::MSG_TABLE,
|
||||||
'constraint'=> array(Db::getId(self::FEED_TABLE) => $this->getFeedId()),
|
'constraint'=> array(Db::getId(self::FEED_TABLE) => $this->getFeedId()),
|
||||||
'constOpe' => array(Db::getId(self::FEED_TABLE) => "="),
|
'constOpe' => array(Db::getId(self::FEED_TABLE) => "="),
|
||||||
@@ -163,7 +163,8 @@ class Feed extends PhpObject {
|
|||||||
'latitude' => $asMsg['latitude'],
|
'latitude' => $asMsg['latitude'],
|
||||||
'longitude' => $asMsg['longitude'],
|
'longitude' => $asMsg['longitude'],
|
||||||
'iso_time' => $asMsg['dateTime'], //ISO 8601 time (backup)
|
'iso_time' => $asMsg['dateTime'], //ISO 8601 time (backup)
|
||||||
'site_time' => date(Db::TIMESTAMP_FORMAT, $asMsg['unixTime']), //Conversion to Site Time (default timezone, see Settings::TIMEZONE)
|
'site_time' => date(Db::TIMESTAMP_FORMAT, $asMsg['unixTime']), //Conversion to Site Time
|
||||||
|
'timezone' => Spot::getTimeZoneFromDate($asMsg['dateTime']), //Local Time Zone
|
||||||
'unix_time' => $asMsg['unixTime'], //UNIX Time (backup)
|
'unix_time' => $asMsg['unixTime'], //UNIX Time (backup)
|
||||||
'content' => $asMsg['messageContent'],
|
'content' => $asMsg['messageContent'],
|
||||||
'battery_state' => $asMsg['batteryState']
|
'battery_state' => $asMsg['batteryState']
|
||||||
@@ -200,13 +201,16 @@ class Feed extends PhpObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function delete() {
|
public function delete() {
|
||||||
$sDesc = '';
|
$asResult = array();
|
||||||
if($this->getFeedId() > 0) {
|
if($this->getFeedId() > 0) {
|
||||||
$bSuccess = $this->oDb->deleteRow(self::FEED_TABLE, $this->getFeedId());
|
$asResult = array(
|
||||||
if(!$bSuccess) $sDesc = $this->oDb->getLastError();
|
'id' => $this->getFeedId(),
|
||||||
|
'del' => $this->oDb->deleteRow(self::FEED_TABLE, $this->getFeedId()),
|
||||||
|
'desc' => $this->oDb->getLastError()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
else $sDesc = 'Error while setting project: no Feed ID';
|
else $asResult = array('del'=>false, 'desc'=>'Error while setting project: no Feed ID');
|
||||||
|
|
||||||
return $sDesc;
|
return $asResult;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
136
inc/media.php
136
inc/media.php
@@ -1,22 +1,22 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
class Media extends PhpObject {
|
class Media extends PhpObject {
|
||||||
|
|
||||||
//DB Tables
|
//DB Tables
|
||||||
const MEDIA_TABLE = 'medias';
|
const MEDIA_TABLE = 'medias';
|
||||||
|
|
||||||
//Media folders
|
//Media folders
|
||||||
const MEDIA_FOLDER = 'files/';
|
const MEDIA_FOLDER = 'files/';
|
||||||
const THUMB_FOLDER = self::MEDIA_FOLDER.'thumbs/';
|
const THUMB_FOLDER = self::MEDIA_FOLDER.'thumbs/';
|
||||||
|
|
||||||
const THUMB_MAX_WIDTH = 400;
|
const THUMB_MAX_WIDTH = 400;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Database Handle
|
* Database Handle
|
||||||
* @var Db
|
* @var Db
|
||||||
*/
|
*/
|
||||||
private $oDb;
|
private $oDb;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Media Project
|
* Media Project
|
||||||
* @var Project
|
* @var Project
|
||||||
@@ -25,9 +25,9 @@ class Media extends PhpObject {
|
|||||||
private $asMedia;
|
private $asMedia;
|
||||||
private $asMedias;
|
private $asMedias;
|
||||||
private $sSystemType;
|
private $sSystemType;
|
||||||
|
|
||||||
private $iMediaId;
|
private $iMediaId;
|
||||||
|
|
||||||
public function __construct(Db &$oDb, &$oProject, $iMediaId=0) {
|
public function __construct(Db &$oDb, &$oProject, $iMediaId=0) {
|
||||||
parent::__construct(__CLASS__, Settings::DEBUG);
|
parent::__construct(__CLASS__, Settings::DEBUG);
|
||||||
$this->oDb = &$oDb;
|
$this->oDb = &$oDb;
|
||||||
@@ -37,19 +37,19 @@ class Media extends PhpObject {
|
|||||||
$this->sSystemType = (substr(php_uname(), 0, 7) == "Windows")?'win':'unix';
|
$this->sSystemType = (substr(php_uname(), 0, 7) == "Windows")?'win':'unix';
|
||||||
$this->setMediaId($iMediaId);
|
$this->setMediaId($iMediaId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setMediaId($iMediaId) {
|
public function setMediaId($iMediaId) {
|
||||||
$this->iMediaId = $iMediaId;
|
$this->iMediaId = $iMediaId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getMediaId() {
|
public function getMediaId() {
|
||||||
return $this->iMediaId;
|
return $this->iMediaId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getProjectCodeName() {
|
public function getProjectCodeName() {
|
||||||
return $this->oProject->getProjectCodeName();
|
return $this->oProject->getProjectCodeName();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setComment($sComment) {
|
public function setComment($sComment) {
|
||||||
$sError = '';
|
$sError = '';
|
||||||
$asData = array();
|
$asData = array();
|
||||||
@@ -59,27 +59,27 @@ class Media extends PhpObject {
|
|||||||
else $asData = $this->getInfo();
|
else $asData = $this->getInfo();
|
||||||
}
|
}
|
||||||
else $sError = 'media_no_id';
|
else $sError = 'media_no_id';
|
||||||
|
|
||||||
return Spot::getResult(($sError==''), $sError, $asData);
|
return Spot::getResult(($sError==''), $sError, $asData);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getMediasInfo($iMediaId=0) {
|
public function getMediasInfo($iMediaId=0) {
|
||||||
$bOwnMedia = ($iMediaId > 0);
|
$bOwnMedia = ($iMediaId > 0);
|
||||||
if($bOwnMedia && empty($this->asMedia) || !$bOwnMedia && empty($this->asMedias)) {
|
if($bOwnMedia && empty($this->asMedia) || !$bOwnMedia && empty($this->asMedias)) {
|
||||||
if($this->oProject->getProjectId()) {
|
if($this->oProject->getProjectId()) {
|
||||||
$asParams = array(
|
$asParams = array(
|
||||||
'select' => array(Db::getId(self::MEDIA_TABLE), 'filename', 'taken_on', 'posted_on', 'rotate', 'type AS subtype', 'comment'),
|
'select' => array(Db::getId(self::MEDIA_TABLE), 'filename', 'taken_on', 'posted_on', 'timezone', 'rotate', 'type AS subtype', 'comment'),
|
||||||
'from' => self::MEDIA_TABLE,
|
'from' => self::MEDIA_TABLE,
|
||||||
'constraint'=> array(Db::getId(Project::PROJ_TABLE) => $this->oProject->getProjectId())
|
'constraint'=> array(Db::getId(Project::PROJ_TABLE) => $this->oProject->getProjectId())
|
||||||
);
|
);
|
||||||
if($bOwnMedia) $asParams['constraint'][Db::getId(self::MEDIA_TABLE)] = $iMediaId;
|
if($bOwnMedia) $asParams['constraint'][Db::getId(self::MEDIA_TABLE)] = $iMediaId;
|
||||||
|
|
||||||
$asMedias = $this->oDb->selectRows($asParams);
|
$asMedias = $this->oDb->selectRows($asParams);
|
||||||
foreach($asMedias as &$asMedia) {
|
foreach($asMedias as &$asMedia) {
|
||||||
$asMedia['media_path'] = self::getMediaPath($asMedia['filename']);
|
$asMedia['media_path'] = self::getMediaPath($asMedia['filename']);
|
||||||
$asMedia['thumb_path'] = $this->getMediaThumbnail($asMedia['filename']);
|
$asMedia['thumb_path'] = $this->getMediaThumbnail($asMedia['filename']);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!empty($asMedias)) {
|
if(!empty($asMedias)) {
|
||||||
if($bOwnMedia) $this->asMedia = array_shift($asMedias);
|
if($bOwnMedia) $this->asMedia = array_shift($asMedias);
|
||||||
else $this->asMedias = $asMedias;
|
else $this->asMedias = $asMedias;
|
||||||
@@ -88,15 +88,15 @@ class Media extends PhpObject {
|
|||||||
}
|
}
|
||||||
return $bOwnMedia?$this->asMedia:$this->asMedias;
|
return $bOwnMedia?$this->asMedia:$this->asMedias;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getInfo() {
|
public function getInfo() {
|
||||||
return $this->getMediasInfo($this->iMediaId);
|
return $this->getMediasInfo($this->iMediaId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function isProjectModeValid() {
|
public function isProjectModeValid() {
|
||||||
return ($this->oProject->getMode() == Project::MODE_BLOG);
|
return ($this->oProject->getMode() == Project::MODE_BLOG);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function addMedia($sMediaName, $sMethod='upload') {
|
public function addMedia($sMediaName, $sMethod='upload') {
|
||||||
$sError = '';
|
$sError = '';
|
||||||
$asParams = array();
|
$asParams = array();
|
||||||
@@ -109,30 +109,32 @@ class Media extends PhpObject {
|
|||||||
$asParams[] = $sMediaName;
|
$asParams[] = $sMediaName;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
//Add media to DB
|
|
||||||
$asMediaInfo = $this->getMediaInfoFromFile($sMediaName);
|
$asMediaInfo = $this->getMediaInfoFromFile($sMediaName);
|
||||||
|
|
||||||
|
//Converting times to DB Time Zone, by using date()
|
||||||
$asDbInfo = array(
|
$asDbInfo = array(
|
||||||
Db::getId(Project::PROJ_TABLE) => $this->oProject->getProjectId(),
|
Db::getId(Project::PROJ_TABLE) => $this->oProject->getProjectId(),
|
||||||
'filename' => $sMediaName,
|
'filename' => $sMediaName,
|
||||||
'taken_on' => ($asMediaInfo['taken_ts'] > 0)?date(Db::TIMESTAMP_FORMAT, $asMediaInfo['taken_ts']):0, //Site Time
|
'taken_on' => ($asMediaInfo['taken_ts'] > 0)?date(Db::TIMESTAMP_FORMAT, $asMediaInfo['taken_ts']):0,
|
||||||
'posted_on' => date(Db::TIMESTAMP_FORMAT, $asMediaInfo['file_ts']), //Site Time
|
'posted_on' => date(Db::TIMESTAMP_FORMAT, $asMediaInfo['file_ts']),
|
||||||
|
'timezone' => $asMediaInfo['timezone'],
|
||||||
'rotate' => $asMediaInfo['rotate'],
|
'rotate' => $asMediaInfo['rotate'],
|
||||||
'type' => $asMediaInfo['type']
|
'type' => $asMediaInfo['type']
|
||||||
);
|
);
|
||||||
|
|
||||||
if($sMethod=='sync') $iMediaId = $this->oDb->insertUpdateRow(self::MEDIA_TABLE, $asDbInfo, array(Db::getId(Project::PROJ_TABLE), 'filename'));
|
if($sMethod=='sync') $iMediaId = $this->oDb->insertUpdateRow(self::MEDIA_TABLE, $asDbInfo, array(Db::getId(Project::PROJ_TABLE), 'filename'));
|
||||||
else $iMediaId = $this->oDb->insertRow(self::MEDIA_TABLE, $asDbInfo);
|
else $iMediaId = $this->oDb->insertRow(self::MEDIA_TABLE, $asDbInfo);
|
||||||
|
|
||||||
if(!$iMediaId) $sError = 'error_commit_db';
|
if(!$iMediaId) $sError = 'error_commit_db';
|
||||||
else {
|
else {
|
||||||
$this->setMediaId($iMediaId);
|
$this->setMediaId($iMediaId);
|
||||||
$asParams = $this->getInfo(); //Creates thumbnail
|
$asParams = $this->getInfo(); //Creates thumbnail
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Spot::getResult(($sError==''), $sError, $asParams);
|
return Spot::getResult(($sError==''), $sError, $asParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* One-shot function to initialize DB with existing images
|
* One-shot function to initialize DB with existing images
|
||||||
*/
|
*/
|
||||||
@@ -146,13 +148,15 @@ class Media extends PhpObject {
|
|||||||
$this->setExtractMode(PhpObject::MODE_HTML);
|
$this->setExtractMode(PhpObject::MODE_HTML);
|
||||||
return $this->getCleanMessageStack();
|
return $this->getCleanMessageStack();
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getMediaInfoFromFile($sMediaName)
|
private function getMediaInfoFromFile($sMediaName)
|
||||||
{
|
{
|
||||||
$sMediaPath = self::getMediaPath($sMediaName);
|
$sMediaPath = self::getMediaPath($sMediaName);
|
||||||
$sType = self::getMediaType($sMediaName);
|
$sType = self::getMediaType($sMediaName);
|
||||||
|
|
||||||
$iTimeStamp = $iTakenOn = $iPostedOn = 0;
|
$iTimeStamp = $iTakenOn = 0;
|
||||||
|
$iPostedOn = filemtime($sMediaPath);
|
||||||
|
$sTimeZone = date_default_timezone_get();
|
||||||
$sRotate = '0';
|
$sRotate = '0';
|
||||||
$sTakenOn = '';
|
$sTakenOn = '';
|
||||||
switch($sType) {
|
switch($sType) {
|
||||||
@@ -161,28 +165,44 @@ class Media extends PhpObject {
|
|||||||
$sParams = implode(' ', array(
|
$sParams = implode(' ', array(
|
||||||
'-loglevel error', //Remove comments
|
'-loglevel error', //Remove comments
|
||||||
'-select_streams v:0', //First video channel
|
'-select_streams v:0', //First video channel
|
||||||
'-show_entries stream_tags=rotate,creation_time', //filter tags :rotation & creation time only
|
'-show_entries '. //filter tags : Creation Time & Rotation
|
||||||
|
'format_tags=creation_time,com.apple.quicktime.creationdate'.':'.
|
||||||
|
'stream_tags=rotate,creation_time',
|
||||||
'-print_format json', //output format: json
|
'-print_format json', //output format: json
|
||||||
'-i' //input file
|
'-i' //input file
|
||||||
));
|
));
|
||||||
exec('ffprobe '.$sParams.' "'.$sMediaPath.'"', $asResult);
|
exec('ffprobe '.$sParams.' "'.$sMediaPath.'"', $asResult);
|
||||||
$asResult = json_decode(implode('', $asResult), true);
|
$asExif = json_decode(implode('', $asResult), true);
|
||||||
|
|
||||||
//Timestamps
|
//Taken On
|
||||||
$sTakenOn = date(Db::TIMESTAMP_FORMAT, strtotime($asResult['streams'][0]['tags']['creation_time']));
|
if(isset($asExif['format']['tags']['com.apple.quicktime.creationdate'])) {
|
||||||
$iPostedOn = filemtime($sMediaPath);
|
$sTakenOn = $asExif['format']['tags']['com.apple.quicktime.creationdate']; //contains Time Zone
|
||||||
|
$sTimeZone = Spot::getTimeZoneFromDate($sTakenOn) ?? $sTimeZone;
|
||||||
|
}
|
||||||
|
else $sTakenOn = $asExif['format']['tags']['creation_time'] ?? $asExif['streams'][0]['tags']['creation_time'];
|
||||||
|
|
||||||
//Orientation
|
//Orientation
|
||||||
if(isset($asResult['streams'][0]['tags']['rotate'])) $sRotate = $asResult['streams'][0]['tags']['rotate'];
|
if(isset($asExif['streams'][0]['tags']['rotate'])) $sRotate = $asExif['streams'][0]['tags']['rotate'];
|
||||||
break;
|
break;
|
||||||
case 'image':
|
case 'image':
|
||||||
$asExif = @exif_read_data($sMediaPath, 0, true);
|
$asExif = @exif_read_data($sMediaPath, 0, true);
|
||||||
if(!$asExif) $asExif['FILE']['FileDateTime'] = filemtime($sMediaPath);
|
|
||||||
|
//Posted On
|
||||||
//Timestamps
|
|
||||||
if(array_key_exists('EXIF', $asExif) && array_key_exists('DateTimeOriginal', $asExif['EXIF'])) $sTakenOn = $asExif['EXIF']['DateTimeOriginal'];
|
|
||||||
if(array_key_exists('FILE', $asExif) && array_key_exists('FileDateTime', $asExif['FILE'])) $iPostedOn = $asExif['FILE']['FileDateTime'];
|
if(array_key_exists('FILE', $asExif) && array_key_exists('FileDateTime', $asExif['FILE'])) $iPostedOn = $asExif['FILE']['FileDateTime'];
|
||||||
|
|
||||||
|
//Taken On & Timezone
|
||||||
|
if(array_key_exists('EXIF', $asExif)) {
|
||||||
|
if(array_key_exists('DateTimeOriginal', $asExif['EXIF'])) $sTakenOn = $asExif['EXIF']['DateTimeOriginal'];
|
||||||
|
|
||||||
|
/* Priorities:
|
||||||
|
* 1. OffsetTimeOriginal: timezone for DateTimeOriginal (exif version >= 2.31)
|
||||||
|
* 2. 0x9011: same as above, but unidentified
|
||||||
|
* 3. Timezone extracted from DateTimeOriginal
|
||||||
|
* 4. Uploader Browser Time Zone (PHP Default Time Zone)
|
||||||
|
*/
|
||||||
|
$sTimeZone = $asExif['EXIF']['OffsetTimeOriginal'] ?? $asExif['EXIF']['UndefinedTag:0x9011'] ?? Spot::getTimeZoneFromDate($sTakenOn) ?? $sTimeZone;
|
||||||
|
}
|
||||||
|
|
||||||
//Orientation
|
//Orientation
|
||||||
if(array_key_exists('IFD0', $asExif) && array_key_exists('Orientation', $asExif['IFD0'])) {
|
if(array_key_exists('IFD0', $asExif) && array_key_exists('Orientation', $asExif['IFD0'])) {
|
||||||
switch($asExif['IFD0']['Orientation'])
|
switch($asExif['IFD0']['Orientation'])
|
||||||
@@ -195,30 +215,32 @@ class Media extends PhpObject {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Media info do not have any TZ: Interpreting date time using project timezone (assuming all medias have been taken in this time zone)
|
//Assign the correct Time Zone to $sTakenOn if it is not already contained in it. Then get Unix Timestamp
|
||||||
|
//Time Zone (2nd parameter) will be ignored if already contained in $sTakenOn
|
||||||
if($sTakenOn != '') {
|
if($sTakenOn != '') {
|
||||||
$oTakenOn = new DateTime($sTakenOn, new DateTimeZone($this->oProject->getTimeZone()));
|
$oTakenOn = new DateTime($sTakenOn, new DateTimeZone($sTimeZone));
|
||||||
$iTakenOn = $oTakenOn->format('U');
|
$iTakenOn = $oTakenOn->format('U');
|
||||||
}
|
}
|
||||||
|
|
||||||
//Merge timestamps
|
//Merge timestamps
|
||||||
$iTimeStamp = ($iTakenOn > 0)?$iTakenOn:$iPostedOn;
|
$iTimeStamp = ($iTakenOn > 0)?$iTakenOn:$iPostedOn;
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
'timestamp' => $iTimeStamp,
|
'timestamp' => $iTimeStamp,
|
||||||
|
'timezone' => $sTimeZone,
|
||||||
'taken_ts' => $iTakenOn,
|
'taken_ts' => $iTakenOn,
|
||||||
'file_ts' => $iPostedOn,
|
'file_ts' => $iPostedOn,
|
||||||
'rotate' => $sRotate,
|
'rotate' => $sRotate,
|
||||||
'type' => $sType
|
'type' => $sType
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getMediaThumbnail($sMediaName)
|
private function getMediaThumbnail($sMediaName)
|
||||||
{
|
{
|
||||||
$sMediaPath = self::getMediaPath($sMediaName);
|
$sMediaPath = self::getMediaPath($sMediaName);
|
||||||
$sThumbPath = self::getMediaPath($sMediaName, 'thumbnail');
|
$sThumbPath = self::getMediaPath($sMediaName, 'thumbnail');
|
||||||
|
|
||||||
if(!file_exists($sThumbPath)) {
|
if(!file_exists($sThumbPath)) {
|
||||||
$sType = self::getMediaType($sMediaName);
|
$sType = self::getMediaType($sMediaName);
|
||||||
switch($sType) {
|
switch($sType) {
|
||||||
@@ -236,23 +258,23 @@ class Media extends PhpObject {
|
|||||||
'"'.$sTempPath.'"', //output file
|
'"'.$sTempPath.'"', //output file
|
||||||
));
|
));
|
||||||
exec('ffmpeg '.$sParams, $asResult);
|
exec('ffmpeg '.$sParams, $asResult);
|
||||||
|
|
||||||
//Resize
|
//Resize
|
||||||
$asThumbInfo = ToolBox::createThumbnail($sTempPath, self::THUMB_MAX_WIDTH, 0, $sThumbPath, true);
|
$asThumbInfo = ToolBox::createThumbnail($sTempPath, self::THUMB_MAX_WIDTH, 0, $sThumbPath, true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else $asThumbInfo = array('error'=>'', 'out'=>$sThumbPath);
|
else $asThumbInfo = array('error'=>'', 'out'=>$sThumbPath);
|
||||||
|
|
||||||
return ($asThumbInfo['error']=='')?$asThumbInfo['out']:$sMediaPath;
|
return ($asThumbInfo['error']=='')?$asThumbInfo['out']:$sMediaPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function getMediaPath($sMediaName, $sFileType='media') {
|
private static function getMediaPath($sMediaName, $sFileType='media') {
|
||||||
if($sFileType=='thumbnail') return self::THUMB_FOLDER.$sMediaName.(strtolower(substr($sMediaName, -3))=='mov'?'.png':'');
|
if($sFileType=='thumbnail') return self::THUMB_FOLDER.$sMediaName.(strtolower(substr($sMediaName, -3))=='mov'?'.png':'');
|
||||||
else return self::MEDIA_FOLDER.$sMediaName;
|
else return self::MEDIA_FOLDER.$sMediaName;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function getMediaType($sMediaName) {
|
private static function getMediaType($sMediaName) {
|
||||||
$sMediaPath = self::getMediaPath($sMediaName);
|
$sMediaPath = self::getMediaPath($sMediaName);
|
||||||
$sMediaMime = mime_content_type($sMediaPath);
|
$sMediaMime = mime_content_type($sMediaPath);
|
||||||
@@ -260,7 +282,7 @@ class Media extends PhpObject {
|
|||||||
case 'video/quicktime': $sType = 'video'; break;
|
case 'video/quicktime': $sType = 'video'; break;
|
||||||
default: $sType = 'image'; break;
|
default: $sType = 'image'; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $sType;
|
return $sType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ class Project extends PhpObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function createProjectId() {
|
public function createProjectId() {
|
||||||
$this->setProjectId($this->oDb->insertRow(self::PROJ_TABLE, array('timezone'=>Settings::TIMEZONE)));
|
$this->setProjectId($this->oDb->insertRow(self::PROJ_TABLE, array('codename'=>'')));
|
||||||
return $this->getProjectId();
|
return $this->getProjectId();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,14 +104,6 @@ class Project extends PhpObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getTimeZone() {
|
|
||||||
return $this->asGeo['timezone'];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setTimeZone($sTimeZone) {
|
|
||||||
return $this->updateField('timezone', $sTimeZone);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getFeedIds() {
|
public function getFeedIds() {
|
||||||
return $this->oDb->selectColumn(
|
return $this->oDb->selectColumn(
|
||||||
Feed::FEED_TABLE,
|
Feed::FEED_TABLE,
|
||||||
@@ -129,8 +121,7 @@ class Project extends PhpObject {
|
|||||||
'name',
|
'name',
|
||||||
'active_from',
|
'active_from',
|
||||||
'active_to',
|
'active_to',
|
||||||
"IF(NOW() BETWEEN active_from AND active_to, 1, IF(NOW() < active_from, 0, 2)) AS mode",
|
"IF(NOW() BETWEEN active_from AND active_to, 1, IF(NOW() < active_from, 0, 2)) AS mode"
|
||||||
'timezone'
|
|
||||||
),
|
),
|
||||||
'from' => self::PROJ_TABLE
|
'from' => self::PROJ_TABLE
|
||||||
);
|
);
|
||||||
@@ -186,7 +177,7 @@ class Project extends PhpObject {
|
|||||||
$this->asActive = array('from'=>$asProject['active_from'], 'to'=>$asProject['active_to']);
|
$this->asActive = array('from'=>$asProject['active_from'], 'to'=>$asProject['active_to']);
|
||||||
$this->sCodeName = $asProject['codename'];
|
$this->sCodeName = $asProject['codename'];
|
||||||
$this->sName = $asProject['name'];
|
$this->sName = $asProject['name'];
|
||||||
$this->asGeo = array('geofile'=>$asProject['geofilepath'], 'gpxfile'=>$asProject['gpxfilepath'], 'timezone'=>$asProject['timezone']);
|
$this->asGeo = array('geofile'=>$asProject['geofilepath'], 'gpxfile'=>$asProject['gpxfilepath']);
|
||||||
}
|
}
|
||||||
else $this->addError('Error while setting project: no project ID');
|
else $this->addError('Error while setting project: no project ID');
|
||||||
}
|
}
|
||||||
@@ -199,13 +190,21 @@ class Project extends PhpObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function delete() {
|
public function delete() {
|
||||||
$sDesc = '';
|
$asResult = array();
|
||||||
if($this->getProjectId() > 0) {
|
if($this->getProjectId() > 0) {
|
||||||
$bSuccess = $this->oDb->deleteRow(self::PROJ_TABLE, $this->getProjectId());
|
$asFeedIds = $this->getFeedIds();
|
||||||
if(!$bSuccess) $sDesc = $this->oDb->getLastError();
|
foreach($asFeedIds as $iFeedId) {
|
||||||
}
|
$asResult['feed'][] = (new Feed($this->oDb, $iFeedId))->delete();
|
||||||
else $sDesc = 'Error while setting project: no project ID';
|
}
|
||||||
|
|
||||||
return $sDesc;
|
$asResult['project'][] = array(
|
||||||
|
'id' => $this->getProjectId(),
|
||||||
|
'del' => $this->oDb->deleteRow(self::PROJ_TABLE, $this->getProjectId()),
|
||||||
|
'desc' => $this->oDb->getLastError()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else $asResult['project'][] = array('del'=>false, 'desc'=>'Error while setting project: no project ID');
|
||||||
|
|
||||||
|
return $asResult;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
121
inc/spot.php
121
inc/spot.php
@@ -1,17 +1,21 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/* Timezones
|
/* Timezones
|
||||||
|
* ---------
|
||||||
|
* Site Time: Time Zone in which the User is viewing the Site (default PHP/SQL Timezone)
|
||||||
|
* Local Time: Time Zone in which the Spot Owner is
|
||||||
|
*
|
||||||
* - Feeds (table `feeds`):
|
* - Feeds (table `feeds`):
|
||||||
* - last_update: timestamp in site time (see Settings::TIMEZONE)
|
* - last_update: timestamp in Site Time
|
||||||
* - Spot Messages (table `messages`):
|
* - Spot Messages (table `messages`):
|
||||||
* - unix_time: UNIX (int) in UTC
|
* - unix_time: UNIX (int) in UTC
|
||||||
* - site_time: timestamp in site time (see Settings::TIMEZONE)
|
* - site_time: timestamp in Site Time
|
||||||
* - iso_time: raw ISO 8601 in local timezone
|
* - iso_time: raw ISO 8601 in Local Time
|
||||||
* - Medias (table `medias`):
|
* - Medias (table `medias`):
|
||||||
* - posted_on: timestamp in site time (see Settings::TIMEZONE)
|
* - posted_on: timestamp in Site Time
|
||||||
* - taken_on: timestamp in site time (see Settings::TIMEZONE)
|
* - taken_on: timestamp in Site Time
|
||||||
* - Posts (table `posts`):
|
* - Posts (table `posts`):
|
||||||
* - site_time: timestamp in site time (see Settings::TIMEZONE)
|
* - site_time: timestamp in Site Time
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class Spot extends Main
|
class Spot extends Main
|
||||||
@@ -71,18 +75,24 @@ class Spot extends Main
|
|||||||
$this->oDb->install();
|
$this->oDb->install();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function syncPics() {
|
||||||
|
if(Settings::DEBUG) {
|
||||||
|
return (new Media($this->oDb, $this->oProject))->syncFileFolder();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected function getSqlOptions()
|
protected function getSqlOptions()
|
||||||
{
|
{
|
||||||
return array
|
return array
|
||||||
(
|
(
|
||||||
'tables' => array
|
'tables' => array
|
||||||
(
|
(
|
||||||
Feed::MSG_TABLE => array('ref_msg_id', Db::getId(Feed::FEED_TABLE), 'type', 'latitude', 'longitude', 'iso_time', 'site_time', 'unix_time', 'content', 'battery_state'),
|
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'),
|
||||||
Feed::FEED_TABLE => array('ref_feed_id', Db::getId(Feed::SPOT_TABLE), Db::getId(Project::PROJ_TABLE), 'name', 'description', 'status', 'last_update'),
|
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'),
|
Feed::SPOT_TABLE => array('ref_spot_id', 'name', 'model'),
|
||||||
Project::PROJ_TABLE => array('name', 'codename', 'active_from', 'active_to', 'timezone'),
|
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'),
|
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', 'rotate', 'comment'),
|
Media::MEDIA_TABLE => array(Db::getId(Project::PROJ_TABLE), 'filename', 'type', 'taken_on', 'posted_on', 'timezone', 'rotate', 'comment'),
|
||||||
User::USER_TABLE => array('name', 'email', 'gravatar', 'language', 'timezone', 'active'),
|
User::USER_TABLE => array('name', 'email', 'gravatar', 'language', 'timezone', 'active'),
|
||||||
self::MAP_TABLE => array('codename', 'geo_name', 'min_zoom', 'max_zoom', 'attribution'),
|
self::MAP_TABLE => array('codename', 'geo_name', 'min_zoom', 'max_zoom', 'attribution'),
|
||||||
self::MAPPING_TABLE => array(Db::getId(self::MAP_TABLE) , Db::getId(Project::PROJ_TABLE))
|
self::MAPPING_TABLE => array(Db::getId(self::MAP_TABLE) , Db::getId(Project::PROJ_TABLE))
|
||||||
@@ -235,11 +245,11 @@ class Spot extends Main
|
|||||||
public function getMarkers()
|
public function getMarkers()
|
||||||
{
|
{
|
||||||
$asMessages = $this->getSpotMessages();
|
$asMessages = $this->getSpotMessages();
|
||||||
$bSuccess = !empty($this->getMedias('posted_on') + $asMessages + $this->getPosts());
|
$bEmptyProject = empty($this->getMedias('posted_on') + $asMessages + $this->getPosts());
|
||||||
$sDesc = $bSuccess?'':self::NO_DATA;
|
$sDesc = '';
|
||||||
|
|
||||||
//Add medias
|
//Add medias
|
||||||
if($bSuccess) {
|
if(!empty($asMessages)) {
|
||||||
$asMedias = $this->getMedias('taken_on');
|
$asMedias = $this->getMedias('taken_on');
|
||||||
|
|
||||||
//Assign medias to closest message
|
//Assign medias to closest message
|
||||||
@@ -264,10 +274,12 @@ class Spot extends Main
|
|||||||
$asLastUpdate = array();
|
$asLastUpdate = array();
|
||||||
$this->addTimeStamp($asLastUpdate, $this->oProject->getLastUpdate());
|
$this->addTimeStamp($asLastUpdate, $this->oProject->getLastUpdate());
|
||||||
|
|
||||||
return self::getJsonResult($bSuccess, $sDesc, array(
|
return self::getJsonResult(true, $sDesc, array(
|
||||||
'messages' => $asMessages,
|
'messages' => $asMessages,
|
||||||
'maps' => $this->oProject->getMaps(),
|
'maps' => $this->oProject->getMaps(),
|
||||||
'last_update' => $asLastUpdate));
|
'last_update' => $asLastUpdate,
|
||||||
|
'empty_project' => $bEmptyProject
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function subscribe($sEmail) {
|
public function subscribe($sEmail) {
|
||||||
@@ -315,7 +327,7 @@ class Spot extends Main
|
|||||||
$asMessage['lat_dms'] = self::decToDms($asMessage['latitude'], 'lat');
|
$asMessage['lat_dms'] = self::decToDms($asMessage['latitude'], 'lat');
|
||||||
$asMessage['lon_dms'] = self::decToDms($asMessage['longitude'], 'lon');
|
$asMessage['lon_dms'] = self::decToDms($asMessage['longitude'], 'lon');
|
||||||
|
|
||||||
$this->addTimeStamp($asMessage, $asMessage['unix_time']);
|
$this->addTimeStamp($asMessage, $asMessage['unix_time'], $asMessage['timezone']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -343,10 +355,14 @@ class Spot extends Main
|
|||||||
foreach($asMedias as $asMedia) {
|
foreach($asMedias as $asMedia) {
|
||||||
$sTimeRef = $asMedia[$sTimeRefField];
|
$sTimeRef = $asMedia[$sTimeRefField];
|
||||||
if($sTimeRef >= $this->oProject->getActivePeriod('from') && $sTimeRef <= $this->oProject->getActivePeriod('to')) {
|
if($sTimeRef >= $this->oProject->getActivePeriod('from') && $sTimeRef <= $this->oProject->getActivePeriod('to')) {
|
||||||
$asMedia['taken_on_formatted'] = $this->getTimeFormat(strtotime($asMedia['taken_on']));
|
$iTimeStampTakenOn = strtotime($asMedia['taken_on']);
|
||||||
$asMedia['posted_on_formatted'] = $this->getTimeFormat(strtotime($asMedia['posted_on']));
|
$iTimeStampPostedOn = strtotime($asMedia['posted_on']);
|
||||||
|
$asMedia['taken_on_formatted'] = $this->getTimeFormat($iTimeStampTakenOn);
|
||||||
|
$asMedia['taken_on_formatted_local'] = $this->getTimeFormat($iTimeStampTakenOn, $asMedia['timezone']);
|
||||||
|
$asMedia['posted_on_formatted'] = $this->getTimeFormat($iTimeStampPostedOn);
|
||||||
|
$asMedia['posted_on_formatted_local'] = $this->getTimeFormat($iTimeStampPostedOn, $asMedia['timezone']);
|
||||||
|
|
||||||
$this->addTimeStamp($asMedia, strtotime($sTimeRef));
|
$this->addTimeStamp($asMedia, strtotime($sTimeRef), $asMedia['timezone']);
|
||||||
$asValidMedias[] = $asMedia;
|
$asValidMedias[] = $asMedia;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -379,17 +395,18 @@ class Spot extends Main
|
|||||||
$asPost['formatted_name'] = Toolbox::mb_ucwords($asPost['name']);
|
$asPost['formatted_name'] = Toolbox::mb_ucwords($asPost['name']);
|
||||||
unset($asPost[Db::getId(User::USER_TABLE)]);
|
unset($asPost[Db::getId(User::USER_TABLE)]);
|
||||||
|
|
||||||
$this->addTimeStamp($asPost, $iUnixTimeStamp);
|
$this->addTimeStamp($asPost, $iUnixTimeStamp, $asPost['timezone']);
|
||||||
}
|
}
|
||||||
usort($asPosts, function($a, $b){return $a['unix_time'] > $b['unix_time'];});
|
usort($asPosts, function($a, $b){return $a['unix_time'] > $b['unix_time'];});
|
||||||
|
|
||||||
return $asPosts;
|
return $asPosts;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function addTimeStamp(&$asData, $iTime) {
|
private function addTimeStamp(&$asData, $iTime, $sTimeZone='') {
|
||||||
$asData['unix_time'] = (int) $iTime;
|
$asData['unix_time'] = (int) $iTime;
|
||||||
$asData['relative_time'] = Toolbox::getDateTimeDesc($iTime, $this->oLang->getLanguage());
|
$asData['relative_time'] = Toolbox::getDateTimeDesc($iTime, $this->oLang->getLanguage());
|
||||||
$asData['formatted_time'] = $this->getTimeFormat($iTime);
|
$asData['formatted_time'] = $this->getTimeFormat($iTime);
|
||||||
|
if($sTimeZone != '') $asData['formatted_time_local'] = $this->getTimeFormat($iTime, $sTimeZone);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getNewsFeed($iChunk=0, $bInternal=false)
|
public function getNewsFeed($iChunk=0, $bInternal=false)
|
||||||
@@ -446,7 +463,8 @@ class Spot extends Main
|
|||||||
Db::getId(Project::PROJ_TABLE) => $this->oProject->getProjectId(),
|
Db::getId(Project::PROJ_TABLE) => $this->oProject->getProjectId(),
|
||||||
'name' => mb_strtolower(trim($sName)),
|
'name' => mb_strtolower(trim($sName)),
|
||||||
'content' => trim($sPost),
|
'content' => trim($sPost),
|
||||||
'site_time' => date(Db::TIMESTAMP_FORMAT) //site time (Settings::TIMEZONE)
|
'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();
|
if($this->oUser->getUserId() > 0) $asData[Db::getId(User::USER_TABLE)] = $this->oUser->getUserId();
|
||||||
|
|
||||||
@@ -471,13 +489,19 @@ class Spot extends Main
|
|||||||
return self::getJsonResult($asResult['result'], $asResult['desc'], $asResult['data']);
|
return self::getJsonResult($asResult['result'], $asResult['desc'], $asResult['data']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getAdminSettings() {
|
public function getAdminSettings($sType='') {
|
||||||
$oFeed = new Feed($this->oDb);
|
$oFeed = new Feed($this->oDb);
|
||||||
$asData = array(
|
$asData = array(
|
||||||
'project' => $this->oProject->getProjects(),
|
'project' => $this->oProject->getProjects(),
|
||||||
'feed' => $oFeed->getFeeds(),
|
'feed' => $oFeed->getFeeds(),
|
||||||
'spot' => $oFeed->getSpots()
|
'spot' => $oFeed->getSpots()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
foreach($asData['project'] as &$asProject) {
|
||||||
|
$asProject['active_from'] = substr($asProject['active_from'], 0, 10);
|
||||||
|
$asProject['active_to'] = substr($asProject['active_to'], 0, 10);
|
||||||
|
}
|
||||||
|
|
||||||
return self::getJsonResult(true, '', $asData);
|
return self::getJsonResult(true, '', $asData);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -502,30 +526,32 @@ class Spot extends Main
|
|||||||
case 'active_to':
|
case 'active_to':
|
||||||
$bSuccess = $oProject->setActivePeriod($sValue.' 23:59:59', 'to');
|
$bSuccess = $oProject->setActivePeriod($sValue.' 23:59:59', 'to');
|
||||||
break;
|
break;
|
||||||
case 'timezone':
|
default:
|
||||||
$bSuccess = $oProject->setTimeZone($sValue);
|
$sDesc = $this->oLang->getTranslation('unknown_field', $sField);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
$asResult = $oProject->getProject();
|
$asResult = $oProject->getProject();
|
||||||
|
$asResult['active_from'] = substr($asResult['active_from'], 0, 10);
|
||||||
|
$asResult['active_to'] = substr($asResult['active_to'], 0, 10);
|
||||||
break;
|
break;
|
||||||
case 'feed':
|
case 'feed':
|
||||||
case 'spot':
|
|
||||||
$oFeed = new Feed($this->oDb, $iId);
|
$oFeed = new Feed($this->oDb, $iId);
|
||||||
switch($sField) {
|
switch($sField) {
|
||||||
case 'ref_feed_id':
|
case 'ref_feed_id':
|
||||||
$bSuccess = $oFeed->setRefFeedId($sValue);
|
$bSuccess = $oFeed->setRefFeedId($sValue);
|
||||||
break;
|
break;
|
||||||
case 'spot_id':
|
case 'id_spot':
|
||||||
$bSuccess = $oFeed->setSpotId($sValue);
|
$bSuccess = $oFeed->setSpotId($sValue);
|
||||||
break;
|
break;
|
||||||
case 'project_id':
|
case 'id_project':
|
||||||
$bSuccess = $oFeed->setProjectId($sValue);
|
$bSuccess = $oFeed->setProjectId($sValue);
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
$sDesc = $this->oLang->getTranslation('unknown_field', $sField);
|
||||||
}
|
}
|
||||||
$asResult = $oFeed->getFeed();
|
$asResult = $oFeed->getFeed();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(!$bSuccess) $sDesc = Mask::LANG_PREFIX.'error_commit_db';
|
if(!$bSuccess && $sDesc=='') $sDesc = Mask::LANG_PREFIX.'error_commit_db';
|
||||||
|
|
||||||
return self::getJsonResult($bSuccess, $sDesc, array($sType=>array($asResult)));
|
return self::getJsonResult($bSuccess, $sDesc, array($sType=>array($asResult)));
|
||||||
}
|
}
|
||||||
@@ -537,16 +563,18 @@ class Spot extends Main
|
|||||||
switch($sType) {
|
switch($sType) {
|
||||||
case 'project':
|
case 'project':
|
||||||
$oProject = new Project($this->oDb, $iId);
|
$oProject = new Project($this->oDb, $iId);
|
||||||
$sDesc = $oProject->delete();
|
$asResult = $oProject->delete();
|
||||||
|
$sDesc = $asResult['project'][0]['desc'];
|
||||||
break;
|
break;
|
||||||
case 'feed':
|
case 'feed':
|
||||||
$oFeed = new Feed($this->oDb, $iId);
|
$oFeed = new Feed($this->oDb, $iId);
|
||||||
$sDesc = $oFeed->delete();
|
$asResult = array('feed'=>array($oFeed->delete()));
|
||||||
|
$sDesc = $asResult['feed'][0]['desc'];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
$bSuccess = ($sDesc=='');
|
$bSuccess = ($sDesc=='');
|
||||||
|
|
||||||
return self::getJsonResult($bSuccess, $sDesc, array($sType=>array(array('id'=>$iId, 'del'=>$bSuccess))));
|
return self::getJsonResult($bSuccess, $sDesc, $asResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function createProject() {
|
public function createProject() {
|
||||||
@@ -586,9 +614,30 @@ class Spot extends Main
|
|||||||
return $iDegree.'°'.$iMinute."'".$fSecond.'"'.$sDirection;
|
return $iDegree.'°'.$iMinute."'".$fSecond.'"'.$sDirection;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getTimeFormat($iTime) {
|
public function getTimeFormat($iTime, $sTimeZone='') {
|
||||||
$sDate = date('d/m/Y', $iTime);
|
if($sTimeZone=='') $sTimeZone = date_default_timezone_get();
|
||||||
$sTime = date('H:i', $iTime);
|
|
||||||
|
$oDate = new DateTime('@'.$iTime);
|
||||||
|
$oDate->setTimezone(new DateTimeZone($sTimeZone));
|
||||||
|
|
||||||
|
$sDate = $oDate->format('d/m/Y');
|
||||||
|
$sTime = $oDate->format('H:i');
|
||||||
return $this->oLang->getTranslation('date_time', array($sDate, $sTime));
|
return $this->oLang->getTranslation('date_time', array($sDate, $sTime));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getTimeZoneFromDate($sDate) {
|
||||||
|
$sTimeZone = null;
|
||||||
|
|
||||||
|
preg_match('/(?<timezone>(\+|\-)\d{2}:?(\d{2}|))$/', $sDate, $asMatch);
|
||||||
|
if(array_key_exists('timezone', $asMatch)) {
|
||||||
|
$sTimeZone = $asMatch['timezone'];
|
||||||
|
|
||||||
|
//Complete short form: +12 => +1200
|
||||||
|
if(strlen($sTimeZone) == 3) $sTimeZone .= '00';
|
||||||
|
|
||||||
|
//Add colon: +1200 => +12:00
|
||||||
|
if(!strpos($sTimeZone, ':')) $sTimeZone = substr_replace($sTimeZone, ':', 3, 0);
|
||||||
|
}
|
||||||
|
return $sTimeZone;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
2939
inc/uploader.php
2939
inc/uploader.php
File diff suppressed because it is too large
Load Diff
@@ -13,11 +13,11 @@ ToolBox::fixGlobalVars(isset($argv)?$argv:array());
|
|||||||
|
|
||||||
//Available variables
|
//Available variables
|
||||||
$sAction = isset($_REQUEST['a'])?$_REQUEST['a']:'';
|
$sAction = isset($_REQUEST['a'])?$_REQUEST['a']:'';
|
||||||
$sTimezone = isset($_REQUEST['t'])?$_REQUEST['t']:'';
|
$sTimezone = $_REQUEST['t'] ?? '';
|
||||||
$sName = isset($_GET['name'])?$_GET['name']:'';
|
$sName = isset($_GET['name'])?$_GET['name']:'';
|
||||||
$sContent = isset($_GET['content'])?$_GET['content']:'';
|
$sContent = isset($_GET['content'])?$_GET['content']:'';
|
||||||
$iChunk = isset($_GET['chunk'])?$_GET['chunk']:0;
|
$iChunk = isset($_GET['chunk'])?$_GET['chunk']:0;
|
||||||
$iProjectId = isset($_REQUEST['project_id'])?$_REQUEST['project_id']:0;
|
$iProjectId = $_REQUEST['id_project'] ?? 0;
|
||||||
$sField = isset($_REQUEST['field'])?$_REQUEST['field']:'';
|
$sField = isset($_REQUEST['field'])?$_REQUEST['field']:'';
|
||||||
$oValue = isset($_REQUEST['value'])?$_REQUEST['value']:'';
|
$oValue = isset($_REQUEST['value'])?$_REQUEST['value']:'';
|
||||||
$iId = isset($_REQUEST['id'])?$_REQUEST['id']:0;
|
$iId = isset($_REQUEST['id'])?$_REQUEST['id']:0;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
locale = en_NZ
|
locale = en_NZ
|
||||||
page_og_desc = Keep contact with François when he is off hiking
|
page_og_desc = Keep contact with François when he is off hiking
|
||||||
error_commit_db = Issue committing to DB
|
error_commit_db = Issue committing to DB
|
||||||
|
unknown_field = Field "$0" is unknown
|
||||||
|
|
||||||
save = Save
|
save = Save
|
||||||
admin_save_success = Saved
|
admin_save_success = Saved
|
||||||
@@ -46,17 +47,21 @@ copy_to_clipboard = Copy direct link to clipboard
|
|||||||
link_copied = Link copied!
|
link_copied = Link copied!
|
||||||
|
|
||||||
city_time = $0 Time
|
city_time = $0 Time
|
||||||
|
local_time = $0 Local Time
|
||||||
|
your_time = $0 Your Time
|
||||||
|
date_time = $0 at $1
|
||||||
|
time_zone = Time Zone
|
||||||
|
|
||||||
project_id = Project ID
|
id_project = Project ID
|
||||||
project = Project
|
project = Project
|
||||||
projects = Projects
|
projects = Projects
|
||||||
mode = Mode
|
mode = Mode
|
||||||
code_name = Code name
|
code_name = Code name
|
||||||
start = Start
|
start = Start
|
||||||
end = End
|
end = End
|
||||||
feed_id = Feed ID
|
id_feed = Feed ID
|
||||||
ref_feed_id = Ref. Feed ID
|
ref_feed_id = Ref. Feed ID
|
||||||
spot_id = Spot ID
|
id_spot = Spot ID
|
||||||
name = Name
|
name = Name
|
||||||
status = Status
|
status = Status
|
||||||
last_update = Last Spot update
|
last_update = Last Spot update
|
||||||
@@ -64,9 +69,6 @@ ref_spot_id = Ref. Spot ID
|
|||||||
model = Model
|
model = Model
|
||||||
delete = Delete
|
delete = Delete
|
||||||
|
|
||||||
date_time = $0 at $1
|
|
||||||
time_zone = Time zone
|
|
||||||
|
|
||||||
unit_day = day
|
unit_day = day
|
||||||
unit_days = days
|
unit_days = days
|
||||||
unit_hour = h
|
unit_hour = h
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
locale = fr_FR
|
locale = fr_FR
|
||||||
page_og_desc = Gardez le contact avec François lorsqu'il part sur les chemins
|
page_og_desc = Gardez le contact avec François lorsqu'il part sur les chemins
|
||||||
error_commit_db = Error lors de la requête SQL
|
error_commit_db = Error lors de la requête SQL
|
||||||
|
unknown_field = Champ "$0" inconnu
|
||||||
|
|
||||||
save = Sauvegarder
|
save = Sauvegarder
|
||||||
admin_save_success = Sauvegardé
|
admin_save_success = Sauvegardé
|
||||||
@@ -46,17 +47,21 @@ copy_to_clipboard = Copie le lien dans le presse-papier
|
|||||||
link_copied = Lien copié !
|
link_copied = Lien copié !
|
||||||
|
|
||||||
city_time = heure de $0
|
city_time = heure de $0
|
||||||
|
local_time = $0 heure locale
|
||||||
|
your_time = $0 dans votre fuseau horaire
|
||||||
|
date_time = $0 à $1
|
||||||
|
time_zone = Fuseau horaire
|
||||||
|
|
||||||
project_id = ID projet
|
id_project = ID projet
|
||||||
project = Projet
|
project = Projet
|
||||||
projects = Projets
|
projects = Projets
|
||||||
mode = Mode
|
mode = Mode
|
||||||
code_name = Nom de code
|
code_name = Nom de code
|
||||||
start = Départ
|
start = Départ
|
||||||
end = Arrivée
|
end = Arrivée
|
||||||
feed_id = ID Feed
|
id_feed = ID Feed
|
||||||
ref_feed_id = ID Feed ref.
|
ref_feed_id = ID Feed ref.
|
||||||
spot_id = ID Spot
|
id_spot = ID Spot
|
||||||
name = Description
|
name = Description
|
||||||
status = Statut
|
status = Statut
|
||||||
last_update = Dernière maj depuis Spot
|
last_update = Dernière maj depuis Spot
|
||||||
@@ -64,9 +69,6 @@ ref_spot_id = ID Spot ref.
|
|||||||
model = Modèle
|
model = Modèle
|
||||||
delete = Supprimer
|
delete = Supprimer
|
||||||
|
|
||||||
date_time = $0 à $1
|
|
||||||
time_zone = Fuseau horaire
|
|
||||||
|
|
||||||
unit_day = jour
|
unit_day = jour
|
||||||
unit_days = jours
|
unit_days = jours
|
||||||
unit_hour = h
|
unit_hour = h
|
||||||
|
|||||||
@@ -4,13 +4,12 @@
|
|||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>[#]lang:project_id[#]</th>
|
<th>[#]lang:id_project[#]</th>
|
||||||
<th>[#]lang:project[#]</th>
|
<th>[#]lang:project[#]</th>
|
||||||
<th>[#]lang:mode[#]</th>
|
<th>[#]lang:mode[#]</th>
|
||||||
<th>[#]lang:code_name[#]</th>
|
<th>[#]lang:code_name[#]</th>
|
||||||
<th>[#]lang:start[#]</th>
|
<th>[#]lang:start[#]</th>
|
||||||
<th>[#]lang:end[#]</th>
|
<th>[#]lang:end[#]</th>
|
||||||
<th>[#]lang:time_zone[#]</th>
|
|
||||||
<th>[#]lang:delete[#]</th>
|
<th>[#]lang:delete[#]</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
@@ -23,10 +22,10 @@
|
|||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>[#]lang:feed_id[#]</th>
|
<th>[#]lang:id_feed[#]</th>
|
||||||
<th>[#]lang:ref_feed_id[#]</th>
|
<th>[#]lang:ref_feed_id[#]</th>
|
||||||
<th>[#]lang:spot_id[#]</th>
|
<th>[#]lang:id_spot[#]</th>
|
||||||
<th>[#]lang:project_id[#]</th>
|
<th>[#]lang:id_project[#]</th>
|
||||||
<th>[#]lang:name[#]</th>
|
<th>[#]lang:name[#]</th>
|
||||||
<th>[#]lang:status[#]</th>
|
<th>[#]lang:status[#]</th>
|
||||||
<th>[#]lang:last_update[#]</th>
|
<th>[#]lang:last_update[#]</th>
|
||||||
@@ -41,7 +40,7 @@
|
|||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>[#]lang:spot_id[#]</th>
|
<th>[#]lang:id_spot[#]</th>
|
||||||
<th>[#]lang:ref_spot_id[#]</th>
|
<th>[#]lang:ref_spot_id[#]</th>
|
||||||
<th>[#]lang:name[#]</th>
|
<th>[#]lang:name[#]</th>
|
||||||
<th>[#]lang:model[#]</th>
|
<th>[#]lang:model[#]</th>
|
||||||
@@ -71,35 +70,41 @@ oSpot.onFeedback = function(sType, sMsg, asContext) {
|
|||||||
|
|
||||||
function setProjects(asElemTypes) {
|
function setProjects(asElemTypes) {
|
||||||
var aoEvents = [{on:'change', callback:commit}, {on:'keyup', callback:waitAndCommit}];
|
var aoEvents = [{on:'change', callback:commit}, {on:'keyup', callback:waitAndCommit}];
|
||||||
|
var aoChangeEvent = [aoEvents[0]];
|
||||||
|
|
||||||
$.each(asElemTypes, function(sElemType, aoElems) {
|
$.each(asElemTypes, function(sElemType, aoElems) {
|
||||||
$.each(aoElems, function(iKey, oElem) {
|
$.each(aoElems, function(iKey, oElem) {
|
||||||
var sElemId = sElemType+'_'+oElem.id;
|
var sElemId = sElemType+'_'+oElem.id;
|
||||||
var bNew = ($('#'+sElemId).length == 0);
|
var bNew = ($('#'+sElemId).length == 0);
|
||||||
|
|
||||||
var $Elem = (bNew?$('<tr>', {'id': sElemId}):$('#'+sElemId).empty())
|
var $Elem = (bNew?$('<tr>', {'id': sElemId}):$('#'+sElemId))
|
||||||
.data('type', sElemType)
|
.data('type', sElemType)
|
||||||
.data('id', oElem.id)
|
.data('id', oElem.id);
|
||||||
.append($('<td>').text(oElem.id || ''));
|
|
||||||
|
|
||||||
if(oElem.del) $Elem.remove();
|
if(oElem.del) $Elem.remove();
|
||||||
|
else if(!bNew) {
|
||||||
|
$Elem.find('input').each(function(iKey, oInput){
|
||||||
|
var $Input = $(oInput);
|
||||||
|
if($Input.attr('name') in oElem && $Input.attr('type')!='date') $Input.val(oElem[$Input.attr('name')]);
|
||||||
|
});
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
|
$Elem.append($('<td>').text(oElem.id || ''));
|
||||||
switch(sElemType) {
|
switch(sElemType) {
|
||||||
case 'project':
|
case 'project':
|
||||||
$Elem
|
$Elem
|
||||||
.append($('<td>').addInput('text', 'name', oElem.name, aoEvents))
|
.append($('<td>').addInput('text', 'name', oElem.name, aoEvents))
|
||||||
.append($('<td>', {'class': 'mode'}).text(oElem.mode))
|
.append($('<td>', {'class': 'mode'}).text(oElem.mode))
|
||||||
.append($('<td>').addInput('text', 'codename', oElem.codename, aoEvents))
|
.append($('<td>').addInput('text', 'codename', oElem.codename, aoEvents))
|
||||||
.append($('<td>').addInput('date', 'active_from', oElem.active_from.substr(0, 10), aoEvents))
|
.append($('<td>').addInput('date', 'active_from', oElem.active_from, aoChangeEvent))
|
||||||
.append($('<td>').addInput('date', 'active_to', oElem.active_to.substr(0, 10), aoEvents))
|
.append($('<td>').addInput('date', 'active_to', oElem.active_to, aoChangeEvent))
|
||||||
.append($('<td>').addInput('text', 'timezone', oElem.timezone, aoEvents))
|
|
||||||
.append($('<td>').addButton('close fa-lg', '', 'del_proj', del));
|
.append($('<td>').addButton('close fa-lg', '', 'del_proj', del));
|
||||||
break;
|
break;
|
||||||
case 'feed':
|
case 'feed':
|
||||||
$Elem
|
$Elem
|
||||||
.append($('<td>').addInput('text', 'ref_feed_id', oElem.ref_feed_id, aoEvents))
|
.append($('<td>').addInput('text', 'ref_feed_id', oElem.ref_feed_id, aoEvents))
|
||||||
.append($('<td>').addInput('number', 'spot_id', oElem.id_spot, aoEvents))
|
.append($('<td>').addInput('number', 'id_spot', oElem.id_spot, aoEvents))
|
||||||
.append($('<td>').addInput('number', 'project_id', oElem.id_project, aoEvents))
|
.append($('<td>').addInput('number', 'id_project', oElem.id_project, aoEvents))
|
||||||
.append($('<td>').text(oElem.name))
|
.append($('<td>').text(oElem.name))
|
||||||
.append($('<td>').text(oElem.status))
|
.append($('<td>').text(oElem.status))
|
||||||
.append($('<td>').text(oElem.last_update))
|
.append($('<td>').text(oElem.last_update))
|
||||||
@@ -112,8 +117,8 @@ function setProjects(asElemTypes) {
|
|||||||
.append($('<td>').text(oElem.model))
|
.append($('<td>').text(oElem.model))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(bNew) $Elem.appendTo($('#'+sElemType+'s').find('table tbody'));
|
$Elem.appendTo($('#'+sElemType+'s').find('table tbody'));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -126,16 +131,16 @@ function createProject() {
|
|||||||
function commit(event, $This) {
|
function commit(event, $This) {
|
||||||
$This = $This || $(this);
|
$This = $This || $(this);
|
||||||
if(typeof self.tmp('wait') != 'undefined') clearTimeout(self.tmp('wait'));
|
if(typeof self.tmp('wait') != 'undefined') clearTimeout(self.tmp('wait'));
|
||||||
|
|
||||||
var sOldVal = $This.data('old_value');
|
var sOldVal = $This.data('old_value');
|
||||||
var sNewVal = $This.val();
|
var sNewVal = $This.val();
|
||||||
if(sOldVal!=sNewVal) {
|
if(sOldVal!=sNewVal) {
|
||||||
$This.data('old_value', sNewVal);
|
$This.data('old_value', sNewVal);
|
||||||
|
|
||||||
var $Record = $This.closest('tr');
|
var $Record = $This.closest('tr');
|
||||||
var asInputs = {type: $Record.data('type'), id: $Record.data('id'), field: $This.attr('name'), value: sNewVal};
|
var asInputs = {type: $Record.data('type'), id: $Record.data('id'), field: $This.attr('name'), value: sNewVal};
|
||||||
self.get(
|
self.get(
|
||||||
'admin_set',
|
'admin_set',
|
||||||
function(asData){
|
function(asData){
|
||||||
oSpot.onFeedback('success', self.lang('admin_save_success'), asInputs);
|
oSpot.onFeedback('success', self.lang('admin_save_success'), asInputs);
|
||||||
setProjects(asData);
|
setProjects(asData);
|
||||||
@@ -156,9 +161,9 @@ function waitAndCommit(event) {
|
|||||||
|
|
||||||
function del() {
|
function del() {
|
||||||
var $Record = $(this).closest('tr');
|
var $Record = $(this).closest('tr');
|
||||||
var asInputs = {type: $Record.data('type'), id: $Record.data('id')};
|
var asInputs = {type: $Record.data('type'), id: $Record.data('id')};
|
||||||
self.get(
|
self.get(
|
||||||
'admin_del',
|
'admin_del',
|
||||||
function(asData){
|
function(asData){
|
||||||
oSpot.onFeedback('success', self.lang('admin_save_success'), asInputs);
|
oSpot.onFeedback('success', self.lang('admin_save_success'), asInputs);
|
||||||
setProjects(asData);
|
setProjects(asData);
|
||||||
@@ -169,4 +174,4 @@ function del() {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -204,21 +204,13 @@ function initProject(sProjectCodeName, oFocusPost){
|
|||||||
//Page Title
|
//Page Title
|
||||||
self.setPageTitle(oSpot.vars(['project', 'name']));
|
self.setPageTitle(oSpot.vars(['project', 'name']));
|
||||||
|
|
||||||
//Timezone difference notice
|
|
||||||
var bSameTime = (
|
|
||||||
(new Date()).toLocaleString([], {timeZone: oSpot.consts.timezone}) ==
|
|
||||||
(new Date()).toLocaleString([], {timeZone: oSpot.vars(['project', 'timezone'])})
|
|
||||||
);
|
|
||||||
self.tmp('site_tz_notice', bSameTime?'':getTimeZoneDesc(oSpot.consts.timezone));
|
|
||||||
self.tmp('proj_tz_notice', bSameTime?'':getTimeZoneDesc(self.vars(['project', 'timezone'])));
|
|
||||||
|
|
||||||
//Load Track & Markers
|
//Load Track & Markers
|
||||||
$.when(
|
$.when(
|
||||||
//Markers: Spot Messages & Medias
|
//Markers: Spot Messages & Medias
|
||||||
self.get(
|
self.get(
|
||||||
'markers',
|
'markers',
|
||||||
function(){},
|
function(){},
|
||||||
{project_id: self.vars(['project', 'id'])},
|
{id_project: self.vars(['project', 'id'])},
|
||||||
function(e){console.log(e);}
|
function(e){console.log(e);}
|
||||||
),
|
),
|
||||||
//Project Geojson: Hike track
|
//Project Geojson: Hike track
|
||||||
@@ -230,7 +222,7 @@ function initProject(sProjectCodeName, oFocusPost){
|
|||||||
).done(function(aoMessages, aoTracks) {
|
).done(function(aoMessages, aoTracks) {
|
||||||
var asData = aoMessages[0]['data'];
|
var asData = aoMessages[0]['data'];
|
||||||
setMapLayers(asData['maps']);
|
setMapLayers(asData['maps']);
|
||||||
initSpotMessages(asData['messages'] || [], aoTracks[0], aoMessages[0]['desc']=='No Data');
|
initSpotMessages(asData['messages'] || [], aoTracks[0], asData['empty_project']);
|
||||||
updateSettingsPanel(asData['last_update']);
|
updateSettingsPanel(asData['last_update']);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -268,7 +260,7 @@ function initPosts() {
|
|||||||
updateFeed(true);
|
updateFeed(true);
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
project_id: self.vars(['project', 'id']),
|
id_project: self.vars(['project', 'id']),
|
||||||
name: $('#name').val(),
|
name: $('#name').val(),
|
||||||
content: $('#post').val()
|
content: $('#post').val()
|
||||||
}
|
}
|
||||||
@@ -590,10 +582,10 @@ function initSpotMessages(aoMessages, aoTracks, bNoFeed) {
|
|||||||
.append(oMsg.formatted_time+(self.vars(['project', 'mode'])==self.consts.modes.blog?' ('+oMsg.relative_time+')':'')));
|
.append(oMsg.formatted_time+(self.vars(['project', 'mode'])==self.consts.modes.blog?' ('+oMsg.relative_time+')':'')));
|
||||||
|
|
||||||
//Tooltip: Time Zone
|
//Tooltip: Time Zone
|
||||||
if(self.tmp('site_tz_notice')!='') {
|
if(oMsg.formatted_time_local != oMsg.formatted_time) {
|
||||||
$Tooltip.append($('<p>', {'class':'timezone'})
|
$Tooltip.append($('<p>', {'class':'timezone'})
|
||||||
.addIcon('fa-timezone fa-fw fa-lg')
|
.addIcon('fa-timezone fa-fw fa-lg')
|
||||||
.append(self.tmp('site_tz_notice')));
|
.append(oSpot.lang('local_time', oMsg.formatted_time_local)));
|
||||||
}
|
}
|
||||||
|
|
||||||
//Tooltip: Medias
|
//Tooltip: Medias
|
||||||
@@ -743,8 +735,8 @@ function updateFeed(bFirstChunk, bDiscrete, fCallback) {
|
|||||||
|
|
||||||
self.tmp('updatable', true);
|
self.tmp('updatable', true);
|
||||||
}, {
|
}, {
|
||||||
'project_id': self.vars(['project', 'id']),
|
id_project: self.vars(['project', 'id']),
|
||||||
'chunk': self.tmp('news_chunk')
|
chunk: self.tmp('news_chunk')
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -789,6 +781,8 @@ function getPost(asPost) {
|
|||||||
|
|
||||||
var sRelTime = (asPost.relative_time!='')?((self.vars('project') && self.vars(['project', 'mode'])==self.consts.modes.histo)?asPost.formatted_time.substr(0, 10):asPost.relative_time):'';
|
var sRelTime = (asPost.relative_time!='')?((self.vars('project') && self.vars(['project', 'mode'])==self.consts.modes.histo)?asPost.formatted_time.substr(0, 10):asPost.relative_time):'';
|
||||||
var sAbsTime = asPost.formatted_time;
|
var sAbsTime = asPost.formatted_time;
|
||||||
|
var sAbsTimeLocal = asPost.formatted_time_local;
|
||||||
|
var bTimeDiff = (sAbsTime && sAbsTimeLocal != sAbsTime);
|
||||||
var sType = asPost.subtype || asPost.type;
|
var sType = asPost.subtype || asPost.type;
|
||||||
var $Body = {};
|
var $Body = {};
|
||||||
|
|
||||||
@@ -800,7 +794,7 @@ function getPost(asPost) {
|
|||||||
.data('clicked', false)
|
.data('clicked', false)
|
||||||
.append($('<p>').addIcon('fa-coords', true).append(getGoogleMapsLink(asPost)))
|
.append($('<p>').addIcon('fa-coords', true).append(getGoogleMapsLink(asPost)))
|
||||||
.append($('<p>').addIcon('fa-time', true).append(sAbsTime))
|
.append($('<p>').addIcon('fa-time', true).append(sAbsTime))
|
||||||
.append((self.tmp('site_tz_notice')!='')?$('<p>').addIcon('fa-timezone', true).append(self.tmp('site_tz_notice')):'')
|
.append(bTimeDiff?$('<p>').addIcon('fa-timezone', true).append(oSpot.lang('local_time', sAbsTimeLocal)):'')
|
||||||
.append($('<a>', {'class':'drill'})
|
.append($('<a>', {'class':'drill'})
|
||||||
.append($('<img>', {'class':'staticmap', title: oSpot.lang('click_zoom'), src: getWmtsApiUrl('static', asPost.latitude, asPost.longitude, 13)}))
|
.append($('<img>', {'class':'staticmap', title: oSpot.lang('click_zoom'), src: getWmtsApiUrl('static', asPost.latitude, asPost.longitude, 13)}))
|
||||||
.append($('<span>', {'class': 'drill-icon fa-stack'})
|
.append($('<span>', {'class': 'drill-icon fa-stack'})
|
||||||
@@ -868,7 +862,7 @@ function getPost(asPost) {
|
|||||||
.addIcon('fa-'+sType)
|
.addIcon('fa-'+sType)
|
||||||
.append(asPost.displayed_id?' '+oSpot.lang('counter', asPost.displayed_id):'')
|
.append(asPost.displayed_id?' '+oSpot.lang('counter', asPost.displayed_id):'')
|
||||||
)
|
)
|
||||||
.append($('<span>', {'class':'time'}).hoverSwap(sRelTime, sAbsTime+((self.tmp('site_tz_notice')!='')?' ('+self.tmp('site_tz_notice')+')':''))))
|
.append($('<span>', {'class':'time', title:bTimeDiff?oSpot.lang('local_time', sAbsTimeLocal):''}).hoverSwap(sRelTime, bTimeDiff?oSpot.lang('your_time', sAbsTime):sAbsTime)))
|
||||||
.append($('<div>', {'class':'body'}).append($Body));
|
.append($('<div>', {'class':'body'}).append($Body));
|
||||||
|
|
||||||
if(bLink) {
|
if(bLink) {
|
||||||
@@ -894,22 +888,19 @@ function getWmtsApiUrl(sMapId, iLat, iLng, iZoom) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getMediaLink(asData, sType) {
|
function getMediaLink(asData, sType) {
|
||||||
|
var bTimeDiff = (asData.posted_on_formatted && asData.posted_on_formatted_local != asData.posted_on_formatted);
|
||||||
|
|
||||||
var $PostedOn =
|
var $PostedOn =
|
||||||
$('<span>', {'class': 'lb-caption-line', title: oSpot.lang(asData.subtype)+' '+oSpot.lang('add_on', asData.posted_on_formatted)})
|
$('<span>', {'class': 'lb-caption-line', title: bTimeDiff?oSpot.lang('local_time', asData.posted_on_formatted_local):''})
|
||||||
.addIcon('fa-upload fa-lg fa-fw', true)
|
.addIcon('fa-upload fa-lg fa-fw', true)
|
||||||
.append(asData.posted_on_formatted);
|
.append(asData.posted_on_formatted);
|
||||||
|
|
||||||
var $TakenOn = (asData.taken_on == '0000-00-00 00:00:00')?'':
|
var $TakenOn = (asData.taken_on == '0000-00-00 00:00:00')?'':
|
||||||
$('<span>', {'class': 'lb-caption-line', title: oSpot.lang(asData.subtype)+' '+oSpot.lang(asData.subtype+'_taken', asData.taken_on_formatted)})
|
$('<span>', {'class': 'lb-caption-line', title: bTimeDiff?oSpot.lang('local_time', asData.taken_on_formatted_local):''})
|
||||||
.addIcon('fa-'+asData.subtype+'-shot fa-lg fa-fw', true)
|
.addIcon('fa-'+asData.subtype+'-shot fa-lg fa-fw', true)
|
||||||
.append(asData.taken_on_formatted);
|
.append(asData.taken_on_formatted);
|
||||||
|
|
||||||
var $Timezone = (self.tmp('site_tz_notice') == '')?'':
|
var $Title = $('<div>').append(sType=='marker'?$TakenOn:$PostedOn).append(sType=='marker'?$PostedOn:$TakenOn);
|
||||||
$('<span>', {'class': 'lb-caption-line'})
|
|
||||||
.addIcon('fa-timezone fa-lg fa-fw', true)
|
|
||||||
.append(self.tmp('site_tz_notice'));
|
|
||||||
|
|
||||||
var $Title = $('<div>').append(sType=='marker'?$TakenOn:$PostedOn).append(sType=='marker'?$PostedOn:$TakenOn).append($Timezone);
|
|
||||||
var $Link =
|
var $Link =
|
||||||
$('<a>', {
|
$('<a>', {
|
||||||
'class': 'drill',
|
'class': 'drill',
|
||||||
|
|||||||
@@ -16,14 +16,15 @@ oSpot.pageInit = function(asHash) {
|
|||||||
.attr('data-url', self.getActionLink('upload'))
|
.attr('data-url', self.getActionLink('upload'))
|
||||||
.fileupload({
|
.fileupload({
|
||||||
dataType: 'json',
|
dataType: 'json',
|
||||||
|
formData: {t: self.consts.timezone},
|
||||||
acceptFileTypes: /(\.|\/)(gif|jpe?g|png|mov)$/i,
|
acceptFileTypes: /(\.|\/)(gif|jpe?g|png|mov)$/i,
|
||||||
done: function (e, asData) {
|
done: function (e, asData) {
|
||||||
$.each(asData.result.files, function(iKey, oFile) {
|
$.each(asData.result.files, function(iKey, oFile) {
|
||||||
var bError = ('error' in oFile);
|
var bError = ('error' in oFile);
|
||||||
|
|
||||||
//Feedback
|
//Feedback
|
||||||
addStatus(bError?oFile.error:(self.lang('upload_success', [oFile.name])));
|
addStatus(bError?oFile.error:(self.lang('upload_success', [oFile.name])));
|
||||||
|
|
||||||
//Comments
|
//Comments
|
||||||
if(!bError) addCommentBox(oFile.id, oFile.thumbnail);
|
if(!bError) addCommentBox(oFile.id, oFile.thumbnail);
|
||||||
});
|
});
|
||||||
@@ -62,7 +63,7 @@ function addCommentBox(iMediaId, sThumbnailPath) {
|
|||||||
function addStatus(sMsg, bClear) {
|
function addStatus(sMsg, bClear) {
|
||||||
bClear = bClear || false;
|
bClear = bClear || false;
|
||||||
if(bClear) self.tmp('status-box').empty();
|
if(bClear) self.tmp('status-box').empty();
|
||||||
|
|
||||||
self.tmp('status-box').append($('<p>').text(sMsg));
|
self.tmp('status-box').append($('<p>').text(sMsg));
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -14,5 +14,5 @@
|
|||||||
* ECMA import/export
|
* ECMA import/export
|
||||||
* Reset zoom on image closing (lightbox)
|
* Reset zoom on image closing (lightbox)
|
||||||
* Add mail frequency slider
|
* Add mail frequency slider
|
||||||
* Replace Project Time Zone with browser Time Zone when uploading media?
|
* Use WMTS servers directly when not using Geo Caching Server
|
||||||
* Use WMTS servers directly when not using Geo Caching Server
|
* Allow HEIF picture format
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -251,14 +251,6 @@ function setElem(aoAnchor, asPath, oValue)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTimeZoneDesc(sTimeZoneName) {
|
|
||||||
if(sTimeZoneName.indexOf('/')==-1) return sTimeZoneName;
|
|
||||||
else {
|
|
||||||
var sCity = sTimeZoneName.split('/')[1].replace('_', ' ') || '';
|
|
||||||
return oSpot.lang('city_time', sCity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$.prototype.addInput = function(sType, sName, sValue, aoEvents)
|
$.prototype.addInput = function(sType, sName, sValue, aoEvents)
|
||||||
{
|
{
|
||||||
aoEvents = aoEvents || [];
|
aoEvents = aoEvents || [];
|
||||||
|
|||||||
@@ -563,8 +563,10 @@ $legend-color: $post-color;
|
|||||||
}
|
}
|
||||||
|
|
||||||
#last_update {
|
#last_update {
|
||||||
|
position: absolute;
|
||||||
margin-top: -2em;
|
margin-top: -2em;
|
||||||
padding: 0 1rem;
|
padding: 0 1rem;
|
||||||
|
width: calc(100% - 2rem);
|
||||||
|
|
||||||
p {
|
p {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user