Working on new user API

This commit is contained in:
Pachira 2015-08-19 04:37:45 +02:00
parent ed8d512977
commit b159477be2
11 changed files with 291 additions and 130 deletions

View file

@ -43,7 +43,8 @@
"20150811",
"20150812",
"20150813",
"20150818"
"20150818",
"20150819"
]
@ -2032,6 +2033,36 @@
"user": "Flashwave"
}
],
"20150819": [
{
"type": "UPD",
"change": "Only make the SQL library fetch an associative array since the numbered one is not used anywhere.",
"user": "Flashwave"
},
{
"type": "FIX",
"change": "Fixed the lie in the previous change changing the __only__ use of it to associative.",
"user": "Flashwave"
},
{
"type": "ADD",
"change": "Begin work on a User class (different from the Users class) to easily get a user's data in a usable state.",
"user": "Flashwave"
},
{
"type": "FIX",
"change": "Fixed incorrect counting on the List view in the memberlist (how did I miss this for 4 months?).",
"user": "Flashwave"
},
{
"type": "UPD",
"change": "Converted most of profile.php to the new user API.",
"user": "Flashwave"
}
]
}

View file

@ -54,7 +54,7 @@ class Configuration {
// Properly sort the values
foreach($_DATA as $_CONF) {
$_DBCN[$_CONF[0]] = $_CONF[1];
$_DBCN[$_CONF['config_name']] = $_CONF['config_value'];
}

View file

@ -8,20 +8,153 @@ namespace Sakura;
class User {
// User data
public $user = [];
private $ranks = [];
public $data = [];
public $ranks = [];
public $mainRank = [];
// Initialise the user
function __contruct($id) {
// Initialise the user object
function __construct($id) {
// Get the user database row
$this->user = Database::fetch('users', false, ['id' => [$id, '=']]);
$this->data = Database::fetch('users', false, ['id' => [$id, '=']]);
// Check if the user actually exists
if(empty($this->data)) {
// If not assign as the fallback user
$this->data = Users::$emptyUser;
}
// Decode the json in the userData column
$this->data['userData'] = json_decode(!empty($this->data['userData']) ? $this->data['userData'] : '[]', true);
// Decode the ranks json array
$ranks = json_decode($this->user['ranks'], true);
$ranks = json_decode($this->data['ranks'], true);
// Get the rows for all the ranks
$this->ranks[] = Database::fetch('ranks', false, ['id' => [$id, '=']]);
foreach($ranks as $rank) {
// Store the database row in the array
$this->ranks[$rank] = Database::fetch('ranks', false, ['id' => [$rank, '=']]);
}
// Check if ranks were set
if(empty($this->ranks)) {
// If not assign the fallback rank
$this->ranks[0] = Users::$emptyRank;
}
// Assign the user's main rank to a special variable since we'll use it a lot
$this->mainRank = $this->ranks[array_key_exists($this->data['rank_main'], $this->ranks) ? $this->data['rank_main'] : array_keys($this->ranks)[0]];
}
// Get the user's colour
public function colour() {
return empty($this->data['name_colour']) ? $this->mainRank['colour'] : $this->data['name_colour'];
}
// Get the user's title
public function userTitle() {
return empty($this->data['usertitle']) ? $this->mainRank['title'] : $this->data['usertitle'];
}
// Get the user's long and short country names
public function country() {
return [
'long' => Main::getCountryName($this->data['country']),
'short' => $this->data['country']
];
}
// Get the user's profile fields
public function profileFields() {
// Get profile fields
$profileFields = Database::fetch('profilefields');
// If there's nothing just return null
if(!count($profileFields)) {
return;
}
// Once again if nothing was returned just return null
if(empty($this->data['userData']['profileFields'])) {
return;
}
// Create output array
$profile = [];
// Check if profile fields aren't fake
foreach($profileFields as $field) {
// Completely strip all special characters from the field name
$fieldName = Main::cleanString($field['name'], true, true);
// Check if the user has the current field set otherwise continue
if(!array_key_exists($fieldName, $this->data['userData']['profileFields'])) {
continue;
}
// Assign field to output with value
$profile[$fieldName] = array();
$profile[$fieldName]['name'] = $field['name'];
$profile[$fieldName]['value'] = $this->data['userData']['profileFields'][$fieldName];
$profile[$fieldName]['islink'] = $field['islink'];
// If the field is set to be a link add a value for that as well
if($field['islink']) {
$profile[$fieldName]['link'] = str_replace('{{ VAL }}', $this->data['userData']['profileFields'][$fieldName], $field['linkformat']);
}
// Check if we have additional options as well
if($field['additional'] != null) {
// Decode the json of the additional stuff
$additional = json_decode($field['additional'], true);
// Go over all additional forms
foreach($additional as $subName => $subField) {
// Check if the user has the current field set otherwise continue
if(!array_key_exists($subName, $this->data['userData']['profileFields'])) {
continue;
}
// Assign field to output with value
$profile[$fieldName][$subName] = $this->data['userData']['profileFields'][$subName];
}
}
}
// Return appropiate profile data
return $profile;
}

View file

@ -19,7 +19,7 @@ class MySQL {
// Constructor
function __construct() {
if(!extension_loaded('PDO')) {
// Return error and die
trigger_error('PDO extension not loaded.', E_USER_ERROR);
@ -51,25 +51,25 @@ class MySQL {
// Regular IP/Hostname connection method prepare function
private function prepareHost($dbHost, $dbName, $dbPort = 3306) {
$DSN = 'mysql:host=' . $dbHost . ';port=' . $dbPort . ';dbname=' . $dbName;
return $DSN;
}
// Unix Socket connection method prepare function
private function prepareSock($dbHost, $dbName) {
$DSN = 'mysql:unix_socket=' . $dbHost . ';dbname=' . $dbName;
return $DSN;
}
// Initialise connection using default PDO stuff
private function initConnect($DSN, $dbUname, $dbPword) {
try {
// Connect to SQL server using PDO
$this->sql = new PDO($DSN, $dbUname, $dbPword, array(PDO::ATTR_EMULATE_PREPARES => false, PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING));
@ -77,9 +77,9 @@ class MySQL {
// Catch connection errors
trigger_error('SQL Driver: '. $e->getMessage(), E_USER_ERROR);
}
return true;
}
// Fetch array from database
@ -124,7 +124,7 @@ class MySQL {
$prepare .= ' ORDER BY `'. $order[0] .'`'. (!empty($order[1]) && $order[1] ? ' DESC' : '');
}
// If $limit is set and is an array continue
if(is_array($limit)) {
@ -163,7 +163,7 @@ class MySQL {
$query->execute();
// Return the output
return $fetchAll ? $query->fetchAll(PDO::FETCH_BOTH) : $query->fetch(PDO::FETCH_BOTH);
return $fetchAll ? $query->fetchAll(PDO::FETCH_ASSOC) : $query->fetch(PDO::FETCH_ASSOC);
}

View file

@ -8,7 +8,7 @@
namespace Sakura;
// Define Sakura version
define('SAKURA_VERSION', '20150818');
define('SAKURA_VERSION', '20150819');
define('SAKURA_VLABEL', 'Eminence');
define('SAKURA_COLOUR', '#6C3082');
define('SAKURA_STABLE', false);

View file

@ -48,7 +48,7 @@
<tbody>
<tr>
<td>
#{{ count + 1 }}
#{{ count }}
</td>
<td>
<a href="/u/{{ user.id }}" class="default" style="font-weight: bold; color: {{ page.ranks[user.rank_main].colour }};">{{ user.username }}</a>

View file

@ -1,5 +1,5 @@
{% include 'global/header.tpl' %}
{% if profile.notset or profile.user.id == 0 or profile.user.password_algo == 'nologin' %}
{% if legacyprofile.notset or profile.data.id < 1 or profile.data.password_algo == 'nologin' %}
<div class="content standalone" style="padding: 20px;">
<h1>The requested user does not exist!</h1>
There are a few possible reasons for this:
@ -11,91 +11,93 @@
</ul>
</div>
{% else %}
<div id="userBackground"></div>
<div class="content profile">
<div class="{% if profile.userPage|length > 1 %}content-right {% endif %}content-column">
<div style="text-align: center;">
<img src="/a/{{ profile.user.id }}" alt="{{ profile.user.username }}'s Avatar" class="default-avatar-setting" style="box-shadow: 0 3px 7px #{% if profile.is_online %}484{% else %}844{% endif %};" /><br />
{% if profile.user.rank_main > 1 and profile.ban_check|length < 1 %}
<span style="font-size: .8em;">{{ profile.ranktitle }}</span>
<h1 style="color: {{ profile.colour }}; text-shadow: 0 0 7px {% if profile.colour != 'inherit' %}{{ profile.colour }}{% else %}#222{% endif %}; padding: 0 0 2px;">{{ profile.user.username }}</h1>
{% if profile.is_premium %}<img src="{{ sakura.content_path }}/images/tenshi.png" alt="Tenshi" /> {% endif %}<img src="{{ sakura.content_path }}/images/flags/{% if profile.user.country|lower == 'eu' %}europeanunion{% else %}{{ profile.user.country|lower }}{% endif %}.png" alt="{{ profile.user.country }}" /> <span style="font-size: .9em; line-height: 11px;">{{ profile.country }}</span>
{% if user.checklogin %}
<div class="user-actions">
{% if user.data.id == profile.user.id %}
<a class="fa fa-pencil-square-o" title="Edit your profile" href="/settings/profile"></a>
{% else %}
{% if profile.friend != 0 %}<a class="fa fa-{% if profile.friend == 2 %}heart{% else %}star{% endif %}" title="You are friends"></a>{% endif %}
<a class="fa fa-user-{% if profile.friend == 0 %}plus{% else %}times{% endif %}" title="{% if profile.friend == 0 %}Add {{ profile.user.username }} as a friend{% else %}Remove friend{% endif %}" href="/friends?{% if profile.friend == 0 %}add{% else %}remove{% endif %}={{ profile.user.id }}&amp;session={{ php.sessionid }}&amp;time={{ php.time }}&amp;redirect={{ sakura.currentpage }}" id="profileFriendToggle"></a>
<a class="fa fa-flag" title="Report {{ profile.user.username }}" href="/u/{{ profile.user.id }}/report"></a>
{% endif %}
</div>
{% endif %}
<hr class="default" />
<b>Joined</b> {{ profile.user.regdate|date(sakura.date_format) }}<br />
{% if profile.user.lastdate == 0 %}
<b>{{ profile.user.username }} hasn't logged in yet.</b>
{% else %}
<b>Last Seen on</b> {{ profile.user.lastdate|date(sakura.date_format) }}
{% endif %}<br />
<b>{{ profile.user.username }} has {% if not profile.forum_stats.posts %}no{% else %}{{ profile.forum_stats.posts }}{% endif %} forum post{% if profile.forum_stats.posts != 1 %}s{% endif %}.</b>
{% if profile.fields is not null %}
<hr class="default" />
{% if user.checklogin %}
<table style="width: 100%;">
{% for name,field in profile.fields %}
<tr>
<td style="text-align: left; font-weight: bold;">
{{ field.name }}
</td>
<td style="text-align: right;">
{% if name == 'youtube' %}
<a href="https://youtube.com/{% if field.youtubetype == 1 %}channel{% else %}user{% endif %}/{{ field.value }}" class="default">{% if field.youtubetype == 1 %}{{ profile.user.username }}'s Channel{% else %}{{ field.value }}{% endif %}</a>
{% else %}
{% if field.islink %}
<a href="{{ field.link }}" class="default">
<div id="userBackground"></div>
<div class="content profile">
<div class="{% if profile.userPage|length > 1 %}content-right {% endif %}content-column">
<div style="text-align: center;">
<img src="/a/{{ profile.data.id }}" alt="{{ profile.data.username }}'s Avatar" class="default-avatar-setting" style="box-shadow: 0 3px 7px #{% if profile.is_online %}484{% else %}844{% endif %};" /><br />
{% if profile.data.rank_main > 1 and legacyprofile.ban_check|length < 1 %}{# !!! #}
<span style="font-size: .8em;">{{ profile.userTitle }}</span>
<h1 style="color: {{ profile.colour }}; text-shadow: 0 0 7px {% if profile.colour != 'inherit' %}{{ profile.colour }}{% else %}#222{% endif %}; padding: 0 0 2px;">{{ profile.data.username }}</h1>
{% if profile.is_premium %}<img src="{{ sakura.content_path }}/images/tenshi.png" alt="Tenshi" /> {% endif %}<img src="{{ sakura.content_path }}/images/flags/{% if profile.country.short|lower == 'eu' %}europeanunion{% else %}{{ profile.country.short|lower }}{% endif %}.png" alt="{{ profile.country.short }}" /> <span style="font-size: .9em; line-height: 11px;">{{ profile.country.long }}</span>
{% if user.checklogin %}
<div class="user-actions">
{% if user.data.id == profile.data.id %}
<a class="fa fa-pencil-square-o" title="Edit your profile" href="/settings/profile"></a>
{% else %}
{% if legacyprofile.friend != 0 %}<a class="fa fa-{% if legacyprofile.friend == 2 %}heart{% else %}star{% endif %}" title="You are friends"></a>{% endif %}
<a class="fa fa-user-{% if legacyprofile.friend == 0 %}plus{% else %}times{% endif %}" title="{% if legacyprofile.friend == 0 %}Add {{ legacyprofile.data.username }} as a friend{% else %}Remove friend{% endif %}" href="/friends?{% if legacyprofile.friend == 0 %}add{% else %}remove{% endif %}={{ profile.data.id }}&amp;session={{ php.sessionid }}&amp;time={{ php.time }}&amp;redirect={{ sakura.currentpage }}" id="profileFriendToggle"></a>
<a class="fa fa-flag" title="Report {{ profile.data.username }}" href="/u/{{ profile.data.id }}/report"></a>
{% endif %}
{{ field.value }}
{% if field.islink %}
</a>
</div>
{% endif %}
<hr class="default" />
<b>Joined</b> {{ profile.data.regdate|date(sakura.date_format) }}
<br />
{% if profile.data.lastdate < 1 %}
<b>{{ profile.data.username }} hasn't logged in yet.</b>
{% else %}
<b>Last Seen on</b> {{ profile.data.lastdate|date(sakura.date_format) }}
{% endif %}
<br />
<b>{{ profile.data.username }} has {% if not legacyprofile.forum_stats.posts %}no{% else %}{{ legacyprofile.forum_stats.posts }}{% endif %} forum post{% if legacyprofile.forum_stats.posts != 1 %}s{% endif %}.</b>
{% if profile.profileFields %}
<hr class="default" />
{% if user.checklogin %}
<table style="width: 100%;">
{% for name,field in profile.profileFields %}
<tr>
<td style="text-align: left; font-weight: bold;">
{{ field.name }}
</td>
<td style="text-align: right;">
{% if name == 'youtube' %}
<a href="https://youtube.com/{% if field.youtubetype == 1 %}channel{% else %}user{% endif %}/{{ field.value }}" class="default">{% if field.youtubetype == 1 %}{{ profile.data.username }}'s Channel{% else %}{{ field.value }}{% endif %}</a>
{% else %}
{% if field.islink %}
<a href="{{ field.link }}" class="default">
{% endif %}
{{ field.value }}
{% if field.islink %}
</a>
{% endif %}
{% endif %}
</td>
</tr>
{% endfor %}
</table>
{% else %}
<b>Log in to view the full profile!</b>
{% endif %}
{% endif %}
</td>
</tr>
{% endfor %}
</table>
{% else %}
<b>Log in to view the full profile!</b>
{% endif %}
{% endif %}
{% else %}
<h1 style="color: #222; text-shadow: 0 0 7px #888; padding: 0 0 2px;">{{ profile.user.username }}</h1>
{% endif %}
<hr class="default" />
<b>Account Standing</b>
{% if profile.user.rank_main < 2 %}
<h2 style="color: #888; text-shadow: 0 0 7px #888; margin-top: 0;">Deactivated</h2>
{% elseif profile.ban_check %}
<h2 style="color: #222; text-shadow: 0 0 7px #222; margin-top: 0;">Banned</h2>
{% else %}
{% if profile.warnings %}
<h2 style="color: red; text-shadow: 0 0 7px #888; margin-top: 0;">Bad</h2>
<span style="font-size: 10px; line-height: 10px;">This user has <b>{{ profile.warnings|length }} warning{% if profile.warnings|length != 1 %}s{% endif %}</b>.<br />After 5 to 10 warnings (depending on what they are for) this user may be permanently banned.</span>
{% else %}
<h2 style="color: green; text-shadow: 0 0 7px #888; margin-top: 0;">Good</h2>
<h1 style="color: #222; text-shadow: 0 0 7px #888; padding: 0 0 2px;">{{ profile.data.username }}</h1>
{% endif %}
{% endif %}
<hr class="default" />
<b>Account Standing</b>
{% if profile.data.rank_main < 2 %}
<h2 style="color: #888; text-shadow: 0 0 7px #888; margin-top: 0;">Deactivated</h2>
{% elseif legacyprofile.ban_check %}
<h2 style="color: #222; text-shadow: 0 0 7px #222; margin-top: 0;">Banned</h2>
{% else %}
{% if legacyprofile.warnings %}
<h2 style="color: red; text-shadow: 0 0 7px #888; margin-top: 0;">Bad</h2>
<span style="font-size: 10px; line-height: 10px;">This user has <b>{{ legacyprofile.warnings|length }} warning{% if legacyprofile.warnings|length != 1 %}s{% endif %}</b>.<br />After 5 to 10 warnings (depending on what they are for) this user may be permanently banned.</span>
{% else %}
<h2 style="color: green; text-shadow: 0 0 7px #888; margin-top: 0;">Good</h2>
{% endif %}
{% endif %}
</div>
</div>
<div class="content-left content-column markdown{% if profile.userPage|length < 1 %} hidden{% endif %}">
{{ profile.userPage|raw }}
</div>
<div class="clear"></div>
</div>
<div class="content-left content-column markdown{% if profile.userPage|length < 1 %} hidden{% endif %}">
{{ profile.userPage|raw }}
</div>
<div class="clear"></div>
</div>
{% if profile.user.userData.profileBackground %}
<script type="text/javascript">
initialiseParallax('userBackground');
</script>
{% endif %}
{% if profile.data.userData.profileBackground is defined %}
<script type="text/javascript">
initialiseParallax('userBackground');
</script>
{% endif %}
{% endif %}
{% include 'global/footer.tpl' %}

0
cache/.htaccess vendored Normal file → Executable file
View file

View file

@ -9,10 +9,6 @@ namespace Sakura;
// Include components
require_once str_replace(basename(__DIR__), '', dirname(__FILE__)) .'_sakura/sakura.php';
$meow = new User(2);
print_r($meow->user);
// Are we in forum mode?
$forumMode = isset($_GET['forums']) ? ($_GET['forums'] == true) : false;

View file

@ -12,42 +12,41 @@ require_once str_replace(basename(__DIR__), '', dirname(__FILE__)) .'_sakura/sak
// Get user data
if(isset($_GET['u'])) {
$renderData['profile'] = [
// Get the user's context
$profile = new User($_GET['u']);
$renderData['legacyprofile'] = [
'notset' => false,
'user' => ($_PROFILE_USER_DATA = Users::getUser(($_USER_USERNAME_ID = Users::userExists($_GET['u'], false)) ? $_USER_USERNAME_ID : $_GET['u'])),
'rank' => ($_PROFILE_RANK_DATA = Users::getRank($_PROFILE_USER_DATA['rank_main'])),
'colour' => ($_PROFILE_USER_DATA['name_colour'] == null ? $_PROFILE_RANK_DATA['colour'] : $_PROFILE_USER_DATA['name_colour']),
'ranktitle' => ($_PROFILE_USER_DATA['usertitle'] == null ? $_PROFILE_RANK_DATA['title'] : $_PROFILE_USER_DATA['usertitle']),
'country' => Main::getCountryName($_PROFILE_USER_DATA['country']),
'is_premium' => Users::checkUserPremium($_PROFILE_USER_DATA['id'])[0],
'is_online' => Users::checkUserOnline($_PROFILE_USER_DATA['id']),
'userPage' => null,
'fields' => Users::getUserProfileFields($_PROFILE_USER_DATA['userData'], true),
'warnings' => Users::getWarnings($_PROFILE_USER_DATA['id']),
'friend' => Users::checkFriend($_PROFILE_USER_DATA['id']),
'forum_stats' => Forum::getUserStats($_PROFILE_USER_DATA['id']),
'ban_check' => Bans::checkBan($_PROFILE_USER_DATA['id'])
'is_premium' => Users::checkUserPremium($profile->data['id'])[0],
'is_online' => Users::checkUserOnline($profile->data['id']),
'warnings' => Users::getWarnings($profile->data['id']),
'friend' => Users::checkFriend($profile->data['id']),
'forum_stats' => Forum::getUserStats($profile->data['id']),
'ban_check' => Bans::checkBan($profile->data['id'])
];
$renderData['profile'] = $profile;
$renderData['page'] = [
'title' => ($_PROFILE_USER_DATA['id'] < 1 || $_PROFILE_USER_DATA['password_algo'] == 'nologin' ? 'User not found!' : 'Profile of '. $_PROFILE_USER_DATA['username']),
'style' => (!empty($_PROFILE_USER_DATA['userData']['profileBackground']) ? [
'title' => ($profile->data['id'] < 1 || $profile->data['password_algo'] == 'nologin' ? 'User not found!' : 'Profile of '. $profile->data['username']),
'style' => (!empty($profile->data['userData']['profileBackground']) ? [
'#userBackground' => [
'background' => 'url("/bg/'. $_PROFILE_USER_DATA['id'] .'") no-repeat center center / cover transparent !important',
'position' => 'fixed',
'top' => '0',
'bottom' => '0',
'right' => '0',
'left' => '0',
'z-index' => '-1'
'background' => 'url("/bg/'. $profile->data['id'] .'") no-repeat center center / cover transparent !important',
'position' => 'fixed',
'top' => '0',
'bottom' => '0',
'right' => '0',
'left' => '0',
'z-index' => '-1'
]
] : null)
];
} else {
$renderData['profile']['notset'] = true;
$renderData['page']['title'] = 'User not found!';
$renderData['legacyprofile']['notset'] = true;
$renderData['page']['title'] = 'User not found!';
}

0
uploads/.htaccess Normal file → Executable file
View file