diff --git a/src/application/controller/api/user/avatar.php b/src/application/controller/api/user/avatar.php index 0dc5148..e95a7e0 100644 --- a/src/application/controller/api/user/avatar.php +++ b/src/application/controller/api/user/avatar.php @@ -13,6 +13,11 @@ if (isset($_SESSION['userName'])) { // Prepare user request, authorized user by default $userName = isset($_GET['userName']) ? Filter::userName($_GET['userName']) : $_SESSION['userName']; + // No cache request + if (isset($_GET['nocache'])) { + $_memcache->delete('api.user.avatar.' . $userName); + } + // Check user exists in the database if ($userId = $_modelUser->getUserId($userName)) { @@ -20,6 +25,7 @@ if (isset($_SESSION['userName'])) { * Step 1: try to obtain avatar from cache * * */ + if ($mcAvatar = $_memcache->get('api.user.avatar.' . $userName)) { $response = [ diff --git a/src/application/controller/api/user/profile.php b/src/application/controller/api/user/profile.php index 0f45432..93bbb52 100644 --- a/src/application/controller/api/user/profile.php +++ b/src/application/controller/api/user/profile.php @@ -13,6 +13,11 @@ if (isset($_SESSION['userName'])) { // Prepare user request, authorized user by default $userName = isset($_GET['userName']) ? Filter::userName($_GET['userName']) : $_SESSION['userName']; + // No cache request + if (isset($_GET['nocache'])) { + $_memcache->delete('api.user.profile.' . $userName); + } + // Check user exists in the database if ($userId = $_modelUser->getUserId($userName)) { @@ -41,20 +46,20 @@ if (isset($_SESSION['userName'])) { // Save revision into the database if not exists if (!$_modelProfile->versionExists($userId, - $dhtProfileRevision['height'], - $dhtProfileRevision['seq'])) { + Filter::int($dhtProfileRevision['height']), + Filter::int($dhtProfileRevision['seq']))) { $_modelProfile->add($userId, - $dhtProfileRevision['height'], - $dhtProfileRevision['seq'], - $dhtProfileRevision['time'], - - $dhtProfileRevision['fullName'], - $dhtProfileRevision['bio'], - $dhtProfileRevision['location'], - $dhtProfileRevision['url'], - $dhtProfileRevision['bitMessage'], - $dhtProfileRevision['tox']); + Filter::int($dhtProfileRevision['height']), + Filter::int($dhtProfileRevision['seq']), + Filter::int($dhtProfileRevision['time']), + + Filter::fullName($dhtProfileRevision['fullName']), + Filter::bio($dhtProfileRevision['bio']), + Filter::location($dhtProfileRevision['location']), + Filter::url($dhtProfileRevision['url']), + Filter::bitMessage($dhtProfileRevision['bitMessage']), + Filter::tox($dhtProfileRevision['tox'])); } } } @@ -68,12 +73,12 @@ if (isset($_SESSION['userName'])) { // Format output $profile = [ 'userName' => $userName, - 'fullName' => Format::text($dbProfileRevision['fullName']), - 'location' => Format::text($dbProfileRevision['location']), - 'url' => Format::text($dbProfileRevision['url']), - 'bitMessage' => Format::text($dbProfileRevision['bitMessage']), - 'tox' => Format::text($dbProfileRevision['tox']), - 'bio' => Format::text($dbProfileRevision['bio']), + 'fullName' => $dbProfileRevision['fullName'], + 'location' => $dbProfileRevision['location'], + 'url' => $dbProfileRevision['url'], + 'bitMessage' => $dbProfileRevision['bitMessage'], + 'tox' => $dbProfileRevision['tox'], + 'bio' => Format::bio($dbProfileRevision['bio']), ]; // Save request into the cache pool diff --git a/src/application/controller/settings/profile.php b/src/application/controller/settings/profile.php index e8e1da9..ac23f56 100644 --- a/src/application/controller/settings/profile.php +++ b/src/application/controller/settings/profile.php @@ -22,37 +22,28 @@ $metaScripts = [ ]; // Init variables -$fullName = false; -$location = false; -$url = false; -$bitMessage = false; -$tox = false; -$bio = false; -$avatar = false; +$successMessage = false; -$errorFullName = false; -$errorLocation = false; -$errorURL = false; -$errorBitMessage = false; -$errorTOX = false; -$errorBio = false; +/* +* Process profile update request +* +* */ -// Save profile details if (isset($_POST) && !empty($_POST)) { - // Prepare request - $fullName = isset($_POST['fullName']) ? Filter::string($_POST['fullName']) : ''; - $location = isset($_POST['location']) ? Filter::string($_POST['location']) : ''; - $url = isset($_POST['url']) ? Filter::string($_POST['url']) : ''; - $bitMessage = isset($_POST['bitMessage']) ? Filter::string($_POST['bitMessage']) : ''; - $tox = isset($_POST['tox']) ? Filter::string($_POST['tox']) : ''; - $bio = isset($_POST['bio']) ? Filter::string($_POST['bio']) : ''; + // Filter form data + $fullName = isset($_POST['fullName']) ? Filter::fullName($_POST['fullName']) : ''; + $location = isset($_POST['location']) ? Filter::location($_POST['location']) : ''; + $url = isset($_POST['url']) ? Filter::url($_POST['url']) : ''; + $bitMessage = isset($_POST['bitMessage']) ? Filter::bitMessage($_POST['bitMessage']) : ''; + $tox = isset($_POST['tox']) ? Filter::tox($_POST['tox']) : ''; + $bio = isset($_POST['bio']) ? Filter::bio($_POST['bio']) : ''; // Get current block number $blockId = $_modelBlock->getThisBlock(); // Avatar provided - if (isset($_FILES['avatar']['tmp_name']) && file_exists($_FILES['avatar']['tmp_name']) && getimagesize($_FILES['avatar']['tmp_name'])) { + if (isset($_FILES['avatar']['tmp_name']) && file_exists($_FILES['avatar']['tmp_name']) && @getimagesize($_FILES['avatar']['tmp_name'])) { // Prepare image $image = new Imagick(); @@ -135,131 +126,23 @@ if (isset($_POST) && !empty($_POST)) { $url, $bitMessage, $tox); - } - - // Update profile cache - $_memcache->replace('api.user.profile.' . $_SESSION['userName'], - [ - 'userName' => $_SESSION['userName'], - 'fullName' => $fullName, - 'location' => $location, - 'url' => $url, - 'bitMessage' => $bitMessage, - 'tox' => $tox, - 'bio' => $bio, - ], - MEMCACHE_COMPRESS, - MEMCACHE_DHT_PROFILE_TIMEOUT); - -} - -// Get avatar details -if ($userAvatar = $_memcache->get('api.user.avatar.' . $_SESSION['userName'])) { - - $avatar = $userAvatar; - -} else if ($avatarVersions = $_twister->getDHT($_SESSION['userName'], 'avatar', 's')) { - - // Add DHT version if not exists - foreach ($avatarVersions as $avatarVersion) { - - if (!$_modelAvatar->versionExists($_SESSION['userId'], - Filter::int($avatarVersion['p']['height']), - Filter::int($avatarVersion['p']['seq']))) { - - $_modelAvatar->add( $_SESSION['userId'], - Filter::int($avatarVersion['p']['height']), - Filter::int($avatarVersion['p']['seq']), - Filter::int($avatarVersion['p']['time']), - Filter::string($avatarVersion['p']['v'])); - } - } - - // Get latest version available - if ($avatarInfo = $_modelAvatar->get($_SESSION['userId'])) { - - $avatar = $avatarInfo['data']; - - $_memcache->set('api.user.avatar.' . $_SESSION['userName'], $avatarInfo['data'], MEMCACHE_COMPRESS, MEMCACHE_DHT_AVATAR_TIMEOUT); - } - -// Generate identity icon -} else { - - $fileName = md5($_SESSION['userName']); - $filePath = PROJECT_DIR . '/cache/image/' . $fileName . '.jpeg'; - - if (!file_exists($filePath)) { - - $icon = new Icon(); - $image = $icon->generateImageResource($fileName, 42, 42, false); - - file_put_contents($filePath, $image); - } - - $avatar = sprintf('data:image/jpeg;base64,%s', base64_encode(file_get_contents($filePath))); -} - -// Get profile details from cache -if ($profile = $_memcache->get('api.user.profile.' . $_SESSION['userName'])) { - - $fullName = $profile['fullName']; - $location = $profile['location']; - $url = $profile['url']; - $bitMessage = $profile['bitMessage']; - $tox = $profile['tox']; - $bio = $profile['bio']; - -// Get profile details from DHT -} else if ($userProfileVersions = $_twister->getDHT($_SESSION['userName'], 'profile', 's')) { - - // Add DHT version if not exists - foreach ($userProfileVersions as $userProfileVersion) { - - if (!$_modelProfile->versionExists($_SESSION['userId'], - Filter::int($userProfileVersion['p']['height']), - Filter::int($userProfileVersion['p']['seq']))) { - - if (isset($userProfileVersion['p']['v'])) { - - $profile = $userProfileVersion['p']['v']; - - $_modelProfile->add($_SESSION['userId'], - Filter::int($userProfileVersion['p']['height']), - Filter::int($userProfileVersion['p']['seq']), - Filter::int($userProfileVersion['p']['time']), - - isset($profile['fullname']) ? Filter::string($profile['fullname']) : '', - isset($profile['bio']) ? Filter::string($profile['bio']) : '', - isset($profile['location']) ? Filter::string($profile['location']) : '', - isset($profile['url']) ? Filter::string($profile['url']) : '', - isset($profile['bitmessage']) ? Filter::string($profile['bitmessage']) : '', - isset($profile['tox']) ? Filter::string($profile['tox']) : ''); - } - } - } - - // Get latest version available - if ($profileInfo = $_modelProfile->get($_SESSION['userId'])) { - - $profile = [ - 'userName' => $_SESSION['userName'], - 'fullName' => $profileInfo['fullName'], - 'location' => $profileInfo['location'], - 'url' => $profileInfo['url'], - 'bitMessage' => $profileInfo['bitMessage'], - 'tox' => $profileInfo['tox'], - 'bio' => $profileInfo['bio'], - ]; - $fullName = $profile['fullName']; - $location = $profile['location']; - $url = $profile['url']; - $bitMessage = $profile['bitMessage']; - $tox = $profile['tox']; - $bio = $profile['bio']; - $_memcache->set('api.user.profile.' . $_SESSION['userName'], $profile, MEMCACHE_COMPRESS, MEMCACHE_DHT_PROFILE_TIMEOUT); + // Update profile cache + $_memcache->replace('api.user.profile.' . $_SESSION['userName'], + [ + 'userName' => $_SESSION['userName'], + 'fullName' => $fullName, + 'location' => $location, + 'url' => $url, + 'bitMessage' => $bitMessage, + 'tox' => $tox, + 'bio' => Format::bio($bio), + ], + MEMCACHE_COMPRESS, + MEMCACHE_DHT_PROFILE_TIMEOUT); + + $successMessage = _('Profile successfully saved!'); } } diff --git a/src/application/view/settings/profile.phtml b/src/application/view/settings/profile.phtml index 596b9fd..72b958d 100644 --- a/src/application/view/settings/profile.phtml +++ b/src/application/view/settings/profile.phtml @@ -9,40 +9,23 @@

- - + +
- - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- + + + + + + + + + + + +
+
diff --git a/src/public/css/template/default/settings/profile.css b/src/public/css/template/default/settings/profile.css index ca4100f..996d6a1 100644 --- a/src/public/css/template/default/settings/profile.css +++ b/src/public/css/template/default/settings/profile.css @@ -1,7 +1,7 @@ .settingsProfile .avatar { margin-bottom: 32px; padding-bottom: 16px; - border-bottom: 1px #4d5666 solid;; + border-bottom: 1px #4d5666 solid; } .settingsProfile .avatar img { @@ -10,6 +10,7 @@ vertical-align: middle; margin-right: 16px; width: 42px; + display: none } .settingsProfile form { @@ -62,7 +63,6 @@ background-color: #337ab7; color: #fff; border: 0; - width: 100%; } .settingsProfile form button:hover { @@ -70,6 +70,19 @@ } .settingsProfile form .actions { - text-align: right; overflow: hidden; + margin-top: 16px; + padding-top: 16px; + border-top: 1px #4d5666 solid;; +} + +.settingsProfile form .actions .success { + color: #44c508; + line-height: 36px; +} + +.settingsProfile form .error { + margin-bottom: 16px; + color: #ee7575; + font-size: 11px; } \ No newline at end of file diff --git a/src/public/js/settings/profile.js b/src/public/js/settings/profile.js index bb17164..9c8d8e7 100644 --- a/src/public/js/settings/profile.js +++ b/src/public/js/settings/profile.js @@ -1,7 +1,72 @@ +var SettingsProfile = { + init: function() { + + // Load avatar + $.ajax({ + url: 'api/user/avatar', + type: 'GET', + data: { + nocache: true + }, + success: function (response) { + + if (response.success) { + + $('#settingsProfileAvatarImage').attr('src', response.avatar ? response.avatar : '').show(); + + setTimeout(function(){ + $('#settingsProfileActionsSuccess').css('opacity', 0); + }, 5000); + + } else { + + console.log(response.message); + + } + }, + error: function(jqXHR, textStatus, errorThrown) { + console.log(textStatus, errorThrown); + } + }); + + // Load profile + $.ajax({ + url: 'api/user/profile', + type: 'GET', + data: { + nocache: true + }, + success: function (response) { + + if (response.success) { + + $('#settingsProfileFullName').val(response.profile.fullName ? response.profile.fullName : ''); + $('#settingsProfileLocation').val(response.profile.location ? response.profile.location : ''); + $('#settingsProfileURL').val(response.profile.url ? response.profile.url : ''); + $('#settingsProfileBitMessage').val(response.profile.bitMessage ? response.profile.bitMessage : ''); + $('#settingsProfileTOX').val(response.profile.tox ? response.profile.tox : ''); + $('#settingsProfileBio').val(response.profile.bio ? response.profile.bio : ''); + + } else { + + console.log(response.message); + + } + }, + error: function(jqXHR, textStatus, errorThrown) { + console.log(textStatus, errorThrown); + } + }); + } +} + $(document).ready(function() { // Init modules ModuleMenu.init('settings'); ModuleSettings.init('settings'); + // Init page + SettingsProfile.init(); + }); \ No newline at end of file diff --git a/src/system/helper/filter.php b/src/system/helper/filter.php index 32345c5..38acba9 100644 --- a/src/system/helper/filter.php +++ b/src/system/helper/filter.php @@ -17,6 +17,48 @@ class Filter { return preg_replace('/[^a-zA-Z0-9]+/u', '', $blockHash); } + public static function fullName(string $string) { + + $string = preg_replace('/[^\s\w]+/u', '', $string); + + return $string; + } + + public static function location(string $string) { + + $string = preg_replace('/[^\s\w\.\,]+/u', '', $string); + + return $string; + } + + public static function url(string $string) { + + $string = preg_replace('/[^\w\?\&\=\.\:\/]+/u', '', $string); + + return $string; + } + + public static function bitMessage(string $string) { + + $string = preg_replace('/[^\w\-]+/u', '', $string); + + return $string; + } + + public static function tox(string $string) { + + $string = preg_replace('/[^\w]+/u', '', $string); + + return $string; + } + + public static function bio(string $string) { + + $string = preg_replace('/[^\s\w\.\,\:\;\@\#\-\_\~\*\/]+/u', '', $string); + + return $string; + } + public static function string(mixed $string) { return (string) $string; diff --git a/src/system/helper/format.php b/src/system/helper/format.php index 57c372e..1248637 100644 --- a/src/system/helper/format.php +++ b/src/system/helper/format.php @@ -2,6 +2,7 @@ class Format { + // Common public static function plural(int $number, array $texts) { $cases = [2, 0, 1, 1, 1, 2]; @@ -44,6 +45,24 @@ class Format { } } + // Profile + public static function bio(string $string) { + + $string = preg_replace("|\*([\S]+)\*|i", "$1", $string); + $string = preg_replace("|\~([\S]+)\~|i", "$1", $string); + $string = preg_replace("|\_([\S]+)\_|i", "$1", $string); + $string = preg_replace("|\-([\S]+)\-|i", "$1", $string); + $string = preg_replace("|\`([\S]+)\`|i", "$1", $string); + + $string = preg_replace("|@([a-zA-Z0-9_]+)|i", "@$1", $string); + $string = preg_replace("|((https?://)+([\d\w\.-]+\.[\w\.]{2,6})[^\s\]\[\<\>]*/?)|i", "$3", $string); + + $string = nl2br($string); + + return $string; + } + + // @TODO REPLACE public static function text(string $string) { $string = html_entity_decode($string, ENT_QUOTES, 'UTF-8');