Huge Database refactor

Signed-off-by: Flashwave <me@flash.moe>
This commit is contained in:
flash 2015-10-10 23:17:50 +02:00
parent 7305267c35
commit 717b0cf27c
55 changed files with 824 additions and 678 deletions

20
.gitattributes vendored
View file

@ -1,22 +1,2 @@
# Auto detect text files and perform LF normalization
* text=auto
# Custom for Visual Studio
*.cs diff=csharp
*.sln merge=union
*.csproj merge=union
*.vbproj merge=union
*.fsproj merge=union
*.dbproj merge=union
# Standard to msysgit
*.doc diff=astextplain
*.DOC diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot diff=astextplain
*.DOT diff=astextplain
*.pdf diff=astextplain
*.PDF diff=astextplain
*.rtf diff=astextplain
*.RTF diff=astextplain

View file

@ -3064,6 +3064,36 @@
"type": "ADD",
"change": "Added permissions to commenting.",
"user": "Flashwave"
},
{
"type": "FIX",
"change": "Fixed comment reply ID collision.",
"user": "Flashwave"
},
{
"type": "ADD",
"change": "Added comment voting.",
"user": "Flashwave"
},
{
"type": "UPD",
"change": "Cleaned up and uniform'd column names.",
"user": "Flashwave"
},
{
"type": "FIX",
"change": "Fixed static urls in settings.",
"user": "Flashwave"
},
{
"type": "FIX",
"change": "Fixed settings index friend count not working.",
"user": "Flashwave"
},
{
"type": "ADD",
"change": "Added signature section to the settings page.",
"user": "Flashwave"
}
]

View file

