self::CLEARANCE_USER, 'admin'=>self::CLEARANCE_ADMIN); //Cookie const COOKIE_ID_USER = 'subscriber'; const COOKIE_DURATION = 60 * 60 * 24 * 365; //1 year /** * Database Handle * @var Db */ private $oDb; //User Info private $iUserId; private $asUserInfo; public function __construct(Db &$oDb) { parent::__construct(__CLASS__, Settings::DEBUG); $this->oDb = &$oDb; $this->iUserId = 0; $this->asUserInfo = array( 'id' => 0, Db::getId(self::USER_TABLE) => 0, 'name' => '', 'email' => '', 'language' => '', 'timezone' => '', 'active' => self::USER_INACTIVE, 'clearance' => self::CLEARANCE_USER ); $this->checkUserCookie(); } public function getLang() { return $this->asUserInfo['language']; } public function addUser($sEmail, $sLang, $sTimezone, $sNickName='') { $bSuccess = false; $sDesc = ''; $sEmail = trim($sEmail); //Check Email availability $iUserId = $this->oDb->selectValue(self::USER_TABLE, Db::getId(self::USER_TABLE), array('email'=>$sEmail, 'active'=>self::USER_ACTIVE)); if($iUserId > 0) { //Just log user in $sDesc = 'lang:nl_email_exists'; $bSuccess = true; } else { //Add/Reactivate user $iUserId = $this->oDb->insertUpdateRow( self::USER_TABLE, array('email'=>$sEmail, 'language'=>$sLang, 'timezone'=>$sTimezone, 'active'=>self::USER_ACTIVE), array('email') ); if($iUserId==0) $sDesc = 'lang:error_commit_db'; else { $sDesc = 'lang:nl_subscribed'; $bSuccess = true; } } 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); } public function removeUser() { $bSuccess = false; $sDesc = ''; if($this->iUserId > 0) { $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'; $this->updateCookie(-60 * 60); //Set Cookie in the past, deleting it $bSuccess = true; } } else $sDesc = 'lang:nl_unknown_email'; return Spot::getResult($bSuccess, $sDesc); } public function updateNickname($sNickname) { if($this->getUserId() > 0 && $sNickname!='') $this->oDb->updateRow(self::USER_TABLE, $this->getUserId(), array('name'=>$sNickname)); } private function updateGravatar($iUserId, $sEmail) { $sImage = ($sEmail != '')?@file_get_contents('https://www.gravatar.com/avatar/'.md5($sEmail).'.png?d=404&s=24'):''; $this->oDb->updateRow(self::USER_TABLE, $iUserId, array('gravatar' => base64_encode($sImage))); } private function checkUserCookie() { if(isset($_COOKIE[self::COOKIE_ID_USER])){ $this->setUserId($_COOKIE[self::COOKIE_ID_USER]); //Extend cookie life if($this->getUserId() > 0) $this->updateCookie(self::COOKIE_DURATION); } } public function getUserId() { return $this->iUserId; } public function setUserId($iUserId) { $this->iUserId = 0; $asUser = $this->getActiveUserInfo($iUserId); if(!empty($asUser)) { $this->iUserId = $iUserId; $this->asUserInfo = $asUser; } } public function getUserInfo() { 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' => $asSelect, 'from' => self::USER_TABLE, 'constraint'=> array('active'=>self::USER_ACTIVE) ); if($iUserId != -1) $asInfo['constraint'][Db::getId(self::USER_TABLE)] = $iUserId; return $this->oDb->selectRows($asInfo); } public function checkUserClearance($iClearance) { 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->getUserId(), array('samesite' => 'Lax', 'expires' => time() + $iDeltaTime)); } }