Add update emails
This commit is contained in:
107
inc/email.php
107
inc/email.php
@@ -10,54 +10,28 @@ require_once 'inc/PHPMailer/SMTP.php';
|
||||
class Email extends PhpObject {
|
||||
|
||||
private $sServName;
|
||||
private $sTemplate;
|
||||
private $sTemplateName;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var Translator[]
|
||||
* Email Template
|
||||
* @var Mask
|
||||
*/
|
||||
private $asTranslators;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var Mask[]
|
||||
*/
|
||||
private $asTemplates;
|
||||
public $oTemplate;
|
||||
|
||||
private $asDests;
|
||||
|
||||
public function __construct($sServName, $sTemplate='') {
|
||||
public function __construct($sServName, $sTemplateName='') {
|
||||
$this->sServName = $sServName;
|
||||
$this->setTemplate($sTemplate);
|
||||
$this->setTemplate($sTemplateName);
|
||||
$this->asDests = array();
|
||||
}
|
||||
|
||||
public function setTemplate($sTemplate) {
|
||||
$this->sTemplate = $sTemplate;
|
||||
$this->asTranslators = array();
|
||||
$this->asTemplates = array();
|
||||
}
|
||||
|
||||
private function getTemplate($sLanguage) {
|
||||
if(!array_key_exists($sLanguage, $this->asTemplates)) {
|
||||
$this->asTranslators[$sLanguage] = new Translator($sLanguage);
|
||||
$this->buildTemplate($sLanguage);
|
||||
}
|
||||
|
||||
return array('subject'=>$this->asTranslators[$sLanguage]->getTranslation('conf_subject'), 'email'=>$this->asTemplates[$sLanguage]);
|
||||
}
|
||||
|
||||
private function buildTemplate($sLanguage) {
|
||||
$oTemplate = new Mask($this->sTemplate, $this->asTranslators[$sLanguage]);
|
||||
|
||||
switch($this->sTemplate) {
|
||||
case 'confirmation':
|
||||
break;
|
||||
case 'update':
|
||||
break;
|
||||
}
|
||||
|
||||
$this->asTemplates[$sLanguage] = $oTemplate;
|
||||
public function setTemplate($sTemplateName) {
|
||||
$this->sTemplateName = $sTemplateName;
|
||||
$this->oTemplate = new Mask($this->sTemplateName);
|
||||
$this->oTemplate->setTag('local_server', $this->sServName);
|
||||
$this->oTemplate->setTag('live_server', Settings::LIVE_SERVER);
|
||||
$this->oTemplate->setTag('geo_server', Settings::GEO_SERVER);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -69,50 +43,8 @@ class Email extends PhpObject {
|
||||
$this->asDests = $asDests;
|
||||
}
|
||||
|
||||
/*public function send() {
|
||||
$sEOL = "\r\n";
|
||||
foreach($this->asDests as $asDest) {
|
||||
//Message
|
||||
$asTemplate = $this->getTemplate($asDest['language']);
|
||||
$oEmail = $asTemplate['email'];
|
||||
|
||||
//Unsubscribe Link
|
||||
$sUnsubLink = $this->sServName.'?a=unsubscribe_email&id='.$asDest['id_user'];
|
||||
$oEmail->setTag('unsubscribe_link', $sUnsubLink);
|
||||
|
||||
//Email Content
|
||||
$sHtmlMessage = $oEmail->getMask();
|
||||
$sPlainMessage = strip_tags(str_replace('<br />', "\n", $sHtmlMessage));
|
||||
|
||||
//Email
|
||||
$iBoundary = uniqid("HTMLEMAIL");
|
||||
$sHeaders =
|
||||
'From: Spotty <spot@lutran.fr>'.$sEOL.
|
||||
'Reply-To: Spotty <spot@lutran.fr>'.$sEOL.
|
||||
'List-Unsubscribe: <mailto:unsubscribe@'.parse_url($this->sServName)['host'].'?subject=unsubscribe>, <'.$sUnsubLink.'>'.$sEOL.
|
||||
'List-Unsubscribe-Post: List-Unsubscribe=One-Click'.$sEOL.
|
||||
'MIME-Version: 1.0'.$sEOL.
|
||||
'Content-Type: multipart/alternative; boundary="'.$iBoundary.'"'.$sEOL;
|
||||
|
||||
$sBody =
|
||||
'--'.$iBoundary.$sEOL. //Plain Message
|
||||
'Content-Type: text/plain; charset=UTF-8'.$sEOL.
|
||||
'Content-Transfer-Encoding: base64'.$sEOL.
|
||||
chunk_split(base64_encode($sPlainMessage)).$sEOL.
|
||||
|
||||
'--'.$iBoundary.$sEOL. //HTML Message
|
||||
'Content-Type: text/html; charset=UTF-8'.$sEOL.
|
||||
'Content-Transfer-Encoding: base64'.$sEOL.
|
||||
chunk_split(base64_encode($sHtmlMessage)).$sEOL.
|
||||
'--'.$iBoundary.'--';
|
||||
|
||||
//Send
|
||||
if(!mail($asDest['email'], $asTemplate['subject'], $sBody, $sHeaders)) $this->addError('Could not send '.$this->sTemplate.' email to '.$asDest['email']);
|
||||
}
|
||||
}*/
|
||||
|
||||
public function send() {
|
||||
//Instantiation and passing `true` enables exceptions
|
||||
foreach($this->asDests as $asDest) {
|
||||
$oPHPMailer = new PHPMailer(true);
|
||||
|
||||
//Server settings
|
||||
@@ -129,20 +61,17 @@ class Email extends PhpObject {
|
||||
$oPHPMailer->setFrom(Settings::MAIL_FROM, 'Spotty');
|
||||
$oPHPMailer->addReplyTo(Settings::MAIL_FROM, 'Spotty');
|
||||
|
||||
foreach($this->asDests as $asDest) {
|
||||
try {
|
||||
//Message
|
||||
$asTemplate = $this->getTemplate($asDest['language']);
|
||||
$oEmail = $asTemplate['email'];
|
||||
$this->oTemplate->setLanguage($asDest['language'], Spot::DEFAULT_LANG);
|
||||
|
||||
//Unsubscribe Link
|
||||
$sUnsubLink = $this->sServName.'?a=unsubscribe_email&id='.$asDest['id_user'];
|
||||
$oEmail->setTag('unsubscribe_link', $sUnsubLink);
|
||||
$this->oTemplate->setTag('unsubscribe_link', htmlspecialchars($sUnsubLink));
|
||||
$oPHPMailer->addCustomHeader('List-Unsubscribe','<mailto:'.Settings::MAIL_FROM.'?subject=unsubscribe>, <'.$sUnsubLink.'>');
|
||||
$oPHPMailer->addCustomHeader('List-Unsubscribe-Post','List-Unsubscribe=One-Click');
|
||||
|
||||
//Email Content
|
||||
$sHtmlMessage = $oEmail->getMask();
|
||||
$sHtmlMessage = $this->oTemplate->getMask();
|
||||
$sPlainMessage = strip_tags(str_replace('<br />', "\n", $sHtmlMessage));
|
||||
|
||||
//Recipients
|
||||
@@ -150,10 +79,11 @@ class Email extends PhpObject {
|
||||
|
||||
//Content
|
||||
$oPHPMailer->isHTML(true);
|
||||
$oPHPMailer->Subject = $asTemplate['subject'];
|
||||
$oPHPMailer->Subject = $this->oTemplate->getTranslator()->getTranslation($this->sTemplateName.'_subject');
|
||||
$oPHPMailer->Body = $sHtmlMessage;
|
||||
$oPHPMailer->AltBody = $sPlainMessage;
|
||||
|
||||
try {
|
||||
$oPHPMailer->send();
|
||||
}
|
||||
catch (Exception $e) {
|
||||
@@ -161,5 +91,4 @@ class Email extends PhpObject {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
44
inc/feed.php
44
inc/feed.php
@@ -10,6 +10,7 @@ class Feed extends PhpObject {
|
||||
const FEED_HOOK = 'https://api.findmespot.com/spot-main-web/consumer/rest-api/2.0/public/feed/';
|
||||
const FEED_TYPE_XML = '/message.xml';
|
||||
const FEED_TYPE_JSON = '/message.json';
|
||||
const FEED_MAX_REFRESH = 5 * 60; //Seconds
|
||||
|
||||
//DB Tables
|
||||
const SPOT_TABLE = 'spots';
|
||||
@@ -101,32 +102,40 @@ class Feed extends PhpObject {
|
||||
}
|
||||
|
||||
public function checkUpdateFeed($sProjectMode) {
|
||||
//Feed updated once every hour in Blog Mode (no need for timezone when substracting 2 dates)
|
||||
$bNewMsg = false;
|
||||
|
||||
//Spam Check: no more than 1 API request per 5 minutes
|
||||
if($sProjectMode == Project::MODE_BLOG) {
|
||||
$oLastUpdate = new DateTime('@'.$this->iLastUpdate);
|
||||
$oNow = new DateTime('now');
|
||||
$iSecDiff = $oNow->getTimestamp() - $oLastUpdate->getTimestamp();
|
||||
|
||||
if(intval($oNow->diff($oLastUpdate)->format('%H')) > 0) $this->updateFeed();
|
||||
if($iSecDiff > self::FEED_MAX_REFRESH) $bNewMsg = $this->updateFeed();
|
||||
}
|
||||
|
||||
return $bNewMsg;
|
||||
}
|
||||
|
||||
private function updateFeed() {
|
||||
$bNewMsg = false;
|
||||
$asData = $this->retrieveFeed();
|
||||
$sLastUpdate = date(Db::TIMESTAMP_FORMAT);
|
||||
if(!isset($asData['response']['errors']) || empty($asData['response']['errors'])) {
|
||||
$asMsgs = $asData['response']['feedMessageResponse']['messages'];
|
||||
if(array_key_exists('message', $asMsgs)) $asMsgs = $asMsgs['message'];
|
||||
|
||||
$asFeed = $asData['response']['feedMessageResponse']['feed'];
|
||||
|
||||
if(!empty($asMsgs))
|
||||
{
|
||||
//Fix unstable Spot API Structure
|
||||
if(array_key_exists('message', $asMsgs)) $asMsgs = $asMsgs['message']; //Sometimes adds an extra "message" level
|
||||
if(!array_key_exists(0, $asMsgs)) $asMsgs = array($asMsgs); //Jumps a level when there is only 1 message
|
||||
|
||||
//Update Spot, Feed & Messages
|
||||
if(!empty($asMsgs) && array_key_exists('messengerId', $asMsgs[0])) {
|
||||
|
||||
//Update Spot Info from the first message
|
||||
$asFirstMsg = array_values($asMsgs)[0];
|
||||
$asSpotInfo = array(
|
||||
'ref_spot_id' => $asFirstMsg['messengerId'],
|
||||
'name' => $asFirstMsg['messengerName'],
|
||||
'model' => $asFirstMsg['modelId']
|
||||
'ref_spot_id' => $asMsgs[0]['messengerId'],
|
||||
'name' => $asMsgs[0]['messengerName'],
|
||||
'model' => $asMsgs[0]['modelId']
|
||||
);
|
||||
$iSpotId = $this->oDb->insertUpdateRow(self::SPOT_TABLE, $asSpotInfo, array('ref_spot_id'));
|
||||
|
||||
@@ -142,8 +151,7 @@ class Feed extends PhpObject {
|
||||
$iFeedId = $this->oDb->insertUpdateRow(self::FEED_TABLE, $asFeedInfo, array('ref_feed_id'));
|
||||
|
||||
//Update Messages
|
||||
foreach($asMsgs as $asMsg)
|
||||
{
|
||||
foreach($asMsgs as $asMsg) {
|
||||
$asMsg = array(
|
||||
'ref_msg_id' => $asMsg['id'],
|
||||
Db::getId(self::FEED_TABLE) => $iFeedId,
|
||||
@@ -151,16 +159,24 @@ class Feed extends PhpObject {
|
||||
'latitude' => $asMsg['latitude'],
|
||||
'longitude' => $asMsg['longitude'],
|
||||
'iso_time' => $asMsg['dateTime'], //ISO 8601 time (backup)
|
||||
'site_time' => date(Db::TIMESTAMP_FORMAT, $asMsg['unixTime']), //Conversion to Site Time (see Settings::TIMEZONE)
|
||||
'site_time' => date(Db::TIMESTAMP_FORMAT, $asMsg['unixTime']), //Conversion to Site Time (default timezone, see Settings::TIMEZONE)
|
||||
'unix_time' => $asMsg['unixTime'], //UNIX Time (backup)
|
||||
'content' => $asMsg['messageContent'],
|
||||
'battery_state' => $asMsg['batteryState']
|
||||
);
|
||||
$this->oDb->insertUpdateRow(self::MSG_TABLE, $asMsg, array('ref_msg_id'));
|
||||
|
||||
$iMsgId = $this->oDb->selectId(self::MSG_TABLE, array('ref_msg_id'=>$asMsg['ref_msg_id']));
|
||||
if(!$iMsgId) {
|
||||
$this->oDb->insertRow(self::MSG_TABLE, $asMsg);
|
||||
$bNewMsg = true;
|
||||
}
|
||||
else $this->oDb->updateRow(self::MSG_TABLE, $iMsgId, $asMsg);
|
||||
}
|
||||
}
|
||||
}
|
||||
else $this->oDb->updateRow(self::FEED_TABLE, $this->getFeedId(), array('last_update'=>$sLastUpdate));
|
||||
|
||||
return $bNewMsg;
|
||||
}
|
||||
|
||||
private function retrieveFeed() {
|
||||
|
||||
45
inc/spot.php
45
inc/spot.php
@@ -163,12 +163,45 @@ class Spot extends Main
|
||||
|
||||
public function setProjectId($iProjectId=0) {
|
||||
$this->oProject->setProjectId($iProjectId);
|
||||
}
|
||||
|
||||
public function updateProject() {
|
||||
$bNewMsg = false;
|
||||
|
||||
//Update all feeds belonging to the project
|
||||
$asFeeds = $this->oProject->getFeedIds();
|
||||
foreach($asFeeds as $iFeedId) {
|
||||
$oFeed = new Feed($this->oDb, $iFeedId);
|
||||
$oFeed->checkUpdateFeed($this->oProject->getMode());
|
||||
$bNewMsg = $bNewMsg || $oFeed->checkUpdateFeed($this->oProject->getMode());
|
||||
}
|
||||
|
||||
//Send Update Email
|
||||
if($bNewMsg) {
|
||||
$oEmail = new Email($this->asContext['serv_name'], 'email_update');
|
||||
$oEmail->setDestInfo($this->oUser->getActiveUsersInfo());
|
||||
|
||||
//Add Position
|
||||
$asMessages = $this->getSpotMessages();
|
||||
$asLastMessage = end($asMessages);
|
||||
$asLastMessage['token'] = Settings::GEO_SERVER_TOKEN;
|
||||
$oEmail->oTemplate->setTags($asLastMessage);
|
||||
$oEmail->oTemplate->setTag('date_time', 'lang:date_time', array(date('d/m/Y', $asLastMessage['unix_time']), date('H:i', $asLastMessage['unix_time'])));
|
||||
|
||||
//Add latest news feed
|
||||
$asNews = $this->getNewsFeed(0, true);
|
||||
$iPostCount = 0;
|
||||
foreach($asNews as $asPost) {
|
||||
if($asPost['type'] != 'message') {
|
||||
$oEmail->oTemplate->newInstance('news');
|
||||
$oEmail->oTemplate->setInstanceTag('news', 'local_server', $this->asContext['serv_name']);
|
||||
$oEmail->oTemplate->addInstance($asPost['type'], $asPost);
|
||||
$oEmail->oTemplate->setInstanceTag($asPost['type'], 'local_server', $this->asContext['serv_name']);
|
||||
$iPostCount++;
|
||||
}
|
||||
if($iPostCount==5) break;
|
||||
}
|
||||
|
||||
$oEmail->send();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,7 +210,7 @@ class Spot extends Main
|
||||
$sFileName = 'spot_cron.sh';
|
||||
$sContent =
|
||||
'#!/bin/bash'."\n".
|
||||
'wget -qO- '.$this->asContext['serv_name'].'index.php?a=dummy > /dev/null'."\n".
|
||||
'wget -qO- '.$this->asContext['serv_name'].'index.php?a=update_project > /dev/null'."\n".
|
||||
'#Crontab job: 0 * * * * . '.dirname($_SERVER['SCRIPT_FILENAME']).'/'.$sFileName.' > /dev/null'."\n";
|
||||
$bSuccess = (file_put_contents($sFileName, $sContent)!==false);
|
||||
return self::getJsonResult($bSuccess, '');
|
||||
@@ -220,7 +253,7 @@ class Spot extends Main
|
||||
|
||||
//Send Confirmation Email
|
||||
if($asResult['result'] && $asResult['desc']=='lang:nl_subscribed') {
|
||||
$oConfEmail = new Email($this->asContext['serv_name'], 'email_confirmation');
|
||||
$oConfEmail = new Email($this->asContext['serv_name'], 'email_conf');
|
||||
$oConfEmail->setDestInfo($asUserInfo);
|
||||
$oConfEmail->send();
|
||||
}
|
||||
@@ -331,7 +364,7 @@ class Spot extends Main
|
||||
$asData['formatted_time'] = $this->getTimeFormat($iTime);
|
||||
}
|
||||
|
||||
public function getNewsFeed($iChunk=0)
|
||||
public function getNewsFeed($iChunk=0, $bInternal=false)
|
||||
{
|
||||
$bHistoMode = ($this->oProject->getMode() == Project::MODE_HISTO);
|
||||
$asFeeds = array();
|
||||
@@ -368,9 +401,9 @@ class Spot extends Main
|
||||
else ksort($asFeeds);
|
||||
|
||||
//Split chunks
|
||||
$asFeeds = array_slice($asFeeds, $iChunk*self::FEED_CHUNK_SIZE, self::FEED_CHUNK_SIZE);
|
||||
$asFeeds = array_slice($asFeeds, $iChunk * self::FEED_CHUNK_SIZE, self::FEED_CHUNK_SIZE);
|
||||
|
||||
return self::getJsonResult(true, '', $asFeeds);
|
||||
return $bInternal?$asFeeds:self::getJsonResult(true, '', $asFeeds);
|
||||
}
|
||||
|
||||
public function syncMedias() {
|
||||
|
||||
27
inc/user.php
27
inc/user.php
@@ -22,7 +22,7 @@ class User extends PhpObject {
|
||||
parent::__construct(__CLASS__, Settings::DEBUG);
|
||||
$this->oDb = &$oDb;
|
||||
$this->iUserId = 0;
|
||||
$this->asUserInfo = array('name'=>'', 'email'=>'', 'language'=>'', 'active'=>'0');
|
||||
$this->asUserInfo = array(Db::getId(self::USER_TABLE)=>0, 'name'=>'', 'email'=>'', 'language'=>'', 'active'=>'0');
|
||||
$this->checkUserCookie();
|
||||
}
|
||||
|
||||
@@ -96,22 +96,31 @@ class User extends PhpObject {
|
||||
return $this->iUserId;
|
||||
}
|
||||
|
||||
public function getUserInfo() {
|
||||
$asUserInfo = $this->asUserInfo;
|
||||
$asUserInfo[Db::getId(self::USER_TABLE)] = $this->iUserId;
|
||||
return $asUserInfo;
|
||||
}
|
||||
|
||||
public function setUserId($iUserId) {
|
||||
$this->iUserId = 0;
|
||||
|
||||
$asUser = $this->oDb->selectRow(self::USER_TABLE, array(Db::getId(self::USER_TABLE)=>$iUserId, 'active'=>'1'), array_keys($this->asUserInfo));
|
||||
$asUser = $this->getActiveUsersInfo($iUserId);
|
||||
if(!empty($asUser)) {
|
||||
$this->iUserId = $iUserId;
|
||||
$this->asUserInfo = $asUser;
|
||||
$this->asUserInfo = array_shift($asUser);
|
||||
}
|
||||
}
|
||||
|
||||
public function getUserInfo() {
|
||||
return $this->asUserInfo;
|
||||
}
|
||||
|
||||
public function getActiveUsersInfo($iUserId=-1) {
|
||||
$asInfo = array(
|
||||
'select' => array_keys($this->asUserInfo),
|
||||
'from' => self::USER_TABLE,
|
||||
'constraint'=> array('active'=>'1')
|
||||
);
|
||||
if($iUserId != -1) $asInfo['constraint'][Db::getId(self::USER_TABLE)] = $iUserId;
|
||||
|
||||
return $this->oDb->selectRows($asInfo);
|
||||
}
|
||||
|
||||
private function updateCookie() {
|
||||
setcookie(self::COOKIE_ID_USER, $this->iUserId, time() + 60 * 60 * 24 * 365);
|
||||
}
|
||||
|
||||
@@ -39,6 +39,9 @@ if($sAction!='')
|
||||
case 'feed':
|
||||
$sResult = $oSpot->getNewsFeed($iChunk);
|
||||
break;
|
||||
case 'update_project':
|
||||
$sResult = $oSpot->updateProject();
|
||||
break;
|
||||
case 'upload':
|
||||
$sResult = $oSpot->upload();
|
||||
break;
|
||||
|
||||
@@ -78,7 +78,10 @@ nl_unsubscribe = Unsubscribe
|
||||
nl_unsubscribed = Done. No more junk mail from us
|
||||
nl_unknown_email = Unknown email address
|
||||
|
||||
conf_subject = Successful Registration
|
||||
email_unsubscribe = PS: Changed your mind?
|
||||
email_unsub_btn = Unsubscribe
|
||||
|
||||
email_conf_subject = Successful Registration
|
||||
conf_preheader = Thanks for keeping in touch!
|
||||
conf_thanks_sub = You're all set!
|
||||
conf_body_para_1 = Thank you for checking in on my wanderings :). I'll make sure to keep you posted on my progress along the trail.
|
||||
@@ -86,5 +89,8 @@ conf_body_para_2 = I usually check-in once a day, plus sometimes on special even
|
||||
conf_body_para_3 = If I've posted some pictures recently, you should also get them in this email.
|
||||
conf_body_conclusion= Happy Trails!
|
||||
conf_signature = --François
|
||||
conf_unsubscribe = PS: Changed your mind?
|
||||
conf_unsubscribe_btn= Unsubscribe
|
||||
|
||||
email_update_subject= Spotted!
|
||||
update_preheader = New position received
|
||||
update_title = Message
|
||||
update_latest_news = Latest news:
|
||||
@@ -78,7 +78,10 @@ nl_unsubscribe = Se désinscrire
|
||||
nl_unsubscribed = C'est fait. Fini le spam!
|
||||
nl_unknown_email = Adresse email inconnue
|
||||
|
||||
conf_subject = Confirmation
|
||||
email_unsubscribe = PS: Trop d'emails ?
|
||||
email_unsub_btn = Se désinscrire
|
||||
|
||||
email_conf_subject = Confirmation
|
||||
conf_preheader = Merci de rester en contact !
|
||||
conf_thanks_sub = C'est tout bon !
|
||||
conf_body_para_1 = C'est gentil de venir voir où j'en suis. Promis, je vous tiendrais au courant de mon avancée.
|
||||
@@ -86,5 +89,8 @@ conf_body_para_2 = En général, j'envoie un message une fois par jour. Lorsque
|
||||
conf_body_para_3 = If I've posted some pictures recently, you should also get them in this email.
|
||||
conf_body_conclusion= A bientôt sur les chemins !
|
||||
conf_signature = --François
|
||||
conf_unsubscribe = PS: Trop d'emails ?
|
||||
conf_unsubscribe_btn= Se désinscrire
|
||||
|
||||
email_update_subject= Nouvelle position reçue
|
||||
update_preheader = Nouvelle position !
|
||||
update_title = Message
|
||||
update_latest_news = Dernières nouvelles :
|
||||
@@ -2,13 +2,13 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html charset=UTF-8" />
|
||||
<title>[#]lang:conf_subject[#]</title>
|
||||
<title>[#]lang:email_conf_subject[#]</title>
|
||||
</head>
|
||||
<body>
|
||||
<span style="color: transparent; display: none !important; height: 0; max-height: 0; max-width: 0; opacity: 0; overflow: hidden; mso-hide: all; visibility: hidden; width: 0;">[#]lang:conf_preheader[#]</span>
|
||||
<table border="0" cellpadding="0" cellspacing="0" width="100%" style="width:100%;max-width:600px;">
|
||||
<tr>
|
||||
<td width="20%"><img src="https://spot.lutran.fr/images/icons/mstile-144x144.png" width="90%" border="0" alt="logo" /></td>
|
||||
<td width="20%"><img src="[#]local_server[#]images/icons/mstile-144x144.png" width="90%" border="0" alt="logo" /></td>
|
||||
<td><h1>[#]lang:conf_thanks_sub[#]</h1></td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -25,7 +25,7 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<p>[#]lang:conf_unsubscribe[#] <a href="[#]unsubscribe_link[#]" target="_blank">[#]lang:conf_unsubscribe_btn[#]</a></p>
|
||||
<p>[#]lang:email_unsubscribe[#] <a href="[#]unsubscribe_link[#]" target="_blank">[#]lang:email_unsub_btn[#]</a></p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
47
masks/email_update.html
Normal file
47
masks/email_update.html
Normal file
@@ -0,0 +1,47 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html charset=UTF-8" />
|
||||
<title>[#]lang:email_update_subject[#]</title>
|
||||
</head>
|
||||
<body>
|
||||
<span style="color: transparent; display: none !important; height: 0; max-height: 0; max-width: 0; opacity: 0; overflow: hidden; mso-hide: all; visibility: hidden; width: 0;">[#]lang:update_preheader[#]</span>
|
||||
<table border="0" cellpadding="0" cellspacing="0" width="100%" style="width:100%;max-width:600px;">
|
||||
<tr>
|
||||
<td width="20%"><img src="[#]local_server[#]images/icons/mstile-144x144.png" width="90%" border="0" alt="logo" /></td>
|
||||
<td><h1>[#]lang:update_title[#] [#]type[#] #[#]displayed_id[#]</h1></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div style="background-color:#6dff58;color:#326526;border-radius:3px;padding:1rem;margin-top:1rem;display:inline-block;box-shadow: 2px 2px 3px 0px rgba(0,0,0,.5);">
|
||||
<a href="[#]local_server[#]" target="_blank"><img style="border-radius:3px;" src="[#]geo_server[#]?a=tile&id=static.marker&z=13&x=[#]longitude[#]&y=[#]latitude[#]&marker=[#]live_server[#]/images/footprint_mapbox.png&token=[#]token[#]" alt="position" /></a>
|
||||
<br />[#]lat_dms[#] [#]lon_dms[#]
|
||||
<br />[#]date_time[#]
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<h2>[#]lang:update_latest_news[#]</h2>
|
||||
<table border="0" cellpadding="0" cellspacing="0" width="100%">
|
||||
<!-- [PART] news [START] -->
|
||||
<tr>
|
||||
<td>
|
||||
<a href="[#]local_server[#]" target="_blank" style="text-decoration:none;background-color:#EEE;color:#333;margin-bottom:1rem;border-radius:3px;padding:5%;display:inline-block;width:90%;box-shadow: 2px 2px 3px 0px rgba(0,0,0,.5);">
|
||||
<!-- [PART] media [START] --><img src="[#]local_server[#][#]thumb_path[#]" style="max-height:200px;image-orientation:from-image;" /><br /><span>[#]comment[#]</span><!-- [PART] media [END] -->
|
||||
<!-- [PART] post [START] --><span>[#]content[#]</span><br /><span style="margin-top:0.5em;float:right;">--[#]formatted_name[#]</span><!-- [PART] post [END] -->
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- [PART] news [END] -->
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<p>[#]lang:email_unsubscribe[#] <a href="[#]unsubscribe_link[#]" target="_blank">[#]lang:email_unsub_btn[#]</a></p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
@@ -15,3 +15,4 @@
|
||||
* Fix lightbox portrait mode: push text under
|
||||
* Subscribe to message feed
|
||||
* Add mail frequency slider
|
||||
* Add Timezone to user table
|
||||
@@ -3,6 +3,8 @@
|
||||
class Settings
|
||||
{
|
||||
const GEO_SERVER = 'http(s)://geo.server.tld';
|
||||
const GEO_SERVER_TOKEN = '';
|
||||
const LIVE_SERVER = 'http(s)://live.server.tld';
|
||||
const DB_SERVER = 'localhost';
|
||||
const DB_LOGIN = '';
|
||||
const DB_PASS = '';
|
||||
|
||||
Reference in New Issue
Block a user