diff --git a/_sakura/changelog.json b/_sakura/changelog.json index 80b29bb..032d7de 100644 --- a/_sakura/changelog.json +++ b/_sakura/changelog.json @@ -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" + } + ] } diff --git a/_sakura/components/Configuration.php b/_sakura/components/Configuration.php index 2b3c175..534edca 100644 --- a/_sakura/components/Configuration.php +++ b/_sakura/components/Configuration.php @@ -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']; } diff --git a/_sakura/components/User.php b/_sakura/components/User.php index 96cdb8b..f9e27c2 100644 --- a/_sakura/components/User.php +++ b/_sakura/components/User.php @@ -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; } diff --git a/_sakura/components/database/mysql.php b/_sakura/components/database/mysql.php index c19d355..6a14b0a 100644 --- a/_sakura/components/database/mysql.php +++ b/_sakura/components/database/mysql.php @@ -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); } diff --git a/_sakura/sakura.php b/_sakura/sakura.php index 1a47efc..17ebe5d 100644 --- a/_sakura/sakura.php +++ b/_sakura/sakura.php @@ -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); diff --git a/_sakura/templates/yuuno/main/memberlist.tpl b/_sakura/templates/yuuno/main/memberlist.tpl index 8a35d3e..68110ee 100644 --- a/_sakura/templates/yuuno/main/memberlist.tpl +++ b/_sakura/templates/yuuno/main/memberlist.tpl @@ -48,7 +48,7 @@ - #{{ count + 1 }} + #{{ count }} {{ user.username }} diff --git a/_sakura/templates/yuuno/main/profile.tpl b/_sakura/templates/yuuno/main/profile.tpl index 2710f9f..cb6010b 100644 --- a/_sakura/templates/yuuno/main/profile.tpl +++ b/_sakura/templates/yuuno/main/profile.tpl @@ -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' %}

The requested user does not exist!

There are a few possible reasons for this: @@ -11,91 +11,93 @@
{% else %} -
-
-
-
- {{ profile.user.username }}'s Avatar
- {% if profile.user.rank_main > 1 and profile.ban_check|length < 1 %} - {{ profile.ranktitle }} -

{{ profile.user.username }}

- {% if profile.is_premium %}Tenshi {% endif %}{{ profile.user.country }} {{ profile.country }} - {% if user.checklogin %} - - {% endif %} -
- Joined {{ profile.user.regdate|date(sakura.date_format) }}
- {% if profile.user.lastdate == 0 %} - {{ profile.user.username }} hasn't logged in yet. - {% else %} - Last Seen on {{ profile.user.lastdate|date(sakura.date_format) }} - {% endif %}
- {{ 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 %}. - {% if profile.fields is not null %} -
- {% if user.checklogin %} - - {% for name,field in profile.fields %} - - - - - {% endfor %} -
- {{ field.name }} - - {% if name == 'youtube' %} - {% if field.youtubetype == 1 %}{{ profile.user.username }}'s Channel{% else %}{{ field.value }}{% endif %} - {% else %} - {% if field.islink %} - +
+
+
+
+ {{ profile.data.username }}'s Avatar
+ {% if profile.data.rank_main > 1 and legacyprofile.ban_check|length < 1 %}{# !!! #} + {{ profile.userTitle }} +

{{ profile.data.username }}

+ {% if profile.is_premium %}Tenshi {% endif %}{{ profile.country.short }} {{ profile.country.long }} + {% if user.checklogin %} +
+ {% endif %} +
+ Joined {{ profile.data.regdate|date(sakura.date_format) }} +
+ {% if profile.data.lastdate < 1 %} + {{ profile.data.username }} hasn't logged in yet. + {% else %} + Last Seen on {{ profile.data.lastdate|date(sakura.date_format) }} + {% endif %} +
+ {{ 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 %}. + {% if profile.profileFields %} +
+ {% if user.checklogin %} + + {% for name,field in profile.profileFields %} + + + + + {% endfor %} +
+ {{ field.name }} + + {% if name == 'youtube' %} + {% if field.youtubetype == 1 %}{{ profile.data.username }}'s Channel{% else %}{{ field.value }}{% endif %} + {% else %} + {% if field.islink %} + + {% endif %} + {{ field.value }} + {% if field.islink %} + + {% endif %} + {% endif %} +
+ {% else %} + Log in to view the full profile! {% endif %} {% endif %} -
- {% else %} - Log in to view the full profile! - {% endif %} - {% endif %} - {% else %} -

{{ profile.user.username }}

- {% endif %} -
- Account Standing - {% if profile.user.rank_main < 2 %} -

Deactivated

- {% elseif profile.ban_check %} -

Banned

- {% else %} - {% if profile.warnings %} -

Bad

- This user has {{ profile.warnings|length }} warning{% if profile.warnings|length != 1 %}s{% endif %}.
After 5 to 10 warnings (depending on what they are for) this user may be permanently banned.
{% else %} -

Good

+

{{ profile.data.username }}

{% endif %} - {% endif %} +
+ Account Standing + {% if profile.data.rank_main < 2 %} +

Deactivated

+ {% elseif legacyprofile.ban_check %} +

Banned

+ {% else %} + {% if legacyprofile.warnings %} +

Bad

+ This user has {{ legacyprofile.warnings|length }} warning{% if legacyprofile.warnings|length != 1 %}s{% endif %}.
After 5 to 10 warnings (depending on what they are for) this user may be permanently banned.
+ {% else %} +

Good

+ {% endif %} + {% endif %} +
+
+ {{ profile.userPage|raw }} +
+
-
- {{ profile.userPage|raw }} -
-
- - {% if profile.user.userData.profileBackground %} - - {% endif %} + {% if profile.data.userData.profileBackground is defined %} + + {% endif %} {% endif %} {% include 'global/footer.tpl' %} diff --git a/cache/.htaccess b/cache/.htaccess old mode 100644 new mode 100755 diff --git a/main/index.php b/main/index.php index f8eb64a..5f3712b 100644 --- a/main/index.php +++ b/main/index.php @@ -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; diff --git a/main/profile.php b/main/profile.php index 809f3cb..69abc87 100644 --- a/main/profile.php +++ b/main/profile.php @@ -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!'; } diff --git a/uploads/.htaccess b/uploads/.htaccess old mode 100644 new mode 100755