r20160227
This commit is contained in:
parent
bca6c5be99
commit
d55ae7e936
30 changed files with 358 additions and 551 deletions
|
@ -1,24 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Holds the auth controllers.
|
||||
*
|
||||
* @package Sakura
|
||||
*/
|
||||
|
||||
namespace Sakura\Controllers;
|
||||
|
||||
use Sakura\Template;
|
||||
|
||||
/**
|
||||
* Authentication controllers.
|
||||
*
|
||||
* @package Sakura
|
||||
* @author Julian van de Groep <me@flash.moe>
|
||||
*/
|
||||
class Auth extends Controller
|
||||
{
|
||||
public function login()
|
||||
{
|
||||
return Template::render('main/login');
|
||||
}
|
||||
}
|
178
libraries/Controllers/AuthController.php
Normal file
178
libraries/Controllers/AuthController.php
Normal file
|
@ -0,0 +1,178 @@
|
|||
<?php
|
||||
/**
|
||||
* Holds the auth controllers.
|
||||
*
|
||||
* @package Sakura
|
||||
*/
|
||||
|
||||
namespace Sakura\Controllers;
|
||||
|
||||
use Sakura\Config;
|
||||
use Sakura\DB;
|
||||
use Sakura\Hashing;
|
||||
use Sakura\Net;
|
||||
use Sakura\Perms\Site;
|
||||
use Sakura\Router;
|
||||
use Sakura\Session;
|
||||
use Sakura\Template;
|
||||
use Sakura\User;
|
||||
use Sakura\Users;
|
||||
use Sakura\Utils;
|
||||
|
||||
/**
|
||||
* Authentication controllers.
|
||||
*
|
||||
* @package Sakura
|
||||
* @author Julian van de Groep <me@flash.moe>
|
||||
*/
|
||||
class AuthController extends Controller
|
||||
{
|
||||
protected function touchRateLimit($user, $mode = 0)
|
||||
{
|
||||
DB::table('login_attempts')
|
||||
->insert([
|
||||
'attempt_success' => $mode,
|
||||
'attempt_timestamp' => time(),
|
||||
'attempt_ip' => Net::pton(Net::IP()),
|
||||
'user_id' => $user,
|
||||
]);
|
||||
}
|
||||
|
||||
public function logout()
|
||||
{
|
||||
// Check if user is logged in
|
||||
$check = Users::checkLogin();
|
||||
|
||||
if (!$check || !isset($_REQUEST['s']) || $_REQUEST['s'] != session_id()) {
|
||||
$message = 'Something happened! This probably happened because you went here without being logged in.';
|
||||
$redirect = (isset($_REQUEST['redirect']) ? $_REQUEST['redirect'] : Router::route('main.index'));
|
||||
|
||||
Template::vars(['page' => ['success' => 0, 'redirect' => $redirect, 'message' => $message]]);
|
||||
|
||||
return Template::render('global/information');
|
||||
}
|
||||
|
||||
// Destroy the active session
|
||||
(new Session($check[0], $check[1]))->destroy();
|
||||
|
||||
// Return true indicating a successful logout
|
||||
$message = 'Goodbye!';
|
||||
$redirect = Router::route('auth.login');
|
||||
|
||||
Template::vars(['page' => ['success' => 1, 'redirect' => $redirect, 'message' => $message]]);
|
||||
|
||||
return Template::render('global/information');
|
||||
}
|
||||
|
||||
public function loginGet()
|
||||
{
|
||||
return Template::render('main/login');
|
||||
}
|
||||
|
||||
public function loginPost()
|
||||
{
|
||||
// Preliminarily set login to failed
|
||||
$success = 0;
|
||||
$redirect = Router::route('auth.login');
|
||||
|
||||
// Check if authentication is disallowed
|
||||
if (Config::get('lock_authentication')) {
|
||||
$message = 'Logging in is disabled for security checkups! Try again later.';
|
||||
Template::vars(['page' => ['success' => $success, 'redirect' => $redirect, 'message' => $message]]);
|
||||
return Template::render('global/information');
|
||||
}
|
||||
|
||||
// Get request variables
|
||||
$username = isset($_REQUEST['username']) ? $_REQUEST['username'] : null;
|
||||
$password = isset($_REQUEST['password']) ? $_REQUEST['password'] : null;
|
||||
$remember = isset($_REQUEST['remember']);
|
||||
|
||||
// Check if we haven't hit the rate limit
|
||||
$rates = DB::table('login_attempts')
|
||||
->where('attempt_ip', Net::pton(Net::IP()))
|
||||
->where('attempt_timestamp', '>', time() - 1800)
|
||||
->where('attempt_success', '0')
|
||||
->count();
|
||||
|
||||
if ($rates > 4) {
|
||||
$message = 'Your have hit the login rate limit, try again later.';
|
||||
Template::vars(['page' => ['success' => $success, 'redirect' => $redirect, 'message' => $message]]);
|
||||
return Template::render('global/information');
|
||||
}
|
||||
|
||||
// Get account data
|
||||
$user = User::construct(Utils::cleanString($username, true, true));
|
||||
|
||||
// Check if the user that's trying to log in actually exists
|
||||
if ($user->id === 0) {
|
||||
$this->touchRateLimit($user->id);
|
||||
$message = 'The user you tried to log into does not exist.';
|
||||
Template::vars(['page' => ['success' => $success, 'redirect' => $redirect, 'message' => $message]]);
|
||||
return Template::render('global/information');
|
||||
}
|
||||
|
||||
// Validate password
|
||||
switch ($user->passwordAlgo) {
|
||||
// Disabled
|
||||
case 'disabled':
|
||||
$this->touchRateLimit($user->id);
|
||||
$message = 'Logging into this account is disabled.';
|
||||
Template::vars(['page' => ['success' => $success, 'redirect' => $redirect, 'message' => $message]]);
|
||||
return Template::render('global/information');
|
||||
|
||||
// Default hashing method
|
||||
default:
|
||||
if (!Hashing::validatePassword($password, [
|
||||
$user->passwordAlgo,
|
||||
$user->passwordIter,
|
||||
$user->passwordSalt,
|
||||
$user->passwordHash,
|
||||
])) {
|
||||
$this->touchRateLimit($user->id);
|
||||
$message = 'The password you entered was invalid.';
|
||||
Template::vars(['page' => ['success' => $success, 'redirect' => $redirect, 'message' => $message]]);
|
||||
return Template::render('global/information');
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the user has the required privs to log in
|
||||
if ($user->permission(Site::DEACTIVATED)) {
|
||||
$this->touchRateLimit($user->id);
|
||||
$message = 'Your account does not have the required permissions to log in.';
|
||||
Template::vars(['page' => ['success' => $success, 'redirect' => $redirect, 'message' => $message]]);
|
||||
return Template::render('global/information');
|
||||
}
|
||||
|
||||
// Create a new session
|
||||
$session = new Session($user->id);
|
||||
|
||||
// Generate a session key
|
||||
$sessionKey = $session->create($remember);
|
||||
|
||||
// User ID cookie
|
||||
setcookie(
|
||||
Config::get('cookie_prefix') . 'id',
|
||||
$user->id,
|
||||
time() + 604800,
|
||||
Config::get('cookie_path')
|
||||
);
|
||||
|
||||
// Session ID cookie
|
||||
setcookie(
|
||||
Config::get('cookie_prefix') . 'session',
|
||||
$sessionKey,
|
||||
time() + 604800,
|
||||
Config::get('cookie_path')
|
||||
);
|
||||
|
||||
$this->touchRateLimit($user->id, 1);
|
||||
|
||||
$success = 1;
|
||||
$redirect = $user->lastOnline ? (isset($_REQUEST['redirect']) ? $_REQUEST['redirect'] : Router::route('main.index')) : Router::route('main.infopage', 'welcome');
|
||||
$message = 'Welcome' . ($user->lastOnline ? ' back' : '') . '!';
|
||||
|
||||
Template::vars(['page' => ['success' => $success, 'redirect' => $redirect, 'message' => $message]]);
|
||||
|
||||
return Template::render('global/information');
|
||||
}
|
||||
}
|
|
@ -18,7 +18,7 @@ use Sakura\Perms\Site;
|
|||
* @package Sakura
|
||||
* @author Julian van de Groep <me@flash.moe>
|
||||
*/
|
||||
class Files extends Controller
|
||||
class FileController extends Controller
|
||||
{
|
||||
private function serveImage($data, $mime, $name)
|
||||
{
|
|
@ -23,7 +23,7 @@ use Sakura\Utils;
|
|||
* @package Sakura
|
||||
* @author Julian van de Groep <me@flash.moe>
|
||||
*/
|
||||
class Forums extends Controller
|
||||
class ForumController extends Controller
|
||||
{
|
||||
/**
|
||||
* Serves the forum index.
|
|
@ -22,7 +22,7 @@ use Sakura\Utils;
|
|||
* @package Sakura
|
||||
* @author Julian van de Groep <me@flash.moe>
|
||||
*/
|
||||
class Meta extends Controller
|
||||
class MetaController extends Controller
|
||||
{
|
||||
/**
|
||||
* Serves the site index.
|
|
@ -22,7 +22,7 @@ use Sakura\Perms\Site;
|
|||
* @package Sakura
|
||||
* @author Julian van de Groep <me@flash.moe>
|
||||
*/
|
||||
class Premium extends Controller
|
||||
class PremiumController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
|
@ -21,7 +21,7 @@ use Sakura\Utils;
|
|||
* @package Sakura
|
||||
* @author Julian van de Groep <me@flash.moe>
|
||||
*/
|
||||
class User extends Controller
|
||||
class UserController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display the profile of a user.
|
||||
|
@ -99,7 +99,7 @@ class User extends Controller
|
|||
*
|
||||
* @return bool|string The memberlist.
|
||||
*/
|
||||
public function members($rank = 0)
|
||||
public function members($rank = null)
|
||||
{
|
||||
global $currentUser;
|
||||
|
||||
|
@ -108,14 +108,31 @@ class User extends Controller
|
|||
return Template::render('global/restricted');
|
||||
}
|
||||
|
||||
// Get all ranks
|
||||
|
||||
// Execute query
|
||||
$getRanks = DB::table('ranks')
|
||||
->get(['rank_id']);
|
||||
|
||||
// Define variable
|
||||
$ranks = [];
|
||||
|
||||
// Add the empty rank
|
||||
$ranks[0] = Rank::construct(0);
|
||||
|
||||
// Reorder shit
|
||||
foreach ($getRanks as $sortRank) {
|
||||
$ranks[$sortRank->rank_id] = Rank::construct($sortRank->rank_id);
|
||||
}
|
||||
|
||||
// Get the active rank
|
||||
$rank = array_key_exists($rank, $ranks) ? $rank : ($rank ? 0 : 2);
|
||||
|
||||
// Set parse variables
|
||||
Template::vars([
|
||||
'memberlist' => [
|
||||
'ranks' => ($_MEMBERLIST_RANKS = \Sakura\Users::getAllRanks()),
|
||||
'active' => ($_MEMBERLIST_ACTIVE = (array_key_exists($rank, $_MEMBERLIST_RANKS) ? $rank : 2)),
|
||||
'users' => Rank::construct($_MEMBERLIST_ACTIVE)->users(),
|
||||
'ranks' => $ranks,
|
||||
'rank' => $rank,
|
||||
'membersPerPage' => Config::get('members_per_page'),
|
||||
]
|
||||
]);
|
||||
|
||||
// Render the template
|
|
@ -118,9 +118,16 @@ class Router
|
|||
*
|
||||
* @return string The generated URI.
|
||||
*/
|
||||
public static function url($name, $args = null)
|
||||
public static function route($name, $args = null)
|
||||
{
|
||||
return self::$router->route($name, $args);
|
||||
// Array-ify the arguments
|
||||
if ($args !== null && !is_array($args)) {
|
||||
$temp = $args;
|
||||
$args = [];
|
||||
$args[] = $temp;
|
||||
}
|
||||
|
||||
return self::$basePath . self::$router->route($name, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -10,6 +10,7 @@ namespace Sakura;
|
|||
use Twig_Environment;
|
||||
use Twig_Extension_StringLoader;
|
||||
use Twig_Loader_Filesystem;
|
||||
use Twig_SimpleFunction;
|
||||
|
||||
/**
|
||||
* Sakura wrapper for Twig.
|
||||
|
@ -98,6 +99,11 @@ class Template
|
|||
|
||||
// Load String template loader
|
||||
self::$template->addExtension(new Twig_Extension_StringLoader());
|
||||
|
||||
// Add route function
|
||||
self::$template->addFunction(new Twig_SimpleFunction('route', function ($name, $args = null) {
|
||||
return Router::route($name, $args);
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -98,130 +98,6 @@ class Users
|
|||
return [$uid, $sid];
|
||||
}
|
||||
|
||||
/**
|
||||
* Log in to an account.
|
||||
*
|
||||
* @param string $username The username.
|
||||
* @param string $password The password.
|
||||
* @param bool $remember Stay logged in "forever"?
|
||||
* @param bool $cookies Set cookies?
|
||||
*
|
||||
* @return array Return the status.
|
||||
*/
|
||||
public static function login($username, $password, $remember = false, $cookies = true)
|
||||
{
|
||||
// Check if authentication is disallowed
|
||||
if (Config::get('lock_authentication')) {
|
||||
return [0, 'AUTH_LOCKED'];
|
||||
}
|
||||
|
||||
// Check if we haven't hit the rate limit
|
||||
$rates = DBv2::prepare('SELECT * FROM `{prefix}login_attempts` WHERE `attempt_ip` = :ip AND `attempt_timestamp` > :time AND `attempt_success` = 0');
|
||||
$rates->execute([
|
||||
'ip' => Net::pton(Net::IP()),
|
||||
'time' => time() - 1800,
|
||||
]);
|
||||
$rates = $rates->fetchAll(\PDO::FETCH_ASSOC);
|
||||
|
||||
if (count($rates) > 4) {
|
||||
return [0, 'RATE_LIMIT'];
|
||||
}
|
||||
|
||||
// Check if the user that's trying to log in actually exists
|
||||
if (!$uid = self::userExists($username, false)) {
|
||||
return [0, 'USER_NOT_EXIST'];
|
||||
}
|
||||
|
||||
// Get account data
|
||||
$user = User::construct($uid);
|
||||
|
||||
// Validate password
|
||||
switch ($user->passwordAlgo) {
|
||||
// Disabled
|
||||
case 'disabled':
|
||||
return [0, 'NO_LOGIN'];
|
||||
|
||||
// Default hashing method
|
||||
default:
|
||||
if (!Hashing::validatePassword($password, [
|
||||
$user->passwordAlgo,
|
||||
$user->passwordIter,
|
||||
$user->passwordSalt,
|
||||
$user->passwordHash,
|
||||
])) {
|
||||
return [0, 'INCORRECT_PASSWORD', $user->id, $user->passwordChan];
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the user has the required privs to log in
|
||||
if ($user->permission(Site::DEACTIVATED)) {
|
||||
return [0, 'NOT_ALLOWED', $user->id];
|
||||
}
|
||||
|
||||
// Create a new session
|
||||
$session = new Session($user->id);
|
||||
|
||||
// Generate a session key
|
||||
$sessionKey = $session->create($remember);
|
||||
|
||||
// Set cookies
|
||||
if ($cookies) {
|
||||
// User ID cookie
|
||||
setcookie(
|
||||
Config::get('cookie_prefix') . 'id',
|
||||
$user->id,
|
||||
time() + 604800,
|
||||
Config::get('cookie_path')
|
||||
);
|
||||
|
||||
// Session ID cookie
|
||||
setcookie(
|
||||
Config::get('cookie_prefix') . 'session',
|
||||
$sessionKey,
|
||||
time() + 604800,
|
||||
Config::get('cookie_path')
|
||||
);
|
||||
}
|
||||
|
||||
// Successful login! (also has a thing for the legacy password system)
|
||||
return [1, 'LOGIN_SUCCESS', $user->id];
|
||||
}
|
||||
|
||||
/**
|
||||
* Logout
|
||||
*
|
||||
* @return bool Was the logout successful?
|
||||
*/
|
||||
public static function logout()
|
||||
{
|
||||
// Check if user is logged in
|
||||
if (!$check = self::checkLogin()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Destroy the active session
|
||||
(new Session($check[0], $check[1]))->destroy();
|
||||
|
||||
// Unset User ID
|
||||
setcookie(
|
||||
Config::get('cookie_prefix') . 'id',
|
||||
0,
|
||||
time() - 60,
|
||||
Config::get('cookie_path')
|
||||
);
|
||||
|
||||
// Unset Session ID
|
||||
setcookie(
|
||||
Config::get('cookie_prefix') . 'session',
|
||||
'',
|
||||
time() - 60,
|
||||
Config::get('cookie_path')
|
||||
);
|
||||
|
||||
// Return true indicating a successful logout
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a new account.
|
||||
*
|
||||
|
|
|
@ -65,16 +65,11 @@ if (isset($_REQUEST['mode'])) {
|
|||
if ($continue) {
|
||||
switch ($_REQUEST['mode']) {
|
||||
case 'logout':
|
||||
// Attempt logout
|
||||
$logout = Users::logout();
|
||||
|
||||
// Add page specific data
|
||||
// Add page specific things
|
||||
$renderData['page'] = [
|
||||
|
||||
'redirect' => ($logout ? $_REQUEST['redirect'] : $urls->format('SITE_LOGIN')),
|
||||
'message' => $logout ? 'You are now logged out.' : 'An unknown error occurred.',
|
||||
'success' => $logout ? 1 : 0,
|
||||
|
||||
'redirect' => Router::route('main.index'),
|
||||
'message' => 'Wrong logout page.',
|
||||
'success' => 0,
|
||||
];
|
||||
break;
|
||||
|
||||
|
@ -165,41 +160,11 @@ if (isset($_REQUEST['mode'])) {
|
|||
|
||||
// Login processing
|
||||
case 'login':
|
||||
// Attempt login
|
||||
$login = Users::login($_REQUEST['username'], $_REQUEST['password'], isset($_REQUEST['remember']));
|
||||
|
||||
// Array containing "human understandable" messages
|
||||
$messages = [
|
||||
|
||||
'AUTH_LOCKED' => 'Authentication is currently not allowed, try again later.',
|
||||
'USER_NOT_EXIST' => 'The user you tried to log into does not exist.',
|
||||
'INCORRECT_PASSWORD' => 'The password you entered was invalid.',
|
||||
'NOT_ALLOWED' => 'Your account does not have the required permissions to log in.',
|
||||
'NO_LOGIN' => 'Logging into this account is disabled.',
|
||||
'RATE_LIMIT' => 'Your IP has hit the login rate limit, try again later.',
|
||||
'LOGIN_SUCCESS' => 'Login successful!',
|
||||
|
||||
];
|
||||
|
||||
// Check if we're not RATE_LIMIT
|
||||
if ($login[1] != 'RATE_LIMIT') {
|
||||
// Add to database
|
||||
DBv2::prepare('INSERT INTO `{prefix}login_attempts` (`attempt_success`, `attempt_timestamp`, `attempt_ip`, `user_id`) VALUES (:succ, :time, :ip, :user)')
|
||||
->execute([
|
||||
'succ' => $login[0],
|
||||
'time' => time(),
|
||||
'ip' => Net::pton(Net::IP()),
|
||||
'user' => isset($login[2]) ? $login[2] : 0,
|
||||
]);
|
||||
}
|
||||
|
||||
// Add page specific things
|
||||
$renderData['page'] = [
|
||||
|
||||
'redirect' => $login[0] ? (User::construct($login[2])->lastOnline ? $_REQUEST['redirect'] : $urls->format('INFO_PAGE', ['welcome'])) : $urls->format('SITE_LOGIN'),
|
||||
'message' => $messages[$login[1]],
|
||||
'success' => $login[0],
|
||||
|
||||
'redirect' => Router::route('auth.login'),
|
||||
'message' => 'Wrong login page.',
|
||||
'success' => 0,
|
||||
];
|
||||
break;
|
||||
|
||||
|
|
2
public/robots.txt
Normal file
2
public/robots.txt
Normal file
|
@ -0,0 +1,2 @@
|
|||
User-agent: *
|
||||
Disallow: /api/
|
160
routes.php
160
routes.php
|
@ -7,38 +7,40 @@
|
|||
namespace Sakura;
|
||||
|
||||
// Meta pages
|
||||
Router::get('/', 'Meta@index', 'main.index');
|
||||
Router::get('/faq', 'Meta@faq', 'main.faq');
|
||||
Router::get('/search', 'Meta@search', 'main.search');
|
||||
Router::get('/p/{id}', 'Meta@infoPage', 'main.infopage');
|
||||
Router::get('/', 'MetaController@index', 'main.index');
|
||||
Router::get('/faq', 'MetaController@faq', 'main.faq');
|
||||
Router::get('/search', 'MetaController@search', 'main.search');
|
||||
Router::get('/p/{id}', 'MetaController@infoPage', 'main.infopage');
|
||||
|
||||
// Auth
|
||||
Router::get('/login', 'Auth@login', 'auth.login');
|
||||
Router::get('/login', 'AuthController@loginGet', 'auth.login');
|
||||
Router::post('/login', 'AuthController@loginPost', 'auth.login');
|
||||
Router::get('/logout', 'AuthController@logout', 'auth.logout');
|
||||
|
||||
// News
|
||||
Router::get('/news', 'Meta@news', 'news.index');
|
||||
Router::get('/news/{category}', 'Meta@news', 'news.category');
|
||||
Router::get('/news/{category}/{id}', 'Meta@news', 'news.post');
|
||||
Router::get('/news', 'MetaController@news', 'news.index');
|
||||
Router::get('/news/{category}', 'MetaController@news', 'news.category');
|
||||
Router::get('/news/{category}/{id}', 'MetaController@news', 'news.post');
|
||||
|
||||
// Forum
|
||||
Router::get('/forum', 'Forums@index', 'forums.index');
|
||||
Router::get('/forum/{id}', 'Forums@forum', 'forums.forum');
|
||||
Router::get('/forum', 'ForumController@index', 'forums.index');
|
||||
Router::get('/forum/{id}', 'ForumController@forum', 'forums.forum');
|
||||
|
||||
// Members
|
||||
Router::get('/members', 'User@members', 'members.index');
|
||||
Router::get('/members/{rank}', 'User@members', 'members.rank');
|
||||
Router::get('/members', 'UserController@members', 'members.index');
|
||||
Router::get('/members/{rank}', 'UserController@members', 'members.rank');
|
||||
|
||||
// User
|
||||
Router::get('/u/{id}', 'User@profile', 'user.profile');
|
||||
Router::get('/u/{id}/header', 'Files@header', 'user.header');
|
||||
Router::get('/u/{id}', 'UserController@profile', 'user.profile');
|
||||
Router::get('/u/{id}/header', 'FileController@header', 'user.header');
|
||||
|
||||
// Files
|
||||
Router::get('/a/{id}', 'Files@avatar', 'file.avatar');
|
||||
Router::get('/bg/{id}', 'Files@background', 'file.background');
|
||||
Router::get('/a/{id}', 'FileController@avatar', 'file.avatar');
|
||||
Router::get('/bg/{id}', 'FileController@background', 'file.background');
|
||||
|
||||
// Premium
|
||||
Router::get('/support', 'Premium@index', 'premium.index');
|
||||
Router::get('/support/tracker', 'Premium@tracker', 'premium.tracker');
|
||||
Router::get('/support', 'PremiumController@index', 'premium.index');
|
||||
Router::get('/support/tracker', 'PremiumController@tracker', 'premium.tracker');
|
||||
|
||||
// Management
|
||||
/*
|
||||
|
@ -71,125 +73,3 @@ Router::get('/support/tracker', 'Premium@tracker', 'premium.tracker');
|
|||
* - Management
|
||||
* - Errors
|
||||
*/
|
||||
|
||||
// Redirections
|
||||
Router::any('/index.php', function () {
|
||||
// Info pages
|
||||
if (isset($_REQUEST['p'])) {
|
||||
header('Location: /p/' . $_REQUEST['p']);
|
||||
return;
|
||||
}
|
||||
|
||||
// Forum index
|
||||
if (isset($_REQUEST['forum']) && $_REQUEST['forum']) {
|
||||
header('Location: /forum');
|
||||
return;
|
||||
}
|
||||
|
||||
// Site index
|
||||
header('Location: /');
|
||||
});
|
||||
|
||||
Router::any('/news.php', function () {
|
||||
// Category + post
|
||||
if (isset($_REQUEST['cat']) && isset($_REQUEST['id'])) {
|
||||
header('Location: /news/' . $_REQUEST['cat'] . '/'. $_REQUEST['id']);
|
||||
return;
|
||||
}
|
||||
|
||||
// Category
|
||||
if (isset($_REQUEST['cat'])) {
|
||||
header('Location: /news/' . $_REQUEST['cat']);
|
||||
return;
|
||||
}
|
||||
|
||||
// Post in the main category
|
||||
if (isset($_REQUEST['id'])) {
|
||||
header('Location: /news/' . $_REQUEST['id']);
|
||||
return;
|
||||
}
|
||||
|
||||
// All posts in main category
|
||||
header('Location: /news');
|
||||
});
|
||||
|
||||
Router::any('/profile.php', function () {
|
||||
// Redirect to the profile
|
||||
if (isset($_REQUEST['u'])) {
|
||||
header('Location: /u/' . $_REQUEST['u']);
|
||||
return;
|
||||
}
|
||||
|
||||
// Redirect to index
|
||||
header('Location: /');
|
||||
});
|
||||
|
||||
Router::any('/members.php', function () {
|
||||
// Append sort
|
||||
$append = isset($_REQUEST['sort']) ? '?sort=' . $_REQUEST['sort'] : '';
|
||||
|
||||
// Redirect to the profile
|
||||
if (isset($_REQUEST['rank'])) {
|
||||
header('Location: /members/' . $_REQUEST['rank'] . $append);
|
||||
return;
|
||||
}
|
||||
|
||||
// Redirect to index
|
||||
header('Location: /members/' . $append);
|
||||
});
|
||||
|
||||
Router::any('/viewforum.php', function () {
|
||||
// Redirect to the profile
|
||||
if (isset($_REQUEST['f'])) {
|
||||
$req = [];
|
||||
foreach ($_REQUEST as $k => $v) {
|
||||
if ($k == 'f') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$req[] = $k . '=' . $v;
|
||||
}
|
||||
|
||||
header('Location: /forum/' . $_REQUEST['f'] . ($req ? '?' . implode('&', $req) : ''));
|
||||
return;
|
||||
}
|
||||
|
||||
// Redirect to index
|
||||
header('Location: /forum/');
|
||||
});
|
||||
|
||||
Router::any('/support.php', function () {
|
||||
if (isset($_GET['tracker'])) {
|
||||
header('Location: /support/tracker');
|
||||
return;
|
||||
}
|
||||
|
||||
header('Location: /support');
|
||||
});
|
||||
|
||||
Router::any('/imageserve.php', function () {
|
||||
// Category + post
|
||||
if (isset($_REQUEST['u']) && isset($_REQUEST['m'])) {
|
||||
switch ($_REQUEST['m']) {
|
||||
case 'avatar':
|
||||
header('Location: /a/' . $_REQUEST['u']);
|
||||
return;
|
||||
case 'background':
|
||||
header('Location: /bg/' . $_REQUEST['u']);
|
||||
return;
|
||||
case 'header':
|
||||
header('Location: /u/' . $_REQUEST['u'] . '/header');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
header('Location: /bg/0');
|
||||
});
|
||||
|
||||
Router::any('/faq.php', function () {
|
||||
header('Location: /faq');
|
||||
});
|
||||
|
||||
Router::any('/search.php', function () {
|
||||
header('Location: /search');
|
||||
});
|
||||
|
|
16
sakura.php
16
sakura.php
|
@ -8,9 +8,7 @@
|
|||
namespace Sakura;
|
||||
|
||||
// Define Sakura version
|
||||
define('SAKURA_VERSION', '20160219');
|
||||
define('SAKURA_VLABEL', 'Amethyst');
|
||||
define('SAKURA_COLOUR', '#9966CC');
|
||||
define('SAKURA_VERSION', '20160227');
|
||||
|
||||
// Define Sakura Path
|
||||
define('ROOT', __DIR__ . '/');
|
||||
|
@ -27,14 +25,17 @@ mb_internal_encoding('utf-8');
|
|||
|
||||
// Stop the execution if the PHP Version is older than 5.5.0
|
||||
if (version_compare(phpversion(), '5.5.0', '<')) {
|
||||
die('Sakura requires at least PHP 5.5.0, please upgrade to a newer PHP version.');
|
||||
throw new \Exception('Sakura requires at least PHP 5.5.0, please upgrade to a newer PHP version.');
|
||||
}
|
||||
|
||||
// Include third-party libraries
|
||||
if (!@include_once ROOT . 'vendor/autoload.php') {
|
||||
die('Autoloader not found, did you run composer?');
|
||||
// Check if the composer autoloader exists
|
||||
if (!file_exists(ROOT . 'vendor/autoload.php')) {
|
||||
throw new \Exception('Autoloader not found, did you run composer?');
|
||||
}
|
||||
|
||||
// Require composer libraries
|
||||
require_once ROOT . 'vendor/autoload.php';
|
||||
|
||||
// Setup the autoloader
|
||||
spl_autoload_register(function ($className) {
|
||||
// Replace \ with /
|
||||
|
@ -187,6 +188,7 @@ if (!defined('SAKURA_NO_TPL')) {
|
|||
|
||||
'get' => $_GET,
|
||||
'post' => $_POST,
|
||||
'server' => $_SERVER,
|
||||
]);
|
||||
|
||||
// Add the default render data
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<li id="comment-{{ comment.comment_id }}">
|
||||
<div class="comment">
|
||||
<a class="comment-avatar clean" href="{{ urls.format('USER_PROFILE', [comment.comment_poster.id]) }}" style="background-image: url('{{ urls.format('IMAGE_AVATAR', [comment.comment_poster.id]) }}');"><span style="color: {{ comment.comment_poster.colour }};">{{ comment.comment_poster.username }}</span></a>
|
||||
<a class="comment-avatar clean" href="{{ route('user.profile', comment.comment_poster.id) }}" style="background-image: url('{{ route('file.avatar', comment.comment_poster.id) }}');"><span style="color: {{ comment.comment_poster.colour }};">{{ comment.comment_poster.username }}</span></a>
|
||||
<div class="comment-pointer"></div>
|
||||
<div class="comment-content">
|
||||
<div class="comment-controls">
|
||||
|
|
|
@ -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.id]) }}');"></div>
|
||||
<div class="comment-avatar" style="background-image: url('{{ route('file.avatar', 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="" />
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<div id="indexPanel">
|
||||
{% if session.checkLogin %}
|
||||
<div class="head">Hi, {{ user.username }}!</div>
|
||||
<a href="{{ urls.format('SETTING_MODE', ['appearance', 'avatar']) }}"><img src="{{ urls.format('IMAGE_AVATAR', [user.id]) }}" alt="{{ user.username }}" class="default-avatar-setting homepage-menu-avatar" /></a>
|
||||
<a href="{{ urls.format('SETTING_MODE', ['appearance', 'avatar']) }}"><img src="{{ route('file.avatar', user.id) }}" alt="{{ user.username }}" 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">{{ user.friends(-1, true)|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>
|
||||
|
@ -19,32 +19,23 @@
|
|||
Welcome to Flashii! This is a site for a bunch of friends to hang out, nothing special. Anyone is pretty much welcome to register so why not have a go?
|
||||
<div class="indexSidePanelLinks">
|
||||
<a class="fa fa-magic" href="{{ urls.format('SITE_REGISTER') }}" title="Register" id="indexSidePanelRegister"></a>
|
||||
<a class="fa fa-sign-in" href="{{ urls.format('SITE_LOGIN') }}" title="Login" id="indexSidePanelLogin"></a>
|
||||
<a class="fa fa-sign-in" href="{{ route('auth.login') }}" title="Login" id="indexSidePanelLogin"></a>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% 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.id]) }}" style="color: {{ stats.newestUser.colour }};" class="default">{{ stats.newestUser.username }}</a></b> is the newest user,
|
||||
<b><a href="{{ route('user.profile', stats.newestUser.id) }}" style="color: {{ stats.newestUser.colour }};" class="default">{{ stats.newestUser.username }}</a></b> is the newest user,
|
||||
it has been <b>{{ stats.lastRegDate }} day{{ stats.lastRegDate == 1 ? '' : 's' }}</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 {{ sakura.onlineTimeout / 60 }} minute{% if sakura.onlineTimeout != 60 %}s{% endif %}
|
||||
<table class="panelTable">
|
||||
{% for amount,onlineUser in stats.onlineUsers %}
|
||||
<tr><td style="text-align: left;"><a href="{{ urls.format('USER_PROFILE', [onlineUser.id]) }}" style="font-weight: bold; color: {{ onlineUser.colour }};" class="default">{{ onlineUser.username }}</a></td><td style="text-align: right;"><time>{{ onlineUser.lastOnline|date(sakura.dateFormat) }}</time></td></tr>
|
||||
<tr><td style="text-align: left;"><a href="{{ route('user.profile', onlineUser.id) }}" style="font-weight: bold; color: {{ onlineUser.colour }};" class="default">{{ onlineUser.username }}</a></td><td style="text-align: right;"><time>{{ onlineUser.lastOnline|date(sakura.dateFormat) }}</time></td></tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% else %}
|
||||
There were no online users in the past {{ sakura.onlineTimeout / 60 }} minute{% if sakura.onlineTimeout != 60 %}s{% endif %}.
|
||||
{% endif %}
|
||||
{% if not user.permission(constant('Sakura\\Perms\\Site::CHANGE_BACKGROUND')) or user.mainRankId == 4 %}
|
||||
<div class="ad-container ad-sidebar" id="sideAd">
|
||||
<div class="ad-box">
|
||||
<a href="http://jbox.com/r.php??&acc=269&___store=jlist&bannerid=28" target="_blank">
|
||||
<img src="https://jlist.com/js/magestore/affiliateplus/banner.php?id=28&account_id=269&store_id=2" alt="250x250 PG senpai shirt" title="250x250 PG senpai shirt" width="250" height="250" />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
{% if not (viewPost and postExists) %}<a href="{{ urls.format('SITE_NEWS_CAT_POST', [post.news_category, post.news_id]) }}" class="news-head" id="{{ post.news_category }}_{{ post.news_id }}">{{ post.news_title }}</a>{% endif %}
|
||||
{% if not (viewPost and postExists) %}<a href="{{ route('news.post', [post.news_category, 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.news_poster.id]) }}">
|
||||
<a class="no-underline" href="{{ route('user.profile', post.news_poster.id) }}">
|
||||
<div class="news-poster">
|
||||
<img src="{{ urls.format('IMAGE_AVATAR', [post.news_poster.id]) }}" alt="{{ post.news_poster.username }}" class="default-avatar-setting" />
|
||||
<img src="{{ route('file.avatar', post.news_poster.id) }}" alt="{{ post.news_poster.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.username }}</h1>
|
||||
</div>
|
||||
</a>
|
||||
|
@ -12,5 +12,5 @@
|
|||
</div>
|
||||
<div class="clear"></div>
|
||||
<div class="news-post-time">
|
||||
Posted <time>{{ post.news_timestamp|date(sakura.dateFormat) }}</time>{% if not (viewPost and postExists) %} <a class="default" href="{{ urls.format('SITE_NEWS_CAT_POST', [post.news_category, post.news_id]) }}#comments">{{ post.news_comments.count }} comment{% if post.news_comments.count != 1 %}s{% endif %}</a>{% endif %}
|
||||
Posted <time>{{ post.news_timestamp|date(sakura.dateFormat) }}</time>{% if not (viewPost and postExists) %} <a class="default" href="{{ route('news.post', [post.news_category, post.news_id]) }}#comments">{{ post.news_comments.count }} comment{% if post.news_comments.count != 1 %}s{% endif %}</a>{% endif %}
|
||||
</div>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
{% if forum.type == 1 %}
|
||||
{% if forum.forums|length and forum.permission(constant('Sakura\\Perms\\Forum::VIEW'), user.id) %}
|
||||
<div class="forumCategory">
|
||||
{% if forum.type != 1 %}Subforums{% else %}<a href="{{ urls.format('FORUM_SUB', [forum.id]) }}" class="clean">{{ forum.name }}</a>{% endif %}
|
||||
{% if forum.type != 1 %}Subforums{% else %}<a href="{{ route('forums.forum', forum.id) }}" class="clean">{{ forum.name }}</a>{% endif %}
|
||||
</div>
|
||||
{% for forum in forum.forums %}
|
||||
{% include 'forum/forumEntry.twig' %}
|
||||
|
@ -19,7 +19,7 @@
|
|||
{% set threads = forum.threads|batch(25) %}
|
||||
|
||||
{% set paginationPages = threads %}
|
||||
{% set paginationUrl %}{{ urls.format('FORUM_SUB', [forum.id]) }}{% endset %}
|
||||
{% set paginationUrl %}{{ route('forums.forum', forum.id) }}{% endset %}
|
||||
|
||||
{% include 'forum/forumBtns.twig' %}
|
||||
{% if forum.threads %}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<div class="forumForum">
|
||||
<div class="forumIcon {% if forum.unread(user.id) %}unread {% endif %}fa fa-3x {% if forum.icon %}{{ forum.icon }}{% else %}{% if forum.type == 2 %}fa-chevron-circle-right{% elseif forum.type == 1 %}fa-folder{% else %}fa-comments{% endif %}{% endif %}"></div>
|
||||
<div class="forumTitle">
|
||||
<div class="name"><a href="{% if forum.type == 2 %}{{ forum.link }}{% else %}{{ urls.format('FORUM_SUB', [forum.id]) }}{% endif %}" class="default">{{ forum.name }}</a></div>
|
||||
<div class="name"><a href="{% if forum.type == 2 %}{{ forum.link }}{% else %}{{ route('forums.forum', forum.id) }}{% endif %}" class="default">{{ forum.name }}</a></div>
|
||||
<div class="desc">
|
||||
{{ forum.description }}
|
||||
{% if forum.forums|length %}
|
||||
|
|
|
@ -73,36 +73,36 @@
|
|||
<div id="container">
|
||||
<span id="top"></span>
|
||||
<div class="header" id="header">
|
||||
<a class="logo" href="{{ urls.format('SITE_HOME') }}">{% if sakura.siteLogo %}<img src="{{ sakura.siteLogo }}" alt="{{ sakura.siteName }}" />{% else %}{{ sakura.siteName }}{% endif %}</a>
|
||||
<a class="logo" href="{{ route('main.index') }}">{% if sakura.siteLogo %}<img src="{{ sakura.siteLogo }}" alt="{{ sakura.siteName }}" />{% else %}{{ sakura.siteName }}{% endif %}</a>
|
||||
<div class="menu fa">
|
||||
<div class="menu-nav" id="navMenuSite">
|
||||
<!-- Navigation menu, displayed on left side of the bar. -->
|
||||
<a class="menu-item fa-home" href="{{ urls.format('SITE_HOME') }}" title="Home"></a>
|
||||
<a class="menu-item fa-newspaper-o" href="{{ urls.format('SITE_NEWS') }}" title="News"></a>
|
||||
<a class="menu-item fa-commenting" href="{{ urls.format('INFO_PAGE', ['chat']) }}" title="Chat"></a>
|
||||
<a class="menu-item fa-list" href="{{ urls.format('FORUM_INDEX') }}" title="Forums"></a>
|
||||
<a class="menu-item fa-search" href="{{ urls.format('SITE_SEARCH') }}" title="Search"></a>
|
||||
<a class="menu-item fa-home" href="{{ route('main.index') }}" title="Home"></a>
|
||||
<a class="menu-item fa-newspaper-o" href="{{ route('news.index') }}" title="News"></a>
|
||||
<a class="menu-item fa-commenting" href="{{ route('main.infopage', 'chat') }}" title="Chat"></a>
|
||||
<a class="menu-item fa-list" href="{{ route('forums.index') }}" title="Forums"></a>
|
||||
<a class="menu-item fa-search" href="{{ route('main.search') }}" title="Search"></a>
|
||||
{% if session.checkLogin %}
|
||||
<a class="menu-item fa-users" href="{{ urls.format('MEMBERLIST_INDEX') }}" title="Members"></a>
|
||||
<a class="menu-item fa-heart" href="{{ urls.format('SITE_PREMIUM') }}" title="Support us"></a>
|
||||
<a class="menu-item fa-users" href="{{ route('members.index') }}" title="Members"></a>
|
||||
<a class="menu-item fa-heart" href="{{ route('premium.index') }}" title="Support us"></a>
|
||||
{% endif %}
|
||||
</div>
|
||||
<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.id]) }}" title="Logged in as {{ user.username }}" style="background-image: url('{{ urls.format('IMAGE_AVATAR', [user.id]) }}'); width: auto; color: {{ user.colour }}; border-color: {{ user.colour }}; font-weight: 700;"></a>
|
||||
<a class="menu-item avatar" href="{{ route('user.profile', user.id) }}" title="Logged in as {{ user.username }}" style="background-image: url('{{ route('file.avatar', 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>#}
|
||||
{% if user.permission(constant('Sakura\\Perms\\Manage::USE_MANAGE'), constant('Sakura\\Perms::MANAGE')) %}
|
||||
<a class="menu-item fa-gavel" href="{{ urls.format('MANAGE_INDEX') }}" title="Manage"></a>
|
||||
{% endif %}
|
||||
<a class="menu-item fa-cogs" href="{{ urls.format('SETTINGS_INDEX') }}" title="Settings"></a>
|
||||
<a class="menu-item fa-sign-out" href="{{ urls.format('USER_LOGOUT', [php.time, php.sessionid, sakura.currentPage]) }}" title="Logout" id="headerLogoutLink"></a>
|
||||
<a class="menu-item fa-sign-out" href="{{ route('auth.logout') }}?s={{ php.sessionid }}" title="Logout" id="headerLogoutLink"></a>
|
||||
{% else %}
|
||||
{% if sakura.lockAuth %}
|
||||
<div class="menu-item fa-lock" style="padding-left: 10px; padding-right: 10px;" title="Authentication is locked"></div>
|
||||
{% else %}
|
||||
<a class="menu-item fa-magic" href="{{ urls.format('SITE_REGISTER') }}" title="Login"></a>
|
||||
<a class="menu-item fa-sign-in" href="{{ urls.format('SITE_LOGIN') }}" title="Login"></a>
|
||||
<a class="menu-item fa-sign-in" href="{{ route('auth.login') }}" title="Login"></a>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</div>
|
||||
|
@ -113,8 +113,8 @@
|
|||
{% if php.self == '/profile.php' ? profile.background : (user.permission(constant('Sakura\\Perms\\Site::CHANGE_BACKGROUND')) and user.optionFields.profileBackgroundSiteWide and user.background) %}
|
||||
<div id="userBackground" style="background-image: url('{{ urls.format('IMAGE_BACKGROUND', [(php.self == '/profile.php' ? profile : user).id]) }}');"></div>
|
||||
{% endif %}
|
||||
{% if not session.checkLogin and php.self != '/authenticate.php' %}
|
||||
<form method="post" action="{{ urls.format('AUTH_ACTION') }}" id="headerLoginForm">
|
||||
{% if not session.checkLogin and sakura.currentPage != route('auth.login') %}
|
||||
<form method="post" action="{{ route('auth.login') }}" id="headerLoginForm">
|
||||
<input type="hidden" name="redirect" value="{{ sakura.currentPage }}" />
|
||||
<input type="hidden" name="session" value="{{ php.sessionid }}" />
|
||||
<input type="hidden" name="time" value="{{ php.time }}" />
|
||||
|
@ -161,32 +161,22 @@
|
|||
{% block content %}
|
||||
<h1 class="stylised" style="text-align: center; margin: 2em auto;">{{ php.self }} is now printing!</h1>
|
||||
{% endblock %}
|
||||
|
||||
{% if not user.permission(constant('Sakura\\Perms\\Site::CHANGE_BACKGROUND')) or user.mainRankId == 4 %}
|
||||
<div class="ad-container ad-footer" id="footerAd">
|
||||
<div class="ad-box">
|
||||
<a href="http://jbox.com/r.php??series/touhou&acc=269&___store=jlist&bannerid=8" target="_blank">
|
||||
<img src="https://jlist.com/js/magestore/affiliateplus/banner.php?id=8&account_id=269&store_id=2" alt="728x90 PG -- Touhou 1" title="728x90 PG -- Touhou 1" width="728" height="90" />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="footer">
|
||||
<div class="ftsections">
|
||||
<div class="copycentre">Powered by <a href="https://github.com/flashwave/sakura/" target="_blank">Sakura</a>{% if sakura.dev.showChangelog %} <a href="https://sakura.flash.moe/#r{{ sakura.versionInfo.version }}" target="_blank">r{{ sakura.versionInfo.version }}</a>{% endif %} © 2013-2016 <a href="http://flash.moe/" target="_blank">Flashwave</a></div>
|
||||
<ul class="ftsection">
|
||||
<li class="fthead">General</li>
|
||||
<li><a href="{{ urls.format('SITE_HOME') }}" title="Flashii Frontpage">Home</a></li>
|
||||
<li><a href="{{ urls.format('SITE_NEWS') }}" title="Flashii News & Updates">News</a></li>
|
||||
<li><a href="{{ urls.format('SITE_SEARCH') }}" title="Do full-site search requests">Search</a></li>
|
||||
<li><a href="{{ urls.format('INFO_PAGE', ['contact']) }}" title="Contact our Staff">Contact</a></li>
|
||||
<li><a href="{{ route('main.index') }}" title="Flashii Frontpage">Home</a></li>
|
||||
<li><a href="{{ route('news.index') }}" title="Flashii News & Updates">News</a></li>
|
||||
<li><a href="{{ route('main.search') }}" title="Do full-site search requests">Search</a></li>
|
||||
<li><a href="{{ route('main.infopage', 'contact') }}" title="Contact our Staff">Contact</a></li>
|
||||
<li><a href="https://sakura.flash.moe" target="_blank" title="All the changes made to Sakura are listed here">Changelog</a></li>
|
||||
<li><a href="{{ urls.format('SITE_PREMIUM') }}" title="Get Tenshi and help us pay the bills">Support us</a></li>
|
||||
<li><a href="{{ route('premium.index') }}" title="Get Tenshi and help us pay the bills">Support us</a></li>
|
||||
</ul>
|
||||
<ul class="ftsection">
|
||||
<li class="fthead">Community</li>
|
||||
<li><a href="{{ urls.format('FORUM_INDEX') }}" title="Read and post on our forums">Forums</a></li>
|
||||
<li><a href="{{ route('forums.index') }}" title="Read and post on our forums">Forums</a></li>
|
||||
<li><a href="https://twitter.com/_flashii" target="_blank" title="Follow us on Twitter for news messages that are too short for the news page">Twitter</a></li>
|
||||
<li><a href="https://youtube.com/user/flashiinet" target="_blank" title="Our YouTube page where stuff barely ever gets uploaded, mainly used to archive community creations">YouTube</a></li>
|
||||
<li><a href="https://steamcommunity.com/groups/flashiinet" target="_blank" title="Our Steam group, play games with other members on the site">Steam</a></li>
|
||||
|
@ -194,73 +184,15 @@
|
|||
</ul>
|
||||
<ul class="ftsection">
|
||||
<li class="fthead">Information</li>
|
||||
<li><a href="{{ urls.format('SITE_FAQ') }}" title="Questions that get Asked Frequently but not actually">FAQ</a></li>
|
||||
<li><a href="{{ urls.format('INFO_PAGE', ['rules']) }}" title="Some Rules and Information kind of summing up the ToS">Rules</a></li>
|
||||
<li><a href="{{ route('main.faq') }}" title="Questions that get Asked Frequently but not actually">FAQ</a></li>
|
||||
<li><a href="{{ route('main.infopage', 'rules') }}" title="Some Rules and Information kind of summing up the ToS">Rules</a></li>
|
||||
<li><a href="//fiistat.us" target="_blank" title="Check the status on our Servers and related services">Server Status</a></li>
|
||||
<li><a href="{{ urls.format('INFO_PAGE', ['terms']) }}" title="Our Terms of Service">Terms of Service</a></li>
|
||||
<li><a href="{{ route('main.infopage', 'terms') }}" title="Our Terms of Service">Terms of Service</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
// Space for things that need to happen onload
|
||||
window.addEventListener("load", function() {
|
||||
{% if session.checkLogin %}
|
||||
// Convert href to object in logout link
|
||||
prepareAjaxLink('headerLogoutLink', 'submitPost', ', true, "Logging out..."');
|
||||
{% elseif not sakura.lockAuth and php.self != '/authenticate.php' %}
|
||||
// Make the header login form dynamic
|
||||
prepareAjaxForm('headerLoginForm', 'Logging in...');
|
||||
{% endif %}
|
||||
|
||||
{% if session.checkLogin %}
|
||||
// Make notification requests (there's a seperate one to make it happen before the first 60 seconds)
|
||||
notifyRequest('{{ php.sessionid }}');
|
||||
|
||||
// Create interval
|
||||
setInterval(function() {
|
||||
notifyRequest('{{ php.sessionid }}');
|
||||
}, 60000);
|
||||
{% endif %}
|
||||
|
||||
{% if php.self == '/profile.php' and session.checkLogin and user.id != profile.id %}
|
||||
// Make friend button dynamic
|
||||
prepareAjaxLink('profileFriendToggle', 'submitPost', ', true, "{% if profile.friend == 0 %}Adding{% else %}Removing{% endif %} friend..."');
|
||||
{% endif %}
|
||||
|
||||
{% if php.self == '/viewtopic.php' and session.checkLogin %}
|
||||
var forumFriendToggles = document.querySelectorAll('.forum-friend-toggle');
|
||||
|
||||
for(var i in forumFriendToggles) {
|
||||
prepareAjaxLink(forumFriendToggles[i], 'submitPost', ', true, "Please wait..."');
|
||||
}
|
||||
{% endif %}
|
||||
|
||||
{% if php.self == '/authenticate.php' and not (sakura.lockAuth or session.checkLogin) %}
|
||||
|
||||
// AJAX Form Submission
|
||||
var forms = {
|
||||
{% if not auth.changingPass %}
|
||||
"loginForm": 'Logging in...',
|
||||
{% if not sakura.disableRegistration %}
|
||||
"registerForm": 'Processing registration...',
|
||||
{% endif %}
|
||||
{% if sakura.requireActivation %}
|
||||
"resendForm": 'Attempting to resend activation...',
|
||||
{% endif %}
|
||||
"passwordForm": 'Sending password recovery mail...'
|
||||
{% else %}
|
||||
"passwordForm": 'Changing password...'
|
||||
{% endif %}
|
||||
};
|
||||
|
||||
for(var i in forms) {
|
||||
prepareAjaxForm(i, forms[i], (i == 'registerForm'));
|
||||
}
|
||||
|
||||
{% endif %}
|
||||
});
|
||||
|
||||
// Parse time elements
|
||||
var timeElems = document.getElementsByTagName('time');
|
||||
|
||||
|
@ -308,7 +240,7 @@
|
|||
changelogLink.href = 'https://sakura.flash.moe/#r{{ sakura.versionInfo.version }}';
|
||||
|
||||
// Create the text container
|
||||
var changelogTitleText = document.createTextNode('Changelog');
|
||||
var changelogTitleText = document.createTextNode('Changelog ({{ sakura.versionInfo.version|slice(0, 4) }}-{{ sakura.versionInfo.version|slice(4, 2) }}-{{ sakura.versionInfo.version|slice(6, 2) }})');
|
||||
|
||||
// Append everything
|
||||
changelogLink.appendChild(changelogTitleText);
|
||||
|
|
|
@ -7,35 +7,6 @@
|
|||
<h1 class="stylised" style="line-height: 1.8em; text-align: center;">Authentication is currently disallowed, try again later.</h1>
|
||||
{% else %}
|
||||
<div class="loginPage">
|
||||
<div class="loginForm">
|
||||
<div class="head">
|
||||
Login to {{ sakura.siteName }}
|
||||
</div>
|
||||
<form method="post" action="{{ urls.format('AUTH_ACTION') }}" id="loginForm">
|
||||
<input type="hidden" name="redirect" value="{{ auth.redirect }}" />
|
||||
<input type="hidden" name="session" value="{{ php.sessionid }}" />
|
||||
<input type="hidden" name="time" value="{{ php.time }}" />
|
||||
<input type="hidden" name="mode" value="login" />
|
||||
<div class="leftAlign">
|
||||
<label for="loginUserName">Username:</label>
|
||||
</div>
|
||||
<div class="centreAlign">
|
||||
<input class="inputStyling" type="text" id="loginUserName" name="username" autofocus="true" />
|
||||
</div>
|
||||
<div class="leftAlign">
|
||||
<label for="loginPassword">Password:</label>
|
||||
</div>
|
||||
<div class="centreAlign">
|
||||
<input class="inputStyling" type="password" id="loginPassword" name="password" />
|
||||
</div>
|
||||
<div class="subLinks centreAlign">
|
||||
<input class="inputStyling" name="remember" type="checkbox" class="ignore-css" id="loginRemember" /><label for="loginRemember">Remember Me</a>
|
||||
</div>
|
||||
<div class="centreAlign">
|
||||
<input class="inputStyling" type="submit" id="loginButton" name="submit" value="Login" />
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="passwordForm">
|
||||
<div class="head">
|
||||
Lost Password
|
||||
|
|
|
@ -21,11 +21,10 @@
|
|||
<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="{{ route('user.profile', ban.issuer.id) }}" class="default">{{ ban.issuer.username }}</a>.</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<iframe src="https://www.youtube.com/embed/Tao67Idz3Uc?autoplay=1&loop=1&playlist=Tao67Idz3Uc" style="display: none;"></iframe>
|
||||
{% endblock %}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
{% block content %}
|
||||
<div class="content standalone bbcode">
|
||||
<div>
|
||||
{{ page.content|raw }}
|
||||
{{ include(template_from_string(page.content|raw)) }}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
{% extends 'global/master.twig' %}
|
||||
|
||||
{% block title %}Authentication{% endblock %}
|
||||
{% block title %}Login{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% if sakura.lockAuth %}
|
||||
<h1 class="stylised" style="line-height: 1.8em; text-align: center;">Authentication is currently disallowed, try again later.</h1>
|
||||
<h1 class="stylised" style="line-height: 1.8em; text-align: center;">Logging in is disabled for security checkups! Try again later.</h1>
|
||||
{% else %}
|
||||
<div class="loginPage">
|
||||
<div class="loginForm">
|
||||
<div class="head">
|
||||
Login to {{ sakura.siteName }}
|
||||
Login
|
||||
</div>
|
||||
<form method="post" action="{{ urls.format('AUTH_ACTION') }}" id="loginForm">
|
||||
<input type="hidden" name="redirect" value="{{ auth.redirect }}" />
|
||||
<form method="post" action="{{ route('auth.login') }}" id="loginForm">
|
||||
<input type="hidden" name="redirect" value="{{ sakura.referrer ? sakura.referrer : route('main.index') }}" />
|
||||
<input type="hidden" name="session" value="{{ php.sessionid }}" />
|
||||
<input type="hidden" name="time" value="{{ php.time }}" />
|
||||
<input type="hidden" name="mode" value="login" />
|
||||
|
@ -34,6 +34,9 @@
|
|||
<div class="centreAlign">
|
||||
<input class="inputStyling" type="submit" id="loginButton" name="submit" value="Login" />
|
||||
</div>
|
||||
<div class="subLinks centreAlign">
|
||||
future links to password forgot, reactivate and register here
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -3,44 +3,44 @@
|
|||
{% set sorts = ['boxes', 'rectangles', 'list'] %}
|
||||
{% set sort = get.sort in sorts ? get.sort : sorts[0] %}
|
||||
|
||||
{% set notfound = memberlist.active == 0 and get.rank is defined %}
|
||||
{% set notfound = rank == 0 %}
|
||||
|
||||
{% set rankTitle %}
|
||||
{% if notfound %}Not found{% else %}{% if not memberlist.active %}All members{% else %}{{ memberlist.ranks[memberlist.active].name(true) }}{% endif %}{% endif %}
|
||||
{% if notfound %}Not found{% else %}{{ ranks[rank].name(true) }}{% endif %}
|
||||
{% endset %}
|
||||
|
||||
{% set rankDescription %}
|
||||
{% if notfound %}The requested rank could not be found!{% else %}{% if not memberlist.active %}The entire user list.{% else %}{{ memberlist.ranks[memberlist.active].description }}{% endif %}{% endif %}
|
||||
{% if notfound %}The requested rank could not be found!{% else %}{{ ranks[rank].description }}{% endif %}
|
||||
{% endset %}
|
||||
|
||||
{% set users = memberlist.users|batch(memberlist.membersPerPage) %}
|
||||
{% set users = ranks[rank].users|batch(membersPerPage) %}
|
||||
|
||||
{% set currPage = get.page|default(1) - 1 %}
|
||||
|
||||
{% set paginationPages = users %}
|
||||
{% set paginationUrl %}{% if sort and memberlist.active %}{{ urls.format('MEMBERLIST_ALL', [sort, memberlist.active]) }}{% elseif sort %}{{ urls.format('MEMBERLIST_SORT', [sort]) }}{% elseif memberlist.active %}{{ urls.format('MEMBERLIST_RANK', [memberlist.active]) }}{% else %}{{ urls.format('MEMBERLIST_INDEX') }}{% endif %}{% endset %}
|
||||
{% set paginationUrl %}{% if rank %}{{ route('members.rank', rank) }}{% else %}{{ route('members.index') }}{% endif %}{% endset %}
|
||||
|
||||
{% block title %}{{ rankTitle }}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="headerNotify" style="margin-bottom: 1px;">
|
||||
<h1 style="{% if memberlist.active %}text-shadow: 0 0 5px {{ memberlist.ranks[memberlist.active].colour }}; color: {{ memberlist.ranks[memberlist.active].colour }};{% else %}text-shadow: 0 0 5px #555;{% endif %}">{{ rankTitle }}</h1>
|
||||
<h1 style="{% if rank %}text-shadow: 0 0 5px {{ ranks[rank].colour }}; color: {{ ranks[rank].colour }};{% else %}text-shadow: 0 0 5px #555;{% endif %}">{{ rankTitle }}</h1>
|
||||
<h3>{{ rankDescription }}</h3>
|
||||
</div>
|
||||
<div class="membersPage" style="min-height: 500px;">
|
||||
<div class="dropDown" style="margin: 0 auto; font-size: 1.5em; line-height: 1.5em; height: 30px;">
|
||||
<div class="dropDownInner" style="float: left; color: #FFF;">
|
||||
<a class="dropDownDesc">Rank:</a>
|
||||
{% for rank in memberlist.ranks %}
|
||||
{% if not rank.hidden or (rank.hidden and memberlist.active == rank.id) %}
|
||||
<a href="{{ urls.format('MEMBERLIST_RANK', [rank.id]) }}" style="color: {{ rank.colour }};"{% if memberlist.active == rank.id %} class="dropDownSelected"{% endif %}>{{ rank.name(true) }}</a>
|
||||
{% for r in ranks %}
|
||||
{% if not r.hidden or (r.hidden and rank == r.id) %}
|
||||
<a href="{{ route('members.rank', r.id) }}{{ server['QUERY_STRING'] ? '?' : '' }}{{ server['QUERY_STRING'] }}" style="color: {{ r.colour }};"{% if rank == r.id %} class="dropDownSelected"{% endif %}>{{ r.id == 0 ? 'Not found' : r.name(true) }}</a>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="dropDownInner" style="float: left;">
|
||||
<a class="dropDownDesc">View:</a>
|
||||
{% for s in sorts %}
|
||||
<a href="{% if memberlist.active %}{{ urls.format('MEMBERLIST_ALL', [s, memberlist.active]) }}{% else %}{{ urls.format('MEMBERLIST_SORT', [s]) }}{% endif %}"{% if s == sort %} class="dropDownSelected"{% endif %}>{{ s|capitalize }}</a>
|
||||
<a href="?{{ server['QUERY_STRING'] }}{{ server['QUERY_STRING'] ? '&' : '' }}sort={{ s }}"{% if s == sort %} class="dropDownSelected"{% endif %}>{{ s|capitalize }}</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -74,10 +74,10 @@
|
|||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
#{{ memberlist.active ? count + 1 : count }}
|
||||
#{{ rank ? count + 1 : count }}
|
||||
</td>
|
||||
<td>
|
||||
<a href="{{ urls.format('USER_PROFILE', [user.id]) }}" class="default" style="font-weight: bold; color: {{ user.colour }}; text-shadow: 0 0 5px {{ user.colour }};">{{ user.username }}</a>
|
||||
<a href="{{ route('user.profile', user.id) }}" class="default" style="font-weight: bold; color: {{ user.colour }}; text-shadow: 0 0 5px {{ user.colour }};">{{ user.username }}</a>
|
||||
</td>
|
||||
<td>
|
||||
<time>{{ user.registered|date(sakura.dateFormat) }}</time>
|
||||
|
@ -97,9 +97,9 @@
|
|||
</table>
|
||||
{% else %}
|
||||
{% for user in users[currPage] %}
|
||||
<a href="{{ urls.format('USER_PROFILE', [user.id]) }}">{# These comment tags are here to prevent the link extending too far
|
||||
<a href="{{ route('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;" />{#
|
||||
#}<img src="{{ sakura.contentPath }}/pixel.png" alt="{{ user.username }}" style="background: url('{{ route('file.avatar', user.id) }}') no-repeat center / contain;" />{#
|
||||
#}<span class="userBoxUserName" style="color: {{ user.colour }};">{#
|
||||
#}{{ user.username }}{#
|
||||
#}</span>{#
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
{% block title %}{% if profileHidden %}User not found!{% else %}Profile of {{ profile.username }}{% endif %}{% endblock %}
|
||||
|
||||
{% block js %}
|
||||
{% if not profileHidden %}
|
||||
<script type="text/javascript">
|
||||
window.addEventListener('load', function () {
|
||||
// Check if location.hash is set
|
||||
|
@ -55,6 +56,7 @@
|
|||
newMode.className = 'profile-mode-current';
|
||||
}
|
||||
</script>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
@ -65,7 +67,7 @@
|
|||
There are a few possible reasons for this:
|
||||
<ul style="padding-left: 40px;">
|
||||
<li>They changed their username.</li>
|
||||
<li>They may have been <a href="{{ urls.format('SITE_FAQ') }}#abyss" class="default">abyss'd</a>.</li>
|
||||
<li>They may have been restricted.</li>
|
||||
<li>You made a typo.</li>
|
||||
<li>They never existed.</li>
|
||||
</ul>
|
||||
|
@ -74,9 +76,9 @@
|
|||
{% else %}
|
||||
<div class="content new-profile">
|
||||
<div class="new-profile-container">
|
||||
<div class="new-profile-header" style="background-image: url({{ urls.format('IMAGE_HEADER', [profile.id]) }});">
|
||||
<div class="new-profile-header" style="background-image: url({{ route('user.header', profile.id) }});">
|
||||
<div class="new-profile-info">
|
||||
<div class="default-avatar-setting new-profile-avatar" style="background-image: url({{ urls.format('IMAGE_AVATAR', [profile.id]) }}); box-shadow: 0 0 5px #{% if profile.isOnline %}484{% else %}844{% endif %};"></div>
|
||||
<div class="default-avatar-setting new-profile-avatar" style="background-image: url({{ route('file.avatar', profile.id) }}); box-shadow: 0 0 5px #{% if profile.isOnline %}484{% else %}844{% endif %};"></div>
|
||||
<div class="new-profile-username">
|
||||
<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.username }}</h1>
|
||||
{% if profile.isPremium[0] %}<img src="{{ sakura.contentPath }}/images/tenshi.png" alt="Tenshi" style="vertical-align: middle;" /> {% endif %}<img src="{{ sakura.contentPath }}/images/flags/{{ profile.country|lower }}.png" alt="{{ profile.country }}" style="vertical-align: middle;" title="{{ profile.country(true) }}" /> <span style="font-size: .8em;">{{ profile.title }}</span>
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
<div class="head">Support {{ sakura.siteName }}</div>
|
||||
<div style="font-size: .9em; margin-bottom: 10px;">
|
||||
<p>In order to keep the site, its services and improvements on it going I need money but I'm not that big of a fan of asking for money without giving anything special in return thus Tenshi exists. Tenshi is the name for our supporter rank which gives you access to an extra set of features (which are listed further down on this page). With your help we can keep adding new stuff, get new hardware and keep the site awesome!</p>
|
||||
<h3><a href="{{ urls.format('SITE_DONATE_TRACK') }}" class="default">Ever wonder what happens on the financial side of things? View the donation tracker!</a></h3>
|
||||
<h3><a href="{{ route('premium.tracker') }}" class="default">Ever wonder what happens on the financial side of things? View the donation tracker!</a></h3>
|
||||
</div>
|
||||
{% if page.current[0] %}
|
||||
<div class="sectionHeader">
|
||||
|
@ -109,7 +109,7 @@
|
|||
{% endif %}
|
||||
</div>
|
||||
{% if session.checkLogin and user.permission(constant('Sakura\\Perms\\Site::OBTAIN_PREMIUM')) %}
|
||||
<form action="{{ urls.format('SITE_PREMIUM') }}" method="post" id="purchaseForm" class="hidden">
|
||||
<form action="{{ route('premium.index') }}" method="post" id="purchaseForm" class="hidden">
|
||||
<input type="hidden" name="mode" value="purchase" />
|
||||
<input type="hidden" name="time" value="{{ php.time }}" />
|
||||
<input type="hidden" name="session" value="{{ php.sessionid }}" />
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
{% block title %}Donation Tracker{% endblock %}
|
||||
|
||||
{% set paginationPages = tracker.table|batch(20) %}
|
||||
{% set paginationUrl %}{{ urls.format('SITE_DONATE_TRACK') }}{% endset %}
|
||||
{% set paginationUrl %}{{ route('premium.tracker') }}{% endset %}
|
||||
|
||||
{% block css %}
|
||||
<style type="text/css">
|
||||
|
@ -39,7 +39,7 @@
|
|||
{% for supporter in tracker.table|batch(20)[get.page|default(1) - 1] %}
|
||||
<tr>
|
||||
<td>
|
||||
<a href="{{ urls.format('USER_PROFILE', [tracker.users[supporter.user_id].id]) }}" class="default" style="color: {{ tracker.users[supporter.user_id].colour }}; text-shadow: 0 0 7px {% if tracker.users[supporter.user_id].colour != 'inherit' %}{{ tracker.users[supporter.user_id].colour }}{% else %}#222{% endif %};">{{ tracker.users[supporter.user_id].username }}</a>
|
||||
<a href="{{ route('user.profile', tracker.users[supporter.user_id].id) }}" class="default" style="color: {{ tracker.users[supporter.user_id].colour }}; text-shadow: 0 0 7px {% if tracker.users[supporter.user_id].colour != 'inherit' %}{{ tracker.users[supporter.user_id].colour }}{% else %}#222{% endif %};">{{ tracker.users[supporter.user_id].username }}</a>
|
||||
</td>
|
||||
<td style="color: {% if supporter.transaction_amount > 0 %}#0A0{% else %}#A00{% endif %};">
|
||||
€{{ supporter.transaction_amount|number_format(2) }}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{% set friends = profile.friends(2)|batch(12) %}
|
||||
|
||||
{% set paginationPages = friends %}
|
||||
{% set paginationUrl %}{{ urls.format('USER_FRIENDS', [profile.id]) }}{% endset %}
|
||||
{% set paginationUrl %}{{ route('user.profile', profile.id) }}{% endset %}
|
||||
|
||||
<div class="new-profile-mode-title">
|
||||
<h1 class="stylised">Friends</h1>
|
||||
|
@ -9,8 +9,8 @@
|
|||
<div class="profile-friends">
|
||||
{% for friend in friends[get.page|default(1) - 1] %}
|
||||
<div class="friend-container" id="friendslist-friend-{{ friend.id }}">
|
||||
<a class="friends-list-data clean" href="{{ urls.format('USER_PROFILE', [friend.id]) }}">
|
||||
<img src="{{ urls.format('IMAGE_AVATAR', [friend.id]) }}" alt="{{ friend.username }}" class="friends-list-avatar default-avatar-setting" style="width: 150px; height: 150px;" />
|
||||
<a class="friends-list-data clean" href="{{ route('user.profile', friend.id) }}">
|
||||
<img src="{{ route('file.avatar', friend.id) }}" alt="{{ friend.username }}" class="friends-list-avatar default-avatar-setting" style="width: 150px; height: 150px;" />
|
||||
<div class="friends-list-name" style="color: {{ friend.colour }};">{{ friend.username }}</div>
|
||||
</a>
|
||||
</div>
|
||||
|
|
Reference in a new issue