From ce9168be5f0d4df5e7adda949a0efd04dc587165 Mon Sep 17 00:00:00 2001 From: Franzz Date: Sat, 6 Nov 2021 19:38:51 +0100 Subject: [PATCH] Navigation between admin/upload and project page --- geo/pct.gpx | 4 +-- inc/Spot.php | 43 +++++++++++++++++++++------ inc/User.php | 64 ++++++++++++++++++++++++++++++++-------- index.php | 2 +- languages/en.lang | 17 +++++++++-- languages/fr.lang | 19 +++++++++--- masks/admin.html | 27 +++++++++-------- masks/index.html | 2 -- masks/project.html | 10 ++++++- masks/upload.html | 1 + script/spot.js | 8 +++-- style/_common.scss | 32 ++++++++++++++------ style/_fa.scss | 33 ++++++++++++--------- style/_mask_admin.scss | 10 +------ style/_mask_project.scss | 27 +++++++++++++++-- style/_mask_upload.scss | 7 ----- style/spot.css | 4 +-- style/spot.css.map | 2 +- 18 files changed, 218 insertions(+), 94 deletions(-) diff --git a/geo/pct.gpx b/geo/pct.gpx index 348624a..0728890 100644 --- a/geo/pct.gpx +++ b/geo/pct.gpx @@ -3908,7 +3908,7 @@ Truck 784.5 - PO0001 + Post Office - 1 Post Office @@ -4133,7 +4133,7 @@ Campground 1803.2 - PO0041 + Post Office - 41 Post Office diff --git a/inc/Spot.php b/inc/Spot.php index 0346895..40fdf7b 100755 --- a/inc/Spot.php +++ b/inc/Spot.php @@ -73,7 +73,16 @@ class Spot extends Main //Install DB $this->oDb->install(); - $this->oUser->addUser('admin@admin.com', $this->oLang->getLanguage(), date_default_timezone_get()); + //Add first user + $iUserId = $this->oDb->insertRow(User::USER_TABLE, array( + 'name' => 'Admin', + 'email' => 'admin@admin.com', + 'language' => self::DEFAULT_LANG, + 'timezone' => date_default_timezone_get(), + 'active' => User::USER_ACTIVE, + 'clearance' => User::CLEARANCE_ADMIN + )); + $this->oUser->setUserId($iUserId); } public function syncPics() { @@ -177,6 +186,7 @@ class Spot extends Main 'server' => $this->asContext['serv_name'], 'geo_server' => Settings::GEO_SERVER, 'modes' => Project::MODES, + 'clearances' => User::CLEARANCES, 'default_timezone' => Settings::TIMEZONE ) ), @@ -310,8 +320,8 @@ class Spot extends Main return $bInternal?$asResult:self::getJsonResult(true, '', $asResult); } - public function subscribe($sEmail) { - $asResult = $this->oUser->addUser($sEmail, $this->oLang->getLanguage(), date_default_timezone_get()); + public function subscribe($sEmail, $sNickName) { + $asResult = $this->oUser->addUser($sEmail, $this->oLang->getLanguage(), date_default_timezone_get(), $sNickName); $asUserInfo = $this->oUser->getUserInfo(); //Send Confirmation Email @@ -521,19 +531,24 @@ class Spot extends Main $this->oDb->cleanSql($sSort); $sMediaRefField = 'posted_on'; + $sProjectIdField = Db::getId(Project::PROJ_TABLE); + $sMsgIdField = Db::getId(Feed::MSG_TABLE); + $sMediaIdField = Db::getId(Media::MEDIA_TABLE); + $sPostIdField = Db::getId(self::POST_TABLE); + $sFeedIdField = Db::getId(Feed::FEED_TABLE); $sQuery = implode(" ", array( "SELECT type, id, ref", "FROM (", - "SELECT id_project, id_message AS id, 'message' AS type, CONCAT(UNIX_TIMESTAMP(site_time), '.0', id_message) AS ref", + "SELECT {$sProjectIdField}, {$sMsgIdField} AS id, 'message' AS type, CONCAT(UNIX_TIMESTAMP(site_time), '.0', {$sMsgIdField}) AS ref", "FROM ".Feed::MSG_TABLE, - "INNER JOIN feeds USING(id_feed)", + "INNER JOIN ".Feed::FEED_TABLE." USING({$sFeedIdField})", $this->getFeedConstraints(Feed::MSG_TABLE, 'site_time', 'sql'), "UNION", - "SELECT id_project, id_media AS id, 'media' AS type, CONCAT(UNIX_TIMESTAMP(".$sMediaRefField."), '.1', id_media) AS ref", + "SELECT {$sProjectIdField}, {$sMediaIdField} AS id, 'media' AS type, CONCAT(UNIX_TIMESTAMP({$sMediaRefField}), '.1', {$sMediaIdField}) AS ref", "FROM ".Media::MEDIA_TABLE, $this->getFeedConstraints(Media::MEDIA_TABLE, $sMediaRefField, 'sql'), "UNION", - "SELECT id_project, id_post AS id, 'post' AS type, CONCAT(UNIX_TIMESTAMP(site_time), '.2', id_post) AS ref", + "SELECT {$sProjectIdField}, {$sPostIdField} AS id, 'post' AS type, CONCAT(UNIX_TIMESTAMP(site_time), '.2', {$sPostIdField}) AS ref", "FROM ".self::POST_TABLE, $this->getFeedConstraints(self::POST_TABLE, 'site_time', 'sql'), ") AS items", @@ -633,8 +648,6 @@ class Spot extends Main $asProject['active_to'] = substr($asProject['active_to'], 0, 10); } - foreach($asData['user'] as &$asUser) $asUser['id'] = $asUser[Db::getId(User::USER_TABLE)]; - return self::getJsonResult(true, '', $asData); } @@ -683,6 +696,18 @@ class Spot extends Main } $asResult = $oFeed->getFeed(); break; + case 'user': + switch($sField) { + case 'clearance': + $asReturnCode = $this->oUser->setUserClearance($iId, $sValue); + $bSuccess = $asReturnCode['result']; + $sDesc = $asReturnCode['desc']; + break; + default: + $sDesc = $this->oLang->getTranslation('unknown_field', $sField); + } + $asResult = $this->oUser->getActiveUserInfo($iId); + break; } if(!$bSuccess && $sDesc=='') $sDesc = Mask::LANG_PREFIX.'error_commit_db'; diff --git a/inc/User.php b/inc/User.php index 9aba091..37e4e4c 100644 --- a/inc/User.php +++ b/inc/User.php @@ -15,6 +15,7 @@ class User extends PhpObject { const USER_INACTIVE = 0; const CLEARANCE_USER = 0; const CLEARANCE_ADMIN = 9; + const CLEARANCES = array('user'=>self::CLEARANCE_USER, 'admin'=>self::CLEARANCE_ADMIN); //Cookie const COOKIE_ID_USER = 'subscriber'; @@ -34,6 +35,7 @@ class User extends PhpObject { $this->oDb = &$oDb; $this->iUserId = 0; $this->asUserInfo = array( + 'id' => 0, Db::getId(self::USER_TABLE) => 0, 'name' => '', 'email' => '', @@ -49,7 +51,7 @@ class User extends PhpObject { return $this->asUserInfo['language']; } - public function addUser($sEmail, $sLang, $sTimezone) { + public function addUser($sEmail, $sLang, $sTimezone, $sNickName='') { $bSuccess = false; $sDesc = ''; $sEmail = trim($sEmail); @@ -58,7 +60,7 @@ class User extends PhpObject { $iUserId = $this->oDb->selectValue(self::USER_TABLE, Db::getId(self::USER_TABLE), array('email'=>$sEmail, 'active'=>self::USER_ACTIVE)); if($iUserId > 0) { - //Log user in + //Just log user in $sDesc = 'lang:nl_email_exists'; $bSuccess = true; } @@ -72,16 +74,23 @@ class User extends PhpObject { if($iUserId==0) $sDesc = 'lang:error_commit_db'; else { - $this->updateGravatar($iUserId, $sEmail); $sDesc = 'lang:nl_subscribed'; $bSuccess = true; } } - //Set Cookie (valid 1 year) + if($bSuccess) { $this->setUserId($iUserId); + + //Set Cookie (valid 1 year) $this->updateCookie(self::COOKIE_DURATION); + + //Update Nickname if user has already posted + $this->updateNickname($sNickName); + + //Retrieve Gravatar image + $this->updateGravatar($iUserId, $sEmail); } return Spot::getResult($bSuccess, $sDesc); @@ -92,7 +101,7 @@ class User extends PhpObject { $sDesc = ''; if($this->iUserId > 0) { - $iUserId = $this->oDb->updateRow(self::USER_TABLE, $this->iUserId, array('active'=>self::USER_INACTIVE)); + $iUserId = $this->oDb->updateRow(self::USER_TABLE, $this->getUserId(), array('active'=>self::USER_INACTIVE)); if($iUserId==0) $sDesc = 'lang:error_commit_db'; else { $sDesc = 'lang:nl_unsubscribed'; @@ -106,7 +115,7 @@ class User extends PhpObject { } public function updateNickname($sNickname) { - if($this->iUserId > 0 && $sNickname!='') $this->oDb->updateRow(self::USER_TABLE, $this->iUserId, array('name'=>$sNickname)); + if($this->getUserId() > 0 && $sNickname!='') $this->oDb->updateRow(self::USER_TABLE, $this->getUserId(), array('name'=>$sNickname)); } private function updateGravatar($iUserId, $sEmail) { @@ -119,7 +128,7 @@ class User extends PhpObject { $this->setUserId($_COOKIE[self::COOKIE_ID_USER]); //Extend cookie life - if($this->iUserId > 0) $this->updateCookie(self::COOKIE_DURATION); + if($this->getUserId() > 0) $this->updateCookie(self::COOKIE_DURATION); } } @@ -130,10 +139,10 @@ class User extends PhpObject { public function setUserId($iUserId) { $this->iUserId = 0; - $asUser = $this->getActiveUsersInfo($iUserId); + $asUser = $this->getActiveUserInfo($iUserId); if(!empty($asUser)) { $this->iUserId = $iUserId; - $this->asUserInfo = array_shift($asUser); + $this->asUserInfo = $asUser; } } @@ -141,16 +150,28 @@ class User extends PhpObject { return $this->asUserInfo; } + public function getActiveUserInfo($iUserId) { + $asUsersInfo = array(); + if($iUserId > 0) $asUsersInfo = $this->getActiveUsersInfo($iUserId); + return empty($asUsersInfo)?array():array_shift($asUsersInfo); + } + public function getActiveUsersInfo($iUserId=-1) { + + //Mapping between user fields and DB fields + $asSelect = array_keys($this->asUserInfo); + $asSelect[array_search('id', $asSelect)] = Db::getId(self::USER_TABLE)." AS id"; + + //Non-admin cannot access clearance info + if(!$this->checkUserClearance(self::CLEARANCE_ADMIN)) unset($asSelect['clearance']); + $asInfo = array( - 'select' => array_keys($this->asUserInfo), + 'select' => $asSelect, 'from' => self::USER_TABLE, 'constraint'=> array('active'=>self::USER_ACTIVE) ); if($iUserId != -1) $asInfo['constraint'][Db::getId(self::USER_TABLE)] = $iUserId; - if(!$this->checkUserClearance(self::CLEARANCE_ADMIN)) unset($asInfo['select']['clearance']); - return $this->oDb->selectRows($asInfo); } @@ -159,7 +180,24 @@ class User extends PhpObject { return ($this->asUserInfo['clearance'] >= $iClearance); } + public function setUserClearance($iUserId, $iClearance) { + $bSuccess = false; + $sDesc = ''; + + if(!$this->checkUserClearance(self::CLEARANCE_ADMIN)) $sDesc = 'unauthorized'; + else { + if(!in_array($iClearance, self::CLEARANCES)) $sDesc = 'Setting wrong clearance "'.$iClearance.'" to user ID "'.$iUserId.'"'; + else { + $iUserId = $this->oDb->updateRow(self::USER_TABLE, $iUserId, array('clearance'=>$iClearance)); + if(!$iUserId) $sDesc = 'lang:error_commit_db'; + else $bSuccess = true; + } + } + + return Spot::getResult($bSuccess, $sDesc); + } + private function updateCookie($iDeltaTime) { - setcookie(self::COOKIE_ID_USER, ($iDeltaTime < 0)?'':$this->iUserId, array('samesite' => 'Lax', 'expires' => time() + $iDeltaTime)); + setcookie(self::COOKIE_ID_USER, ($iDeltaTime < 0)?'':$this->getUserId(), array('samesite' => 'Lax', 'expires' => time() + $iDeltaTime)); } } diff --git a/index.php b/index.php index 36d979f..6c8e1e0 100755 --- a/index.php +++ b/index.php @@ -53,7 +53,7 @@ if($sAction!='') $sResult = $oSpot->addPost($sName, $sContent); break; case 'subscribe': - $sResult = $oSpot->subscribe($sEmail); + $sResult = $oSpot->subscribe($sEmail, $sName); break; case 'unsubscribe': $sResult = $oSpot->unsubscribe(); diff --git a/languages/en.lang b/languages/en.lang index 24b3f50..dda6518 100644 --- a/languages/en.lang +++ b/languages/en.lang @@ -3,6 +3,11 @@ page_og_desc = Keep contact with François when he is off hiking error_commit_db = Issue committing to DB unknown_field = Field "$0" is unknown +nav_back = Back + +admin = Admin Panel +admin_config = Config +admin_upload = Upload save = Save admin_save_success = Saved @@ -27,9 +32,9 @@ map_satellite = Satellite map_otm = Open Topo Map map_ign_france = IGN (France) map_ign_spain = IGN (Spain) -map_linz = LINZ (New Zealand) -map_usgs = USGS (USA) -map_natgeo = National Geographic (USA) +map_linz = LINZ +map_usgs = USGS +map_natgeo = National Geographic image = Picture images = Pictures @@ -55,6 +60,8 @@ time_zone = Time Zone id_project = Project ID project = Project projects = Projects +new_project = New Project +update_project = Update Project hikes = Hikes mode = Mode mode_previz = Project in preparation @@ -63,6 +70,7 @@ mode_histo = Archived Project code_name = Code name start = Start end = End +feeds = Feeds id_feed = Feed ID ref_feed_id = Ref. Feed ID id_spot = Spot ID @@ -73,8 +81,11 @@ ref_spot_id = Ref. Spot ID model = Model delete = Delete id_user = User ID +user_name = User Name +active_users = Active Users language = Language clearance = Clearance +toolbox = Toolbox unit_day = day unit_days = days diff --git a/languages/fr.lang b/languages/fr.lang index 81c7c03..81fe0bc 100644 --- a/languages/fr.lang +++ b/languages/fr.lang @@ -1,8 +1,13 @@ -locale = fr_FR +locale = fr_CH 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 unknown_field = Champ "$0" inconnu +nav_back = Retour + +admin = Administration +admin_config = Paramètres +admin_upload = Uploader save = Sauvegarder admin_save_success = Sauvegardé @@ -27,9 +32,9 @@ map_satellite = Satellite map_otm = Open Topo Map map_ign_france = IGN (France) map_ign_spain = IGN (Espagne) -map_linz = LINZ (Nouvelle-Zélande) -map_usgs = USGS (États-Unis) -map_natgeo = National Geographic (États-Unis) +map_linz = LINZ +map_usgs = USGS +map_natgeo = National Geographic image = Photo images = Photos @@ -55,6 +60,8 @@ time_zone = Fuseau horaire id_project = ID projet project = Projet projects = Projets +new_project = Nouveau projet +update_project = Mettre à jour le projet hikes = Randonnées mode = Mode mode_previz = Project en cours de préparation @@ -63,6 +70,7 @@ mode_histo = Project archivé code_name = Nom de code start = Départ end = Arrivée +feeds = Feeds id_feed = ID Feed ref_feed_id = ID Feed ref. id_spot = ID Spot @@ -73,8 +81,11 @@ ref_spot_id = ID Spot ref. model = Modèle delete = Supprimer id_user = ID Utilisateur +user_name = Nom +active_users = Utilisateurs actifs language = Langue clearance = Niveau d'autorisation +toolbox = Boite à outils unit_day = jour unit_days = jours diff --git a/masks/admin.html b/masks/admin.html index 592de1e..70dd777 100644 --- a/masks/admin.html +++ b/masks/admin.html @@ -1,6 +1,7 @@
-

Projects

-
+ [#]lang:nav_back[#] +

[#]lang:projects[#]

+
@@ -17,8 +18,8 @@
-

Feeds

-
+

[#]lang:feeds[#]

+
@@ -36,7 +37,7 @@

Spots

-
+
@@ -49,13 +50,13 @@
-

Users

-
+

[#]lang:active_users[#]

+
- + @@ -64,15 +65,15 @@
[#]lang:id_user[#][#]lang:name[#][#]lang:user_name[#] [#]lang:language[#] [#]lang:time_zone[#] [#]lang:clearance[#]
-

ToolBox

+

[#]lang:toolbox[#]