Browse Source

update profile page: add filtering, formatting, update styles, add success message, move profile load to the API call

main
ghost 3 years ago
parent
commit
932fb81cfa
  1. 6
      src/application/controller/api/user/avatar.php
  2. 41
      src/application/controller/api/user/profile.php
  3. 149
      src/application/controller/settings/profile.php
  4. 47
      src/application/view/settings/profile.phtml
  5. 19
      src/public/css/template/default/settings/profile.css
  6. 65
      src/public/js/settings/profile.js
  7. 42
      src/system/helper/filter.php
  8. 19
      src/system/helper/format.php

6
src/application/controller/api/user/avatar.php

@ -13,6 +13,11 @@ if (isset($_SESSION['userName'])) { @@ -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'])) { @@ -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 = [

41
src/application/controller/api/user/profile.php

@ -13,6 +13,11 @@ if (isset($_SESSION['userName'])) { @@ -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'])) { @@ -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'])) { @@ -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

149
src/application/controller/settings/profile.php

@ -22,37 +22,28 @@ $metaScripts = [ @@ -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,7 +126,7 @@ if (isset($_POST) && !empty($_POST)) { @@ -135,7 +126,7 @@ if (isset($_POST) && !empty($_POST)) {
$url,
$bitMessage,
$tox);
}
// Update profile cache
$_memcache->replace('api.user.profile.' . $_SESSION['userName'],
@ -146,120 +137,12 @@ if (isset($_POST) && !empty($_POST)) { @@ -146,120 +137,12 @@ if (isset($_POST) && !empty($_POST)) {
'url' => $url,
'bitMessage' => $bitMessage,
'tox' => $tox,
'bio' => $bio,
'bio' => Format::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);
$successMessage = _('Profile successfully saved!');
}
}

47
src/application/view/settings/profile.phtml

@ -9,40 +9,23 @@ @@ -9,40 +9,23 @@
<h1><?php echo $pageTitle ?></h1>
<form action="settings" name="profile" enctype="multipart/form-data" method="POST">
<div class="avatar">
<img src="<?php echo $avatar ?>" alt="" />
<input name="avatar" type="file" value="" />
<img src="" alt="" id="settingsProfileAvatarImage" />
<input name="avatar" id="settingsProfileAvatar" type="file" value="" />
</div>
<label for="fullName"><?php echo _('Full name') ?></label>
<input type="text" name="fullName" id="fullName" value="<?php echo $fullName ?>" placeholder="<?php echo _('Not provided') ?>" />
<?php if ($errorFullName) { ?>
<div class="error"><?php echo $errorFullName ?></div>
<?php } ?>
<label for="location"><?php echo _('Location') ?></label>
<input type="text" name="location" id="location" value="<?php echo $location ?>" placeholder="<?php echo _('Not provided') ?>" />
<?php if ($errorLocation) { ?>
<div class="error"><?php echo $errorLocation ?></div>
<?php } ?>
<label for="url"><?php echo _('Website') ?></label>
<input type="text" name="url" id="url" value="<?php echo $url ?>" placeholder="<?php echo _('Not provided') ?>" />
<?php if ($errorURL) { ?>
<div class="error"><?php echo $errorURL ?></div>
<?php } ?>
<label for="bitMessage"><?php echo _('BitMessage') ?></label>
<input type="text" name="bitMessage" id="bitMessage" value="<?php echo $bitMessage ?>" placeholder="<?php echo _('Not provided') ?>" />
<?php if ($errorBitMessage) { ?>
<div class="error"><?php echo $errorBitMessage ?></div>
<?php } ?>
<label for="tox"><?php echo _('TOX') ?></label>
<input type="text" name="tox" id="tox" value="<?php echo $tox ?>" placeholder="<?php echo _('Not provided') ?>" />
<?php if ($errorTOX) { ?>
<div class="error"><?php echo $errorTOX ?></div>
<?php } ?>
<label for="bio"><?php echo _('Bio') ?></label>
<textarea name="bio" id="bio" placeholder="<?php echo _('Not provided') ?>"><?php echo $bio ?></textarea>
<?php if ($errorBio) { ?>
<div class="error"><?php echo $errorBio ?></div>
<?php } ?>
<label for="settingsProfileFullName"><?php echo _('Full name') ?></label>
<input type="text" name="fullName" id="settingsProfileFullName" value="" placeholder="<?php echo _('Not provided') ?>" />
<label for="settingsProfileLocation"><?php echo _('Location') ?></label>
<input type="text" name="location" id="settingsProfileLocation" value="" placeholder="<?php echo _('Not provided') ?>" />
<label for="settingsProfileURL"><?php echo _('Website') ?></label>
<input type="text" name="url" id="settingsProfileURL" value="" placeholder="<?php echo _('Not provided') ?>" />
<label for="settingsProfileBitMessage"><?php echo _('BitMessage') ?></label>
<input type="text" name="bitMessage" id="settingsProfileBitMessage" value="" placeholder="<?php echo _('Not provided') ?>" />
<label for="settingsProfileTOX"><?php echo _('TOX') ?></label>
<input type="text" name="tox" id="settingsProfileTOX" value="" placeholder="<?php echo _('Not provided') ?>" />
<label for="settingsProfileBio"><?php echo _('Bio') ?></label>
<textarea name="bio" id="settingsProfileBio" placeholder="<?php echo _('Not provided') ?>"></textarea>
<div class="actions">
<span class="success" id="settingsProfileActionsSuccess"><?php echo $successMessage ?></span>
<button type="submit"><?php echo _('Save') ?></button>
</div>
</form>

19
src/public/css/template/default/settings/profile.css

@ -1,7 +1,7 @@ @@ -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 @@ @@ -10,6 +10,7 @@
vertical-align: middle;
margin-right: 16px;
width: 42px;
display: none
}
.settingsProfile form {
@ -62,7 +63,6 @@ @@ -62,7 +63,6 @@
background-color: #337ab7;
color: #fff;
border: 0;
width: 100%;
}
.settingsProfile form button:hover {
@ -70,6 +70,19 @@ @@ -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;
}

65
src/public/js/settings/profile.js

@ -1,7 +1,72 @@ @@ -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();
});

42
src/system/helper/filter.php

@ -17,6 +17,48 @@ class Filter { @@ -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;

19
src/system/helper/format.php

@ -2,6 +2,7 @@ @@ -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 { @@ -44,6 +45,24 @@ class Format {
}
}
// Profile
public static function bio(string $string) {
$string = preg_replace("|\*([\S]+)\*|i", "<b>$1</b>", $string);
$string = preg_replace("|\~([\S]+)\~|i", "<i>$1</i>", $string);
$string = preg_replace("|\_([\S]+)\_|i", "<u>$1</u>", $string);
$string = preg_replace("|\-([\S]+)\-|i", "<s>$1</s>", $string);
$string = preg_replace("|\`([\S]+)\`|i", "<samp>$1</samp>", $string);
$string = preg_replace("|@([a-zA-Z0-9_]+)|i", "<a href=\"people/$1\">@$1</a>", $string);
$string = preg_replace("|((https?://)+([\d\w\.-]+\.[\w\.]{2,6})[^\s\]\[\<\>]*/?)|i", "<a href=\"$1\" target=\"_blank\">$3</a>", $string);
$string = nl2br($string);
return $string;
}
// @TODO REPLACE
public static function text(string $string) {
$string = html_entity_decode($string, ENT_QUOTES, 'UTF-8');

Loading…
Cancel
Save