@ -12,7 +12,7 @@ class Bans
{
// Attempt to get a ban from this user
$bans = Database::fetch('bans', true, ['uid' => [$uid, '=']]);
$bans = Database::fetch('bans', true, ['user_id' => [$uid, '=']]);
// Reverse the array so new bans are listed first
$bans = array_reverse($bans);
@ -22,15 +22,15 @@ class Bans
// Check if it hasn't expired
if ($ban['ban_end'] != 0 && $ban['ban_end'] < time()) {
// If it has delete the entry and continue
Database::delete('bans', ['id' => [$ban['uid'], '=']]);
Database::delete('bans', ['id' => [$ban['user_id'], '=']]);
continue;
}
// Return the ban if all checks were passed
return [
'user' => $ban['uid'],
'issuer' => $ban['mod_uid'],
'user' => $ban['user_id'],
'issuer' => $ban['ban_moderator'],
'issued' => $ban['ban_begin'],
'expires' => $ban['ban_end'],
'reason' => $ban['ban_reason'],

View file

@ -53,6 +53,20 @@ class Comments
$comment['comment_poster'] = $this->commenters[$comment['comment_poster']];
$comment['comment_text'] = Main::parseEmotes(Main::cleanString($comment['comment_text']));
// Get likes and dislikes
$votes = $this->getVotes($comment['comment_id']);
$comment['comment_likes'] = 0;
$comment['comment_dislikes'] = 0;
// Store amount in their respective variables
foreach ($votes as $vote) {
if ($vote['vote_state']) {
$comment['comment_likes'] += 1;
} else {
$comment['comment_dislikes'] += 1;
}
}
// Add post to posts array
$layer[$comment['comment_id']] = $comment;
@ -87,6 +101,17 @@ class Comments
}
// Getting comment votes
public function getVotes($cid)
{
// Get from database
return Database::fetch('comment_votes', true, [
'vote_comment' => [$cid, '='],
]);
}
// Creating
public function makeComment($uid, $reply, $content)
{
@ -115,6 +140,50 @@ class Comments
}
// Voting
public function makeVote($uid, $cid, $mode)
{
// Attempt to get previous vote
$vote = Database::fetch('comment_votes', false, [
'vote_user' => [$uid, '='],
'vote_comment' => [$cid, '='],
]);
// Check if anything was returned
if ($vote) {
// Check if the vote that's being casted is the same
if ($vote['vote_state'] == $mode) {
// Delete the vote
Database::delete('comment_votes', [
'vote_user' => [$uid, '='],
'vote_comment' => [$cid, '='],
]);
} else {
// Otherwise update the vote
Database::update('comment_votes', [
[
'vote_state' => $mode,
],
[
'vote_user' => [$uid, '='],
'vote_comment' => [$cid, '='],
],
]);
}
} else {
// Create a vote
Database::insert('comment_votes', [
'vote_user' => $uid,
'vote_comment' => $cid,
'vote_state' => $mode,
]);
}
return true;
}
// Deleting
public function removeComment($cid)
{

View file

@ -259,7 +259,7 @@ class Forum
'user' => (new User($post['poster_id'])),
'elapsed' => Main::timeElapsed($post['post_time']),
'is_op' => ($post['poster_id'] == $firstPost['poster_id'] ? '1' : '0'),
'parsed_post' => self::parseMarkUp($post['post_text'], $post['parse_mode'], $post['enable_emotes']),
'parsed_post' => self::parseMarkUp($post['post_text'], $post['post_parse'], $post['post_emotes']),
'signature' => empty($_POSTER['userData']['signature']) ?
'' :
self::parseMarkUp(

View file

@ -57,12 +57,12 @@ class Main
// Split the regex
$regex = array_map(function ($arr) {
return $arr['regex'];
return $arr['bbcode_regex'];
}, $bbcodes);
// Split the replacement
$replace = array_map(function ($arr) {
return $arr['replace'];
return $arr['bbcode_replace'];
}, $bbcodes);
// Do the replacement
@ -145,7 +145,7 @@ class Main
'error_log',
false,
[
'backtrace' => [$backtrace, '=', true],
'error_backtrace' => [$backtrace, '=', true],
'error_string' => [$errstr, '='],
'error_line' => [$errline, '='],
]
@ -159,14 +159,14 @@ class Main
// Log the error
Database::insert('error_log', [
'id' => $errid,
'timestamp' => date("r"),
'revision' => SAKURA_VERSION,
'error_id' => $errid,
'error_timestamp' => date("r"),
'error_revision' => SAKURA_VERSION,
'error_type' => $errno,
'error_line' => $errline,
'error_string' => $errstr,
'error_file' => $errfile,
'backtrace' => $backtrace,
'error_backtrace' => $backtrace,
]);
}
@ -382,7 +382,7 @@ class Main
{
// Get contents from the database
$infopage = Database::fetch('infopages', false, ['shorthand' => [$id, '=']]);
$infopage = Database::fetch('infopages', false, ['page_shorthand' => [$id, '=']]);
// Return the data if there is any else just return false
return count($infopage) ? $infopage : false;
@ -663,7 +663,7 @@ class Main
{
// Do database call
$faq = Database::fetch('faq', true, null, ['id']);
$faq = Database::fetch('faq', true, null, ['faq_id']);
// Return FAQ data
return $faq;
@ -783,7 +783,7 @@ class Main
$data = [];
// Get database stuff
$table = Database::fetch('premium_log', true, null, ['id', true]);
$table = Database::fetch('premium_log', true, null, ['transaction_id', true]);
// Add raw table data to data array
$data['table'] = $table;
@ -797,11 +797,11 @@ class Main
// Calculate the thing
foreach ($table as $row) {
// Calculate balance
$data['balance'] = $data['balance'] + $row['amount'];
$data['balance'] = $data['balance'] + $row['transaction_amount'];
// Add userdata to table
if (!array_key_exists($row['uid'], $data['users'])) {
$data['users'][$row['uid']] = new User($row['uid']);
if (!array_key_exists($row['user_id'], $data['users'])) {
$data['users'][$row['user_id']] = new User($row['user_id']);
}
}
@ -816,10 +816,10 @@ class Main
Database::insert('premium_log', [
'uid' => $id,
'amount' => $amount,
'date' => time(),
'comment' => $comment,
'user_id' => $id,
'transaction_amount' => $amount,
'transaction_date' => time(),
'transaction_comment' => $comment,
]);

View file

@ -15,27 +15,27 @@ class News
{
// Get the news posts and assign them to $posts
$posts = Database::fetch('news', true, ['category' => [$category, '=']], ['id', true]);
$posts = Database::fetch('news', true, ['news_category' => [$category, '=']], ['news_id', true]);
// Attach poster data
foreach ($posts as $post) {
// Check if we already have an object for this user
if (!array_key_exists($post['uid'], $this->posters)) {
if (!array_key_exists($post['user_id'], $this->posters)) {
// Create new object
$this->posters[$post['uid']] = new User($post['uid']);
$this->posters[$post['user_id']] = new User($post['user_id']);
}
// Parse the news post
$post['content_parsed'] = Main::mdParse($post['content']);
$post['news_content_parsed'] = Main::mdParse($post['news_content']);
// Attach the poster
$post['poster'] = $this->posters[$post['uid']];
$post['news_poster'] = $this->posters[$post['user_id']];
// Load comments
$post['comments'] = $this->comments = new Comments('news-' . $category . '-' . $post['id']);
$post['news_comments'] = $this->comments = new Comments('news-' . $category . '-' . $post['news_id']);
// Add post to posts array
$this->posts[$post['id']] = $post;
$this->posts[$post['news_id']] = $post;
}
}

View file

@ -10,12 +10,12 @@ class Permissions
// Fallback permission data
private static $fallback = [
'rid' => 0,
'uid' => 0,
'siteperms' => 1,
'manageperms' => 0,
'forumperms' => 0,
'rankinherit' => 111,
'rank_id' => 0,
'user_id' => 0,
'permissions_site' => 1,
'permissions_manage' => 0,
'permissions_forums' => 0,
'permissions_inherit' => 111,
];
@ -56,6 +56,7 @@ class Permissions
'CREATE_COMMENTS' => 268435456, // User can make comments
'DELETE_COMMENTS' => 536870912, // User can delete own comments
'VOTE_COMMENTS' => 1073741824, // User can vote on comments
'CHANGE_SIGNATURE' => 2147483648, // User can vote on comments
],
@ -111,7 +112,7 @@ class Permissions
// Get permission row for all ranks
foreach ($ranks as $rank) {
$getRanks[] = Database::fetch('permissions', false, ['rid' => [$rank, '='], 'uid' => [0, '=']]);
$getRanks[] = Database::fetch('permissions', false, ['rank_id' => [$rank, '='], 'user_id' => [0, '=']]);
}
// Check if getRanks is empty or if the rank id is 0 return the fallback
@ -126,18 +127,18 @@ class Permissions
// Store the data of the current rank in $perms
$perms = [
'SITE' => $rank['siteperms'],
'MANAGE' => $rank['manageperms'],
'FORUM' => $rank['forumperms'],
'SITE' => $rank['permissions_site'],
'MANAGE' => $rank['permissions_manage'],
'FORUM' => $rank['permissions_forums'],
];
} else {
// Perform a bitwise OR on the ranks
$perms = [
'SITE' => $perms['SITE'] | $rank['siteperms'],
'MANAGE' => $perms['MANAGE'] | $rank['manageperms'],
'FORUM' => $perms['FORUM'] | $rank['forumperms'],
'SITE' => $perms['SITE'] | $rank['permissions_site'],
'MANAGE' => $perms['MANAGE'] | $rank['permissions_manage'],
'FORUM' => $perms['FORUM'] | $rank['permissions_forums'],
];
}
@ -156,10 +157,10 @@ class Permissions
$user = new User($uid);
// Attempt to get the permission row of a user
$userPerms = Database::fetch('permissions', false, ['rid' => [0, '='], 'uid' => [$user->data['id'], '=']]);
$userPerms = Database::fetch('permissions', false, ['rank_id' => [0, '='], 'user_id' => [$user->data['user_id'], '=']]);
// Get their rank permissions
$rankPerms = self::getRankPermissions(json_decode($user->data['ranks'], true));
$rankPerms = self::getRankPermissions(json_decode($user->data['user_ranks'], true));
// Just return the rank permissions if no special ones are set
if (empty($userPerms)) {
@ -167,21 +168,21 @@ class Permissions
}
// Split the inherit option things up
$inheritance = str_split($userPerms['rankinherit']);
$inheritance = str_split($userPerms['permissions_inherit']);
// Override site permissions
if (!$inheritance[0]) {
$rankPerms['SITE'] = $userPerms['siteperms'];
$rankPerms['SITE'] = $userPerms['permissions_site'];
}
// Override management permissions
if (!$inheritance[1]) {
$rankPerms['MANAGE'] = $userPerms['manageperms'];
$rankPerms['MANAGE'] = $userPerms['permissions_manage'];
}
// Override forum permissions
if (!$inheritance[2]) {
$rankPerms['FORUM'] = $userPerms['forumperms'];
$rankPerms['FORUM'] = $userPerms['permissions_forums'];
}
// Return permissions

View file

@ -0,0 +1,11 @@
<?php
/*
* Rank Class
*/
namespace Sakura;
class Rank
{
}

View file

@ -43,13 +43,13 @@ class Session
// Insert the session into the database
Database::insert('sessions', [
'userip' => Main::getRemoteIP(),
'useragent' => Main::cleanString($_SERVER['HTTP_USER_AGENT']),
'userid' => $userId,
'skey' => $session,
'started' => time(),
'expire' => time() + 604800,
'remember' => $remember ? '1' : '0',
'user_id' => $userId,
'user_ip' => Main::getRemoteIP(),
'user_agent' => Main::cleanString($_SERVER['HTTP_USER_AGENT']),
'session_key' => $session,
'session_start' => time(),
'session_expire' => time() + 604800,
'session_remember' => $remember ? '1' : '0',
]);
// Return the session key
@ -62,7 +62,7 @@ class Session
{
// Get session from database
$session = Database::fetch('sessions', true, ['userid' => [$userId, '='], 'skey' => [$sessionId, '=']]);
$session = Database::fetch('sessions', true, ['user_id' => [$userId, '='], 'session_key' => [$sessionId, '=']]);
// Check if we actually got something in return
if (!count($session)) {
@ -72,9 +72,9 @@ class Session
$session = $session[0];
// Check if the session expired
if ($session['expire'] < time()) {
if ($session['session_expire'] < time()) {
// If it is delete the session...
self::deleteSession($session['id']);
self::deleteSession($session['session_id']);
// ...and return false
return false;
@ -83,7 +83,7 @@ class Session
// Origin checking
if ($ipCheck = Configuration::getConfig('session_check')) {
// Split both IPs up
$sessionIP = explode('.', $session['userip']);
$sessionIP = explode('.', $session['user_ip']);
$userIP = explode('.', Main::getRemoteIP());
// Take 1 off the ipCheck variable so it's equal to the array keys
@ -124,12 +124,12 @@ class Session
}
// If the remember flag is set extend the session time
if ($session['remember']) {
Database::update('sessions', [['expire' => time() + 604800], ['id' => [$session['id'], '=']]]);
if ($session['session_remember']) {
Database::update('sessions', [['session_expire' => time() + 604800], ['session_id' => [$session['session_id'], '=']]]);
}
// Return 2 if the remember flag is set and return 1 if not
return $session['remember'] ? 2 : 1;
return $session['session_remember'] ? 2 : 1;
}
@ -138,12 +138,12 @@ class Session
{
// Check if the session exists
if (!Database::fetch('sessions', [($key ? 'skey' : 'id'), true, [$sessionId, '=']])) {
if (!Database::fetch('sessions', [($key ? 'session_key' : 'session_id'), true, [$sessionId, '=']])) {
return false;
}
// Run the query
Database::delete('sessions', [($key ? 'skey' : 'id') => [$sessionId, '=']]);
Database::delete('sessions', [($key ? 'session_key' : 'session_id') => [$sessionId, '=']]);
// Return true if key was found and deleted
return true;

View file

@ -205,6 +205,10 @@ class Urls
'/settings.php?cat=%s&mode=%s',
'/settings/%s/%s',
],
'SETTING_PAGE' => [
'/settings.php?cat=%s&mode=%s&page=%u',
'/settings/%s/%s/p%u',
],
// Friend Actions
'FRIEND_ACTION' => [
@ -239,13 +243,9 @@ class Urls
'/settings.php?comment-action=true',
'/comments',
],
'COMMENT_LIKE' => [
'/settings.php?comment-action=true&id=%u&mode=like&session=%s',
'/comments?id=%u&mode=like&session=%s',
],
'COMMENT_DISLIKE' => [
'/settings.php?comment-action=true&id=%u&mode=dislike&session=%s',
'/comments?id=%u&mode=dislike&session=%s',
'COMMENT_VOTE' => [
'/settings.php?comment-action=true&id=%u&mode=vote&state=%u&category=%s&session=%s',
'/comments?id=%u&mode=vote&state=%u&category=%s&session=%s',
],
'COMMENT_DELETE' => [
'/settings.php?comment-action=true&id=%u&category=%s&mode=delete&session=%s',

View file

@ -21,7 +21,7 @@ class User
'users',
false,
[
'id' => [$uid, '=', true],
'user_id' => [$uid, '=', true],
'username_clean' => [Main::cleanString($uid, true), '=', true],
]
);
@ -43,16 +43,16 @@ class 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 json in the user_data column
$this->data['user_data'] = json_decode(!empty($this->data['user_data']) ? $this->data['user_data'] : '[]', true);
// Decode the ranks json array
$ranks = json_decode($this->data['ranks'], true);
$ranks = json_decode($this->data['user_ranks'], true);
// Get the rows for all the ranks
foreach ($ranks as $rank) {
// Store the database row in the array
$this->ranks[$rank] = Database::fetch('ranks', false, ['id' => [$rank, '=']]);
$this->ranks[$rank] = Database::fetch('ranks', false, ['rank_id' => [$rank, '=']]);
}
// Check if ranks were set
@ -75,7 +75,7 @@ class User
{
// Check if the main rank is the specified rank
if (in_array($this->mainRank['id'], $ranks)) {
if (in_array($this->mainRank['rank_id'], $ranks)) {
return true;
}
@ -96,7 +96,7 @@ class User
public function colour()
{
return empty($this->data['name_colour']) ? $this->mainRank['colour'] : $this->data['name_colour'];
return empty($this->data['user_colour']) ? $this->mainRank['rank_colour'] : $this->data['user_colour'];
}
@ -104,7 +104,7 @@ class User
public function userTitle()
{
return empty($this->data['usertitle']) ? $this->mainRank['title'] : $this->data['usertitle'];
return empty($this->data['user_title']) ? $this->mainRank['rank_title'] : $this->data['user_title'];
}
@ -114,8 +114,8 @@ class User
return [
'long' => Main::getCountryName($this->data['country']),
'short' => $this->data['country'],
'long' => Main::getCountryName($this->data['user_country']),
'short' => $this->data['user_country'],
];
@ -125,7 +125,7 @@ class User
public function checkOnline()
{
return $this->data['lastdate'] > (time() - Configuration::getConfig('max_online_time'));
return $this->data['user_last_online'] > (time() - Configuration::getConfig('max_online_time'));
}
@ -133,7 +133,7 @@ class User
public function forumStats()
{
return Forum::getUserStats($this->data['id']);
return Forum::getUserStats($this->data['user_id']);
}
@ -141,7 +141,7 @@ class User
public function checkFriends($with)
{
return Users::checkFriend($this->data['id'], $with);
return Users::checkFriend($this->data['user_id'], $with);
}
@ -149,7 +149,7 @@ class User
public function getFriends($timestamps = false, $getData = false, $checkOnline = false)
{
return Users::getFriends($this->data['id'], $timestamps, $getData, $checkOnline);
return Users::getFriends($this->data['user_id'], $timestamps, $getData, $checkOnline);
}
@ -157,7 +157,7 @@ class User
public function checkBan()
{
return Bans::checkBan($this->data['id']);
return Bans::checkBan($this->data['user_id']);
}
@ -165,7 +165,7 @@ class User
public function checkPermission($layer, $action)
{
return Permissions::check($layer, $action, $this->data['id'], 1);
return Permissions::check($layer, $action, $this->data['user_id'], 1);
}
@ -173,7 +173,7 @@ class User
public function profileComments()
{
return new Comments('profile-' . $this->data['id']);
return new Comments('profile-' . $this->data['user_id']);
}
@ -183,9 +183,9 @@ class User
return [
'joined' => Main::timeElapsed($this->data['regdate'], $append, $none),
'lastOnline' => Main::timeElapsed($this->data['lastdate'], $append, $none),
'birth' => Main::timeElapsed(strtotime($this->data['birthday']), $append, $none),
'joined' => Main::timeElapsed($this->data['user_registered'], $append, $none),
'lastOnline' => Main::timeElapsed($this->data['user_last_online'], $append, $none),
'birth' => Main::timeElapsed(strtotime($this->data['user_birthday']), $append, $none),
];
@ -204,7 +204,7 @@ class User
}
// Once again if nothing was returned just return null
if (empty($this->data['userData']['profileFields'])) {
if (empty($this->data['user_data']['profileFields'])) {
return;
}
@ -214,42 +214,42 @@ class User
// 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);
$fieldName = Main::cleanString($field['field_name'], true, true);
// Check if the user has the current field set otherwise continue
if (!array_key_exists($fieldName, $this->data['userData']['profileFields'])) {
if (!array_key_exists($fieldName, $this->data['user_data']['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'];
$profile[$fieldName]['name'] = $field['field_name'];
$profile[$fieldName]['value'] = $this->data['user_data']['profileFields'][$fieldName];
$profile[$fieldName]['islink'] = $field['field_link'];
// If the field is set to be a link add a value for that as well
if ($field['islink']) {
if ($field['field_link']) {
$profile[$fieldName]['link'] = str_replace(
'{{ VAL }}',
$this->data['userData']['profileFields'][$fieldName],
$field['linkformat']
$this->data['user_data']['profileFields'][$fieldName],
$field['field_linkformat']
);
}
// Check if we have additional options as well
if ($field['additional'] != null) {
if ($field['field_additional'] != null) {
// Decode the json of the additional stuff
$additional = json_decode($field['additional'], true);
$additional = json_decode($field['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'])) {
if (!array_key_exists($subName, $this->data['user_data']['profileFields'])) {
continue;
}
// Assign field to output with value
$profile[$fieldName][$subName] = $this->data['userData']['profileFields'][$subName];
$profile[$fieldName][$subName] = $this->data['user_data']['profileFields'][$subName];
}
}
}
@ -272,7 +272,7 @@ class User
}
// Once again if nothing was returned just return null
if (empty($this->data['userData']['userOptions'])) {
if (empty($this->data['user_data']['userOptions'])) {
return;
}
@ -282,17 +282,17 @@ class User
// Check if profile fields aren't fake
foreach ($optionFields as $field) {
// Check if the user has the current field set otherwise continue
if (!array_key_exists($field['id'], $this->data['userData']['userOptions'])) {
if (!array_key_exists($field['option_id'], $this->data['user_data']['userOptions'])) {
continue;
}
// Make sure the user has the proper permissions to use this option
if (!$this->checkPermission('SITE', $field['require_perm'])) {
if (!$this->checkPermission('SITE', $field['option_permission'])) {
continue;
}
// Assign field to output with value
$options[$field['id']] = $this->data['userData']['userOptions'][$field['id']];
$options[$field['option_id']] = $this->data['user_data']['userOptions'][$field['option_id']];
}
// Return appropiate profile data
@ -305,13 +305,13 @@ class User
{
// Check if the user has static premium
if (Permissions::check('SITE', 'STATIC_PREMIUM', $this->data['id'], 1)) {
if (Permissions::check('SITE', 'STATIC_PREMIUM', $this->data['user_id'], 1)) {
return [2, 0, time() + 1];
}
// Attempt to retrieve the premium record from the database
$getRecord = Database::fetch('premium', false, [
'uid' => [$this->data['id'], '='],
'user_id' => [$this->data['user_id'], '='],
]);
// If nothing was returned just return false
@ -320,14 +320,14 @@ class User
}
// Check if the Tenshi hasn't expired
if ($getRecord['expiredate'] < time()) {
Users::removeUserPremium($this->data['id']);
Users::updatePremiumMeta($this->data['id']);
return [0, $getRecord['startdate'], $getRecord['expiredate']];
if ($getRecord['premium_expire'] < time()) {
Users::removeUserPremium($this->data['user_id']);
Users::updatePremiumMeta($this->data['user_id']);
return [0, $getRecord['premium_start'], $getRecord['premium_expire']];
}
// Else return the start and expiration date
return [1, $getRecord['startdate'], $getRecord['expiredate']];
return [1, $getRecord['premium_start'], $getRecord['premium_expire']];
}
@ -337,7 +337,7 @@ class User
// Do the database query
$warnings = Database::fetch('warnings', true, [
'uid' => [$this->data['id'], '='],
'user_id' => [$this->data['user_id'], '='],
]);
// Return all the warnings
@ -349,10 +349,10 @@ class User
public function userPage()
{
return isset($this->data['userData']['userPage']) ?
return isset($this->data['user_data']['userPage']) ?
Main::mdParse(
base64_decode(
$this->data['userData']['userPage']
$this->data['user_data']['userPage']
),
true
) :
@ -366,7 +366,7 @@ class User
// Do the database query
$changes = Database::fetch('username_history', true, [
'user_id' => [$this->data['id'], '='],
'user_id' => [$this->data['user_id'], '='],
], ['change_id', true]);
// Return all the warnings
@ -415,7 +415,7 @@ class User
// Insert into username_history table
Database::insert('username_history', [
'change_time' => time(),
'user_id' => $this->data['id'],
'user_id' => $this->data['user_id'],
'username_new' => $username,
'username_new_clean' => $username_clean,
'username_old' => $this->data['username'],
@ -429,7 +429,7 @@ class User
'username_clean' => $username_clean,
],
[
'id' => [$this->data['id'], '='],
'id' => [$this->data['user_id'], '='],
],
]);
@ -463,7 +463,7 @@ class User
'email' => $email,
],
[
'id' => [$this->data['id'], '='],
'id' => [$this->data['user_id'], '='],
],
]);
@ -517,7 +517,7 @@ class User
'password_chan' => time(),
],
[
'id' => [$this->data['id'], '='],
'id' => [$this->data['user_id'], '='],
],
]);

View file

@ -32,16 +32,18 @@ class Users
'birthday' => '',
'posts' => 0,
'country' => 'XX',
'userData' => '[]',
'user_data' => '[]',
];
// Empty rank template
public static $emptyRank = [
'id' => 0,
'rankname' => 'Sakura Rank',
'multi' => 0,
'colour' => '#444',
'description' => 'A hardcoded dummy rank for fallback.',
'rank_id' => 0,
'rank_name' => 'Sakura Rank',
'rank_multiple' => null,
'rank_hidden' => 1,
'rank_colour' => '#444',
'rank_description' => 'A hardcoded dummy rank for fallback.',
'rank_title' => '',
];
// Check if a user is logged in
@ -115,10 +117,10 @@ class Users
// Update last online
Database::update('users', [
[
'lastdate' => time(),
'user_last_online' => time(),
],
[
'id' => [$uid, '='],
'user_id' => [$uid, '='],
],
]);
@ -324,17 +326,17 @@ class Users
'password_iter' => $password[1],
'email' => $emailClean,
'rank_main' => $userRank[0],
'ranks' => $userRankJson,
'user_ranks' => $userRankJson,
'register_ip' => Main::getRemoteIP(),
'last_ip' => Main::getRemoteIP(),
'regdate' => time(),
'lastdate' => 0,
'country' => Main::getCountryCode(),
'userData' => '[]',
'user_registered' => time(),
'user_last_online' => 0,
'user_country' => Main::getCountryCode(),
'user_data' => '[]',
]);
// Get userid of the new user
$uid = Database::fetch('users', false, ['username_clean' => [$usernameClean, '=']])['id'];
$uid = Database::fetch('users', false, ['username_clean' => [$usernameClean, '=']])['user_id'];
// Check if we require e-mail activation
if ($requireActive) {
@ -378,12 +380,12 @@ class Users
}
// Check if the user has the required privs to log in
if (Permissions::check('SITE', 'DEACTIVATED', $user['id'], 1)) {
if (Permissions::check('SITE', 'DEACTIVATED', $user['user_id'], 1)) {
return [0, 'NOT_ALLOWED'];
}
// Generate the verification key
$verk = Main::newActionCode('LOST_PASS', $user['id'], [
$verk = Main::newActionCode('LOST_PASS', $user['user_id'], [
'meta' => [
'password_change' => 1,
],
@ -396,9 +398,9 @@ class Users
$message = "Hello " . $user['username'] . ",\r\n\r\n";
$message .= "You are receiving this notification because you have (or someone pretending to be you has) requested a password reset link to be sent for your account on \"" . Configuration::getConfig('sitename') . "\". If you did not request this notification then please ignore it, if you keep receiving it please contact the site administrator.\r\n\r\n";
$message .= "To use this password reset key you need to go to a special page. To do this click the link provided below.\r\n\r\n";
$message .= "http://" . Configuration::getConfig('url_main') . $urls->format('SITE_FORGOT_PASSWORD') . "?pw=true&uid=" . $user['id'] . "&key=" . $verk . "\r\n\r\n";
$message .= "http://" . Configuration::getConfig('url_main') . $urls->format('SITE_FORGOT_PASSWORD') . "?pw=true&uid=" . $user['user_id'] . "&key=" . $verk . "\r\n\r\n";
$message .= "If successful you should be able to change your password here.\r\n\r\n";
$message .= "Alternatively if the above method fails for some reason you can go to http://" . Configuration::getConfig('url_main') . $urls->format('SITE_FORGOT_PASSWORD') . "?pw=true&uid=" . $user['id'] . " and use the key listed below:\r\n\r\n";
$message .= "Alternatively if the above method fails for some reason you can go to http://" . Configuration::getConfig('url_main') . $urls->format('SITE_FORGOT_PASSWORD') . "?pw=true&uid=" . $user['user_id'] . " and use the key listed below:\r\n\r\n";
$message .= "Verification key: " . $verk . "\r\n\r\n";
$message .= "You can of course change this password yourself via the profile page. If you have any difficulties please contact the site administrator.\r\n\r\n";
$message .= "--\r\n\r\nThanks\r\n\r\n" . Configuration::getConfig('mail_signature');
@ -452,7 +454,7 @@ class Users
'password_chan' => $time,
],
[
'id' => [$uid, '='],
'user_id' => [$uid, '='],
],
]);
@ -486,12 +488,12 @@ class Users
}
// Check if a user is activated
if (!Permissions::check('SITE', 'DEACTIVATED', $user['id'], 1)) {
if (!Permissions::check('SITE', 'DEACTIVATED', $user['user_id'], 1)) {
return [0, 'USER_ALREADY_ACTIVE'];
}
// Send activation e-mail
self::sendActivationMail($user['id']);
self::sendActivationMail($user['user_id']);
// Return success
return [1, 'SUCCESS'];
@ -503,10 +505,10 @@ class Users
{
// Get the user data
$user = Database::fetch('users', false, ['id' => [$uid, '=']]);
$user = Database::fetch('users', false, ['user_id' => [$uid, '=']]);
// User is already activated or doesn't even exist
if (count($user) < 2 || !Permissions::check('SITE', 'DEACTIVATED', $user['id'], 1)) {
if (count($user) < 2 || !Permissions::check('SITE', 'DEACTIVATED', $user['user_id'], 1)) {
return false;
}
@ -514,7 +516,7 @@ class Users
$activate = ($customKey ? $customKey : Main::newActionCode('ACTIVATE', $uid, [
'user' => [
'rank_main' => 2,
'ranks' => json_encode([2]),
'user_ranks' => json_encode([2]),
],
]));
@ -526,10 +528,10 @@ class Users
$message .= "Please keep this e-mail for your records. Your account intormation is as follows:\r\n\r\n";
$message .= "----------------------------\r\n\r\n";
$message .= "Username: " . $user['username'] . "\r\n\r\n";
$message .= "Your profile: http://" . Configuration::getConfig('url_main') . $urls->format('USER_PROFILE', [$user['id']]) . "\r\n\r\n";
$message .= "Your profile: http://" . Configuration::getConfig('url_main') . $urls->format('USER_PROFILE', [$user['user_id']]) . "\r\n\r\n";
$message .= "----------------------------\r\n\r\n";
$message .= "Please visit the following link in order to activate your account:\r\n\r\n";
$message .= "http://" . Configuration::getConfig('url_main') . $urls->format('SITE_ACTIVATE') . "?mode=activate&u=" . $user['id'] . "&k=" . $activate . "\r\n\r\n";
$message .= "http://" . Configuration::getConfig('url_main') . $urls->format('SITE_ACTIVATE') . "?mode=activate&u=" . $user['user_id'] . "&k=" . $activate . "\r\n\r\n";
$message .= "Your password has been securely stored in our database and cannot be retrieved. ";
$message .= "In the event that it is forgotten, you will be able to reset it using the email address associated with your account.\r\n\r\n";
$message .= "Thank you for registering.\r\n\r\n";
@ -554,7 +556,7 @@ class Users
{
// Get the user data
$user = Database::fetch('users', false, ['id' => [$uid, '=']]);
$user = Database::fetch('users', false, ['user_id' => [$uid, '=']]);
// Check if user exists
if (!count($user) > 1) {
@ -562,7 +564,7 @@ class Users
}
// Check if user is already activated
if (!Permissions::check('SITE', 'DEACTIVATED', $user['id'], 1)) {
if (!Permissions::check('SITE', 'DEACTIVATED', $user['user_id'], 1)) {
return [0, 'USER_ALREADY_ACTIVE'];
}
@ -584,17 +586,17 @@ class Users
// Assign the special values
$instructionData = json_decode($action[2], true);
$rank = $instructionData['user']['rank_main'];
$ranks = $instructionData['user']['ranks'];
$ranks = $instructionData['user']['user_ranks'];
}
// Activate the account
Database::update('users', [
[
'rank_main' => $rank,
'ranks' => $ranks,
'user_ranks' => $ranks,
],
[
'id' => [$uid, '='],
'user_id' => [$uid, '='],
],
]);
@ -608,7 +610,7 @@ class Users
{
// Get the user data
$user = Database::fetch('users', false, ['id' => [$uid, '=']]);
$user = Database::fetch('users', false, ['user_id' => [$uid, '=']]);
// Check if user exists
if (!count($user) > 1) {
@ -616,7 +618,7 @@ class Users
}
// Check if user is already deactivated
if (Permissions::check('SITE', 'DEACTIVATED', $user['id'], 1)) {
if (Permissions::check('SITE', 'DEACTIVATED', $user['user_id'], 1)) {
return [0, 'USER_ALREADY_DEACTIVE'];
}
@ -624,10 +626,10 @@ class Users
Database::update('users', [
[
'rank_main' => 2,
'ranks' => json_encode([2]),
'user_ranks' => json_encode([2]),
],
[
'id' => [$uid, '='],
'user_id' => [$uid, '='],
],
]);
@ -715,7 +717,7 @@ class Users
$user = $userIdIsUserData ? $uid : self::getUser($uid);
// Decode the json
$ranks = json_decode($user['ranks'], true);
$ranks = json_decode($user['user_ranks'], true);
// Check if the rank we're trying to set is actually there
if (!in_array($rid, $ranks)) {
@ -728,7 +730,7 @@ class Users
'rank_main' => $rid,
],
[
'id' => [$uid, '='],
'user_id' => [$uid, '='],
],
]);
@ -745,7 +747,7 @@ class Users
$user = $userIdIsUserData ? $uid : self::getUser($uid);
// Decode the array
$current = json_decode($user['ranks'], true);
$current = json_decode($user['user_ranks'], true);
// Go over all the new ranks
foreach ($ranks as $rank) {
@ -761,10 +763,10 @@ class Users
// Update the row
Database::update('users', [
[
'ranks' => $current,
'user_ranks' => $current,
],
[
'id' => [$uid, '='],
'user_id' => [$uid, '='],
],
]);
@ -781,7 +783,7 @@ class Users
$user = $userIdIsUserData ? $uid : self::getUser($uid);
// Get the ranks
$current = json_decode($user['ranks'], true);
$current = json_decode($user['user_ranks'], true);
// Check the current ranks for ranks in the set array
foreach ($current as $key => $rank) {
@ -797,10 +799,10 @@ class Users
// Update the row
Database::update('users', [
[
'ranks' => $current,
'user_ranks' => $current,
],
[
'id' => [$uid, '='],
'user_id' => [$uid, '='],
],
]);
@ -822,7 +824,7 @@ class Users
}
// Decode the json for the user's ranks
$uRanks = json_decode($user['ranks'], true);
$uRanks = json_decode($user['user_ranks'], true);
// If not go over all ranks and check if the user has them
foreach ($ranks as $rank) {
@ -845,10 +847,10 @@ class Users
$user = Main::cleanString($user, true);
// Do database request
$user = Database::fetch('users', true, [($id ? 'id' : 'username_clean') => [$user, '=']]);
$user = Database::fetch('users', true, [($id ? 'user_id' : 'username_clean') => [$user, '=']]);
// Return count (which would return 0, aka false, if nothing was found)
return count($user) ? $user[0]['id'] : false;
return count($user) ? $user[0]['user_id'] : false;
}
@ -869,9 +871,9 @@ class Users
// Iterate over the fields and clean them up
foreach ($profileFields as $field) {
$fields[$field['id']] = $field;
$fields[$field['id']]['ident'] = Main::cleanString($field['name'], true, true);
$fields[$field['id']]['addit'] = json_decode($field['additional'], true);
$fields[$field['field_id']] = $field;
$fields[$field['field_id']]['field_identity'] = Main::cleanString($field['field_name'], true, true);
$fields[$field['field_id']]['field_additional'] = json_decode($field['field_additional'], true);
}
// Return the yeahs
@ -896,11 +898,11 @@ class Users
// Iterate over the fields and clean them up
foreach ($optionFields as $field) {
if (!Permissions::check('SITE', $field['require_perm'], Session::$userId, 1)) {
if (!Permissions::check('SITE', $field['option_permission'], Session::$userId, 1)) {
continue;
}
$fields[$field['id']] = $field;
$fields[$field['option_id']] = $field;
}
// Return the yeahs
@ -921,7 +923,7 @@ class Users
}
// Assign the profileData variable
$profileData = ($inputIsData ? $id : self::getUser($id)['userData']);
$profileData = ($inputIsData ? $id : self::getUser($id)['user_data']);
// Once again if nothing was returned just return null
if (count($profileData) < 1 || $profileData == null || empty($profileData['profileFields'])) {
@ -983,7 +985,7 @@ class Users
{
// We retrieve the current content from the database
$current = self::getUser($id)['userData'];
$current = self::getUser($id)['user_data'];
// Merge the arrays
$data = array_merge($current, $data);
@ -994,10 +996,10 @@ class Users
// Store it in the database
Database::update('users', [
[
'userData' => $data,
'user_data' => $data,
],
[
'id' => [$id, '='],
'user_id' => [$id, '='],
],
]);
@ -1016,7 +1018,7 @@ class Users
}
// Return true if the user was online in the last 5 minutes
return ($user['lastdate'] > (time() - 500));
return ($user['user_last_online'] > (time() - 500));
}
@ -1028,7 +1030,7 @@ class Users
$time = time() - 500;
// Get all online users in the past 5 minutes
$getAll = Database::fetch('users', true, ['lastdate' => [$time, '>']]);
$getAll = Database::fetch('users', true, ['user_last_online' => [$time, '>']]);
// Return all the online users
return $getAll;
@ -1041,27 +1043,27 @@ class Users
// Check if there's already a record of premium for this user in the database
$getUser = Database::fetch('premium', false, [
'uid' => [$id, '='],
'user_id' => [$id, '='],
]);
// Calculate the (new) start and expiration timestamp
$start = isset($getUser['startdate']) ? $getUser['startdate'] : time();
$expire = isset($getUser['expiredate']) ? $getUser['expiredate'] + $seconds : time() + $seconds;
$start = isset($getUser['premium_start']) ? $getUser['premium_start'] : time();
$expire = isset($getUser['premium_expire']) ? $getUser['premium_expire'] + $seconds : time() + $seconds;
// If the user already exists do an update call, otherwise an insert call
if (empty($getUser)) {
Database::insert('premium', [
'uid' => $id,
'startdate' => $start,
'expiredate' => $expire,
'user_id' => $id,
'premium_start' => $start,
'premium_expire' => $expire,
]);
} else {
Database::update('premium', [
[
'expiredate' => $expire,
'premium_expire' => $expire,
],
[
'uid' => [$id, '='],
'user_id' => [$id, '='],
],
]);
}
@ -1076,7 +1078,7 @@ class Users
{
Database::delete('premium', [
'uid' => [$id, '='],
'user_id' => [$id, '='],
]);
}
@ -1092,7 +1094,7 @@ class Users
// Attempt to retrieve the premium record from the database
$getRecord = Database::fetch('premium', false, [
'uid' => [$id, '='],
'user_id' => [$id, '='],
]);
// If nothing was returned just return false
@ -1101,14 +1103,14 @@ class Users
}
// Check if the Tenshi hasn't expired
if ($getRecord['expiredate'] < time()) {
if ($getRecord['premium_expire'] < time()) {
self::removeUserPremium($id);
self::updatePremiumMeta($id);
return [0, $getRecord['startdate'], $getRecord['expiredate']];
return [0, $getRecord['premium_start'], $getRecord['premium_expire']];
}
// Else return the start and expiration date
return [1, $getRecord['startdate'], $getRecord['expiredate']];
return [1, $getRecord['premium_start'], $getRecord['premium_expire']];
}
@ -1152,7 +1154,7 @@ class Users
{
// Execute query
$rank = Database::fetch('ranks', false, ['id' => [$id, '=']]);
$rank = Database::fetch('ranks', false, ['rank_id' => [$id, '=']]);
// Return false if no rank was found
if (empty($rank)) {
@ -1226,11 +1228,11 @@ class Users
}
// Skip if inactive and not include deactivated users
if (!$includeInactive && Permissions::check('SITE', 'DEACTIVATED', $user['id'], 1)) {
if (!$includeInactive && Permissions::check('SITE', 'DEACTIVATED', $user['user_id'], 1)) {
continue;
}
$users[$user['id']] = $user;
$users[$user['user_id']] = $user;
}
// and return an array with the users
@ -1250,7 +1252,7 @@ class Users
// Reorder shit
foreach ($getRanks as $rank) {
$ranks[$rank['id']] = $rank;
$ranks[$rank['rank_id']] = $rank;
}
// and return an array with the ranks
@ -1264,7 +1266,7 @@ class Users
// Do the database query
$warnings = Database::fetch('warnings', true, ($uid ? [
($iid ? 'iid' : 'uid') => [$uid, '='],
($iid ? 'moderator_id' : 'user_id') => [$uid, '='],
] : null));
// Return all the warnings
@ -1278,14 +1280,14 @@ class Users
// Prepare conditions
$conditions = array();
$conditions['uid'] = [($uid ? $uid : Session::$userId), '='];
$conditions['user_id'] = [($uid ? $uid : Session::$userId), '='];
if ($timediff) {
$conditions['timestamp'] = [time() - $timediff, '>'];
$conditions['alert_timestamp'] = [time() - $timediff, '>'];
}
if ($excludeRead) {
$conditions['notif_read'] = [0, '='];
$conditions['alert_read'] = [0, '='];
}
// Get notifications for the database
@ -1296,12 +1298,12 @@ class Users
// Iterate over all entries
foreach ($notifications as $notification) {
// If the notifcation is already read skip
if ($notification['notif_read']) {
if ($notification['alert_read']) {
continue;
}
// Mark them as read
self::markNotificationRead($notification['id']);
self::markNotificationRead($notification['user_id']);
}
}
@ -1317,10 +1319,10 @@ class Users
// Execute an update statement
Database::update('notifications', [
[
'notif_read' => ($mode ? 1 : 0),
'alert_read' => ($mode ? 1 : 0),
],
[
'id' => [$id, '='],
'alert_id' => [$id, '='],
],
]);
@ -1335,15 +1337,15 @@ class Users
// Insert it into the database
Database::insert('notifications', [
'uid' => $user,
'timestamp' => $time,
'notif_read' => 0,
'notif_sound' => ($sound ? 1 : 0),
'notif_title' => $title,
'notif_text' => $text,
'notif_link' => $link,
'notif_img' => $img,
'notif_timeout' => $timeout,
'user_id' => $user,
'alert_timestamp' => $time,
'alert_read' => 0,
'alert_sound' => ($sound ? 1 : 0),
'alert_title' => $title,
'alert_text' => $text,
'alert_link' => $link,
'alert_img' => $img,
'alert_timeout' => $timeout,
]);
}
@ -1388,7 +1390,7 @@ class Users
// Get all friends
$getFriends = Database::fetch('friends', true, [
'uid' => [$uid, '='],
'user_id' => [$uid, '='],
]);
// Create the friends array
@ -1397,12 +1399,12 @@ class Users
// Iterate over the raw database return
foreach ($getFriends as $key => $friend) {
// Add friend to array
$friends[($timestamps ? $friend['fid'] : $key)] = $getData ? ([
$friends[($timestamps ? $friend['friend_id'] : $key)] = $getData ? ([
'user' => ($_UDATA = self::getUser($friend['fid'])),
'user' => ($_UDATA = self::getUser($friend['friend_id'])),
'rank' => self::getRank($_UDATA['rank_main']),
]) : $friend[($timestamps ? 'timestamp' : 'fid')];
]) : $friend[($timestamps ? 'friend_timestamp' : 'friend_id')];
}
// Check who is online and who isn't
@ -1410,7 +1412,7 @@ class Users
// Check each user
foreach ($friends as $key => $friend) {
$friends[
self::checkUserOnline($getData ? $friend['user']['id'] : $friend) ? 'online' : 'offline'
self::checkUserOnline($getData ? $friend['user']['user_id'] : $friend) ? 'online' : 'offline'
][] = $friend;
}
}
@ -1431,7 +1433,7 @@ class Users
// Get all friend entries from other people involved the current user
$friends = Database::fetch('friends', true, [
'fid' => [$uid, '='],
'friend_id' => [$uid, '='],
]);
// Create pending array
@ -1440,10 +1442,10 @@ class Users
// Check if the friends are mutual
foreach ($friends as $friend) {
// Check if the friend is mutual
if (!self::checkFriend($friend['uid'], $uid)) {
if (!self::checkFriend($friend['user_id'], $uid)) {
$pending[] = $getData ? ([
'user' => ($_UDATA = self::getUser($friend['uid'])),
'user' => ($_UDATA = self::getUser($friend['user_id'])),
'rank' => self::getRank($_UDATA['rank_main']),
]) : $friend;
@ -1495,15 +1497,15 @@ class Users
}
// Check if the user already has this user a friend
if (Database::fetch('friends', false, ['fid' => [$uid, '='], 'uid' => [Session::$userId, '=']])) {
if (Database::fetch('friends', false, ['friend_id' => [$uid, '='], 'user_id' => [Session::$userId, '=']])) {
return [0, 'ALREADY_FRIENDS'];
}
// Add friend
Database::insert('friends', [
'uid' => Session::$userId,
'fid' => $uid,
'timestamp' => time(),
'user_id' => Session::$userId,
'friend_id' => $uid,
'friend_timestamp' => time(),
]);
// Return true because yay
@ -1516,21 +1518,21 @@ class Users
{
// Check if the user has this user a friend
if (!Database::fetch('friends', false, ['fid' => [$uid, '='], 'uid' => [Session::$userId, '=']])) {
if (!Database::fetch('friends', false, ['friend_id' => [$uid, '='], 'user_id' => [Session::$userId, '=']])) {
return [0, 'ALREADY_REMOVED'];
}
// Remove friend
Database::delete('friends', [
'uid' => [Session::$userId, '='],
'fid' => [$uid, '='],
'user_id' => [Session::$userId, '='],
'friend_id' => [$uid, '='],
]);
// Attempt to remove the request
if ($deleteRequest) {
Database::delete('friends', [
'fid' => [Session::$userId, '='],
'uid' => [$uid, '='],
'friend_id' => [Session::$userId, '='],
'user_id' => [$uid, '='],
]);
}
@ -1543,7 +1545,7 @@ class Users
public static function getNewestUserId()
{
return Database::fetch('users', false, ['password_algo' => ['nologin', '!=']], ['id', true], ['1'])['id'];
return Database::fetch('users', false, ['password_algo' => ['nologin', '!=']], ['user_id', true], ['1'])['user_id'];
}
}

View file

@ -27,27 +27,27 @@ set_time_limit(0);
// Clean expired sessions
Database::delete('sessions', [
'expire' => [time(), '<'],
'remember' => ['1', '!='],
'session_expire' => [time(), '<'],
'session_remember' => ['1', '!='],
]);
// Delete notifications that are older than a month but not unread
Database::delete('notifications', [
'timestamp' => [(time() - 109500), '<'],
'notif_read' => ['1', '='],
'alert_timestamp' => [(time() - 109500), '<'],
'alert_read' => ['1', '='],
]);
// Get expired premium accounts
$expiredPremium = Database::fetch('premium', true, [
'expiredate' => [time(), '<'],
'premium_expire' => [time(), '<'],
]);
// Process expired premium accounts
foreach ($expiredPremium as $expired) {
Users::updatePremiumMeta($expired['uid']);
Users::updatePremiumMeta($expired['user_id']);
}

View file

@ -1,7 +1,7 @@
<?php
/*
* Sakura Community Management System
* (c) 2013-2015 Flashwave <http://flash.moe> & Circlestorm <http://circlestorm.net>
* (c) 2013-2015 Flashwave <http://flash.moe>
*/
// Declare namespace
@ -38,6 +38,7 @@ require_once ROOT . '_sakura/components/Templates.php';
require_once ROOT . '_sakura/components/Permissions.php';
require_once ROOT . '_sakura/components/Sessions.php';
require_once ROOT . '_sakura/components/User.php';
require_once ROOT . '_sakura/components/Rank.php';
require_once ROOT . '_sakura/components/Users.php';
require_once ROOT . '_sakura/components/Forum.php';
require_once ROOT . '_sakura/components/News.php';

View file

@ -87,7 +87,7 @@
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false" style="color: {{ user.colour }};">{{ user.data.username }} <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="{{ urls.format('USER_PROFILE', [user.data.id]) }}">View Profile</a></li>
<li><a href="{{ urls.format('USER_PROFILE', [user.data.user_id]) }}">View Profile</a></li>
<li><a href="{{ urls.format('SETTINGS_INDEX') }}">Site settings</a></li>
<li role="separator" class="divider"></li>
<li><a href="{{ urls.format('SITE_HOME') }}">Back to site</a></li>

View file

@ -1,18 +1,18 @@
<li id="comment-{{ comment.comment_id }}">
<div class="comment">
<a class="comment-avatar clean" href="{{ urls.format('USER_PROFILE', [comment.comment_poster.data.id]) }}" style="background-image: url('{{ urls.format('IMAGE_AVATAR', [comment.comment_poster.data.id]) }}');"><span style="color: {{ comment.comment_poster.colour }};">{{ comment.comment_poster.data.username }}</span></a>
<a class="comment-avatar clean" href="{{ urls.format('USER_PROFILE', [comment.comment_poster.data.user_id]) }}" style="background-image: url('{{ urls.format('IMAGE_AVATAR', [comment.comment_poster.data.user_id]) }}');"><span style="color: {{ comment.comment_poster.colour }};">{{ comment.comment_poster.data.username }}</span></a>
<div class="comment-pointer"></div>
<div class="comment-content">
<div class="comment-controls">
<ul>
{% if comment.comment_poster.data.id == user.data.id %}
<li><a href="{{ urls.format('COMMENT_DELETE', [comment.comment_id, comment.comment_category, php.sessionid])}}" class="clean fa fa-trash-o comment-deletion-link" title="Delete" id="comment-delete-{{ comment.comment_id }}"></a></li>
{% if comment.comment_poster.data.user_id == user.data.user_id %}
<li><a href="{{ urls.format('COMMENT_DELETE', [comment.comment_id, comment.comment_category, php.sessionid])}}" class="clean fa fa-trash-o comment-deletion-link" title="Delete" id="comment-action-delete-{{ comment.comment_id }}"></a></li>
{% else %}
<li><a href="{{ urls.format('USER_REPORT', [comment.comment_poster.data.id]) }}" class="clean fa fa-exclamation-circle" title="Report" id="comment-report-{{ comment.comment_id }}"></a></li>
<li><a href="{{ urls.format('USER_REPORT', [comment.comment_poster.data.user_id]) }}" class="clean fa fa-exclamation-circle" title="Report" id="comment-action-report-{{ comment.comment_id }}"></a></li>
{% endif %}
<li><a href="javascript:void(0);" onclick="commentReply({{ comment.comment_id }}, '{{ php.sessionid }}', '{{ comment.comment_category }}', '{{ urls.format('COMMENT_POST') }}', '{{ urls.format('IMAGE_AVATAR', [user.data.id]) }}');" class="clean fa fa-reply" title="Reply" id="comment-reply-{{ comment.comment_id }}"></a></li>
<li class="shown voting like"><a href="{{ urls.format('COMMENT_LIKE', [comment.comment_id, php.sessionid])}}" class="clean" id="comment-link-{{ comment.comment_id }}"><span class="fa fa-thumbs-up"></span> {{ comment.comment_likes }}</a></li>
<li class="shown voting dislike" id="comment-dislike-{{ comment.comment_id }}"><a href="{{ urls.format('COMMENT_DISLIKE', [comment.comment_id, php.sessionid])}}" class="clean"><span class="fa fa-thumbs-down"></span> {{ comment.comment_dislikes }}</a></li>
<li><a href="javascript:void(0);" onclick="commentReply({{ comment.comment_id }}, '{{ php.sessionid }}', '{{ comment.comment_category }}', '{{ urls.format('COMMENT_POST') }}', '{{ urls.format('IMAGE_AVATAR', [user.data.user_id]) }}');" class="clean fa fa-reply" title="Reply" id="comment-action-reply-{{ comment.comment_id }}"></a></li>
<li class="shown voting like"><a href="{{ urls.format('COMMENT_VOTE', [comment.comment_id, 1, comment.comment_category, php.sessionid])}}" class="clean comment-like-link" id="comment-action-like-{{ comment.comment_id }}"><span class="fa fa-thumbs-up"></span> <span id="comment-{{ comment.comment_id }}-likes">{{ comment.comment_likes }}</span></a></li>
<li class="shown voting dislike"><a id="comment-action-dislike-{{ comment.comment_id }}" href="{{ urls.format('COMMENT_VOTE', [comment.comment_id, 0, comment.comment_category, php.sessionid])}}" class="clean comment-dislike-link"><span class="fa fa-thumbs-down"></span> <span id="comment-{{ comment.comment_id }}-dislikes">{{ comment.comment_dislikes }}</span></a></li>
</ul>
<div class="clear"></div>
</div>

View file

@ -7,7 +7,7 @@
<input type="hidden" name="replyto" value="0" />
<input type="hidden" name="mode" value="comment" />
<div class="comment">
<div class="comment-avatar" style="background-image: url('{{ urls.format('IMAGE_AVATAR', [user.data.id]) }}');"></div>
<div class="comment-avatar" style="background-image: url('{{ urls.format('IMAGE_AVATAR', [user.data.user_id]) }}');"></div>
<div class="comment-pointer"></div>
<textarea class="comment-content" name="comment" placeholder="Join the conversation..."></textarea>
<input class="comment-submit new" name="submit" type="submit" value="&#xf1d8;" />
@ -38,9 +38,17 @@
{% block js %}
<script type="text/javascript">
var deletionLinks = document.querySelectorAll('.comment-deletion-link');
var likeLinks = document.querySelectorAll('.comment-like-link');
var dislikeLinks = document.querySelectorAll('.comment-dislike-link');
for(var link in deletionLinks) {
prepareAjaxLink(deletionLinks[link].id, 'submitPost', ', true, "Deleting..."');
}
for(var link in dislikeLinks) {
prepareAjaxLink(likeLinks[link].id, 'submitPost', ', true, "Voting..."');
}
for(var link in dislikeLinks) {
prepareAjaxLink(dislikeLinks[link].id, 'submitPost', ', true, "Voting..."');
}
</script>
{% endblock %}

View file

@ -1,6 +1,6 @@
{% if session.checkLogin %}
<div class="head">Hi, {{ user.data.username }}!</div>
<a href="{{ urls.format('SETTING_MODE', ['appearance', 'avatar']) }}"><img src="{{ urls.format('IMAGE_AVATAR', [user.data.id]) }}" class="default-avatar-setting homepage-menu-avatar" /></a>
<a href="{{ urls.format('SETTING_MODE', ['appearance', 'avatar']) }}"><img src="{{ urls.format('IMAGE_AVATAR', [user.data.user_id]) }}" class="default-avatar-setting homepage-menu-avatar" /></a>
<ul class="panelQuickLinks">
<li><a href="{{ urls.format('SETTING_MODE', ['friends', 'requests']) }}" title="Pending friend requests"><span class="fa fa-user-plus"></span><span class="count">{{ page.friend_req|length }}</span></a></li>
<li><a href="{{ urls.format('MESSAGES_INDEX') }}" title="View private messages"><span class="fa fa-envelope"></span><span class="count">0</span></a></li>
@ -24,13 +24,13 @@
{% endif %}
<div class="head">Stats</div>
We have <b>{{ stats.userCount }} user{% if stats.userCount != 1 %}s{% endif %}</b>,
<b><a href="{{ urls.format('USER_PROFILE', [stats.newestUser.data.id]) }}" class="default">{{ stats.newestUser.data.username }}</a></b> is the newest user,
<b><a href="{{ urls.format('USER_PROFILE', [stats.newestUser.data.user_id]) }}" class="default">{{ stats.newestUser.data.username }}</a></b> is the newest user,
it has been <b>{{ stats.lastRegDate }}</b> since the last user registered and the forum has <b>{{ stats.topicCount }} thread{% if stats.topicCount != 1 %}s{% endif %}</b> and <b>{{ stats.postCount }} post{% if stats.postCount != 1 %}s{% endif %}</b>.
<div class="head">Online Users</div>
{% if stats.onlineUsers %}
All active users in the past 5 minutes:<br />
{% for amount,onlineUser in stats.onlineUsers %}
<a href="{{ urls.format('USER_PROFILE', [onlineUser.id]) }}" style="font-weight: bold;" class="default">{{ onlineUser.username }}</a>{% if amount != (stats.onlineUsers|length - 1) %}, {% endif %}
<a href="{{ urls.format('USER_PROFILE', [onlineUser.user_id]) }}" style="font-weight: bold;" class="default">{{ onlineUser.username }}</a>{% if amount != (stats.onlineUsers|length - 1) %}, {% endif %}
{% endfor %}
{% else %}
There were no online users in the past 5 minutes.

View file

@ -1,16 +1,16 @@
{% if not (viewPost and postExists) %}<a href="{{ urls.format('SITE_NEWS_POST', [post.id]) }}" class="news-head" id="{{ post.category }}_{{ post.id }}">{{ post.title }}</a>{% endif %}
{% if not (viewPost and postExists) %}<a href="{{ urls.format('SITE_NEWS_POST', [post.news_id]) }}" class="news-head" id="{{ post.news_category }}_{{ post.news_id }}">{{ post.news_title }}</a>{% endif %}
<div class="news-body">
<a class="no-underline" href="{{ urls.format('USER_PROFILE', [post.poster.data.id]) }}">
<a class="no-underline" href="{{ urls.format('USER_PROFILE', [post.news_poster.data.user_id]) }}">
<div class="news-poster">
<img src="{{ urls.format('IMAGE_AVATAR', [post.poster.data.id]) }}" alt="{{ post.poster.data.username }}" class="default-avatar-setting" />
<h1 style="color: {{ post.poster.colour }}; text-shadow: 0 0 7px {% if post.poster.colour != 'inherit' %}{{ post.poster.colour }}{% else %}#222{% endif %}; padding: 0 0 10px;">{{ post.poster.data.username }}</h1>
<img src="{{ urls.format('IMAGE_AVATAR', [post.news_poster.data.user_id]) }}" alt="{{ post.news_poster.data.username }}" class="default-avatar-setting" />
<h1 style="color: {{ post.news_poster.colour }}; text-shadow: 0 0 7px {% if post.news_poster.colour != 'inherit' %}{{ post.news_poster.colour }}{% else %}#222{% endif %}; padding: 0 0 10px;">{{ post.news_poster.data.username }}</h1>
</div>
</a>
<div class="markdown">
{{ post.content_parsed|raw }}
{{ post.news_content_parsed|raw }}
</div>
</div>
<div class="clear"></div>
<div class="news-post-time">
Posted on {{ post.date|date(sakura.dateFormat) }}{% if not (viewPost and postExists) %} <a class="default" href="{{ urls.format('SITE_NEWS_POST', [post.id]) }}#comments">{{ post.comments.count }} comment{% if post.comments.count != 1 %}s{% endif %}</a>{% endif %}
Posted on {{ post.news_timestamp|date(sakura.dateFormat) }}{% if not (viewPost and postExists) %} <a class="default" href="{{ urls.format('SITE_NEWS_POST', [post.news_id]) }}#comments">{{ post.news_comments.count }} comment{% if post.news_comments.count != 1 %}s{% endif %}</a>{% endif %}
</div>

View file

@ -29,7 +29,7 @@
<td class="forumLastColumn">
<div>
{% if forum.last_post.post_id %}
<a href="{{ urls.format('FORUM_THREAD', [forum.last_post.topic_id]) }}" class="default">{{ forum.last_post.post_subject }}</a><br /><span title="{{ forum.last_post.post_time|date(sakura.dateFormat) }}">{{ forum.last_post.elapsed }}</span> by {% if forum.last_poster.data.id %}<a href="{{ urls.format('USER_PROFILE', [forum.last_poster.data.id]) }}" class="default" style="color: {{ forum.last_poster.colour }}; text-shadow: 0 0 5px {% if forum.last_poster.colour != 'inherit' %}{{ forum.last_poster.colour }}{% else %}#222{% endif %};">{{ forum.last_poster.data.username }}</a>{% else %}[deleted user]{% endif %} <a href="{{ urls.format('FORUM_POST', [forum.last_poster.post.post_id]) }}#p{{ forum.last_poster.post.post_id }}" class="default fa fa-tag"></a>
<a href="{{ urls.format('FORUM_THREAD', [forum.last_post.topic_id]) }}" class="default">{{ forum.last_post.post_subject }}</a><br /><span title="{{ forum.last_post.post_time|date(sakura.dateFormat) }}">{{ forum.last_post.elapsed }}</span> by {% if forum.last_poster.data.user_id %}<a href="{{ urls.format('USER_PROFILE', [forum.last_poster.data.user_id]) }}" class="default" style="color: {{ forum.last_poster.colour }}; text-shadow: 0 0 5px {% if forum.last_poster.colour != 'inherit' %}{{ forum.last_poster.colour }}{% else %}#222{% endif %};">{{ forum.last_poster.data.username }}</a>{% else %}[deleted user]{% endif %} <a href="{{ urls.format('FORUM_POST', [forum.last_poster.post.post_id]) }}#p{{ forum.last_poster.post.post_id }}" class="default fa fa-tag"></a>
{% else %}
There are no posts in this forum.<br />&nbsp;
{% endif %}

View file

@ -13,8 +13,8 @@
<hr class="default" />
<div class="posting-bbcodes">
{% for bbcode in posting.bbcodes %}
{% if bbcode.on_posting %}
<button type="button" class="inputStyling small">{{ bbcode.title }}</button>
{% if bbcode.bbcode_display %}
<button type="button" class="inputStyling small">{{ bbcode.bbcode_title }}</button>
{% endif %}
{% endfor %}
</div>

View file

@ -6,8 +6,8 @@
<a href="{{ urls.format('FORUM_THREAD', [topic.topic_id]) }}" class="default">{{ topic.topic_title }}</a>
</td>
<td class="topicAuthor">
{% if topic.first_poster.data.id %}
<a href="{{ urls.format('USER_PROFILE', [topic.first_poster.data.id]) }}" class="default" style="color: {{ topic.first_poster.colour }}; text-shadow: 0 0 5px {% if topic.first_poster.colour != 'inherit' %}{{ topic.first_poster.colour }}{% else %}#222{% endif %};">{{ topic.first_poster.data.username }}</a>
{% if topic.first_poster.data.user_id %}
<a href="{{ urls.format('USER_PROFILE', [topic.first_poster.data.user_id]) }}" class="default" style="color: {{ topic.first_poster.colour }}; text-shadow: 0 0 5px {% if topic.first_poster.colour != 'inherit' %}{{ topic.first_poster.colour }}{% else %}#222{% endif %};">{{ topic.first_poster.data.username }}</a>
{% else %}
[deleted user]
{% endif %}
@ -17,8 +17,8 @@
<div class="views" title="Amount of times this topic has been viewed.">{{ topic.topic_views }}</div>
</td>
<td class="topicLast">
{% if topic.last_poster.data.id %}
<a href="{{ urls.format('USER_PROFILE', [topic.last_poster.data.id]) }}" class="default" style="color: {{ topic.last_poster.colour }}; text-shadow: 0 0 5px {% if topic.last_poster.colour != 'inherit' %}{{ topic.last_poster.colour }}{% else %}#222{% endif %};">{{ topic.last_poster.data.username }}</a>
{% if topic.last_poster.data.user_id %}
<a href="{{ urls.format('USER_PROFILE', [topic.last_poster.data.user_id]) }}" class="default" style="color: {{ topic.last_poster.colour }}; text-shadow: 0 0 5px {% if topic.last_poster.colour != 'inherit' %}{{ topic.last_poster.colour }}{% else %}#222{% endif %};">{{ topic.last_poster.data.username }}</a>
{% else %}
[deleted user]
{% endif %} <a href="{{ urls.format('FORUM_POST', [topic.last_post.post.post_id]) }}#p{{ topic.last_post.post.post_id }}" class="default fa fa-tag"></a><br />

View file

@ -11,25 +11,25 @@
{% for post in posts %}
<tr class="post" id="p{{ post.post_id }}">
<td class="userpanel">
{% if not post.user.checkPermission('SITE', 'DEACTIVATED') or post.user.checkPermission('SITE', 'RESTRICTED') %}<a href="{{ urls.format('USER_PROFILE', [post.user.data.id]) }}" class="default username" style="color: {{ post.user.colour }}; text-shadow: 0 0 5px {% if post.user.colour != 'inherit' %}{{ post.user.colour }}{% else %}#222{% endif %};" title="Go to {{ post.user.data.username }}'s profile">{{ post.user.data.username }}</a>
<img src="{{ urls.format('IMAGE_AVATAR', [post.user.data.id]) }}" alt="{{ post.user.data.username }}" class="avatar" style="box-shadow: 0 3px 7px #{% if post.is_online %}484{% else %}844{% endif %};" />
{% if not post.user.checkPermission('SITE', 'DEACTIVATED') or post.user.checkPermission('SITE', 'RESTRICTED') %}<a href="{{ urls.format('USER_PROFILE', [post.user.data.user_id]) }}" class="default username" style="color: {{ post.user.colour }}; text-shadow: 0 0 5px {% if post.user.colour != 'inherit' %}{{ post.user.colour }}{% else %}#222{% endif %};" title="Go to {{ post.user.data.username }}'s profile">{{ post.user.data.username }}</a>
<img src="{{ urls.format('IMAGE_AVATAR', [post.user.data.user_id]) }}" alt="{{ post.user.data.username }}" class="avatar" style="box-shadow: 0 3px 7px #{% if post.is_online %}484{% else %}844{% endif %};" />
{% else %}
<a class="username">[deleted user]</a>
{% endif %}
<div class="userdata">
<div class="usertitle">{% if not post.user.usertitle %}{{ post.rank.title }}{% else %}{{ post.user.usertitle }}{% endif %}</div>
<div class="usertitle">{% if not post.user.usertitle %}{{ post.rank.title }}{% else %}{{ post.user.user_title }}{% endif %}</div>
<img src="{{ sakura.contentPath }}/images/tenshi.png" alt="Tenshi"{% if not post.user.checkPremium[0] %} style="opacity: 0;"{% endif %} /> <img src="{{ sakura.contentPath }}/images/flags/{{ post.user.country.short|lower }}.png" alt="{{ post.user.country.long }}" />
{% if session.checkLogin %}
<div class="actions">
{% if user.data.id == post.user.data.id %}
{% if user.data.user_id == post.user.data.user_id %}
<a class="fa fa-pencil-square-o" title="Edit this post" href="{{ urls.format('FORUM_EDIT_POST', [post.post_id]) }}"></a>
<a class="fa fa-trash" title="Delete this post" href="{{ urls.format('FORUM_DELETE_POST', [post.post_id]) }}"></a>
{% elseif not post.user.checkPermission('SITE', 'DEACTIVATED') or post.user.checkPermission('SITE', 'RESTRICTED') %}
{% if post.user.checkFriends(user.data.id) != 0 %}
<a class="fa fa-{% if post.user.checkFriends(user.data.id) == 2 %}heart{% else %}star{% endif %}" title="You are friends"></a>
{% if post.user.checkFriends(user.data.user_id) != 0 %}
<a class="fa fa-{% if post.user.checkFriends(user.data.user_id) == 2 %}heart{% else %}star{% endif %}" title="You are friends"></a>
{% endif %}
<a class="fa fa-user-{% if post.user.checkFriends(user.data.id) == 0 %}plus{% else %}times{% endif %} forum-friend-toggle" title="{% if post.user.checkFriends(user.data.id) == 0 %}Add {{ post.user.data.username }} as a friend{% else %}Remove friend{% endif %}" href="{% if post.user.checkFriends(user.data.id) == 0 %}{{ urls.format('FRIEND_ADD', [post.user.data.id, php.sessionid, php.time, sakura.currentPage]) }}{% else %}{{ urls.format('FRIEND_REMOVE', [post.user.data.id, php.sessionid, php.time, sakura.currentPage]) }}{% endif %}"></a>
<a class="fa fa-flag" title="Report {{ post.user.data.username }}" href="{{ urls.format('USER_REPORT', [post.user.data.id]) }}"></a>
<a class="fa fa-user-{% if post.user.checkFriends(user.data.user_id) == 0 %}plus{% else %}times{% endif %} forum-friend-toggle" title="{% if post.user.checkFriends(user.data.user_id) == 0 %}Add {{ post.user.data.username }} as a friend{% else %}Remove friend{% endif %}" href="{% if post.user.checkFriends(user.data.user_id) == 0 %}{{ urls.format('FRIEND_ADD', [post.user.data.user_id, php.sessionid, php.time, sakura.currentPage]) }}{% else %}{{ urls.format('FRIEND_REMOVE', [post.user.data.user_id, php.sessionid, php.time, sakura.currentPage]) }}{% endif %}"></a>
<a class="fa fa-flag" title="Report {{ post.user.data.username }}" href="{{ urls.format('USER_REPORT', [post.user.data.user_id]) }}"></a>
{% endif %}
<a class="fa fa-reply" title="Quote this post" href="{{ urls.format('FORUM_QUOTE_POST', [post.post_id]) }}"></a>
</div>
@ -49,7 +49,7 @@
<div class="post-text markdown">
{{ post.parsed_post|raw }}
</div>
{% if post.enable_sig and post.signature %}
{% if post.post_signature and post.signature %}
<div class="clear"></div>
<div class="signature">
{{ post.signature|raw }}

View file

@ -80,7 +80,7 @@
}, 60000);
{% endif %}
{% if php.self == '/profile.php' and session.checkLogin and user.data.id != profile.user.id %}
{% if php.self == '/profile.php' and session.checkLogin and user.data.user_id != profile.user.user_id %}
// Make friend button dynamic
prepareAjaxLink('profileFriendToggle', 'submitPost', ', true, "{% if profile.friend == 0 %}Adding{% else %}Removing{% endif %} friend..."');
{% endif %}
@ -117,7 +117,7 @@
{% endif %}
{% if php.self == '/profile.php' ? (profile.data.userData.profileBackground and not profile.data.userData.userOptions.disableProfileParallax) : (user.checkPermission('SITE', 'CREATE_BACKGROUND') and user.data.userData.userOptions.profileBackgroundSiteWide and user.data.userData.profileBackground and not user.data.userData.userOptions.disableProfileParallax) %}
{% if php.self == '/profile.php' ? (profile.data.user_data.profileBackground and not profile.data.user_data.userOptions.disableProfileParallax) : (user.checkPermission('SITE', 'CREATE_BACKGROUND') and user.data.user_data.userOptions.profileBackgroundSiteWide and user.data.user_data.profileBackground and not user.data.user_data.userOptions.disableProfileParallax) %}
initialiseParallax('userBackground');
@ -169,7 +169,7 @@
<div class="menu-ucp" id="navMenuUser">
<!-- User menu, displayed on right side of the bar. -->
{% if session.checkLogin %}
<a class="menu-item avatar" href="{{ urls.format('USER_PROFILE', [user.data.id]) }}" title="Logged in as {{ user.data.username }}" style="background-image: url('{{ urls.format('IMAGE_AVATAR', [user.data.id]) }}'); width: auto; color: {{ user.colour }}; font-weight: 700;"></a>
<a class="menu-item avatar" href="{{ urls.format('USER_PROFILE', [user.data.user_id]) }}" title="Logged in as {{ user.data.username }}" style="background-image: url('{{ urls.format('IMAGE_AVATAR', [user.data.user_id]) }}'); width: auto; color: {{ user.colour }}; border-color: {{ user.colour }}; font-weight: 700;"></a>
<a class="menu-item fa-envelope" href="{{ urls.format('SETTING_CAT', ['messages']) }}" title="Messages"></a>
<a class="menu-item fa-gavel" href="{{ urls.format('MANAGE_INDEX') }}" title="Manage"></a>
<a class="menu-item fa-cogs" href="{{ urls.format('SETTINGS_INDEX') }}" title="Settings"></a>
@ -186,8 +186,8 @@
</div>
<div id="contentwrapper">
<div id="notifications"></div>
{% if php.self == '/profile.php' ? profile.data.userData.profileBackground : (user.checkPermission('SITE', 'CREATE_BACKGROUND') and user.data.userData.userOptions.profileBackgroundSiteWide and user.data.userData.profileBackground) %}
<div id="userBackground" style="background-image: url('{{ urls.format('IMAGE_BACKGROUND', [(php.self == '/profile.php' ? profile : user).data.id]) }}');"></div>
{% if php.self == '/profile.php' ? profile.data.user_data.profileBackground : (user.checkPermission('SITE', 'CREATE_BACKGROUND') and user.data.user_data.userOptions.profileBackgroundSiteWide and user.data.user_data.profileBackground) %}
<div id="userBackground" style="background-image: url('{{ urls.format('IMAGE_BACKGROUND', [(php.self == '/profile.php' ? profile : user).data.user_id]) }}');"></div>
{% endif %}
{% if not session.checkLogin and php.self != '/authenticate.php' %}
<form method="post" action="{{ urls.format('AUTH_ACTION') }}" id="headerLoginForm">

View file

@ -21,7 +21,7 @@
<li>You were banned on {{ ban.issued|date(sakura.dateFormat) }}.</li>
<li>{% if ban.expires %}This ban expires on {{ ban.expires|date(sakura.dateFormat) }}.{% else %}<b>You are permanently banned.</b>{% endif %}</li>
{% if ban.expires %}
<li>You were banned by <a href="{{ urls.format('USER_PROFILE', [ban.issuer.id]) }}" class="default">{{ ban.issuer.username }}</a>.</li>
<li>You were banned by <a href="{{ urls.format('USER_PROFILE', [ban.issuer.user_id]) }}" class="default">{{ ban.issuer.username }}</a>.</li>
{% endif %}
</ul>
</div>

View file

@ -10,17 +10,17 @@
</div>
<div class="right-menu-nav">
{% for question in page.questions %}
<a href="#{{ question.short }}" class="default">{{ question.question }}</a>
<a href="#{{ question.faq_shorthand }}" class="default">{{ question.faq_question }}</a>
{% endfor %}
</div>
</div>
<div class="content-left content-column">
{% for question in page.questions %}
<div class="head" id="{{ question.short }}">
{{ question.question }}
<a href="#{{ question.short }}" class="fa fa-quote-right news-rss default"></a>
<div class="head" id="{{ question.faq_shorthand }}">
{{ question.faq_question }}
<a href="#{{ question.faq_shorthand }}" class="fa fa-quote-right news-rss default"></a>
</div>
<p>{{ question.answer }}</p>
<p>{{ question.faq_answer }}</p>
{% endfor %}
</div>
<div class="clear"></div>

View file

@ -1,18 +1,18 @@
{% extends 'global/master.tpl' %}
{% set rankTitle %}
{% if page.notfound %}Not found{% else %}{% if not page.active %}All members{% else %}{{ page.ranks[page.active].name }}{% if page.ranks[page.active].multi %}s{% endif %}{% endif %}{% endif %}
{% if page.notfound %}Not found{% else %}{% if not page.active %}All members{% else %}{{ page.ranks[page.active].rank_name }}{{ page.ranks[page.active].rank_multiple }}{% endif %}{% endif %}
{% endset %}
{% set rankDescription %}
{% if page.notfound %}The requested rank could not be found!{% else %}{% if not page.active %}The entire user list.{% else %}{{ page.ranks[page.active].description }}{% endif %}{% endif %}
{% if page.notfound %}The requested rank could not be found!{% else %}{% if not page.active %}The entire user list.{% else %}{{ page.ranks[page.active].rank_description }}{% endif %}{% endif %}
{% endset %}
{% block title %}{{ rankTitle }}{% endblock %}
{% block content %}
<div class="headerNotify" style="margin-bottom: 1px;">
<h1 style="text-shadow: 0px 0px 5px #555;{% if page.active %} color: {{ page.ranks[page.active].colour }};{% endif %}">{{ rankTitle }}</h1>
<h1 style="text-shadow: 0px 0px 5px #555;{% if page.active %} color: {{ page.ranks[page.active].rank_colour }};{% endif %}">{{ rankTitle }}</h1>
<h3>{{ rankDescription }}</h3>
</div>
<div class="membersPage" style="min-height: 500px;">
@ -21,8 +21,8 @@
<a class="dropDownDesc">Rank:</a>
<a href="{% if page.page and page.sort %}{{ urls.format('MEMBERLIST_SORT_PAGE', [page.sort, (page.page + 1)]) }}{% elseif page.sort %}{{ urls.format('MEMBERLIST_SORT', [page.sort]) }}{% elseif page.page %}{{ urls.format('MEMBERLIST_PAGE', [(page.page + 1)]) }}{% else %}{{ urls.format('MEMBERLIST_INDEX') }}{% endif %}"{% if not page.active %} class="dropDownSelected"{% endif %}>All members</a>
{% for rank in page.ranks %}
{% if not rank.hidden or (rank.hidden and page.active == rank.id) %}
<a href="{% if page.sort %}{{ urls.format('MEMBERLIST_SORT_RANK', [page.sort, rank.id]) }}{% else %}{{ urls.format('MEMBERLIST_RANK', [rank.id]) }}{% endif %}" style="color: {{ rank.colour }};"{% if page.active == rank.id %} class="dropDownSelected"{% endif %}>{{ rank.name }}{% if rank.multi %}s{% endif %}</a>
{% if not rank.rank_hidden or (rank.rank_hidden and page.active == rank.rank_id) %}
<a href="{% if page.sort %}{{ urls.format('MEMBERLIST_SORT_RANK', [page.sort, rank.rank_id]) }}{% else %}{{ urls.format('MEMBERLIST_RANK', [rank.rank_id]) }}{% endif %}" style="color: {{ rank.rank_colour }};"{% if page.active == rank.rank_id %} class="dropDownSelected"{% endif %}>{{ rank.rank_name }}{{ rank.rank_multiple }}</a>
{% endif %}
{% endfor %}
</div>
@ -66,19 +66,19 @@
#{{ page.active ? count + 1 : count }}
</td>
<td>
<a href="{{ urls.format('USER_PROFILE', [user.id]) }}" class="default" style="font-weight: bold; color: {{ page.ranks[user.rank_main].colour }};">{{ user.username }}</a>
<a href="{{ urls.format('USER_PROFILE', [user.user_id]) }}" class="default" style="font-weight: bold; color: {{ page.ranks[user.rank_main].rank_colour }};">{{ user.username }}</a>
</td>
<td>
{{ user.regdate|date(sakura.dateFormat) }}
</td>
<td>
{% if user.lastdate == 0 %}<i>Never logged in.</i>{% else %}{{ user.lastdate|date(sakura.dateFormat) }}{% endif %}
{% if user.user_last_online == 0 %}<i>Never logged in.</i>{% else %}{{ user.user_last_online|date(sakura.dateFormat) }}{% endif %}
</td>
<td>
{% if not user.usertitle %}<i>{{ page.ranks[user.rank_main].title }}</i>{% else %}{{ user.usertitle }}{% endif %}
{% if not user.user_title %}<i>{{ page.ranks[user.rank_main].rank_title }}</i>{% else %}{{ user.user_title }}{% endif %}
</td>
<td>
<img src="{{ sakura.contentPath }}/images/flags/{{ user.country|lower }}.png" alt="{% if user.country|lower == 'eu' %}?{% else %}{{ user.country }}{% endif %}" />
<img src="{{ sakura.contentPath }}/images/flags/{{ user.user_country|lower }}.png" alt="{% if user.user_country|lower == 'eu' %}?{% else %}{{ user.user_country }}{% endif %}" />
</td>
</tr>
</tbody>
@ -86,10 +86,10 @@
</table>
{% else %}
{% for user in page.users[page.page] %}
<a href="{{ urls.format('USER_PROFILE', [user.id]) }}">{# These comment tags are here to prevent the link extending too far
#}<div class="userBox" id="u{{ user.id }}">{#
#}<img src="{{ sakura.contentPath }}/pixel.png" alt="{{ user.username }}" style="background: url('{{ urls.format('IMAGE_AVATAR', [user.id]) }}') no-repeat center / contain;" />{#
#}<span class="userBoxUserName"{% if page.sort == page.sorts[1] %} style="color: {{ page.ranks[user.rank_main].colour }};"{% endif %}>{#
<a href="{{ urls.format('USER_PROFILE', [user.user_id]) }}">{# These comment tags are here to prevent the link extending too far
#}<div class="userBox" id="u{{ user.user_id }}">{#
#}<img src="{{ sakura.contentPath }}/pixel.png" alt="{{ user.username }}" style="background: url('{{ urls.format('IMAGE_AVATAR', [user.user_id]) }}') no-repeat center / contain;" />{#
#}<span class="userBoxUserName"{% if page.sort == page.sorts[1] %} style="color: {{ page.ranks[user.rank_main].rank_colour }};"{% endif %}>{#
#}{{ user.username }}{#
#}</span>{#
#}</div>{#

View file

@ -5,12 +5,12 @@
{% set pagination = {'page': currentPage, 'pages': news.getPosts(postsPerPage), 'urlPattern': 'SITE_NEWS_PAGE'} %}
{% if viewPost and postExists %}
{% set commentsCategory = 'news-' ~ newsPosts[0].category ~ '-' ~ newsPosts[0].id %}
{% set comments = newsPosts[0].comments.comments %}
{% set commentsCategory = 'news-' ~ newsPosts[0].news_category ~ '-' ~ newsPosts[0].news_id %}
{% set comments = newsPosts[0].news_comments.comments %}
{% endif %}
{% set title %}
{% if not (viewPost ? postExists : newsPosts|length) %}Post does not exist!{% elseif viewPost and postExists %}{{ newsPosts[0].title }}{% else %}News{% endif %}
{% if not (viewPost ? postExists : newsPosts|length) %}Post does not exist!{% elseif viewPost and postExists %}{{ newsPosts[0].news_title }}{% else %}News{% endif %}
{% endset %}
{% block title %}{{ title }}{% endblock %}

View file

@ -1,6 +1,6 @@
{% extends 'global/master.tpl' %}
{% set profileHidden = profile.checkPermission('SITE', 'DEACTIVATED') or profile.data.password_algo == 'nologin' or (profile.checkPermission('SITE', 'RESTRICTED') and (user.data.id != profile.data.id and not user.checkPermission('MANAGE', 'USE_MANAGE'))) %}
{% set profileHidden = profile.checkPermission('SITE', 'DEACTIVATED') or profile.data.password_algo == 'nologin' or (profile.checkPermission('SITE', 'RESTRICTED') and (user.data.user_id != profile.data.user_id and not user.checkPermission('MANAGE', 'USE_MANAGE'))) %}
{% set noUserpage = profile.userPage|length < 1 %}
@ -24,41 +24,41 @@
<div class="content profile">
<div class="content-right content-column">
<div style="text-align: center;">
<img src="{{ urls.format('IMAGE_AVATAR', [profile.data.id]) }}" alt="{{ profile.data.username }}'s Avatar" class="default-avatar-setting" style="box-shadow: 0 3px 7px #{% if profile.checkOnline %}484{% else %}844{% endif %};" /><br />
<img src="{{ urls.format('IMAGE_AVATAR', [profile.data.user_id]) }}" alt="{{ profile.data.username }}'s Avatar" class="default-avatar-setting" style="box-shadow: 0 3px 7px #{% if profile.checkOnline %}484{% else %}844{% endif %};" /><br />
{% if profile.data.rank_main > 1 and profile.checkBan|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;"{% if profile.getUsernameHistory %} title="Known as {{ profile.getUsernameHistory[0]['username_old'] }} before {{ profile.getUsernameHistory[0]['change_time']|date(sakura.dateFormat) }}."{% endif %}>{{ profile.data.username }}</h1>
{% if profile.checkPremium[0] %}<img src="{{ sakura.contentPath }}/images/tenshi.png" alt="Tenshi" /> {% endif %}<img src="{{ sakura.contentPath }}/images/flags/{{ profile.country.short|lower }}.png" alt="{{ profile.country.short }}" /> <span style="font-size: .9em; line-height: 11px;">{{ profile.country.long }}</span>
{% if session.checkLogin %}
<div class="user-actions">
{% if user.data.id == profile.data.id %}
{% if user.data.user_id == profile.data.user_id %}
<a class="fa fa-pencil-square-o" title="Edit your profile" href="{{ urls.format('SETTING_MODE', ['general', 'profile']) }}"></a>
{% else %}
{% if profile.checkFriends(user.data.id) != 0 %}<a class="fa fa-{% if profile.checkFriends(user.data.id) == 2 %}heart{% else %}star{% endif %}" title="You are friends"></a>{% endif %}
<a class="fa fa-user-{% if profile.checkFriends(user.data.id) == 0 %}plus{% else %}times{% endif %}" title="{% if profile.checkFriends(user.data.id) == 0 %}Add {{ legacyprofile.data.username }} as a friend{% else %}Remove friend{% endif %}" href="{% if profile.checkFriends(user.data.id) == 0 %}{{ urls.format('FRIEND_ADD', [profile.data.id, php.sessionid, php.time, sakura.currentPage]) }}{% else %}{{ urls.format('FRIEND_REMOVE', [profile.data.id, php.sessionid, php.time, sakura.currentPage]) }}{% endif %}" id="profileFriendToggle"></a>
<a class="fa fa-exclamation-circle" title="Report {{ profile.data.username }}" href="{{ urls.format('USER_REPORT', [profile.data.id]) }}"></a>
{% if profile.checkFriends(user.data.user_id) != 0 %}<a class="fa fa-{% if profile.checkFriends(user.data.user_id) == 2 %}heart{% else %}star{% endif %}" title="You are friends"></a>{% endif %}
<a class="fa fa-user-{% if profile.checkFriends(user.data.user_id) == 0 %}plus{% else %}times{% endif %}" title="{% if profile.checkFriends(user.data.user_id) == 0 %}Add {{ legacyprofile.data.username }} as a friend{% else %}Remove friend{% endif %}" href="{% if profile.checkFriends(user.data.user_id) == 0 %}{{ urls.format('FRIEND_ADD', [profile.data.user_id, php.sessionid, php.time, sakura.currentPage]) }}{% else %}{{ urls.format('FRIEND_REMOVE', [profile.data.user_id, php.sessionid, php.time, sakura.currentPage]) }}{% endif %}" id="profileFriendToggle"></a>
<a class="fa fa-exclamation-circle" title="Report {{ profile.data.username }}" href="{{ urls.format('USER_REPORT', [profile.data.user_id]) }}"></a>
{% endif %}
<hr class="default" />
<a class="fa fa-file-text-o" title="View {{ profile.data.username }}'s profile page" href="{{ urls.format('USER_PROFILE', [profile.data.id]) }}"></a>
<a class="fa fa-plus-square" title="View {{ profile.data.username }} threads" href="{{ urls.format('USER_THREADS', [profile.data.id]) }}"></a>
<a class="fa fa-reply" title="View {{ profile.data.username }} posts" href="{{ urls.format('USER_POSTS', [profile.data.id]) }}"></a>
<a class="fa fa-file-text-o" title="View {{ profile.data.username }}'s profile page" href="{{ urls.format('USER_PROFILE', [profile.data.user_id]) }}"></a>
<a class="fa fa-plus-square" title="View {{ profile.data.username }} threads" href="{{ urls.format('USER_THREADS', [profile.data.user_id]) }}"></a>
<a class="fa fa-reply" title="View {{ profile.data.username }} posts" href="{{ urls.format('USER_POSTS', [profile.data.user_id]) }}"></a>
{% if not noUserpage %}
<a class="fa fa-comments-o" title="View {{ profile.data.username }}'s profile comments" href="{{ urls.format('USER_COMMENTS', [profile.data.id]) }}"></a>
<a class="fa fa-comments-o" title="View {{ profile.data.username }}'s profile comments" href="{{ urls.format('USER_COMMENTS', [profile.data.user_id]) }}"></a>
{% endif %}
</div>
{% endif %}
<hr class="default" />
<b>Joined</b> <span title="{{ profile.data.regdate|date(sakura.dateFormat) }}">{{ profile.elapsed.joined }}</span>
<b>Joined</b> <span title="{{ profile.data.user_registered|date(sakura.dateFormat) }}">{{ profile.elapsed.joined }}</span>
<br />
{% if profile.data.lastdate < 1 %}
{% if profile.data.user_last_online < 1 %}
<b>{{ profile.data.username }} hasn't logged in yet.</b>
{% else %}
<b>Last online</b> <span title="{{ profile.data.lastdate|date(sakura.dateFormat) }}">{{ profile.elapsed.lastOnline }}</span>
<b>Last online</b> <span title="{{ profile.data.user_last_online|date(sakura.dateFormat) }}">{{ profile.elapsed.lastOnline }}</span>
{% endif %}
<br />
<b>{{ profile.data.username }} has {% if not profile.forumStats.posts %}no{% else %}{{ profile.forumStats.posts }}{% endif %} forum post{% if profile.forumStats.posts != 1 %}s{% endif %}.</b>
{% if profile.data.birthday != '0000-00-00' and profile.data.birthday|split('-')[0] > 0 %}
<br /><b>Age</b> <span title="{{ profile.data.birthday }}">{{ profile.elapsed(' old').birth }}</span>
<br /><b>Age</b> <span title="{{ profile.data.user_birthday }}">{{ profile.elapsed(' old').birth }}</span>
{% endif %}
{% if profile.profileFields %}
<hr class="default" />

View file

@ -40,13 +40,13 @@
{% for supporter in page.premiumTable[page.currentPage] %}
<tr>
<td>
<a href="{{ urls.format('USER_PROFILE', [page.premiumData.users[supporter.uid].data.id]) }}" class="default" style="color: {{ page.premiumData.users[supporter.uid].colour }}; text-shadow: 0 0 7px {% if page.premiumData.users[supporter.uid].colour != 'inherit' %}{{ page.premiumData.users[supporter.uid].colour }}{% else %}#222{% endif %};">{{ page.premiumData.users[supporter.uid].data.username }}</a>
<a href="{{ urls.format('USER_PROFILE', [page.premiumData.users[supporter.user_id].data.user_id]) }}" class="default" style="color: {{ page.premiumData.users[supporter.user_id].colour }}; text-shadow: 0 0 7px {% if page.premiumData.users[supporter.user_id].colour != 'inherit' %}{{ page.premiumData.users[supporter.user_id].colour }}{% else %}#222{% endif %};">{{ page.premiumData.users[supporter.user_id].data.username }}</a>
</td>
<td style="color: {% if supporter.amount > 0 %}#0A0{% else %}#A00{% endif %};">
&#8364;{{ supporter.amount|number_format(2) }}
<td style="color: {% if supporter.transaction_amount > 0 %}#0A0{% else %}#A00{% endif %};">
&#8364;{{ supporter.transaction_amount|number_format(2) }}
</td>
<td>
{{ supporter.comment }}
{{ supporter.transaction_comment }}
</td>
</tr>
{% endfor %}

View file

@ -5,7 +5,7 @@
<h3 style="text-align: center;">Your current user title is:<br /><span style="font-weight: 700;">{{ user.userTitle }}</span></h3>
<div class="profile-field">
<div><h2>Usertitle</h2></div>
<div><input type="text" name="usertitle" placeholder="Enter your new user title (Max 64 characters)" class="inputStyling" value="{{ user.data.usertitle }}" /></div>
<div><input type="text" name="usertitle" placeholder="Enter your new user title (Max 64 characters)" class="inputStyling" value="{{ user.userTitle }}" /></div>
</div>
<div class="profile-save">
<input type="submit" value="Save" name="submit" class="inputStyling" />

View file

@ -5,7 +5,7 @@
<input type="hidden" name="MAX_FILE_SIZE" value="{{ avatar.max_size }}" />
<div style="text-align: center;">
<div>
<img src="/a/{{ user.data.id }}" alt="Your Avatar" class="default-avatar-setting" />
<img src="/a/{{ user.data.user_id }}" alt="Your Avatar" class="default-avatar-setting" />
</div>
<div>
<input type="file" name="avatar" />

View file

@ -6,7 +6,7 @@
<input type="hidden" name="MAX_FILE_SIZE" value="{{ background.max_size }}" />
<div style="text-align: center;">
<div>
<img src="/bg/{{ user.data.id }}" alt="Your Background" class="default-avatar-setting" style="max-width: 90%; max-height: 90%;" />
<img src="/bg/{{ user.data.user_id }}" alt="Your Background" class="default-avatar-setting" style="max-width: 90%; max-height: 90%;" />
</div>
<div>
<input type="file" name="background" />

View file

@ -1,5 +1,5 @@
{% block js %}
<script type="text/javascript" charset="utf-8" src="{{ sakura.contentPath }}/libraries/showdown.js"></script>
<script type="text/javascript" charset="utf-8" src="{{ sakura.contentPath }}/libraries/showdown.js"></script>
{% endblock %}
<div class="markdown" id="userPagePreview" style="max-height: 500px; overflow-y: auto; background: #C2AEEE; box-shadow: inset 0 0 1em 1em #D3BFFF;">

View file

@ -13,13 +13,13 @@ window.addEventListener("load", function() {
{% if friends|length %}
<div class="friends-list">
{% for friend in friends[page.currentPage] %}
<div class="friend-container" id="friendslist-friend-{{ friend.user.id }}">
<a class="friends-list-data clean" href="/u/{{ friend.user.id }}">
<img src="/a/{{ friend.user.id }}" alt="{{ friend.user.username }}" class="friends-list-avatar default-avatar-setting" style="width: 150px; height: 150px;" />
<div class="friends-list-name" style="color: {% if friend.user.name_colour %}{{ friend.user.name_colour }}{% else %}{{ friend.rank.colour }}{% endif %};">{{ friend.user.username }}</div>
<div class="friend-container" id="friendslist-friend-{{ friend.user.user_id }}">
<a class="friends-list-data clean" href="/u/{{ friend.user.user_id }}">
<img src="/a/{{ friend.user.user_id }}" alt="{{ friend.user.username }}" class="friends-list-avatar default-avatar-setting" style="width: 150px; height: 150px;" />
<div class="friends-list-name" style="color: {% if friend.user.user_colour %}{{ friend.user.user_colour }}{% else %}{{ friend.rank.rank_colour }}{% endif %};">{{ friend.user.username }}</div>
</a>
<div class="friends-list-actions">
<a class="remove fill fa fa-remove" title="Remove friend" href="/friends?remove={{ friend.user.id }}&amp;session={{ php.sessionid }}&amp;time={{ php.time }}&amp;redirect=/settings/listing/friends&amp;direct=true" id="friendslist-friend-action-remove-{{ friend.user.id }}"></a>
<a class="remove fill fa fa-remove" title="Remove friend" href="/friends?remove={{ friend.user.user_id }}&amp;session={{ php.sessionid }}&amp;time={{ php.time }}" id="friendslist-friend-action-remove-{{ friend.user.id }}"></a>
<div class="clear"></div>
</div>
</div>
@ -30,13 +30,13 @@ window.addEventListener("load", function() {
<div>
<div class="pagination" style="float: right;">
{% if page.currentPage > 0 %}
<a href="/settings/friends/listing/p{{ page.currentPage }}"><span class="fa fa-step-backward"></span></a>
<a href="{{ urls.format('SETTING_PAGE', ['friends', 'listing', page.currentPage]) }}"><span class="fa fa-step-backward"></span></a>
{% endif %}
{% for id,npage in friends %}
<a href="/settings/friends/listing/p{{ id + 1 }}"{% if id == page.currentPage %} class="current"{% endif %}>{{ id + 1 }}</a>
<a href="{{ urls.format('SETTING_PAGE', ['friends', 'listing', id + 1]) }}"{% if id == page.currentPage %} class="current"{% endif %}>{{ id + 1 }}</a>
{% endfor %}
{% if page.currentPage + 1 < friends|length %}
<a href="/settings/friends/listing/p{{ page.currentPage + 2 }}"><span class="fa fa-step-forward"></span></a>
<a href="{{ urls.format('SETTING_PAGE', ['friends', 'listing', page.currentPage + 2]) }}"><span class="fa fa-step-forward"></span></a>
{% endif %}
</div>
<div class="clear"></div>

View file

@ -13,14 +13,14 @@ window.addEventListener("load", function() {
{% if friends|length %}
<div class="friends-list">
{% for friend in friends[page.currentPage] %}
<div class="friend-container" id="friend-{{ friend.user.id }}">
<a class="friends-list-data clean" href="/u/{{ friend.user.id }}">
<img src="/a/{{ friend.user.id }}" alt="{{ friend.user.username }}" class="friends-list-avatar default-avatar-setting" style="width: 150px; height: 150px;" />
<div class="friend-container" id="friend-{{ friend.user.user_id }}">
<a class="friends-list-data clean" href="/u/{{ friend.user.user_id }}">
<img src="/a/{{ friend.user.user_id }}" alt="{{ friend.user.username }}" class="friends-list-avatar default-avatar-setting" style="width: 150px; height: 150px;" />
<div class="friends-list-name" style="color: {% if friend.user.name_colour %}{{ friend.user.name_colour }}{% else %}{{ friend.rank.colour }}{% endif %};">{{ friend.user.username }}</div>
</a>
<div class="friends-list-actions">
<a class="add fa fa-check" title="Add friend" href="/friends?add={{ friend.user.id }}&amp;session={{ php.sessionid }}&amp;time={{ php.time }}&amp;redirect=/settings/friendrequests&amp;direct=true" id="friendslist-friend-action-add-{{ friend.user.id }}"></a>
<a class="remove fa fa-remove" title="Remove friend" href="/friends?remove={{ friend.user.id }}&amp;session={{ php.sessionid }}&amp;time={{ php.time }}&amp;redirect=/settings/friends/requests&amp;direct=true" id="friendslist-friend-action-remove-{{ friend.user.id }}"></a>
<a class="add fa fa-check" title="Add friend" href="/friends?add={{ friend.user.id }}&amp;session={{ php.sessionid }}&amp;time={{ php.time }}" id="friendslist-friend-action-add-{{ friend.user.id }}"></a>
<a class="remove fa fa-remove" title="Remove friend" href="/friends?remove={{ friend.user.id }}&amp;session={{ php.sessionid }}&amp;time={{ php.time }}" id="friendslist-friend-action-remove-{{ friend.user.id }}"></a>
<div class="clear"></div>
</div>
</div>
@ -31,13 +31,13 @@ window.addEventListener("load", function() {
<div>
<div class="pagination" style="float: right;">
{% if page.currentPage > 0 %}
<a href="/settings/friends/requests/p{{ page.currentPage }}"><span class="fa fa-step-backward"></span></a>
<a href="{{ urls.format('SETTING_PAGE', ['friends', 'requests', page.currentPage]) }}"><span class="fa fa-step-backward"></span></a>
{% endif %}
{% for id,npage in friends %}
<a href="/settings/friends/requests/p{{ id + 1 }}"{% if id == page.currentPage %} class="current"{% endif %}>{{ id + 1 }}</a>
<a href="{{ urls.format('SETTING_PAGE', ['friends', 'requests', id + 1]) }}"{% if id == page.currentPage %} class="current"{% endif %}>{{ id + 1 }}</a>
{% endfor %}
{% if page.currentPage + 1 < friends|length %}
<a href="/settings/friends/requests/p{{ page.currentPage + 2 }}"><span class="fa fa-step-forward"></span></a>
<a href="{{ urls.format('SETTING_PAGE', ['friends', 'requests', page.currentPage + 2]) }}"><span class="fa fa-step-forward"></span></a>
{% endif %}
</div>
<div class="clear"></div>

View file

@ -2,35 +2,35 @@
<h1 class="stylised">Common Tasks</h1>
<h2>Profile</h2>
<ul>
<li><a href="/settings/appearance/avatar" class="default">Change Avatar</a></li>
<li><a href="/settings/appearance/userpage" class="default">Change Userpage</a></li>
<li><a href="/settings/appearance/signature" class="default">Change Signature</a></li>
<li><a href="/settings/general/profile" class="default">Change Profile Details</a></li>
<li><a href="{{ urls.format('SETTING_MODE', ['appearance', 'avatar']) }}" class="default">Change Avatar</a></li>
<li><a href="{{ urls.format('SETTING_MODE', ['appearance', 'userpage']) }}" class="default">Change Userpage</a></li>
<li><a href="{{ urls.format('SETTING_MODE', ['appearance', 'signature']) }}" class="default">Change Signature</a></li>
<li><a href="{{ urls.format('SETTING_MODE', ['general', 'profile']) }}" class="default">Change Profile Details</a></li>
</ul>
<h2>Messaging</h2>
<ul>
<li><a href="/messages/inbox" class="default">View Inbox</a></li>
<li><a href="/messages/compose" class="default">Send PM</a></li>
<li><a href="{{ urls.format('SETTING_MODE', ['messages', 'inbox']) }}" class="default">View Inbox</a></li>
<li><a href="{{ urls.format('SETTING_MODE', ['messages', 'compose']) }}" class="default">Send PM</a></li>
</ul>
<h2>Account</h2>
<ul>
<li><a href="/settings/advanced/sessions" class="default">Manage Active Sessions</a></li>
<li><a href="/settings/account/password" class="default">Change Password</a></li>
<li><a href="{{ urls.format('SETTING_MODE', ['advanced', 'sessions']) }}" class="default">Manage Active Sessions</a></li>
<li><a href="{{ urls.format('SETTING_MODE', ['account', 'password']) }}" class="default">Change Password</a></li>
</ul>
<br />
<h1 class="stylised">Personal Statistics</h1>
<ul>
<li>You joined on <b>{{ user.data.regdate|date(sakura.dateFormat) }}</b>.</li>
<li>You joined on <b>{{ user.data.user_registered|date(sakura.dateFormat) }}</b>.</li>
<li>You have made <b>{{ user.forumStats.posts }} forum post{% if user.forumStats.posts != 1 %}s{% endif %}</b> and started <b>{{ user.forumStats.topics }} forum thread{% if user.forumStats.topics != 1 %}s{% endif %}</b>.</li>
<li>You have <b>x</b> warnings.</li>
<li>You have <b>{{ settings.friends|length - (settings.friends.online ? 1 : 0) - (settings.friends.offline ? 1 : 0) }} friend{% if settings.friends|length - (settings.friends.online ? 1 : 0) - (settings.friends.offline ? 1 : 0) != 1 %}s{% endif %}</b>.</li>
<li>You have <b>{{ user.getFriends|length }} friend{% if user.getFriends|length != 1 %}s{% endif %}</b>.</li>
</ul>
<br />
<h1 class="stylised"><a class="clean" href="/settings/friends/listing">Friends</a></h1>
<h1 class="stylised"><a class="clean" href="{{ urls.format('SETTING_MODE', ['friends', 'listing']) }}">Friends</a></h1>
<h2 style="color: #080;">Online</h2>
{% if user.getFriends(true, true, true).online %}
{% for key,friend in user.getFriends(true, true, true).online %}
<a href="/u/{{ friend.user.username }}" class="default" style="color: {% if friend.user.name_colour %}{{ friend.user.name_colour }}{% else %}{{ friend.rank.colour }}{% endif %}">{{ friend.user.username }}</a>{% if key + 1 != user.getFriends(true, true, true).online|length %},{% endif %}
<a href="/u/{{ friend.user.user_id }}" class="default" style="color: {% if friend.user.user_colour %}{{ friend.user.user_colour }}{% else %}{{ friend.rank.rank_colour }}{% endif %}">{{ friend.user.username }}</a>{% if key + 1 != user.getFriends(true, true, true).online|length %},{% endif %}
{% endfor %}
{% else %}
<h4>No friends are online.</h4>
@ -38,7 +38,7 @@
<h2 style="color: #800;">Offline</h2>
{% if user.getFriends(true, true, true).offline %}
{% for key,friend in user.getFriends(true, true, true).offline %}
<a href="/u/{{ friend.user.username }}" class="default" style="color: {% if friend.user.name_colour %}{{ friend.user.name_colour }}{% else %}{{ friend.rank.colour }}{% endif %}">{{ friend.user.username }}</a>{% if key + 1 != user.getFriends(true, true, true).offline|length %},{% endif %}
<a href="/u/{{ friend.user.user_id }}" class="default" style="color: {% if friend.user.user_colour %}{{ friend.user.user_colour }}{% else %}{{ friend.rank.rank_colour }}{% endif %}">{{ friend.user.username }}</a>{% if key + 1 != user.getFriends(true, true, true).offline|length %},{% endif %}
{% endfor %}
{% else %}
<h4>No friends are offline.</h4>

View file

@ -6,13 +6,13 @@
{% for field in options.fields %}
<div class="profile-field">
<div>
<h2>{{ field.name }}</h2>
<h2>{{ field.option_name }}</h2>
<div style="font-size: .8em; line-height: 110%;">
{{ field.description }}
{{ field.option_description }}
</div>
</div>
<div style="padding: 8px 0;">
<input type="{{ field.formtype }}" name="option_{{ field.id }}" class="inputStyling"{% if user.data.userData.userOptions[field.id] %}{% if field.formtype == 'checkbox' and user.data.userData.userOptions[field.id] %} checked="checked" value="option_{{ field.id }}"{% else %} value="{{ user.data.userData.userOptions[field.id] }}"{% endif %}{% endif %} />
<input type="{{ field.option_type }}" name="option_{{ field.option_id }}" class="inputStyling"{% if user.data.user_data.userOptions[field.option_id] %}{% if field.option_type == 'checkbox' and user.data.user_data.userOptions[field.option_id] %} checked="checked" value="option_{{ field.option_id }}"{% else %} value="{{ user.data.user_data.userOptions[field.option_id] }}"{% endif %}{% endif %} />
</div>
</div>
{% endfor %}

View file

@ -1,4 +1,4 @@
{% set birthday = user.data.birthday|split('-') %}
{% set birthday = user.data.user_birthday|split('-') %}
<form enctype="multipart/form-data" method="post" action="{{ sakura.currentPage }}" id="editProfileForm">
<input type="hidden" name="sessid" value="{{ php.sessionid }}" />
@ -7,15 +7,15 @@
{% for field in profile.fields %}
<div class="profile-field">
<div>
<h2>{{ field.name }}</h2>
<h2>{{ field.field_name }}</h2>
</div>
<div>
<input type="{{ field.formtype }}" name="profile_{{ field.ident }}" class="inputStyling" placeholder="{{ field.description }}"{% if user.profileFields[field.ident].value %}{% if field.formtype == 'checkbox' and user.profileFields[field.ident].value == 'true' %} checked="checked" value="profile_{{ field.ident }}"{% else %} value="{{ user.profileFields[field.ident].value }}"{% endif %}{% endif %} />
<input type="{{ field.field_type }}" name="profile_{{ field.field_identity }}" class="inputStyling" placeholder="{{ field.field_description }}"{% if user.profileFields[field.field_identity].value %}{% if field.field_type == 'checkbox' and user.profileFields[field.field_identity].value == 'true' %} checked="checked" value="profile_{{ field.field_identity }}"{% else %} value="{{ user.profileFields[field.field_identity].value }}"{% endif %}{% endif %} />
</div>
{% if field.addit %}
{% for id,addit in field.addit %}
{% if field.field_additional %}
{% for id,addit in field.field_additional %}
<div>
<input type="{{ addit[0] }}" id="{{ id }}" name="profile_additional_{{ id }}"{% if user.profileFields[field.ident][id] %}{% if addit[0] == 'checkbox' and user.profileFields[field.ident][id] == true %} checked="checked"{% else %} value="{{ user.profileFields[field.ident][id] }}"{% endif %}{% endif %} />
<input type="{{ addit[0] }}" id="{{ id }}" name="profile_additional_{{ id }}"{% if user.profileFields[field.field_identity][id] %}{% if addit[0] == 'checkbox' and user.profileFields[field.field_identity][id] == true %} checked="checked"{% else %} value="{{ user.profileFields[field.field_identity][id] }}"{% endif %}{% endif %} />
<label for="{{ id }}" style="font-size: 10px;">{{ addit[1]|raw }}</label>
</div>
{% endfor %}

View file

@ -10,7 +10,7 @@
<tbody>
{% for message in messages %}
<tr>
<td><a href="/u/{{ message.data.from.user.id }}" class="default" style="font-weight: 700; color: {% if message.data.from.user.name_colour == null %}{{ message.data.from.rank.colour }}{% else %}{{ message.data.from.user.name_colour }}{% endif %};">{{ message.data.from.user.username }}</a></td>
<td><a href="/u/{{ message.data.from.user.user_id }}" class="default" style="font-weight: 700; color: {% if message.data.from.user.user_colour == null %}{{ message.data.from.rank.rank_colour }}{% else %}{{ message.data.from.user.user_colour }}{% endif %};">{{ message.data.from.user.username }}</a></td>
<td><a href="/messages/read/{{ message.id }}" class="default">{{ message.subject }}</a></td>
<td>{{ message.time|date(sakura.dateFormat) }}</td>
</tr>

View file

@ -1,42 +1,42 @@
{% if notifs %}
{% if alerts %}
<div class="notification-history">
{% for notif in notifs[page.currentPage] %}
<a id="notif-hist-{{ notif.id }}" class="clean {% if notif.notif_read %}read{% endif %}"{% if notif.notif_link %} href="{{ notif.notif_link }}"{% endif %}>
{% for alert in alerts[page.currentPage] %}
<a id="notif-hist-{{ alert.id }}" class="clean {% if alert.alert_read %}read{% endif %}"{% if alert.alert_link %} href="{{ alert.alert_link }}"{% endif %}>
<div class="notif-hist-icon">
{% if 'FONT:' in notif.notif_img %}
<div class="font-icon fa {{ notif.notif_img|replace({'FONT:': ''}) }} fa-4x"></div>
{% if 'FONT:' in alert.alert_img %}
<div class="font-icon fa {{ alert.alert_img|replace({'FONT:': ''}) }} fa-4x"></div>
{% else %}
<img src="{{ notif.notif_img }}" alt="Notification" />
<img src="{{ alert.alert_img }}" alt="Notification" />
{% endif %}
</div>
<div class="notif-hist-content">
<div class="notif-hist-inside">
<div class="notif-hist-title">
{{ notif.notif_title }}
{{ alert.alert_title }}
</div>
<div class="notif-hist-text">
{{ notif.notif_text }}
{{ alert.alert_text }}
</div>
</div>
<div class="notif-hist-time">
{{ notif.timestamp|date(sakura.dateFormat) }}
{{ alert.alert_timestamp|date(sakura.dateFormat) }}
</div>
</div>
<div class="clear"></div>
</a>
{% endfor %}
</div>
{% if notifs|length > 1 %}
{% if alerts|length > 1 %}
<div>
<div class="pagination" style="float: right;">
{% if page.currentPage > 0 %}
<a href="/settings/notifications/history/p{{ page.currentPage }}"><span class="fa fa-step-backward"></span></a>
<a href="{{ urls.format('SETTING_PAGE', ['notifications', 'history', page.currentPage]) }}"><span class="fa fa-step-backward"></span></a>
{% endif %}
{% for id,npage in notifs %}
<a href="/settings/notifications/history/p{{ id + 1 }}"{% if id == page.currentPage %} class="current"{% endif %}>{{ id + 1 }}</a>
{% for id,npage in alerts %}
<a href="{{ urls.format('SETTING_PAGE', ['notifications', 'history', id + 1]) }}"{% if id == page.currentPage %} class="current"{% endif %}>{{ id + 1 }}</a>
{% endfor %}
{% if page.currentPage + 1 < notifs|length %}
<a href="/settings/notifications/history/p{{ page.currentPage + 2 }}"><span class="fa fa-step-forward"></span></a>
{% if page.currentPage + 1 < alerts|length %}
<a href="{{ urls.format('SETTING_PAGE', ['notifications', 'history', page.currentPage + 2]) }}"><span class="fa fa-step-forward"></span></a>
{% endif %}
</div>
<div class="clear"></div>

View file

@ -5,8 +5,9 @@ SET time_zone = '+00:00';
SET foreign_key_checks = 0;
SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO';
TRUNCATE `sakura_bbcodes`;
INSERT INTO `sakura_bbcodes` (`id`, `regex`, `replace`, `title`, `description`, `on_posting`) VALUES
USE `sakura-development`;
INSERT INTO `sakura_bbcodes` (`bbcode_id`, `bbcode_regex`, `bbcode_replace`, `bbcode_title`, `bbcode_description`, `bbcode_display`) VALUES
(1, '/\\[b\\](.*?)\\[\\/b\\]/is', '<b>$1</b>', 'Bold', 'Make text bold. Usage: [b]text[/b].', 1),
(2, '/\\[i\\](.*?)\\[\\/i\\]/is', '<i>$1</i>', 'Italics', 'Make text italic. Usage: [i]text[/i].', 1),
(3, '/\\[u\\](.*?)\\[\\/u\\]/is', '<u>$1</u>', 'Underline', 'Make text underlined. Usage: [u]text[/u].', 1),
@ -15,43 +16,43 @@ INSERT INTO `sakura_bbcodes` (`id`, `regex`, `replace`, `title`, `description`,
(6, '/\\[url=([a-zA-Z0-9\\.\\$\\-\\_\\.\\+\\*\\!\\\'\\(\\)\\/\\:\\#]+)\\](.*?)\\[\\/url\\]/is', '<a href=\"$1\" target=\"_blank\">$2</a>', 'Link', 'Embed a URL. Usage: [url=http://google.com]Link to google![/url]', 0),
(7, '/\\[url\\]([a-zA-Z0-9\\.\\$\\-\\_\\.\\+\\*\\!\\\'\\(\\)\\/\\:\\#]+)\\[\\/url\\]/is', '<a href=\"$1\" target=\"_blank\">$1</a>', 'Link', 'Make a link clickable (if the automatic algorithm doesn\'t do it already). Usage: [url]http://google.com[/url]', 1),
(8, '/\\[quote\\=\\\"(.+)\\\"\\](.+)\\[\\/quote]/is', '<div class=\"quote\"><div class=\"quotee\">$1 wrote:</div><div class=\"text\">$2</div></div>', 'Quote', 'Quote a user\'s post. Usage: [quote=Flashwave]nookls is pretty[/quote]', 0),
(9, '/\\[quote\\](.+)\\[\\/quote]/is', '<div class=\"quote\"><div class=\"quotee\">Quote:</div><div class=\"text\">$1</div></div>', 'Quote', 'Quote a user\'s post. Usage: [quote]nookls is pretty[/quote]', 1);
(9, '/\\[quote\\](.+)\\[\\/quote]/is', '<div class=\"quote\"><div class=\"quotee\">Quote:</div><div class=\"text\">$1</div></div>', 'Quote', 'Quote a user\'s post. Usage: [quote]nookls is pretty[/quote]', 1)
ON DUPLICATE KEY UPDATE `bbcode_id` = VALUES(`bbcode_id`), `bbcode_regex` = VALUES(`bbcode_regex`), `bbcode_replace` = VALUES(`bbcode_replace`), `bbcode_title` = VALUES(`bbcode_title`), `bbcode_description` = VALUES(`bbcode_description`), `bbcode_display` = VALUES(`bbcode_display`);
TRUNCATE `sakura_config`;
INSERT INTO `sakura_config` (`config_name`, `config_value`) VALUES
('recaptcha_public', ''),
('recaptcha_private', ''),
('charset', 'utf-8'),
('cookie_prefix', 'fii_'),
('cookie_domain', 'flashii.test'),
('cookie_prefix', 'sakura_'),
('cookie_domain', 'sakura.dev'),
('cookie_path', '/'),
('site_style', 'yuuno'),
('manage_style', 'broomcloset'),
('smtp_server', ''),
('smtp_auth', '1'),
('smtp_secure', 'tls'),
('smtp_auth', '0'),
('smtp_secure', ''),
('smtp_port', ''),
('smtp_username', ''),
('smtp_password', ''),
('smtp_replyto_mail', ''),
('smtp_replyto_name', 'Flashwave'),
('smtp_replyto_name', ''),
('smtp_from_email', ''),
('smtp_from_name', 'Flashii Noreply'),
('sitename', 'Cutting Edgii'),
('smtp_from_name', ''),
('sitename', 'Sakura'),
('recaptcha', '0'),
('require_activation', '0'),
('require_registration_code', '0'),
('disable_registration', '0'),
('max_reg_keys', '5'),
('mail_signature', 'Team Flashii'),
('mail_signature', ''),
('lock_authentication', '0'),
('min_entropy', '1'),
('sitedesc', 'Live development environment for the script that powers Flashii.net called Sakura.'),
('sitetags', '[\"Flashii\",\"Media\",\"Flashwave\",\"Circle\",\"Zeniea\",\"MalwareUp\",\"Cybernetics\",\"Saibateku\",\"Community\",\"osu!\",\"osu\"]'),
('sitedesc', 'The script that powers Flashii.'),
('sitetags', ''),
('username_min_length', '3'),
('username_max_length', '16'),
('site_closed', '0'),
('site_closed_reason', 'meow'),
('site_closed_reason', ''),
('use_gzip', '0'),
('enable_tpl_cache', '0'),
('paypal_client_id', ''),
@ -60,7 +61,7 @@ INSERT INTO `sakura_config` (`config_name`, `config_value`) VALUES
('premium_rank_id', '8'),
('premium_amount_max', '24'),
('alumni_rank_id', '9'),
('url_main', 'flashii.test'),
('url_main', 'sakura.dev'),
('front_page_news_posts', '3'),
('date_format', 'D Y-m-d H:i:s T'),
('news_posts_per_page', '3'),
@ -69,7 +70,7 @@ INSERT INTO `sakura_config` (`config_name`, `config_value`) VALUES
('avatar_max_height', '512'),
('avatar_max_width', '512'),
('avatar_max_fsize', '2097152'),
('url_api', 'api.flashii.test'),
('url_api', 'api.sakura.dev'),
('content_path', '/content'),
('user_uploads', 'uploads'),
('no_background_img', 'public/content/pixel.png'),
@ -87,14 +88,17 @@ INSERT INTO `sakura_config` (`config_name`, `config_value`) VALUES
('session_check', '4'),
('url_rewrite', '1'),
('members_per_page', '30'),
('admin_email', 'me@flash.moe'),
('admin_email', 'admin@sakura.dev'),
('site_news_category', 'site-news'),
('no_cron_service', '1'),
('no_cron_interval', '30'),
('no_cron_last', '1443040870'),
('old_username_reserve', '90');
('no_cron_last', '1444511632'),
('old_username_reserve', '90'),
('comment_max_length', '500'),
('comment_min_length', '1'),
('sitelogo', '')
ON DUPLICATE KEY UPDATE `config_name` = VALUES(`config_name`), `config_value` = VALUES(`config_value`);
TRUNCATE `sakura_emoticons`;
INSERT INTO `sakura_emoticons` (`emote_string`, `emote_path`) VALUES
(':amu:', '/content/images/emoticons/amu.png'),
(':angrier:', '/content/images/emoticons/angrier.png'),
@ -133,52 +137,30 @@ INSERT INTO `sakura_emoticons` (`emote_string`, `emote_path`) VALUES
(':wtf:', '/content/images/emoticons/wtf.gif'),
(':sleep:', '/content/images/emoticons/zzz.gif'),
(':what:', '/content/images/emoticons/what.png'),
(':smug:', '/content/images/emoticons/smug.png');
(':smug:', '/content/images/emoticons/smug.png')
ON DUPLICATE KEY UPDATE `emote_string` = VALUES(`emote_string`), `emote_path` = VALUES(`emote_path`);
TRUNCATE `sakura_forums`;
INSERT INTO `sakura_forums` (`forum_id`, `forum_name`, `forum_desc`, `forum_link`, `forum_category`, `forum_type`, `forum_icon`) VALUES
(1, 'General', 'General category', '', 0, 1, ''),
(2, 'Introductions', 'Help us get to know you better!', '', 1, 0, 'fa-smile-o'),
(3, 'General Discussion', 'Civilised discussions about things that don\'t have their own subforum.', '', 1, 0, 'fa-comments'),
(4, 'BUG SPORTS', 'Post all new BUG SPORTS tutorials here (this is the off topic forum for those who couldn\'t guess).', '', 1, 0, 'fa-bug'),
(5, 'Programming', 'Programming discussion', '', 0, 1, ''),
(6, 'Web Development', 'Talk about the PHPython on Rails.js.', '', 5, 0, 'fa-html5'),
(7, 'General Programming', 'Mostly desktop stuff here.', '', 5, 0, 'fa-code'),
(8, 'Media', 'Media discussion', '', 0, 1, ''),
(9, 'Anime & Manga', 'Your waifu is shit.', '', 8, 0, 'fa-yen'),
(10, 'Video Games', 'Sakura Clicker is the best game ever and you know it.', '', 8, 0, 'fa-gamepad'),
(11, 'osu!', 'Talk about clicking circles like an insane person.', '', 10, 0, 'fa-dot-circle-o'),
(12, 'Feedback', 'Site Feedback', '', 0, 1, ''),
(13, 'Staff', 'Tell us how to do our jobs.', '', 12, 0, 'fa-balance-scale'),
(14, 'Sakura', 'Report bugs or give us feature suggestions about the script Flashii runs on here.', '', 12, 0, 'fa-heartbeat'),
(15, 'Staff', 'Staff discussion', '', 0, 1, ''),
(16, 'Slack', 'A direct link to Slack.', 'https://circlestorm.slack.com/', 15, 2, 'fa-slack'),
(17, 'Office 365', 'A direct link to Office 365.', 'https://login.microsoftonline.com/', 15, 2, 'fa-envelope-o'),
(18, 'General Discussion', 'Discuss Staff Stuff.', '', 15, 0, 'fa-user-secret'),
(19, 'Retarded Palace', 'This is where deleted threads rot.', '', 15, 0, 'fa-trash-o');
TRUNCATE `sakura_optionfields`;
INSERT INTO `sakura_optionfields` (`id`, `name`, `description`, `formtype`, `require_perm`) VALUES
INSERT INTO `sakura_optionfields` (`option_id`, `option_name`, `option_description`, `option_type`, `option_permission`) VALUES
('disableProfileParallax', 'Disable Parallaxing', 'This will stop your background from responding to your mouse movement, this will only affect your background.', 'checkbox', 'CHANGE_BACKGROUND'),
('profileBackgroundSiteWide', 'Display profile background site wide', 'This will make the profile background you set on your profile appear on the entire site (except on other profiles).', 'checkbox', 'CREATE_BACKGROUND'),
('useMisaki', 'Use the testing style', 'This will make the site use the new Misaki style instead of Yuuno.', 'checkbox', 'ALTER_PROFILE');
('useMisaki', 'Use the testing style', 'This will make the site use the new Misaki style instead of Yuuno.', 'checkbox', 'ALTER_PROFILE')
ON DUPLICATE KEY UPDATE `option_id` = VALUES(`option_id`), `option_name` = VALUES(`option_name`), `option_description` = VALUES(`option_description`), `option_type` = VALUES(`option_type`), `option_permission` = VALUES(`option_permission`);
TRUNCATE `sakura_permissions`;
INSERT INTO `sakura_permissions` (`rid`, `uid`, `siteperms`, `manageperms`, `forumperms`, `rankinherit`) VALUES
(1, 0, '0000000000000000000000000001', '00', '0', '000'),
(2, 0, '0000111111111100111101101100', '00', '1', '000'),
(3, 0, '0001111111111111111111111100', '11', '1', '000'),
(4, 0, '1111111111111111111111111100', '11', '1', '000'),
(5, 0, '0001111111111111111111111100', '11', '1', '000'),
(6, 0, '0000111111111100111101101100', '00', '0', '000'),
(7, 0, '0001111111111111111111111100', '01', '1', '000'),
(8, 0, '0001111111111111111111111100', '00', '1', '000'),
(9, 0, '0001111111111111111111111100', '00', '1', '000'),
(10, 0, '0000000011010100101000100010', '00', '0', '000'),
(11, 0, '0000111111111100111101101100', '00', '1', '000');
INSERT INTO `sakura_permissions` (`rank_id`, `user_id`, `permissions_site`, `permissions_manage`, `permissions_forums`, `permissions_inherit`) VALUES
(1, 0, '00000000000000000000000000000001', '00', '0', '000'),
(2, 0, '11110000111111111100111101101100', '00', '1', '000'),
(3, 0, '11110001111111111111111111111100', '11', '1', '000'),
(4, 0, '11111111111111111111111111111100', '11', '1', '000'),
(5, 0, '11110001111111111111111111111100', '11', '1', '000'),
(6, 0, '11110000111111111100111101101100', '00', '0', '000'),
(7, 0, '11110001111111111111111111111100', '01', '1', '000'),
(8, 0, '11110001111111111111111111111100', '00', '1', '000'),
(9, 0, '11110001111111111111111111111100', '00', '1', '000'),
(10, 0, '11110000000011010100101000100010', '00', '0', '000'),
(11, 0, '11110000111111111100111101101100', '00', '1', '000')
ON DUPLICATE KEY UPDATE `rank_id` = VALUES(`rank_id`), `user_id` = VALUES(`user_id`), `permissions_site` = VALUES(`permissions_site`), `permissions_manage` = VALUES(`permissions_manage`), `permissions_forums` = VALUES(`permissions_forums`), `permissions_inherit` = VALUES(`permissions_inherit`);
TRUNCATE `sakura_profilefields`;
INSERT INTO `sakura_profilefields` (`id`, `name`, `formtype`, `islink`, `linkformat`, `description`, `additional`) VALUES
INSERT INTO `sakura_profilefields` (`field_id`, `field_name`, `field_type`, `field_link`, `field_linkformat`, `field_description`, `field_additional`) VALUES
(1, 'Website', 'url', 1, '{{ VAL }}', 'URL to your website', ''),
(2, 'Twitter', 'text', 1, 'https://twitter.com/{{ VAL }}', 'Your @twitter Username', ''),
(3, 'BitBucket', 'text', 1, 'https://bitbucket.org/{{ VAL }}', 'Your BitBucket Username', ''),
@ -190,20 +172,21 @@ INSERT INTO `sakura_profilefields` (`id`, `name`, `formtype`, `islink`, `linkfor
(9, 'Origin', 'text', 0, '', 'Your Origin User ID', ''),
(10, 'Xbox Live', 'text', 1, 'https://account.xbox.com/en-GB/Profile?Gamertag={{ VAL }}', 'Your Xbox User ID', ''),
(11, 'PSN', 'text', 1, 'http://psnprofiles.com/{{ VAL }}', 'Your PSN User ID', ''),
(12, 'Last.fm', 'text', 1, 'http://last.fm/user/{{ VAL }}', 'Your Last.fm username', '');
(12, 'Last.fm', 'text', 1, 'http://last.fm/user/{{ VAL }}', 'Your Last.fm username', '')
ON DUPLICATE KEY UPDATE `field_id` = VALUES(`field_id`), `field_name` = VALUES(`field_name`), `field_type` = VALUES(`field_type`), `field_link` = VALUES(`field_link`), `field_linkformat` = VALUES(`field_linkformat`), `field_description` = VALUES(`field_description`), `field_additional` = VALUES(`field_additional`);
TRUNCATE `sakura_ranks`;
INSERT INTO `sakura_ranks` (`id`, `name`, `multi`, `hidden`, `colour`, `description`, `title`) VALUES
(1, 'Deactivated', 0, 1, '#555', 'Users that are yet to be activated or that deactivated their own account.', 'Deactivated'),
(2, 'Regular user', 1, 0, 'inherit', 'Regular users with regular permissions.', 'Regular user'),
(3, 'Site moderator', 1, 0, '#0A0', 'Users with special permissions like being able to ban and modify users if needed.', 'Staff'),
(4, 'Administrator', 1, 0, '#C00', 'Users that manage the server and everything around that.', 'Administrator'),
(5, 'Developer', 1, 0, '#824CA0', 'Users that either create or test new features of the site.', 'Staff'),
(6, 'Bot', 1, 1, '#9E8DA7', 'Reserved user accounts for services.', 'Bot'),
(7, 'Chat moderator', 1, 0, '#09F', 'Moderators of the chat room.', 'Staff'),
(8, 'Tenshi', 0, 0, '#EE9400', 'Users that bought premium to help us keep the site and its services alive!', 'Tenshi'),
(9, 'Alumnii', 0, 0, '#FF69B4', 'People who have contributed to the community but have moved on or resigned.', 'Alumnii'),
(10, 'Restricted', 0, 1, '#333', 'Users that are restricted.', 'Restricted'),
(11, 'Early Supporter', 1, 0, '#0049EE', 'User that donated before the premium system.', 'Early Supporter');
INSERT INTO `sakura_ranks` (`rank_id`, `rank_hierarchy`, `rank_name`, `rank_multiple`, `rank_hidden`, `rank_colour`, `rank_description`, `rank_title`) VALUES
(1, 0, 'Deactivated', '', 1, '#555', 'Users that are yet to be activated or that deactivated their own account.', 'Deactivated'),
(2, 1, 'Regular user', 's', 0, 'inherit', 'Regular users with regular permissions.', 'Regular user'),
(3, 3, 'Site moderator', 's', 0, '#0A0', 'Users with special permissions like being able to ban and modify users if needed.', 'Staff'),
(4, 4, 'Administrator', 's', 0, '#C00', 'Users that manage the server and everything around that.', 'Administrator'),
(5, 3, 'Developer', 's', 0, '#824CA0', 'Users that either create or test new features of the site.', 'Staff'),
(6, 1, 'Bot', 's', 1, '#9E8DA7', 'Reserved user accounts for services.', 'Bot'),
(7, 2, 'Chat moderator', 's', 0, '#09F', 'Moderators of the chat room.', 'Staff'),
(8, 1, 'Tenshi', '', 0, '#EE9400', 'Users that bought premium to help us keep the site and its services alive!', 'Tenshi'),
(9, 1, 'Alumnii', '', 0, '#FF69B4', 'People who have contributed to the community but have moved on or resigned.', 'Alumnii'),
(10, 0, 'Restricted', 's', 1, '#333', 'Users that are restricted.', 'Restricted'),
(11, 1, 'Early Supporter', 's', 0, '#0049EE', 'User that donated before the premium system.', 'Early Supporter')
ON DUPLICATE KEY UPDATE `rank_id` = VALUES(`rank_id`), `rank_hierarchy` = VALUES(`rank_hierarchy`), `rank_name` = VALUES(`rank_name`), `rank_multiple` = VALUES(`rank_multiple`), `rank_hidden` = VALUES(`rank_hidden`), `rank_colour` = VALUES(`rank_colour`), `rank_description` = VALUES(`rank_description`), `rank_title` = VALUES(`rank_title`);
-- 2015-09-23 20:43:17
-- 2015-10-10 21:15:55

View file

@ -3,8 +3,6 @@
SET NAMES utf8;
SET time_zone = '+00:00';
DROP DATABASE IF EXISTS `sakura-development`;
CREATE DATABASE `sakura-development` /*!40100 DEFAULT CHARACTER SET utf8 COLLATE utf8_bin */;
USE `sakura-development`;
DROP TABLE IF EXISTS `sakura_actioncodes`;
@ -29,29 +27,29 @@ CREATE TABLE `sakura_apikeys` (
DROP TABLE IF EXISTS `sakura_bans`;
CREATE TABLE `sakura_bans` (
`id` bigint(255) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Automatically generated ID by MySQL for management.',
`uid` bigint(255) unsigned NOT NULL COMMENT 'ID of user that was banned, 0 for just an IP ban.',
`ban_id` bigint(255) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Automatically generated ID by MySQL for management.',
`user_id` bigint(255) unsigned NOT NULL COMMENT 'ID of user that was banned, 0 for just an IP ban.',
`ban_begin` int(11) unsigned NOT NULL COMMENT 'Timestamp when the user was banned.',
`ban_end` int(11) unsigned NOT NULL COMMENT 'Timestamp when the user should regain access to the site.',
`ban_reason` varchar(512) COLLATE utf8_bin DEFAULT NULL COMMENT 'Reason given for the ban.',
`mod_id` bigint(255) unsigned NOT NULL COMMENT 'ID of moderator that banned this user,',
PRIMARY KEY (`id`),
KEY `uid` (`uid`),
KEY `mod_id` (`mod_id`),
CONSTRAINT `sakura_bans_ibfk_1` FOREIGN KEY (`uid`) REFERENCES `sakura_users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `sakura_bans_ibfk_2` FOREIGN KEY (`mod_id`) REFERENCES `sakura_users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
`ban_moderator` bigint(255) unsigned NOT NULL COMMENT 'ID of moderator that banned this user,',
PRIMARY KEY (`ban_id`),
KEY `uid` (`user_id`),
KEY `mod_id` (`ban_moderator`),
CONSTRAINT `sakura_bans_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `sakura_users` (`user_id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `sakura_bans_ibfk_2` FOREIGN KEY (`ban_moderator`) REFERENCES `sakura_users` (`user_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
DROP TABLE IF EXISTS `sakura_bbcodes`;
CREATE TABLE `sakura_bbcodes` (
`id` int(64) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Automatically generated ID by MySQL for management.',
`regex` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Regular expression string for the BBCode.',
`replace` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'What to replace it with.',
`title` varchar(128) COLLATE utf8_bin NOT NULL COMMENT 'Button title for this bbcode.',
`description` varchar(512) COLLATE utf8_bin NOT NULL COMMENT 'Description of what this does.',
`on_posting` tinyint(1) unsigned NOT NULL COMMENT 'Set if this bbcode is displayed on the posting page.',
PRIMARY KEY (`id`)
`bbcode_id` int(64) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Automatically generated ID by MySQL for management.',
`bbcode_regex` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Regular expression string for the BBCode.',
`bbcode_replace` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'What to replace it with.',
`bbcode_title` varchar(128) COLLATE utf8_bin NOT NULL COMMENT 'Button title for this bbcode.',
`bbcode_description` varchar(512) COLLATE utf8_bin NOT NULL COMMENT 'Description of what this does.',
`bbcode_display` tinyint(1) unsigned NOT NULL COMMENT 'Set if this bbcode is displayed on the posting page.',
PRIMARY KEY (`bbcode_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
@ -61,14 +59,20 @@ CREATE TABLE `sakura_comments` (
`comment_category` varchar(32) COLLATE utf8_bin NOT NULL COMMENT 'Comment category.',
`comment_timestamp` int(11) unsigned NOT NULL COMMENT 'Timestamp of when this comment was posted.',
`comment_poster` bigint(255) unsigned NOT NULL COMMENT 'User ID of the poster.',
`comment_likes` int(11) unsigned NOT NULL DEFAULT '0' COMMENT 'Upvotes of the comments.',
`comment_dislikes` int(11) unsigned NOT NULL DEFAULT '0' COMMENT 'Downvotes of the comments.',
`comment_reply_to` bigint(255) unsigned NOT NULL DEFAULT '0' COMMENT 'ID of the comment this comment is a reply to',
`comment_text` text COLLATE utf8_bin NOT NULL COMMENT 'Content of the comment.',
PRIMARY KEY (`comment_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
DROP TABLE IF EXISTS `sakura_comment_votes`;
CREATE TABLE `sakura_comment_votes` (
`vote_comment` bigint(255) unsigned NOT NULL COMMENT 'ID of the comment that was voted on.',
`vote_user` bigint(255) unsigned NOT NULL COMMENT 'ID of the voter.',
`vote_state` tinyint(1) unsigned NOT NULL COMMENT '0 = dislike, 1 = like.'
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
DROP TABLE IF EXISTS `sakura_config`;
CREATE TABLE `sakura_config` (
`config_name` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Array key for configuration value',
@ -85,24 +89,24 @@ CREATE TABLE `sakura_emoticons` (
DROP TABLE IF EXISTS `sakura_error_log`;
CREATE TABLE `sakura_error_log` (
`id` varchar(32) COLLATE utf8_bin NOT NULL COMMENT 'An ID that is created when an error occurs.',
`timestamp` varchar(128) COLLATE utf8_bin NOT NULL COMMENT 'A datestring from when the error occurred.',
`revision` int(16) unsigned NOT NULL COMMENT 'Sakura Revision number.',
`error_id` varchar(32) COLLATE utf8_bin NOT NULL COMMENT 'An ID that is created when an error occurs.',
`error_timestamp` varchar(128) COLLATE utf8_bin NOT NULL COMMENT 'A datestring from when the error occurred.',
`error_revision` int(16) unsigned NOT NULL COMMENT 'Sakura Revision number.',
`error_type` int(16) unsigned NOT NULL COMMENT 'The PHP error type of this error.',
`error_line` int(32) unsigned NOT NULL COMMENT 'The line that caused this error.',
`error_string` varchar(512) COLLATE utf8_bin NOT NULL COMMENT 'PHP''s description of this error.',
`error_file` varchar(512) COLLATE utf8_bin NOT NULL COMMENT 'The file in which this error occurred.',
`backtrace` text COLLATE utf8_bin NOT NULL COMMENT 'A full base64 and json encoded backtrace containing all environment data.'
`error_backtrace` text COLLATE utf8_bin NOT NULL COMMENT 'A full base64 and json encoded backtrace containing all environment data.'
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
DROP TABLE IF EXISTS `sakura_faq`;
CREATE TABLE `sakura_faq` (
`id` bigint(128) unsigned NOT NULL AUTO_INCREMENT COMMENT 'MySQL Generated ID used for sorting.',
`short` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Used for linking directly to a question.',
`question` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'The question.',
`answer` text COLLATE utf8_bin NOT NULL COMMENT 'The answer.',
PRIMARY KEY (`id`)
`faq_id` bigint(128) unsigned NOT NULL AUTO_INCREMENT COMMENT 'MySQL Generated ID used for sorting.',
`faq_shorthand` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Used for linking directly to a question.',
`faq_question` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'The question.',
`faq_answer` text COLLATE utf8_bin NOT NULL COMMENT 'The answer.',
PRIMARY KEY (`faq_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
@ -119,23 +123,32 @@ CREATE TABLE `sakura_forums` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
DROP TABLE IF EXISTS `sakura_forum_permissions`;
CREATE TABLE `sakura_forum_permissions` (
`forum_id` bigint(255) unsigned NOT NULL COMMENT 'Forum ID',
`rank_id` bigint(128) unsigned NOT NULL COMMENT 'Rank ID, leave 0 for a user',
`user_id` bigint(255) unsigned NOT NULL COMMENT 'User ID, leave 0 for a rank',
`forum_perms` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Forum action permission string'
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
DROP TABLE IF EXISTS `sakura_friends`;
CREATE TABLE `sakura_friends` (
`uid` bigint(255) unsigned NOT NULL COMMENT 'ID of the user that added the friend.',
`fid` bigint(255) unsigned NOT NULL COMMENT 'ID of the user that was added as a friend.',
`timestamp` int(11) unsigned NOT NULL COMMENT 'Timestamp of action.',
KEY `uid` (`uid`),
KEY `fid` (`fid`),
CONSTRAINT `sakura_friends_ibfk_1` FOREIGN KEY (`uid`) REFERENCES `sakura_users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `sakura_friends_ibfk_2` FOREIGN KEY (`fid`) REFERENCES `sakura_users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
`user_id` bigint(255) unsigned NOT NULL COMMENT 'ID of the user that added the friend.',
`friend_id` bigint(255) unsigned NOT NULL COMMENT 'ID of the user that was added as a friend.',
`friend_timestamp` int(11) unsigned NOT NULL COMMENT 'Timestamp of action.',
KEY `uid` (`user_id`),
KEY `fid` (`friend_id`),
CONSTRAINT `sakura_friends_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `sakura_users` (`user_id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `sakura_friends_ibfk_2` FOREIGN KEY (`friend_id`) REFERENCES `sakura_users` (`user_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
DROP TABLE IF EXISTS `sakura_infopages`;
CREATE TABLE `sakura_infopages` (
`shorthand` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Name used for calling this page up in the /r/URL',
`pagetitle` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Title displayed on the top of the page',
`content` text COLLATE utf8_bin NOT NULL COMMENT 'Content of the page'
`page_shorthand` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Name used for calling this page up in the /r/URL',
`page_title` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Title displayed on the top of the page',
`page_content` text COLLATE utf8_bin NOT NULL COMMENT 'Content of the page'
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
@ -147,7 +160,7 @@ CREATE TABLE `sakura_logs` (
`attribs` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Optional attributes, vsprintf() style.',
PRIMARY KEY (`id`),
KEY `uid` (`uid`),
CONSTRAINT `sakura_logs_ibfk_1` FOREIGN KEY (`uid`) REFERENCES `sakura_users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
CONSTRAINT `sakura_logs_ibfk_1` FOREIGN KEY (`uid`) REFERENCES `sakura_users` (`user_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
@ -174,53 +187,53 @@ CREATE TABLE `sakura_messages` (
DROP TABLE IF EXISTS `sakura_news`;
CREATE TABLE `sakura_news` (
`id` bigint(255) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Automatically generated ID by MySQL for management.',
`category` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Category ID.',
`uid` bigint(255) unsigned NOT NULL COMMENT 'ID of user who posted this news message.',
`date` int(11) unsigned NOT NULL COMMENT 'News post timestamp.',
`title` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Title of the post.',
`content` text COLLATE utf8_bin NOT NULL COMMENT 'Contents of the post',
PRIMARY KEY (`id`)
`news_id` bigint(255) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Automatically generated ID by MySQL for management.',
`news_category` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Category ID.',
`user_id` bigint(255) unsigned NOT NULL COMMENT 'ID of user who posted this news message.',
`news_timestamp` int(11) unsigned NOT NULL COMMENT 'News post timestamp.',
`news_title` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Title of the post.',
`news_content` text COLLATE utf8_bin NOT NULL COMMENT 'Contents of the post',
PRIMARY KEY (`news_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
DROP TABLE IF EXISTS `sakura_notifications`;
CREATE TABLE `sakura_notifications` (
`id` bigint(255) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Automatically generated ID by MySQL for management.',
`uid` bigint(255) unsigned NOT NULL DEFAULT '0' COMMENT 'User ID this notification is intended for.',
`timestamp` int(11) unsigned NOT NULL DEFAULT '0' COMMENT 'Timestamp when this notification was created.',
`notif_read` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT 'Toggle for unread and read.',
`notif_sound` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT 'Toggle if a sound should be played upon receiving the notification.',
`notif_title` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Title displayed on the notification.',
`notif_text` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Text displayed.',
`notif_link` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT 'Link (empty for no link).',
`notif_img` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Image path, prefix with font: to use a font class instead of an image.',
`notif_timeout` int(16) unsigned NOT NULL DEFAULT '0' COMMENT 'How long the notification should stay on screen in milliseconds, 0 for forever.',
PRIMARY KEY (`id`),
KEY `uid` (`uid`),
CONSTRAINT `sakura_notifications_ibfk_1` FOREIGN KEY (`uid`) REFERENCES `sakura_users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
`alert_id` bigint(255) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Automatically generated ID by MySQL for management.',
`user_id` bigint(255) unsigned NOT NULL DEFAULT '0' COMMENT 'User ID this notification is intended for.',
`alert_timestamp` int(11) unsigned NOT NULL DEFAULT '0' COMMENT 'Timestamp when this notification was created.',
`alert_read` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT 'Toggle for unread and read.',
`alert_sound` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT 'Toggle if a sound should be played upon receiving the notification.',
`alert_title` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Title displayed on the notification.',
`alert_text` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Text displayed.',
`alert_link` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT 'Link (empty for no link).',
`alert_img` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Image path, prefix with font: to use a font class instead of an image.',
`alert_timeout` int(16) unsigned NOT NULL DEFAULT '0' COMMENT 'How long the notification should stay on screen in milliseconds, 0 for forever.',
PRIMARY KEY (`alert_id`),
KEY `uid` (`user_id`),
CONSTRAINT `sakura_notifications_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `sakura_users` (`user_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
DROP TABLE IF EXISTS `sakura_optionfields`;
CREATE TABLE `sakura_optionfields` (
`id` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Unique identifier for accessing this option.',
`name` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Description of the field in a proper way.',
`description` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Longer description of the option.',
`formtype` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Type attribute in the input element.',
`require_perm` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'The minimum permission level this option requires.',
UNIQUE KEY `id` (`id`)
`option_id` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Unique identifier for accessing this option.',
`option_name` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Description of the field in a proper way.',
`option_description` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Longer description of the option.',
`option_type` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Type attribute in the input element.',
`option_permission` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'The minimum permission level this option requires.',
UNIQUE KEY `id` (`option_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
DROP TABLE IF EXISTS `sakura_permissions`;
CREATE TABLE `sakura_permissions` (
`rid` bigint(128) unsigned NOT NULL DEFAULT '0' COMMENT 'ID of the rank this permissions set is used for.',
`uid` bigint(255) unsigned NOT NULL DEFAULT '0' COMMENT 'ID of the user this permissions set is used for.',
`siteperms` varchar(255) COLLATE utf8_bin NOT NULL DEFAULT '000000000000000000000000000' COMMENT 'Site permissions.',
`manageperms` varchar(255) COLLATE utf8_bin NOT NULL DEFAULT '0' COMMENT 'Site management permissions',
`forumperms` varchar(255) COLLATE utf8_bin NOT NULL DEFAULT '0' COMMENT 'Forum permissions.',
`rankinherit` varchar(4) COLLATE utf8_bin NOT NULL DEFAULT '000' COMMENT 'Rank inheritance, only used when user specific.'
`rank_id` bigint(255) unsigned NOT NULL DEFAULT '0' COMMENT 'ID of the rank this permissions set is used for.',
`user_id` bigint(255) unsigned NOT NULL DEFAULT '0' COMMENT 'ID of the user this permissions set is used for.',
`permissions_site` varchar(255) COLLATE utf8_bin NOT NULL DEFAULT '0' COMMENT 'Site permissions.',
`permissions_manage` varchar(255) COLLATE utf8_bin NOT NULL DEFAULT '0' COMMENT 'Site management permissions',
`permissions_forums` varchar(255) COLLATE utf8_bin NOT NULL DEFAULT '0' COMMENT 'Forum permissions.',
`permissions_inherit` varchar(4) COLLATE utf8_bin NOT NULL DEFAULT '0' COMMENT 'Rank inheritance, only used when user specific.'
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
@ -232,9 +245,9 @@ CREATE TABLE `sakura_posts` (
`poster_id` bigint(255) unsigned DEFAULT '0' COMMENT 'ID of poster of this post.',
`poster_ip` varchar(40) COLLATE utf8_bin NOT NULL COMMENT 'IP of poster.',
`post_time` int(11) unsigned NOT NULL DEFAULT '0' COMMENT 'Time this post was made.',
`parse_mode` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT 'Switch the type of parser that''s used.',
`enable_sig` tinyint(1) unsigned NOT NULL DEFAULT '1' COMMENT 'Toggle if signature should be shown.',
`enable_emotes` tinyint(1) unsigned NOT NULL DEFAULT '1' COMMENT 'Toggle if emoticons should be parsed.',
`post_parse` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT 'Switch the type of parser that''s used.',
`post_signature` tinyint(1) unsigned NOT NULL DEFAULT '1' COMMENT 'Toggle if signature should be shown.',
`post_emotes` tinyint(1) unsigned NOT NULL DEFAULT '1' COMMENT 'Toggle if emoticons should be parsed.',
`post_subject` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Subject of the post.',
`post_text` text COLLATE utf8_bin NOT NULL COMMENT 'Contents of the post.',
`post_edit_time` int(11) unsigned NOT NULL DEFAULT '0' COMMENT 'Time this post was last edited.',
@ -251,48 +264,49 @@ CREATE TABLE `sakura_posts` (
DROP TABLE IF EXISTS `sakura_premium`;
CREATE TABLE `sakura_premium` (
`uid` bigint(255) unsigned NOT NULL COMMENT 'ID of the user that purchased Tenshi.',
`startdate` int(11) unsigned NOT NULL COMMENT 'Timestamp of first purchase.',
`expiredate` int(11) unsigned NOT NULL COMMENT 'Expiration timestamp.',
UNIQUE KEY `uid` (`uid`),
CONSTRAINT `sakura_premium_ibfk_1` FOREIGN KEY (`uid`) REFERENCES `sakura_users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
`user_id` bigint(255) unsigned NOT NULL COMMENT 'ID of the user that purchased Tenshi.',
`premium_start` int(11) unsigned NOT NULL COMMENT 'Timestamp of first purchase.',
`premium_expire` int(11) unsigned NOT NULL COMMENT 'Expiration timestamp.',
UNIQUE KEY `uid` (`user_id`),
CONSTRAINT `sakura_premium_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `sakura_users` (`user_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
DROP TABLE IF EXISTS `sakura_premium_log`;
CREATE TABLE `sakura_premium_log` (
`id` int(16) unsigned NOT NULL AUTO_INCREMENT COMMENT 'MySQL Generated ID used for sorting.',
`uid` bigint(255) unsigned NOT NULL COMMENT 'User ID of purchaser',
`amount` float NOT NULL COMMENT 'Amount that was transferred.',
`date` int(11) unsigned NOT NULL COMMENT 'Date when the purchase was made.',
`comment` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'A short description of the action taken.',
PRIMARY KEY (`id`)
`transaction_id` int(16) unsigned NOT NULL AUTO_INCREMENT COMMENT 'MySQL Generated ID used for sorting.',
`user_id` bigint(255) unsigned NOT NULL COMMENT 'User ID of purchaser',
`transaction_amount` float NOT NULL COMMENT 'Amount that was transferred.',
`transaction_date` int(11) unsigned NOT NULL COMMENT 'Date when the purchase was made.',
`transaction_comment` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'A short description of the action taken.',
PRIMARY KEY (`transaction_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
DROP TABLE IF EXISTS `sakura_profilefields`;
CREATE TABLE `sakura_profilefields` (
`id` int(64) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID used for ordering on the userpage.',
`name` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Name of the field.',
`formtype` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Type attribute in the input element.',
`islink` tinyint(1) unsigned NOT NULL COMMENT 'Set if this value should be put in a href.',
`linkformat` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'If the form is a link how should it be formatted? {{ VAL }} gets replace with the value.',
`description` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Description of the field displayed in the control panel.',
`additional` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Undocumented JSON array containing special options if needed (probably only going to be used for the YouTube field).',
PRIMARY KEY (`id`)
`field_id` int(64) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID used for ordering on the userpage.',
`field_name` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Name of the field.',
`field_type` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Type attribute in the input element.',
`field_link` tinyint(1) unsigned NOT NULL COMMENT 'Set if this value should be put in a href.',
`field_linkformat` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'If the form is a link how should it be formatted? {{ VAL }} gets replace with the value.',
`field_description` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Description of the field displayed in the control panel.',
`field_additional` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Undocumented JSON array containing special options if needed (probably only going to be used for the YouTube field).',
PRIMARY KEY (`field_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
DROP TABLE IF EXISTS `sakura_ranks`;
CREATE TABLE `sakura_ranks` (
`id` bigint(128) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Automatically generated ID by MySQL for management.',
`name` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Display name of the rank.',
`multi` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT 'Can the rank name have an s at the end?',
`hidden` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT 'Don''t show any public links to this rank.',
`colour` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Colour used for the username of a member of this rank.',
`description` text COLLATE utf8_bin NOT NULL COMMENT 'A description of what a user of this rank can do/is supposed to do.',
`title` varchar(64) COLLATE utf8_bin NOT NULL COMMENT 'Default user title if user has none set.',
PRIMARY KEY (`id`)
`rank_id` bigint(128) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Automatically generated ID by MySQL for management.',
`rank_hierarchy` int(11) unsigned NOT NULL COMMENT 'Rank hierarchy.',
`rank_name` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Display name of the rank.',
`rank_multiple` varchar(10) COLLATE utf8_bin DEFAULT NULL COMMENT 'Used when addressing this rank as a multiple',
`rank_hidden` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT 'Don''t show any public links to this rank.',
`rank_colour` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Colour used for the username of a member of this rank.',
`rank_description` text COLLATE utf8_bin NOT NULL COMMENT 'A description of what a user of this rank can do/is supposed to do.',
`rank_title` varchar(64) COLLATE utf8_bin NOT NULL COMMENT 'Default user title if user has none set.',
PRIMARY KEY (`rank_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
@ -305,7 +319,7 @@ CREATE TABLE `sakura_regcodes` (
`key_used` tinyint(1) unsigned NOT NULL COMMENT 'Boolean for setting this key as used.',
PRIMARY KEY (`id`),
KEY `created_by` (`created_by`),
CONSTRAINT `sakura_regcodes_ibfk_1` FOREIGN KEY (`created_by`) REFERENCES `sakura_users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
CONSTRAINT `sakura_regcodes_ibfk_1` FOREIGN KEY (`created_by`) REFERENCES `sakura_users` (`user_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
@ -324,16 +338,16 @@ CREATE TABLE `sakura_reports` (
DROP TABLE IF EXISTS `sakura_sessions`;
CREATE TABLE `sakura_sessions` (
`id` bigint(255) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Automatically generated ID by MySQL for management. ',
`userip` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'IP of the user this session is spawned for.',
`useragent` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT 'User agent of the user this session is spawned for.',
`userid` bigint(255) unsigned NOT NULL COMMENT 'ID of the user this session is spawned for. ',
`skey` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Session key, allow direct access to the user''s account. ',
`started` int(16) unsigned NOT NULL COMMENT 'The timestamp for when the session was started. ',
`expire` int(16) unsigned NOT NULL COMMENT 'The timestamp for when this session should end, -1 for permanent. ',
`remember` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT 'If set to 1 session will be extended each time a page is loaded.',
PRIMARY KEY (`id`),
KEY `userid` (`userid`)
`session_id` bigint(255) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Automatically generated ID by MySQL for management. ',
`user_id` bigint(255) unsigned NOT NULL COMMENT 'ID of the user this session is spawned for. ',
`user_ip` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'IP of the user this session is spawned for.',
`user_agent` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT 'User agent of the user this session is spawned for.',
`session_key` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Session key, allow direct access to the user''s account. ',
`session_start` int(16) unsigned NOT NULL COMMENT 'The timestamp for when the session was started. ',
`session_expire` int(16) unsigned NOT NULL COMMENT 'The timestamp for when this session should end, -1 for permanent. ',
`session_remember` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT 'If set to 1 session will be extended each time a page is loaded.',
PRIMARY KEY (`session_id`),
KEY `userid` (`user_id`)
) ENGINE=MEMORY DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
@ -371,7 +385,7 @@ CREATE TABLE `sakura_username_history` (
DROP TABLE IF EXISTS `sakura_users`;
CREATE TABLE `sakura_users` (
`id` bigint(255) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Automatically generated ID by MySQL for management. ',
`user_id` bigint(255) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Automatically generated ID by MySQL for management. ',
`username` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Username set at registration.',
`username_clean` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'A more cleaned up version of the username for backend usage.',
`password_hash` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Hashing algo used for the password hash.',
@ -382,35 +396,35 @@ CREATE TABLE `sakura_users` (
`password_new` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT 'Field with array containing new password data beit that they requested a password change.',
`email` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'E-mail of the user for password restoring etc.',
`rank_main` mediumint(4) unsigned NOT NULL DEFAULT '0' COMMENT 'Main rank of the user.',
`ranks` varchar(255) COLLATE utf8_bin NOT NULL DEFAULT '[0]' COMMENT 'Array containing the ranks the user is part of.',
`name_colour` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT 'Additional name colour, when empty colour defaults to group colour.',
`user_ranks` varchar(255) COLLATE utf8_bin NOT NULL DEFAULT '[0]' COMMENT 'Array containing the ranks the user is part of.',
`user_colour` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT 'Additional name colour, when empty colour defaults to group colour.',
`register_ip` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'IP used for the creation of this account.',
`last_ip` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Last IP that was used to log into this account.',
`usertitle` varchar(64) COLLATE utf8_bin DEFAULT NULL COMMENT 'Custom user title of the user, when empty reverts to their derault group name.',
`regdate` int(11) unsigned NOT NULL DEFAULT '0' COMMENT 'Timestamp of account creation.',
`lastdate` int(11) unsigned NOT NULL DEFAULT '0' COMMENT 'Last time anything was done on this account.',
`birthday` date NOT NULL COMMENT 'Birthdate of the user.',
`country` char(2) COLLATE utf8_bin NOT NULL COMMENT 'Contains ISO 3166 country code of user''s registration location.',
`userData` text COLLATE utf8_bin COMMENT 'All additional profile data.',
PRIMARY KEY (`id`),
`user_title` varchar(64) COLLATE utf8_bin DEFAULT NULL COMMENT 'Custom user title of the user, when empty reverts to their derault group name.',
`user_registered` int(11) unsigned NOT NULL DEFAULT '0' COMMENT 'Timestamp of account creation.',
`user_last_online` int(11) unsigned NOT NULL DEFAULT '0' COMMENT 'Last time anything was done on this account.',
`user_birthday` date NOT NULL COMMENT 'Birthdate of the user.',
`user_country` char(2) COLLATE utf8_bin NOT NULL COMMENT 'Contains ISO 3166 country code of user''s registration location.',
`user_data` text COLLATE utf8_bin COMMENT 'All additional profile data.',
PRIMARY KEY (`user_id`),
UNIQUE KEY `username_clean` (`username_clean`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
DROP TABLE IF EXISTS `sakura_warnings`;
CREATE TABLE `sakura_warnings` (
`id` bigint(255) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Automatically generated ID by MySQL for management.',
`uid` bigint(255) unsigned NOT NULL COMMENT 'ID of user that was warned.',
`iid` bigint(255) unsigned NOT NULL COMMENT 'ID of the user that issued the warning.',
`issued` int(16) unsigned NOT NULL COMMENT 'Timestamp of the date the warning was issued.',
`expire` int(16) unsigned NOT NULL COMMENT 'Timstamp when the warning should expire, 0 for a permanent warning.',
`reason` varchar(512) COLLATE utf8_bin DEFAULT NULL COMMENT 'Reason for the warning.',
PRIMARY KEY (`id`),
KEY `uid` (`uid`),
KEY `iid` (`iid`),
CONSTRAINT `sakura_warnings_ibfk_1` FOREIGN KEY (`uid`) REFERENCES `sakura_users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `sakura_warnings_ibfk_2` FOREIGN KEY (`iid`) REFERENCES `sakura_users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
`warning_id` bigint(255) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Automatically generated ID by MySQL for management.',
`user_id` bigint(255) unsigned NOT NULL COMMENT 'ID of user that was warned.',
`moderator_id` bigint(255) unsigned NOT NULL COMMENT 'ID of the user that issued the warning.',
`warning_issued` int(16) unsigned NOT NULL COMMENT 'Timestamp of the date the warning was issued.',
`warning_expire` int(16) unsigned NOT NULL COMMENT 'Timstamp when the warning should expire, 0 for a permanent warning.',
`warning_reason` varchar(512) COLLATE utf8_bin DEFAULT NULL COMMENT 'Reason for the warning.',
PRIMARY KEY (`warning_id`),
KEY `uid` (`user_id`),
KEY `iid` (`moderator_id`),
CONSTRAINT `sakura_warnings_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `sakura_users` (`user_id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `sakura_warnings_ibfk_2` FOREIGN KEY (`moderator_id`) REFERENCES `sakura_users` (`user_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
-- 2015-09-23 20:45:04
-- 2015-10-10 21:14:40

View file

@ -53,14 +53,14 @@ if (Auth::getPageType() == AUTH_FETCH) {
// Set the user's data
Auth::SetUserData(
$user->data['id'],
$user->data['user_id'],
$user->data['username'],
$user->colour()
);
// Set the common permissions
Auth::SetCommonPermissions(
bindec(Permissions::getUserPermissions($uid)['SITE']),
$user->mainRank['hierarchy'],
Permissions::check('MANAGE', 'USE_MANAGE', $uid, 1) ? 1 : 0,
Permissions::check('SITE', 'CREATE_BACKGROUND', $uid, 1) ? 1 : 0,
Permissions::check('SITE', 'CHANGE_USERNAME', $uid, 1) ? 1 : 0,

View file

@ -1,8 +1,3 @@
# Block access to every file starting with a dot
<Files ".*">
Require all denied
</Files>
# Set Error documents
ErrorDocument 404 /404.php
ErrorDocument 403 /404.php

View file

@ -185,7 +185,7 @@ if (isset($_REQUEST['mode'])) {
// Add page specific things
$renderData['page'] = [
'redirect' => $login[0] ? ((new User($login[2]))->data['lastdate'] ? $_REQUEST['redirect'] : $urls->format('INFO_PAGE', ['welcome'])) : $urls->format('SITE_LOGIN'),
'redirect' => $login[0] ? ((new User($login[2]))->data['user_last_online'] ? $_REQUEST['redirect'] : $urls->format('INFO_PAGE', ['welcome'])) : $urls->format('SITE_LOGIN'),
'message' => $messages[$login[1]],
'success' => $login[0],

View file

@ -1,2 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<browserconfig><msapplication><tile><square70x70logo src="/content/images/icons/ms-icon-70x70.png"/><square150x150logo src="/content/images/icons/ms-icon-150x150.png"/><square310x310logo src="/content/images/icons/ms-icon-310x310.png"/><TileColor>#fbeeff</TileColor></tile></msapplication></browserconfig>
<browserconfig>
<msapplication>
<tile>
<square70x70logo src="/content/images/icons/ms-icon-70x70.png" />
<square150x150logo src="/content/images/icons/ms-icon-150x150.png" />
<square310x310logo src="/content/images/icons/ms-icon-310x310.png" />
<TileColor>#9475b2</TileColor>
</tile>
</msapplication>
</browserconfig>

View file

@ -13,7 +13,7 @@ define('SAKURA_NO_TPL', true);
require_once str_replace(basename(__DIR__), '', dirname(__FILE__)) . '_sakura/sakura.php';
// Set Content type
//header('Content-Type: application/octet-stream');
header('Content-Type: application/octet-stream');
// Path to user uploads
$userDirPath = ROOT . Configuration::getConfig('user_uploads') . '/';
@ -61,13 +61,13 @@ if (isset($_GET['m'])) {
}
// Check if user has an avatar set
if (empty($user->data['userData']['userAvatar']) || !file_exists($userDirPath . $user->data['userData']['userAvatar'])) {
if (empty($user->data['user_data']['userAvatar']) || !file_exists($userDirPath . $user->data['user_data']['userAvatar'])) {
$serveImage = $noAvatar;
break;
}
// Check if the avatar exist and assign it to a value
$serveImage = $userDirPath . $user->data['userData']['userAvatar'];
$serveImage = $userDirPath . $user->data['user_data']['userAvatar'];
break;
case 'background':
@ -96,14 +96,14 @@ if (isset($_GET['m'])) {
}
// Check if user has a background set
if (empty($user->data['userData']['profileBackground'])
|| !file_exists($userDirPath . $user->data['userData']['profileBackground'])) {
if (empty($user->data['user_data']['profileBackground'])
|| !file_exists($userDirPath . $user->data['user_data']['profileBackground'])) {
$serveImage = $noBackground;
break;
}
// Check if the avatar exist and assign it to a value
$serveImage = $userDirPath . $user->data['userData']['profileBackground'];
$serveImage = $userDirPath . $user->data['user_data']['profileBackground'];
break;
case 'header':
@ -132,14 +132,14 @@ if (isset($_GET['m'])) {
}
// Check if user has a background set
if (empty($user->data['userData']['profileHeader'])
|| !file_exists($userDirPath . $user->data['userData']['profileHeader'])) {
if (empty($user->data['user_data']['profileHeader'])
|| !file_exists($userDirPath . $user->data['user_data']['profileHeader'])) {
$serveImage = $noHeader;
break;
}
// Check if the avatar exist and assign it to a value
$serveImage = $userDirPath . $user->data['userData']['profileHeader'];
$serveImage = $userDirPath . $user->data['user_data']['profileHeader'];
break;
default:

View file

@ -27,8 +27,8 @@ if (isset($_GET['p'])) {
$renderData['page'] = [
'id' => $pageId,
'title' => $ipData['pagetitle'],
'content' => Main::mdParse($ipData['content']),
'title' => $ipData['page_title'],
'content' => Main::mdParse($ipData['page_content']),
];
}
@ -62,7 +62,7 @@ $renderData['stats'] = [
date_create(
date(
'Y-m-d',
$_INDEX_NEWEST_USER->data['regdate']
$_INDEX_NEWEST_USER->data['user_registered']
)
),
date_create(

View file

@ -78,8 +78,6 @@ switch ($category . '.' . $mode) {
]);
break;
case 'config.index':
$renderData = array_merge($renderData, [
]);
break;
}

View file

@ -1,5 +1,5 @@
{
"name": "App",
"name": "Sakura",
"icons": [
{
"src": "\/content\/images\/icons\/android-icon-36x36.png",

View file

@ -27,8 +27,8 @@ if (isset($_GET['xml'])) {
'link' => ($_FEED_URL = 'http://' . Configuration::getConfig('url_main')),
'description' => 'News about ' . $_FEED_TITLE,
'language' => 'en-gb',
'webMaster' => (new User(1))->data['email'] . ' (' . $_FEED_TITLE . ' Webmaster)',
'pubDate' => ($_FEED_DATE = date('r', $posts[array_keys($posts)[0]]['date'])),
'webMaster' => Configuration::getConfig('admin_email') . ' (' . $_FEED_TITLE . ' Webmaster)',
'pubDate' => ($_FEED_DATE = date('r', $posts[array_keys($posts)[0]]['news_timestamp'])),
'lastBuildDate' => $_FEED_DATE,
];
@ -36,12 +36,12 @@ if (isset($_GET['xml'])) {
// Item attributes
$itemData = [
'title' => ['text' => '{EVAL}', 'eval' => '$post["title"]'],
'link' => ['text' => $_FEED_URL . '/news/{EVAL}', 'eval' => '$post["id"]'],
'guid' => ['text' => $_FEED_URL . '/news/{EVAL}', 'eval' => '$post["id"]'],
'pubDate' => ['text' => '{EVAL}', 'eval' => 'date("D, d M Y G:i:s O", $post["date"])'],
'dc:publisher' => ['text' => '{EVAL}', 'eval' => '$post["poster"]->data["username"]'],
'description' => ['cdata' => '{EVAL}', 'eval' => '$post["content_parsed"]'],
'title' => ['text' => '0', 'eval' => '$post["news_title"]'],
'link' => ['text' => $_FEED_URL . (new Urls())->format('SITE_NEWS_POST', ['0']), 'eval' => '$post["news_id"]'],
'guid' => ['text' => $_FEED_URL . (new Urls())->format('SITE_NEWS_POST', ['0']), 'eval' => '$post["news_id"]'],
'pubDate' => ['text' => '{EVAL}', 'eval' => 'date("D, d M Y G:i:s O", $post["news_timestamp"])'],
'dc:publisher' => ['text' => '0', 'eval' => '$post["news_poster"]->data["username"]'],
'description' => ['cdata' => '0', 'eval' => '$post["news_content_parsed"]'],
];
@ -87,7 +87,7 @@ if (isset($_GET['xml'])) {
// Create value
eval('$value = ' . $valueData['eval'] . ';');
$value = str_replace(
'{EVAL}',
'0',
$value,
$valueData[(array_key_exists('cdata', $valueData) ? 'cdata' : 'text')]
);

View file

@ -30,15 +30,15 @@ if (isset($_REQUEST['request-notifications']) && $_REQUEST['request-notification
// Add the proper values to the array
foreach ($userNotifs as $notif) {
// Add the notification to the display array
$notifications[$notif['timestamp']] = [
$notifications[$notif['alert_timestamp']] = [
'read' => $notif['notif_read'],
'title' => $notif['notif_title'],
'text' => $notif['notif_text'],
'link' => $notif['notif_link'],
'img' => $notif['notif_img'],
'timeout' => $notif['notif_timeout'],
'sound' => $notif['notif_sound'],
'read' => $notif['alert_read'],
'title' => $notif['alert_title'],
'text' => $notif['alert_text'],
'link' => $notif['alert_link'],
'img' => $notif['alert_img'],
'timeout' => $notif['alert_timeout'],
'sound' => $notif['alert_sound'],
];
}
@ -87,10 +87,46 @@ if (isset($_REQUEST['request-notifications']) && $_REQUEST['request-notification
$comments = new Comments($_REQUEST['category']);
switch (isset($_REQUEST['mode']) ? $_REQUEST['mode'] : false) {
case 'like':
break;
case 'vote':
$comment = $comments->getComment(isset($_REQUEST['id']) ? $_REQUEST['id'] : 0);
case 'dislike':
// Check if the comment was actually made by the current user
if (!$comment) {
$renderData['page'] = [
'redirect' => $redirect,
'message' => 'The requested comment does not exist.',
'success' => 0,
];
break;
}
// Check if the user can delete comments
if (!$currentUser->checkPermission('SITE', 'VOTE_COMMENTS')) {
$renderData['page'] = [
'redirect' => $redirect,
'message' => 'You aren\'t allowed to vote on comments.',
'success' => 0,
];
break;
}
$comments->makeVote(
$currentUser->data['id'],
isset($_REQUEST['id']) ? $_REQUEST['id'] : 0,
isset($_REQUEST['state']) && $_REQUEST['state'] ? '1' : '0'
);
$renderData['page'] = [
'redirect' => $redirect,
'message' => 'Your vote has been cast!',
'success' => 1,
];
break;
case 'delete':
@ -113,7 +149,7 @@ if (isset($_REQUEST['request-notifications']) && $_REQUEST['request-notification
$renderData['page'] = [
'redirect' => $redirect,
'message' => 'You aren\'t allowed delete to comments.',
'message' => 'You aren\'t allowed to delete comments.',
'success' => 0,
];
@ -157,7 +193,7 @@ if (isset($_REQUEST['request-notifications']) && $_REQUEST['request-notification
}
// Attempt to make a new comment
$comment = $comments->makeComment($currentUser->data['id'], $_POST['replyto'], $_POST['comment']);
$comment = $comments->makeComment($currentUser->data['user_id'], $_POST['replyto'], $_POST['comment']);
// Messages
$messages = [
@ -311,8 +347,8 @@ if (isset($_REQUEST['request-notifications']) && $_REQUEST['request-notification
sprintf($notifStrings[$action[1]][0], $user->data['username']),
$notifStrings[$action[1]][1],
60000,
'//' . Configuration::getConfig('url_main') . '/a/' . $user->data['id'],
'//' . Configuration::getConfig('url_main') . '/u/' . $user->data['id'],
'//' . Configuration::getConfig('url_main') . '/a/' . $user->data['user_id'],
'//' . Configuration::getConfig('url_main') . '/u/' . $user->data['user_id'],
'1'
);
}
@ -379,7 +415,7 @@ if (isset($_REQUEST['request-notifications']) && $_REQUEST['request-notification
$userDataKey = 'profileBackground';
$msgTitle = 'Background';
$permission = (
!empty($currentUser->data['userData'][$userDataKey])
!empty($currentUser->data['user_data'][$userDataKey])
&& $currentUser->checkPermission('SITE', 'CHANGE_BACKGROUND')
) || $currentUser->checkPermission('SITE', 'CREATE_BACKGROUND');
break;
@ -408,8 +444,8 @@ if (isset($_REQUEST['request-notifications']) && $_REQUEST['request-notification
// Set path variables
$filepath = ROOT . Configuration::getConfig('user_uploads') . '/';
$filename = $filepath . $mode . '_' . Session::$userId;
$currfile = isset($currentUser->data['userData'][$userDataKey])
&& !empty($_OLDFILE = $currentUser->data['userData'][$userDataKey]) ? $_OLDFILE : null;
$currfile = isset($currentUser->data['user_data'][$userDataKey])
&& !empty($_OLDFILE = $currentUser->data['user_data'][$userDataKey]) ? $_OLDFILE : null;
// Check if $_FILES is set
if (!isset($_FILES[$mode]) && empty($_FILES[$mode])) {
@ -588,17 +624,14 @@ if (isset($_REQUEST['request-notifications']) && $_REQUEST['request-notification
// Go over each field
foreach ($fields as $field) {
// Add to the store array
if (isset($_POST['profile_' . $field['ident']]) && !empty($_POST['profile_' . $field['ident']])) {
$store[$field['ident']] = $_POST['profile_' . $field['ident']];
if (isset($_POST['profile_' . $field['field_identity']]) && !empty($_POST['profile_' . $field['field_identity']])) {
$store[$field['field_identity']] = $_POST['profile_' . $field['field_identity']];
}
// Check if there's additional values we should keep in mind
if (isset($field['additional']) && !empty($field['additional'])) {
// Decode the json
$field['additional'] = json_decode($field['additional'], true);
if (isset($field['field_additional']) && !empty($field['field_additional'])) {
// Go over each additional value
foreach ($field['additional'] as $addKey => $addVal) {
foreach ($field['field_additional'] as $addKey => $addVal) {
// Add to the array
$store[$addKey] = (isset($_POST['profile_additional_' . $addKey])
|| !empty($_POST['profile_additional_' . $addKey])) ?
@ -672,10 +705,10 @@ if (isset($_REQUEST['request-notifications']) && $_REQUEST['request-notification
Database::update('users', [
[
'birthday' => $birthdate,
'user_birthday' => $birthdate,
],
[
'id' => [Session::$userId, '='],
'user_id' => [Session::$userId, '='],
],
]);
@ -691,14 +724,14 @@ if (isset($_REQUEST['request-notifications']) && $_REQUEST['request-notification
// Go over each field
foreach ($fields as $field) {
// Make sure the user has sufficient permissions to complete this action
if (!$currentUser->checkPermission('SITE', $field['require_perm'])) {
$store[$field['id']] = false;
if (!$currentUser->checkPermission('SITE', $field['option_permission'])) {
$store[$field['option_id']] = false;
continue;
}
$store[$field['id']] = isset($_POST['option_' . $field['id']])
&& !empty($_POST['option_' . $field['id']]) ?
$_POST['option_' . $field['id']] :
$store[$field['option_id']] = isset($_POST['option_' . $field['option_id']])
&& !empty($_POST['option_' . $field['option_id']]) ?
$_POST['option_' . $field['option_id']] :
null;
}
@ -746,10 +779,10 @@ if (isset($_REQUEST['request-notifications']) && $_REQUEST['request-notification
'users',
[
[
'usertitle' => (isset($_POST['usertitle']) ? $_POST['usertitle'] : null),
'user_title' => (isset($_POST['usertitle']) ? $_POST['usertitle'] : null),
],
[
'id' => [Session::$userId, '='],
'user_id' => [Session::$userId, '='],
],
]
);
@ -1155,7 +1188,7 @@ if (Users::checkLogin()) {
],
'access' => (
isset($currentUser->data['userData']['profileBackground'])
isset($currentUser->data['user_data']['profileBackground'])
&& $currentUser->checkPermission('SITE', 'CHANGE_BACKGROUND')
) || $currentUser->checkPermission('SITE', 'CREATE_BACKGROUND'),
'menu' => true,
@ -1170,12 +1203,24 @@ if (Users::checkLogin()) {
],
'access' => (
isset($currentUser->data['userData']['userPage'])
isset($currentUser->data['user_data']['userPage'])
&& $currentUser->checkPermission('SITE', 'CHANGE_USERPAGE')
) || $currentUser->checkPermission('SITE', 'CREATE_USERPAGE'),
'menu' => true,
],
'signature' => [
'title' => 'Signature',
'description' => [
'This signature is displayed at the end of all your posts (unless you choose not to show it).',
],
'access' => $currentUser->checkPermission('SITE', 'CHANGE_SIGNATURE'),
'menu' => true,
],
],
@ -1403,7 +1448,7 @@ if (Users::checkLogin()) {
// Notification history
case 'notifications.history':
$renderData['notifs'] = array_chunk(array_reverse(Users::getNotifications(null, 0, false, true)), 10, true);
$renderData['alerts'] = array_chunk(array_reverse(Users::getNotifications(null, 0, false, true)), 10, true);
break;
// Avatar and background sizes
@ -1423,7 +1468,7 @@ if (Users::checkLogin()) {
// Profile
case 'appearance.userpage':
$renderData['userPage'] = isset($currentUser->data['userData']['userPage']) ? base64_decode($currentUser->data['userData']['userPage']) : '';
$renderData['userPage'] = isset($currentUser->data['user_data']['userPage']) ? base64_decode($currentUser->data['user_data']['userPage']) : '';
break;
// Username changing