some permission stuff (forum remaining)

This commit is contained in:
flash 2016-11-01 22:14:02 +01:00
parent 13e78189f4
commit 8b6bb48231
29 changed files with 330 additions and 446 deletions

View file

@ -112,48 +112,82 @@ class SetupCommand extends Command
DB::table('ranks')->insert($rank);
}
// Permission data (alumni doesn't have special privs)
$permissions = [
[
'rank_id' => config('rank.inactive'),
'permissions_site' => '00000000000000000000000000000001',
'permissions_manage' => '000',
],
// Permission data
$perms = [
[
'rank_id' => config('rank.regular'),
'permissions_site' => '11110000111111111100111101101100',
'permissions_manage' => '000',
'perm_change_profile' => true,
'perm_change_avatar' => true,
'perm_change_userpage' => true,
'perm_change_signature' => true,
'perm_deactivate_account' => true,
'perm_view_user_links' => true,
'perm_manage_ranks' => true,
'perm_manage_friends' => true,
'perm_comments_create' => true,
'perm_comments_edit' => true,
'perm_comments_delete' => true,
'perm_comments_vote' => true,
],
[
'rank_id' => config('rank.mod'),
'permissions_site' => '11110001111111111111111111111100',
'permissions_manage' => '111',
'perm_change_background' => true,
'perm_change_header' => true,
'perm_change_username' => true,
'perm_change_user_title' => true,
'perm_view_user_details' => true,
'perm_is_mod' => true,
'perm_can_restrict' => true,
'perm_manage_profile_images' => true,
],
[
'rank_id' => config('rank.admin'),
'permissions_site' => '11110111111111111111111111111100',
'permissions_manage' => '111',
],
[
'rank_id' => config('rank.bot'),
'permissions_site' => '11110000111111111100111101101100',
'permissions_manage' => '000',
'perm_change_background' => true,
'perm_change_header' => true,
'perm_change_username' => true,
'perm_change_user_title' => true,
'perm_view_user_details' => true,
'perm_is_mod' => true,
'perm_is_admin' => true,
'perm_can_restrict' => true,
'perm_manage_profile_images' => true,
],
[
'rank_id' => config('rank.premium'),
'permissions_site' => '11110001111111111111111111111100',
'permissions_manage' => '000',
'perm_change_background' => true,
'perm_change_header' => true,
'perm_change_username' => true,
'perm_change_user_title' => true,
],
[
'rank_id' => config('rank.banned'),
'permissions_site' => '11110000000011010100101000100010',
'permissions_manage' => '000',
'perm_change_profile' => false,
'perm_change_avatar' => false,
'perm_change_background' => false,
'perm_change_header' => false,
'perm_change_userpage' => false,
'perm_change_signature' => false,
'perm_change_username' => false,
'perm_change_user_title' => false,
'perm_deactivate_account' => false,
'perm_view_user_links' => false,
'perm_view_user_details' => false,
'perm_manage_ranks' => false,
'perm_manage_friends' => false,
'perm_comments_create' => false,
'perm_comments_edit' => false,
'perm_comments_delete' => false,
'perm_comments_vote' => false,
'perm_is_mod' => false,
'perm_is_admin' => false,
'perm_can_restrict' => false,
'perm_manage_profile_images' => false,
],
];
// Insert all the permission strings into the database
foreach ($permissions as $perm) {
DB::table('permissions')->insert($perm);
// Insert all the permissions into the database
foreach ($perms as $perm) {
DB::table('perms')->insert($perm);
}
// Forum data
@ -194,58 +228,93 @@ class SetupCommand extends Command
[
'forum_id' => 1,
'rank_id' => config('rank.inactive'),
'forum_perms' => '00000000001',
'perm_view' => true,
],
[
'forum_id' => 3,
'rank_id' => config('rank.inactive'),
'forum_perms' => '00000000000',
'perm_view' => false,
],
[
'forum_id' => 1,
'rank_id' => config('rank.regular'),
'forum_perms' => '00000011111',
'perm_view' => true,
'perm_reply' => true,
'perm_topic_create' => true,
'perm_edit' => true,
'perm_delete' => true,
],
[
'forum_id' => 3,
'rank_id' => config('rank.regular'),
'forum_perms' => '00000000000',
'perm_view' => false,
],
[
'forum_id' => 1,
'rank_id' => config('rank.mod'),
'forum_perms' => '11111111111',
'perm_topic_delete' => true,
'perm_topic_move' => true,
'perm_edit_any' => true,
'perm_delete_any' => true,
'perm_change_type' => true,
'perm_change_status' => true,
],
[
'forum_id' => 3,
'rank_id' => config('rank.mod'),
'forum_perms' => '00000111111',
'perm_topic_delete' => true,
'perm_topic_move' => true,
'perm_edit_any' => true,
'perm_delete_any' => true,
'perm_change_type' => true,
],
[
'forum_id' => 1,
'forum_id' => 0,
'rank_id' => config('rank.admin'),
'forum_perms' => '11111111111',
'perm_view' => true,
'perm_reply' => true,
'perm_topic_create' => true,
'perm_topic_delete' => true,
'perm_topic_move' => true,
'perm_edit' => true,
'perm_edit_any' => true,
'perm_delete' => true,
'perm_delete_any' => true,
'perm_bypass_rules' => true,
'perm_change_type' => true,
'perm_change_status' => true,
],
[
'forum_id' => 3,
'rank_id' => config('rank.admin'),
'forum_perms' => '11111111111',
'forum_id' => 0,
'rank_id' => config('rank.banned'),
'perm_reply' => false,
'perm_topic_create' => false,
'perm_topic_delete' => false,
'perm_topic_move' => false,
'perm_edit' => false,
'perm_edit_any' => false,
'perm_delete' => false,
'perm_delete_any' => false,
'perm_bypass_rules' => false,
'perm_change_type' => false,
'perm_change_status' => false,
],
[
'forum_id' => 1,
'rank_id' => config('rank.banned'),
'forum_perms' => '00000000001',
'perm_view' => true,
],
[
'forum_id' => 3,
'rank_id' => config('rank.banned'),
'forum_perms' => '00000000000',
'perm_view' => false,
],
];
// Insert all the forum permissions into the database
foreach ($forum_perms as $fperm) {
DB::table('forum_permissions')->insert($fperm);
DB::table('forum_perms')->insert($fperm);
}
// Bot user
@ -259,6 +328,8 @@ class SetupCommand extends Command
'user_registered' => time(),
'user_last_online' => 0,
'user_country' => 'JP',
'user_activated' => true,
'user_verified' => true,
]);
// Create the actual user object

View file

@ -11,7 +11,6 @@ use Sakura\Config;
use Sakura\CurrentSession;
use Sakura\DB;
use Sakura\Net;
use Sakura\Perms\Site;
use Sakura\User;
/**
@ -107,7 +106,7 @@ class AuthController extends Controller
}
// Check if the user has the required privs to log in
if ($user->permission(Site::DEACTIVATED)) {
if (!$user->activated) {
$this->touchRateLimit($user->id);
$message = 'Your account is deactivated, activate it first!';
$redirect = route('auth.reactivate');
@ -284,7 +283,7 @@ class AuthController extends Controller
}
// Check if the user is already active
if (!$user->permission(Site::DEACTIVATED)) {
if (!$user->activated) {
$message = "Your account is already activated! Why are you here?";
return view('global/information', compact('message', 'redirect'));
}
@ -345,7 +344,7 @@ class AuthController extends Controller
$user = User::construct($getUser[0]->user_id);
// Check if a user is activated
if (!$user->permission(Site::DEACTIVATED)) {
if (!$user->activated) {
$message = "Your account is already activated! Why are you here?";
return view('global/information', compact('message', 'redirect'));
}
@ -389,7 +388,7 @@ class AuthController extends Controller
}
// Check if the user is active
if ($user->permission(Site::DEACTIVATED)) {
if (!$user->activated) {
$message = "Your account is deactivated, go activate it first...";
return view('global/information', compact('message', 'redirect'));
}

View file

@ -10,9 +10,6 @@ use Sakura\Chat\LinkInfo;
use Sakura\Chat\Settings;
use Sakura\Chat\URLResolver;
use Sakura\DB;
use Sakura\Perms;
use Sakura\Perms\Manage;
use Sakura\Perms\Site;
use Sakura\Session;
use Sakura\User;
@ -111,13 +108,14 @@ class ChatController extends Controller
$session = new Session($_GET['arg2'] ?? null);
if ($session->validate($user->id)
&& !$user->permission(Site::DEACTIVATED)
&& !$user->permission(Site::RESTRICTED)) {
&& !$user->activated
&& $user->verified
&& !$user->restricted) {
$hierarchy = $user->hierarchy();
$moderator = $user->permission(Manage::USE_MANAGE, Perms::MANAGE) ? 1 : 0;
$changeName = $user->permission(Site::CHANGE_USERNAME) ? 1 : 0;
$createChans = $user->permission(Site::MULTIPLE_GROUPS) ? 2 : (
$user->permission(Site::CREATE_GROUP) ? 1 : 0
$moderator = $user->perms->isMod || $user->perms->isAdmin ? 1 : 0;
$changeName = $user->perms->changeUsername ? 1 : 0;
$createChans = $user->perms->isAdmin ? 2 : (
$user->perms->isMod ? 1 : 0
);
// The single 0 in here is used to determine log access, which isn't supported by sakurako anymore since it

View file

@ -9,7 +9,6 @@ namespace Sakura\Controllers;
use Sakura\Comment;
use Sakura\Config;
use Sakura\CurrentSession;
use Sakura\Perms\Site;
/**
* Handles comment stuff.
@ -33,7 +32,7 @@ class CommentsController extends Controller
}
// Check if the user can comment
if (!CurrentSession::$user->permission(Site::CREATE_COMMENTS)) {
if (!CurrentSession::$user->perms->commentsCreate) {
$error = "You aren't allowed to make comments!";
return $this->json(compact('error'));
}
@ -74,7 +73,7 @@ class CommentsController extends Controller
public function delete($id = 0)
{
// Check if the user can delete comments
if (!CurrentSession::$user->permission(Site::DELETE_COMMENTS)) {
if (!CurrentSession::$user->perms->commentsDelete) {
$error = "You aren't allowed to delete comments!";
return $this->json(compact('error'));
}
@ -109,7 +108,7 @@ class CommentsController extends Controller
$vote = $vote != 0;
// Check if the user can delete comments
if (!CurrentSession::$user->permission(Site::VOTE_COMMENTS)) {
if (!CurrentSession::$user->perms->commentsVote) {
$error = "You aren't allowed to vote on comments!";
return $this->json(compact('error'));
}

View file

@ -13,9 +13,6 @@ use Sakura\CurrentSession;
use Sakura\DB;
use Sakura\Exceptions\FileException;
use Sakura\File;
use Sakura\Perms;
use Sakura\Perms\Manage;
use Sakura\Perms\Site;
use Sakura\Template;
use Sakura\User;
@ -163,11 +160,13 @@ class FileController extends Controller
$user = User::construct($params[0] ?? 0);
if (session_check()) {
if (!CurrentSession::$user->permission(Manage::CHANGE_IMAGES, Perms::MANAGE)
$perm_var = "change" . ucfirst(strtolower($method));
if (!CurrentSession::$user->perms->manageProfileImages
&& ($user->id !== CurrentSession::$user->id
|| !$user->permission(constant("Sakura\Perms\Site::CHANGE_" . strtoupper($method)))
|| $user->permission(Site::DEACTIVATED)
|| $user->permission(Site::RESTRICTED))
|| !$user->perms->{$perm_var}
|| !$user->activated
|| $user->restricted)
) {
throw new HttpMethodNotAllowedException;
}
@ -199,8 +198,8 @@ class FileController extends Controller
'mime' => getimagesizefromstring($noFile)['mime'],
];
if ($user->permission(Site::DEACTIVATED)
|| $user->permission(Site::RESTRICTED)
if (!$user->activated
|| $user->restricted
|| !$user->{$method}) {
return $this->serve($none['data'], $none['mime'], $none['name']);
}

View file

@ -8,7 +8,6 @@ namespace Sakura\Controllers;
use Sakura\CurrentSession;
use Sakura\Notification;
use Sakura\Perms\Site;
use Sakura\User;
/**
@ -57,8 +56,7 @@ class FriendsController extends Controller
$friend = User::construct($id);
if ($friend->permission(Site::DEACTIVATED)
|| $user->permission(Site::DEACTIVATED)) {
if (!$friend->activated || !$user->activated) {
$error = "The user you tried to add does not exist!";
return $this->json(compact('error'));
}
@ -119,8 +117,7 @@ class FriendsController extends Controller
$friend = User::construct($id);
if ($friend->permission(Site::DEACTIVATED)
|| $user->permission(Site::DEACTIVATED)) {
if (!$friend->activated || !$user->activated) {
$error = "The user you tried to remove does not exist!";
return $this->json(compact('error'));
}

View file

@ -8,7 +8,6 @@ namespace Sakura\Controllers;
use Sakura\CurrentSession;
use Sakura\Notification;
use Sakura\Perms\Site;
/**
* Notification stuff.
@ -34,8 +33,7 @@ class NotificationsController extends Controller
*/
public function mark($id = 0)
{
// Check permission
if (CurrentSession::$user->permission(Site::DEACTIVATED)) {
if (!CurrentSession::$user->activated) {
return '0';
}

View file

@ -11,7 +11,6 @@ use Phroute\Phroute\Exception\HttpMethodNotAllowedException;
use Sakura\Config;
use Sakura\CurrentSession;
use Sakura\Payments;
use Sakura\Perms\Site;
/**
* Premium pages controller.
@ -56,8 +55,9 @@ class PremiumController extends Controller
// Check if the session is valid
if (!session_check()
|| CurrentSession::$user->permission(Site::DEACTIVATED)
|| !CurrentSession::$user->permission(Site::OBTAIN_PREMIUM)) {
|| !CurrentSession::$user->activated
|| !CurrentSession::$user->verified
|| CurrentSession::$user->restricted) {
throw new HttpMethodNotAllowedException();
}

View file

@ -9,7 +9,6 @@ namespace Sakura\Controllers\Settings;
use Phroute\Phroute\Exception\HttpMethodNotAllowedException;
use Sakura\CurrentSession;
use Sakura\DB;
use Sakura\Perms\Site;
/**
* Account settings.
@ -24,8 +23,7 @@ class AccountController extends Controller
*/
public function profile()
{
// Check permission
if (!CurrentSession::$user->permission(Site::ALTER_PROFILE)) {
if (!CurrentSession::$user->perms->changeProfile) {
throw new HttpMethodNotAllowedException();
}
@ -92,12 +90,8 @@ class AccountController extends Controller
public function details()
{
$user = CurrentSession::$user;
// Check permissions
$edit_email = $user->permission(Site::CHANGE_EMAIL);
$edit_usern = $user->permission(Site::CHANGE_USERNAME);
$edit_title = $user->permission(Site::CHANGE_USERTITLE);
$edit_passw = $user->permission(Site::CHANGE_PASSWORD);
$edit_usern = $user->perms->changeUsername;
$edit_title = $user->perms->changeUserTitle;
$last_name_change = 0;
if ($edit_usern) {
@ -222,10 +216,8 @@ class AccountController extends Controller
}
return view('settings/account/details', compact(
'edit_email',
'edit_usern',
'edit_title',
'edit_passw',
'last_name_change',
'username_allow'
));
@ -237,8 +229,7 @@ class AccountController extends Controller
*/
public function ranks()
{
// Check permission
if (!CurrentSession::$user->permission(Site::ALTER_RANKS)) {
if (!CurrentSession::$user->perms->manageRanks) {
throw new HttpMethodNotAllowedException();
}
@ -287,11 +278,7 @@ class AccountController extends Controller
*/
public function userpage()
{
// Check permission
if (!(
CurrentSession::$user->page
&& CurrentSession::$user->permission(Site::CHANGE_USERPAGE)
) && !CurrentSession::$user->permission(Site::CREATE_USERPAGE)) {
if (!CurrentSession::$user->perms->changeUserpage) {
throw new HttpMethodNotAllowedException();
}
@ -325,8 +312,7 @@ class AccountController extends Controller
*/
public function signature()
{
// Check permission
if (!CurrentSession::$user->permission(Site::CHANGE_SIGNATURE)) {
if (!CurrentSession::$user->perms->changeSignature) {
throw new HttpMethodNotAllowedException();
}

View file

@ -8,7 +8,6 @@ namespace Sakura\Controllers\Settings;
use Phroute\Phroute\Exception\HttpMethodNotAllowedException;
use Sakura\CurrentSession;
use Sakura\Perms\Site;
use Sakura\Session;
/**
@ -24,11 +23,6 @@ class AdvancedController extends Controller
*/
public function sessions()
{
// Check permission
if (!CurrentSession::$user->permission(Site::MANAGE_SESSIONS)) {
throw new HttpMethodNotAllowedException();
}
$id = $_POST['id'] ?? null;
$all = isset($_POST['all']);
@ -70,7 +64,7 @@ class AdvancedController extends Controller
*/
public function deactivate()
{
if (!CurrentSession::$user->permission(Site::DEACTIVATE_ACCOUNT)) {
if (!CurrentSession::$user->perms->deactivateAccount) {
throw new HttpMethodNotAllowedException();
}

View file

@ -8,7 +8,6 @@ namespace Sakura\Controllers\Settings;
use Sakura\Controllers\Controller as BaseController;
use Sakura\CurrentSession;
use Sakura\Perms\Site;
use Sakura\Template;
/**
@ -35,39 +34,29 @@ class Controller extends BaseController
$nav = [];
// Account
if (CurrentSession::$user->permission(Site::ALTER_PROFILE)) {
if (CurrentSession::$user->perms->changeProfile) {
$nav["Account"]["Profile"] = route('settings.account.profile');
}
if (CurrentSession::$user->permission(Site::CHANGE_EMAIL)
|| CurrentSession::$user->permission(Site::CHANGE_USERNAME)
|| CurrentSession::$user->permission(Site::CHANGE_USERTITLE)
|| CurrentSession::$user->permission(Site::CHANGE_PASSWORD)) {
$nav["Account"]["Details"] = route('settings.account.details');
}
if (CurrentSession::$user->permission(Site::ALTER_RANKS)) {
if (CurrentSession::$user->perms->manageRanks) {
$nav["Account"]["Ranks"] = route('settings.account.ranks');
}
if ((
CurrentSession::$user->page
&& CurrentSession::$user->permission(Site::CHANGE_USERPAGE)
) || CurrentSession::$user->permission(Site::CREATE_USERPAGE)) {
if (CurrentSession::$user->perms->changeUserpage) {
$nav["Account"]["Userpage"] = route('settings.account.userpage');
}
if (CurrentSession::$user->permission(Site::CHANGE_SIGNATURE)) {
if (CurrentSession::$user->perms->changeSignature) {
$nav["Account"]["Signature"] = route('settings.account.signature');
}
// Friends
if (CurrentSession::$user->permission(Site::MANAGE_FRIENDS)) {
if (CurrentSession::$user->perms->manageFriends) {
$nav["Friends"]["Listing"] = route('settings.friends.listing');
$nav["Friends"]["Requests"] = route('settings.friends.requests');
}
// Advanced
if (CurrentSession::$user->permission(Site::MANAGE_SESSIONS)) {
$nav["Advanced"]["Sessions"] = route('settings.advanced.sessions');
}
if (CurrentSession::$user->permission(Site::DEACTIVATE_ACCOUNT)) {
if (CurrentSession::$user->perms->deactivateAccount) {
$nav["Advanced"]["Deactivate"] = route('settings.advanced.deactivate');
}

View file

@ -8,7 +8,6 @@ namespace Sakura\Controllers\Settings;
use Phroute\Phroute\Exception\HttpMethodNotAllowedException;
use Sakura\CurrentSession;
use Sakura\Perms\Site;
/**
* Friends settings.
@ -23,8 +22,7 @@ class FriendsController extends Controller
*/
public function listing()
{
// Check permission
if (!CurrentSession::$user->permission(Site::MANAGE_FRIENDS)) {
if (!CurrentSession::$user->perms->manageFriends) {
throw new HttpMethodNotAllowedException();
}
@ -37,8 +35,7 @@ class FriendsController extends Controller
*/
public function requests()
{
// Check permission
if (!CurrentSession::$user->permission(Site::MANAGE_FRIENDS)) {
if (!CurrentSession::$user->perms->manageFriends) {
throw new HttpMethodNotAllowedException();
}

View file

@ -11,7 +11,6 @@ use Phroute\Phroute\Exception\HttpRouteNotFoundException;
use Sakura\Config;
use Sakura\CurrentSession;
use Sakura\DB;
use Sakura\Perms\Site;
use Sakura\Rank;
use Sakura\User;
@ -86,8 +85,7 @@ class UserController extends Controller
*/
public function members($rank = null)
{
// Check permission
if (!CurrentSession::$user->permission(Site::VIEW_MEMBERLIST)) {
if (!CurrentSession::$user->activated) {
throw new HttpMethodNotAllowedException;
}

View file

@ -6,8 +6,6 @@
namespace Sakura;
use Sakura\Perms\Site;
/**
* Information about the current active user and session.
* @package Sakura
@ -48,7 +46,7 @@ class CurrentSession
// Check if the session exists and check if the user is activated
if (self::$session->validate($user->id, $ip)
&& !$user->permission(Site::DEACTIVATED)) {
&& $user->activated) {
// Assign the user object
self::$user = $user;
} else {

View file

@ -7,7 +7,7 @@
namespace Sakura\Forum;
use Sakura\DB;
use Sakura\Perms;
use Sakura\CurrentSession;
/**
* Used to serve forums.
@ -64,6 +64,12 @@ class Forum
*/
public $icon = "";
/**
* Holds the permission handler.
* @var ForumPerms
*/
public $perms;
/**
* A cached instance of the first post in this forum.
* @var Post
@ -88,12 +94,6 @@ class Forum
*/
private $topicsCache = [];
/**
* The permission container.
* @var Perms
*/
private $permissionsCache;
/**
* Constructor.
* @param int $forumId
@ -105,9 +105,6 @@ class Forum
->where('forum_id', $forumId)
->first();
// Create permissions object
$this->permissionsCache = new Perms(Perms::FORUM);
// Populate the variables
if ($forumRow) {
$this->id = intval($forumRow->forum_id);
@ -121,6 +118,8 @@ class Forum
} elseif ($forumId !== 0) {
$this->id = -1;
}
$this->perms = new ForumPerms($this, CurrentSession::$user);
}
/**
@ -132,18 +131,7 @@ class Forum
*/
public function permission($flag, $user, $raw = false)
{
// Set default permission value
$perm = 0;
// Get the permissions of the parent forum if there is one
if ($this->category) {
$perm = $perm | (new Forum($this->category))->permission($flag, $user, true);
}
// Bitwise OR it with the permissions for this forum
$perm = $perm | $this->permissionsCache->user($user, ['forum_id' => [$this->id, '=']]);
return $raw ? $perm : $this->permissionsCache->check($flag, $perm);
return $raw ? 1024 : true;
}
/**

46
app/Forum/ForumPerms.php Normal file
View file

@ -0,0 +1,46 @@
<?php
/**
* Holds the forum permission handler.
* @package Sakura
*/
namespace Sakura\Forum;
use Sakura\User;
/**
* Forum permission handler.
* @package Sakura
* @author Julian van de Groep <me@flash.moe>
*/
class ForumPerms
{
private $forum = [];
private $user = 0;
private $ranks = [];
private $cache = [];
public function __construct(Forum $forum, User $user)
{
//
}
public function __get($name)
{
if (!array_key_exists($name, $this->cache)) {
$column = 'perm_' . camel_to_snake($name);
$result = array_column(DB::table('forum_perms')
->whereIn('forum_id', $this->forum)
->where(function ($query) {
$query->whereIn('rank_id', $this->ranks)
->orWhere('user_id', $this->user);
})
->get([$column]), $column);
$this->cache[$name] = !in_array('0', $result, true) && in_array('1', $result, true);
}
return $this->cache[$name];
}
}

View file

@ -13,16 +13,6 @@ namespace Sakura;
*/
class Perms
{
/**
* SITE permission mode, used for general permissions.
*/
const SITE = 'permissions\permissions_site';
/**
* MANAGE permission mode, used for site management actions.
*/
const MANAGE = 'permissions\permissions_manage';
/**
* FORUM permission mode, used per forum.
*/

View file

@ -1,30 +0,0 @@
<?php
/**
* Holds the site management permission flags.
* @package Sakura
*/
namespace Sakura\Perms;
/**
* All site management permission flags.
* @package Sakura
* @author Julian van de Groep <me@flash.moe>
*/
class Manage
{
/**
* Can this user use the management panel?
*/
const USE_MANAGE = 1;
/**
* Can this user toggle the restriction status of users?
*/
const CAN_RESTRICT_USERS = 2;
/**
* Can this user alter other user's profile images?
*/
const CHANGE_IMAGES = 4;
}

View file

@ -1,170 +0,0 @@
<?php
/**
* Holds the global site permission flags.
* @package Sakura
*/
namespace Sakura\Perms;
/**
* All global site permissions.
* @package Sakura
* @author Julian van de Groep <me@flash.moe>
*/
class Site
{
/**
* Is this user deactivated?
*/
const DEACTIVATED = 1;
/**
* Is this user restricted?
*/
const RESTRICTED = 2;
/**
* Can this user alter their profile?
*/
const ALTER_PROFILE = 4;
/**
* Can this user change their avatar?
*/
const CHANGE_AVATAR = 8;
/**
* Can this user change their profile background?
*/
const CHANGE_BACKGROUND = 16;
/**
* Can this user change their profile header?
*/
const CHANGE_HEADER = 32;
/**
* Can this user view the memberlist?
*/
const VIEW_MEMBERLIST = 64;
/**
* Can this user create a userpage?
*/
const CREATE_USERPAGE = 128;
/**
* Can this user change their userpage?
*/
const CHANGE_USERPAGE = 256;
/**
* Can this user use the private messaging system?
*/
const USE_MESSAGES = 512;
/**
* Can this user send private messages?
*/
const SEND_MESSAGES = 1024;
/**
* Can this user change the e-mail address associated with their account?
*/
const CHANGE_EMAIL = 2048;
/**
* Can this user change their username (within the configured timeframe)?
*/
const CHANGE_USERNAME = 4096;
/**
* Can this user change the user title?
*/
const CHANGE_USERTITLE = 8192;
/**
* Can this user change the password to their account?
*/
const CHANGE_PASSWORD = 16384;
/**
* Can this user manage the ranks they're part of?
*/
const ALTER_RANKS = 32768;
/**
* Can this user manage the active sessions on their account?
*/
const MANAGE_SESSIONS = 65536;
/**
* Can this user change their forum signature?
*/
const CHANGE_SIGNATURE = 131072;
/**
* Can this user deactivate their account?
*/
const DEACTIVATE_ACCOUNT = 262144;
/**
* Can this user view the external accounts on other's profiles?
*/
const VIEW_PROFILE_DATA = 524288;
/**
* Can this user manage friends?
*/
const MANAGE_FRIENDS = 1048576;
/**
* Can this user report other users?
*/
const REPORT_USERS = 2097152;
/**
* Is this user allowed to buy premium?
*/
const OBTAIN_PREMIUM = 4194304;
/**
* Can this user join groups?
*/
const JOIN_GROUPS = 8388608;
/**
* Can this user create a group?
*/
const CREATE_GROUP = 16777216;
/**
* Can this user create more than one group (requires CREATE_GROUP permission as well)?
*/
const MULTIPLE_GROUPS = 33554432;
/**
* Can this user change the colour of their username?
*/
const CHANGE_NAMECOLOUR = 67108864;
/**
* Does this user have infinite premium?
*/
const STATIC_PREMIUM = 134217728;
/**
* Can this user create comments?
*/
const CREATE_COMMENTS = 268435456;
/**
* Can this user delete their own comments?
*/
const DELETE_COMMENTS = 536870912;
/**
* Can this user vote on comments?
*/
const VOTE_COMMENTS = 1073741824;
}

View file

@ -7,7 +7,6 @@
namespace Sakura;
use Sakura\Perms;
use Sakura\Perms\Site;
/**
* Serves Rank data.
@ -116,9 +115,6 @@ class Rank
$this->description = $rankRow->rank_description;
$this->title = $rankRow->rank_title;
}
// Init the permissions
$this->permissions = new Perms(Perms::SITE);
}
/**
@ -137,7 +133,7 @@ class Rank
*/
public function hidden()
{
return $this->hidden || $this->permission(Site::DEACTIVATED) || $this->permission(Site::RESTRICTED);
return $this->hidden;
}
/**

View file

@ -12,7 +12,6 @@ use LastFmApi\Api\UserApi;
use LastFmApi\Exception\LastFmApiExeption;
use Sakura\Exceptions\NetAddressTypeException;
use Sakura\Perms;
use Sakura\Perms\Site;
use stdClass;
/**
@ -263,10 +262,10 @@ class User
private $birthday = '0000-00-00';
/**
* The user's permission container.
* @var Perms
* Holds the permission checker for this user.
* @var UserPerms
*/
private $permissions;
public $perms;
/**
* The User instance cache array.
@ -445,7 +444,7 @@ class User
$this->title = $this->title ? $this->title : $this->mainRank->title;
// Init the permissions
$this->permissions = new Perms(Perms::SITE);
$this->perms = new UserPerms($this);
}
/**
@ -542,7 +541,7 @@ class User
*/
public function isActive()
{
return $this->id !== 0 && !$this->permission(Site::DEACTIVATED);
return $this->id !== 0 && $this->activated;
}
/**
@ -911,7 +910,7 @@ class User
$expire = $this->premiumInfo()->expire;
// Check if the user has static premium
if (!$expire && $this->permission(Site::STATIC_PREMIUM)) {
if (!$expire) {
$expire = time() + 1;
}

43
app/UserPerms.php Normal file
View file

@ -0,0 +1,43 @@
<?php
/**
* Holds the user permission handler.
* @package Sakura
*/
namespace Sakura;
/**
* User permission handler.
* @package Sakura
* @author Julian van de Groep <me@flash.moe>
*/
class UserPerms
{
private $user = 0;
private $ranks = [];
private $cache = [];
public function __construct(User $user)
{
$this->user = $user->id;
$this->ranks = array_keys($user->ranks);
}
public function __get($name)
{
if (!array_key_exists($name, $this->cache)) {
$column = 'perm_' . camel_to_snake($name);
$result = array_column(DB::table('perms')
->where(function ($query) {
$query->whereIn('rank_id', $this->ranks)
->orWhere('user_id', $this->user);
})
->get([$column]), $column);
$this->cache[$name] = !in_array('0', $result, true) && in_array('1', $result, true);
}
return $this->cache[$name];
}
}

View file

@ -28,32 +28,32 @@ class RestructurePermissions extends Migration
$table->integer('user_id')->default(0);
$table->integer('rank_id')->default(0);
$table->boolean('perm_change_profile')->default(false);
$table->boolean('perm_change_avatar')->default(false);
$table->boolean('perm_change_background')->default(false);
$table->boolean('perm_change_header')->default(false);
$table->boolean('perm_change_userpage')->default(false);
$table->boolean('perm_change_signature')->default(false);
$table->boolean('perm_change_username')->default(false);
$table->boolean('perm_change_user_title')->default(false);
$table->boolean('perm_change_profile')->nullable()->default(null);
$table->boolean('perm_change_avatar')->nullable()->default(null);
$table->boolean('perm_change_background')->nullable()->default(null);
$table->boolean('perm_change_header')->nullable()->default(null);
$table->boolean('perm_change_userpage')->nullable()->default(null);
$table->boolean('perm_change_signature')->nullable()->default(null);
$table->boolean('perm_change_username')->nullable()->default(null);
$table->boolean('perm_change_user_title')->nullable()->default(null);
$table->boolean('perm_deactivate_account')->default(false);
$table->boolean('perm_deactivate_account')->nullable()->default(null);
$table->boolean('perm_view_user_links')->default(false);
$table->boolean('perm_view_user_details')->default(false);
$table->boolean('perm_view_user_links')->nullable()->default(null);
$table->boolean('perm_view_user_details')->nullable()->default(null);
$table->boolean('perm_manage_ranks')->default(false);
$table->boolean('perm_manage_friends')->default(false);
$table->boolean('perm_manage_ranks')->nullable()->default(null);
$table->boolean('perm_manage_friends')->nullable()->default(null);
$table->boolean('perm_comments_create')->default(false);
$table->boolean('perm_comments_edit')->default(false);
$table->boolean('perm_comments_delete')->default(false);
$table->boolean('perm_comments_vote')->default(false);
$table->boolean('perm_comments_create')->nullable()->default(null);
$table->boolean('perm_comments_edit')->nullable()->default(null);
$table->boolean('perm_comments_delete')->nullable()->default(null);
$table->boolean('perm_comments_vote')->nullable()->default(null);
$table->boolean('perm_is_mod')->default(false);
$table->boolean('perm_is_admin')->default(false);
$table->boolean('perm_can_restrict')->default(false);
$table->boolean('perm_manage_profile_images')->default(false);
$table->boolean('perm_is_mod')->nullable()->default(null);
$table->boolean('perm_is_admin')->nullable()->default(null);
$table->boolean('perm_can_restrict')->nullable()->default(null);
$table->boolean('perm_manage_profile_images')->nullable()->default(null);
});
$schema->create('forum_perms', function (Blueprint $table) {
@ -61,23 +61,23 @@ class RestructurePermissions extends Migration
$table->integer('user_id')->default(0);
$table->integer('rank_id')->default(0);
$table->boolean('perm_view')->default(false);
$table->boolean('perm_reply')->default(false);
$table->boolean('perm_view')->nullable()->default(null);
$table->boolean('perm_reply')->nullable()->default(null);
$table->boolean('perm_topic_create')->default(false);
$table->boolean('perm_topic_delete')->default(false);
$table->boolean('perm_topic_move')->default(false);
$table->boolean('perm_topic_create')->nullable()->default(null);
$table->boolean('perm_topic_delete')->nullable()->default(null);
$table->boolean('perm_topic_move')->nullable()->default(null);
$table->boolean('perm_edit')->default(false);
$table->boolean('perm_edit_any')->default(false);
$table->boolean('perm_edit')->nullable()->default(null);
$table->boolean('perm_edit_any')->nullable()->default(null);
$table->boolean('perm_delete')->default(false);
$table->boolean('perm_delete_any')->default(false);
$table->boolean('perm_delete')->nullable()->default(null);
$table->boolean('perm_delete_any')->nullable()->default(null);
$table->boolean('perm_bypass_rules')->default(false);
$table->boolean('perm_bypass_rules')->nullable()->default(null);
$table->boolean('perm_change_type')->default(false);
$table->boolean('perm_change_status')->default(false);
$table->boolean('perm_change_type')->nullable()->default(null);
$table->boolean('perm_change_status')->nullable()->default(null);
});
}

View file

@ -106,7 +106,7 @@
{% for post in posts[get.page|default(1) - 1] %}
<tr class="post" id="p{{ post.id }}">
<td class="userpanel">
{% if not post.poster.permission(constant('Sakura\\Perms\\Site::DEACTIVATED')) or post.poster.permission(constant('Sakura\\Perms\\Site::RESTRICTED')) %}<a href="{{ route('user.profile', post.poster.id) }}" class="default username" style="color: {{ post.poster.colour }}; text-shadow: 0 0 5px {% if post.poster.colour != 'inherit' %}{{ post.poster.colour }}{% else %}#222{% endif %};" title="Go to {{ post.poster.username }}'s profile">{{ post.poster.username }}</a>
{% if post.poster.activated or post.poster.restricted %}<a href="{{ route('user.profile', post.poster.id) }}" class="default username" style="color: {{ post.poster.colour }}; text-shadow: 0 0 5px {% if post.poster.colour != 'inherit' %}{{ post.poster.colour }}{% else %}#222{% endif %};" title="Go to {{ post.poster.username }}'s profile">{{ post.poster.username }}</a>
<img src="{{ route('user.avatar', post.poster.id) }}" alt="{{ post.poster.username }}" class="avatar" style="box-shadow: 0 3px 7px #{% if post.poster.isOnline %}484{% else %}844{% endif %};">
{% else %}
<a class="username">[deleted user]</a>
@ -122,7 +122,7 @@
{% if (user.id == post.poster.id and forum.permission(constant('Sakura\\Perms\\Forum::DELETE_OWN'), user.id)) or forum.permission(constant('Sakura\\Perms\\Forum::DELETE_ANY'), user.id) %}
<a class="fa fa-trash" title="Delete this post" href="javascript:;" onclick="deletePost({{ post.id }})"></a>
{% endif %}
{% if not (post.poster.permission(constant('Sakura\\Perms\\Site::DEACTIVATED')) or post.poster.permission(constant('Sakura\\Perms\\Site::RESTRICTED')) or user.id == post.poster.id) %}
{% if not (post.poster.activated or post.poster.restricted or user.id == post.poster.id) %}
<a class="fa fa-{% if user.isFriends(post.poster.id) == 2 %}heart{% else %}star{% endif %} friend-{{ post.poster.id }}-level" title="You are friends" {% if user.isFriends(post.poster.id) == 0 %}style="display: none;"{% endif %}></a>
<a class="fa fa-user-{% if user.isFriends(post.poster.id) == 0 %}plus{% else %}times{% endif %} forum-friend-toggle friend-{{ post.poster.id }}-toggle" title="{% if user.isFriends(post.poster.id) == 0 %}Add {{ post.poster.username }} as a friend{% else %}Remove friend{% endif %}" href="javascript:void(0);" onclick="Sakura.Friend.{% if user.isFriends(post.poster.id) == 0 %}Add({{ post.poster.id }}){% else %}Remove({{ post.poster.id }}){% endif %}"></a>
<a class="fa fa-flag" title="Report {{ post.poster.username }}" href="{{ route('user.report', post.poster.id) }}"></a>
@ -145,7 +145,7 @@
<div class="post-text bbcode">
{{ post.parsed|raw }}
</div>
{% if post.poster.signature and post.poster.permission(constant('Sakura\\Perms\\Site::CHANGE_SIGNATURE')) %}
{% if post.poster.signature and post.poster.perms.changeSignature %}
<div class="clear"></div>
<div class="signature bbcode">
{{ post.poster.signature()|raw|nl2br }}
@ -176,7 +176,7 @@
<div class="clear"></div>
</div>
<div class="post-text bbcode" id="previewText"></div>
{% if user.signature and user.permission(constant('Sakura\\Perms\\Site::CHANGE_SIGNATURE')) %}
{% if user.signature and user.perms.changeSignature %}
<div class="clear"></div>
<div class="signature bbcode">
{{ user.signature()|raw|nl2br }}

View file

@ -13,7 +13,7 @@
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css" rel="stylesheet" type="text/css">
<link rel="stylesheet" type="text/css" href="/css/yuuno.css">
{{ block('css') }}
<script type="text/javascript" src="/js/app.js"></script>
<script type="text/javascript" src="/js/sakura.js"></script>
<script type="text/javascript" src="/js/yuuno.js"></script>
{{ block('js') }}
</head>
@ -47,7 +47,7 @@
<a class="menu-item avatar" href="{{ route('user.profile', user.id) }}" title="Logged in as {{ user.username }}" style="background-image: url('{{ route('user.avatar', user.id) }}'); width: auto; color: {{ user.colour }}; border-color: {{ user.colour }}; font-weight: 700;"></a>
<a class="menu-item fa-envelope" href="#" title="Messages"></a>
<a class="menu-item fa-bell" href="javascript:;" title="Notifications"></a>
{% if user.permission(constant('Sakura\\Perms\\Manage::USE_MANAGE'), constant('Sakura\\Perms::MANAGE')) %}
{% if user.perms.isMod or user.perms.isAdmin %}
<a class="menu-item fa-gavel" href="{{ route('manage.index') }}" title="Manage"></a>
{% endif %}
<a class="menu-item fa-cogs" href="{{ route('settings.index') }}" title="Settings"></a>
@ -62,7 +62,7 @@
<div id="contentwrapper">
<div id="notifications" class="alerts"></div>
<div id="dialogues" class="dialogues"></div>
{% if profile is defined ? profile.background : (user.permission(constant('Sakura\\Perms\\Site::CHANGE_BACKGROUND')) and (user.backgroundSitewide or showBG) and user.background) %}
{% if profile is defined ? profile.background : (user.perms.changeBackground and (user.backgroundSitewide or showBG) and user.background) %}
<div id="userBackground" style="background-image: url('{{ route('user.background', (profile is defined ? profile : user).id) }}');"></div>
{% endif %}
{% if not user.isActive and server['REQUEST_URI'] != route('auth.login') %}
@ -87,7 +87,7 @@
</form>
</div>
{% endif %}
{% if user.permission(constant('Sakura\\Perms\\Site::RESTRICTED')) %}
{% if user.restricted %}
<div class="headerNotify" style="background: repeating-linear-gradient(-45deg, #B33, #B33 10px, #B00 10px, #B00 20px); color: #FFF; border: 1px solid #C00; box-shadow: 0 0 3px #C00;">
<h1>Your account is currently in <span style="font-weight: 700 !important;">restricted mode</span>!</h1>
<div>A staff member has set your account to restricted mode most likely due to violation of the rules. While restricted you won't be able to use most public features of the site. If you think this is a mistake please <a href="{{ route('info.contact') }}" style="color: inherit;">get in touch with one of our staff members</a>.</div>

View file

@ -2,8 +2,6 @@
{% set title %}Support {{ config('general.name') }}{% endset %}
{% set persistentPremium = user.permission(constant('Sakura\\Perms\\Site::STATIC_PREMIUM')) %}
{% set features = {
"money": "Helping us pay for the bills to survive",
"certificate": "A <span style='font-weight: bold; color: #EE9400'>special</span> name colour to stand out in the crowd",
@ -24,8 +22,8 @@
Your current Tenshi tag
</div>
<div style="margin-bottom: 10px;">
<h3>{% if persistentPremium %}Your rank has persistent Tenshi.{% else %}Your Tenshi tag is valid till {{ user.premiumInfo.expire|date(config('general.date_format')) }}.{% endif %}</h3>
<progress value="{{ persistentPremium ? 100 : (100 - (((date().timestamp - user.premiumInfo.start) / (user.premiumInfo.expire - user.premiumInfo.start)) * 100)) }}" max="100" style="width: 100%"></progress>
<h3>Your Tenshi tag is valid till {{ user.premiumInfo.expire|date(config('general.date_format')) }}.</h3>
<progress value="{{ 100 - (((date().timestamp - user.premiumInfo.start) / (user.premiumInfo.expire - user.premiumInfo.start)) * 100) }}" max="100" style="width: 100%"></progress>
</div>
{% endif %}
<div class="sectionHeader">
@ -60,7 +58,7 @@
</div>
</div>
</div>
{% if user.isActive and user.permission(constant('Sakura\\Perms\\Site::OBTAIN_PREMIUM')) %}
{% if user.isActive and user.verified %}
<div class="slider">
<input class="inputStyling" type="range" min="1" max="{{ amountLimit }}" value="1" onchange="document.getElementById('monthsNo').value = this.value; document.getElementById('monthNoBtn').innerText = this.value; document.getElementById('monthsTrailingS').innerText = (this.value == 1 ? '' : 's'); document.getElementById('totalAmount').innerText = (this.value * {{ price }});">
</div>
@ -79,7 +77,7 @@
<h1 style="text-align: center; margin: 1em auto;" class="stylised">You need to be logged in to get Tenshi!</h1>
{% endif %}
</div>
{% if user.isActive and user.permission(constant('Sakura\\Perms\\Site::OBTAIN_PREMIUM')) %}
{% if user.isActive and user.verified %}
<form action="{{ route('premium.purchase') }}" method="post" id="purchaseForm" class="hidden">
<input type="hidden" name="mode" value="purchase">
<input type="hidden" name="time" value="{{ date().timestamp }}">

View file

@ -8,12 +8,10 @@
{% block settingsContent %}
<form enctype="multipart/form-data" method="post" action="javascript:;" onsubmit="updateSettingsConfirm(this, '{{ route('settings.account.details') }}');">
{% if edit_email %}
<div class="profile-field">
<div><h2>E-mail address</h2></div>
<div><input type="text" name="email" placeholder="{{ user.email }}" class="inputStyling"></div>
</div>
{% endif %}
{% if edit_usern %}
<div class="profile-field">
<div><h2>Username {% if last_name_change %}(last change was <time class="time-ago" datetime="{{ last_name_change|date('r') }}">{{ last_name_change|date(config('general.date_format')) }}</time>){% endif %}</h2></div>
@ -26,12 +24,10 @@
<div><input type="text" name="title" placeholder="Max 64 characters, leaving this empty will actually reset it" class="inputStyling" value="{{ user.title }}"></div>
</div>
{% endif %}
{% if edit_passw %}
<div class="profile-field">
<div><h2>Password</h2></div>
<div><input type="password" name="password" placeholder="Must be at least decently strong, size doesn't matter" class="inputStyling"></div>
</div>
{% endif %}
<div class="profile-save">
<button value="{{ session_id() }}" name="session" class="inputStyling">Save</button>
<button type="reset" class="inputStyling">Reset</button>

View file

@ -1,6 +1,6 @@
{% extends 'master.twig' %}
{% set profileHidden = profile.permission(constant('Sakura\\Perms\\Site::DEACTIVATED')) or (profile.permission(constant('Sakura\\Perms\\Site::RESTRICTED')) and (user.id != profile.id and not user.permission(constant('Sakura\\Perms\\Manage::USE_MANAGE'), constant('Sakura\\Perms::MANAGE')))) %}
{% set profileHidden = not profile.activated and (user.id != profile.id and not (user.perms.isMod or user.perms.isAdmin)) %}
{% set noUserpage = profile.userPage|length < 1 %}
@ -8,8 +8,6 @@
{% set youtubeIsChannelId = profile.youtube|slice(0, 2) == 'UC' and profile.youtube|length == 24 %}
{% set canViewSecret = user.permission(constant('Sakura\\Perms\\Manage::USE_MANAGE'), constant('Sakura\\Perms::MANAGE')) %}
{% set fields = {
"website": {
"title": "Website",
@ -59,16 +57,16 @@
},
"email": {
"title": "E-mail address",
"value": canViewSecret ? profile.email : null,
"value": user.perms.viewUserDetails ? profile.email : null,
"link": "mailto:%s"
},
"registerip": {
"title": "Register IP",
"value": canViewSecret ? profile.registerIp : null,
"value": user.perms.viewUserDetails ? profile.registerIp : null,
},
"lastip": {
"title": "Last IP",
"value": canViewSecret ? profile.lastIp : null,
"value": user.perms.viewUserDetails ? profile.lastIp : null,
},
} %}
@ -191,7 +189,7 @@
<a class="fa fa-reply" title="View {{ profile.username }}'s posts" href="#_posts" onclick="profileMode('posts');"></a>
<a class="fa fa-star" title="View {{ profile.username }}'s friends" href="#_friends" onclick="profileMode('friends');"></a>
<a class="fa fa-comments-o" title="View {{ profile.username }}'s profile comments" href="#_comments" onclick="profileMode('comments');"></a>
{% if (profile.isActive and profile.id == user.id) or user.permission(constant('Sakura\\Perms\\Manage::CHANGE_IMAGES'), constant('Sakura\\Perms::MANAGE')) %}
{% if (profile.isActive and profile.id == user.id) or user.perms.manageProfileImages %}
<a class="fa fa-picture-o" title="Edit your avatar, background and header" href="#_images" onclick="profileMode('images');"></a>
{% endif %}
</div>
@ -204,7 +202,7 @@
<a class="fa fa-user-{% if user.isFriends(profile.id) == 0 %}plus{% else %}times{% endif %}" title="{% if user.isFriends(profile.id) == 0 %}Add {{ profile.username }} as a friend{% else %}Remove friend{% endif %}" href="javascript:void(0);" onclick="Sakura.Friend.{% if user.isFriends(profile.id) == 0 %}Add({{ profile.id }}){% else %}Remove({{ profile.id }}){% endif %}"></a>
<a class="fa fa-exclamation-circle" title="Report {{ profile.username }}" href="{{ route('user.report', profile.id) }}"></a>
{% endif %}
{% if user.permission(constant('Sakura\\Perms\\Manage::CAN_RESTRICT_USERS'), constant('Sakura\\Perms::MANAGE')) %}
{% if user.perms.canRestrict %}
<a class="fa fa-trash" title="Restrict {{ profile.username }}" href="?restrict={{ session_id() }}"></a>
{% endif %}
</div>
@ -265,6 +263,7 @@
</table>
<hr class="default">
{% if user.isActive %}
{# if user.perms.viewUserLinks or user.perms.viewUserDetails #}
<table style="width: 100%;">
{% for id, data in fields %}
{% if data.value != null %}
@ -287,9 +286,9 @@
<b>Log in to view the full profile!</b>
{% endif %}
<b>Account Standing</b>
{% if profile.permission(constant('Sakura\\Perms\\Site::DEACTIVATED')) %}
{% if not profile.activated %}
<h2 style="color: #888; text-shadow: 0 0 7px #888; margin-top: 0;">Deactivated</h2>
{% elseif profile.permission(constant('Sakura\\Perms\\Site::RESTRICTED')) %}
{% elseif profile.restricted %}
<h2 style="color: #222; text-shadow: 0 0 7px #800; margin-top: 0;">Restricted</h2>
{% elseif false %}
<h2 style="color: #A00; text-shadow: 0 0 7px #A00; margin-top: 0;">Bad</h2>

View file

@ -59,6 +59,12 @@ function path($path)
return FileSystem::getPath($path);
}
// Convert camel case to snake case
function camel_to_snake($text)
{
return ltrim(strtolower(preg_replace('#[A-Z]#', '_$0', $text)), '_');
}
function clean_string($string, $lower = false, $noSpecial = false, $replaceSpecial = '')
{
// Run common sanitisation function over string