Backlog of things.
This commit is contained in:
parent
5b828279a1
commit
c1259ef503
22 changed files with 490 additions and 211 deletions
20
assets/less/manage/classes/button.less
Normal file
20
assets/less/manage/classes/button.less
Normal file
|
@ -0,0 +1,20 @@
|
|||
.button {
|
||||
display: inline-block;
|
||||
font: 12px/20px @manage-font;
|
||||
background-color: #666;
|
||||
border: 1px solid #555;
|
||||
border-radius: 2px;
|
||||
text-decoration: none;
|
||||
color: #111;
|
||||
padding: 2px 5px;
|
||||
cursor: pointer;
|
||||
transition: background-color .2s;
|
||||
|
||||
&:hover {
|
||||
background-color: #777;
|
||||
}
|
||||
|
||||
&:active {
|
||||
background-color: #666;
|
||||
}
|
||||
}
|
|
@ -5,4 +5,16 @@
|
|||
&--center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
&__title {
|
||||
font-size: 2em;
|
||||
line-height: 1.7em;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
&__subtitle {
|
||||
font-size: 1.5em;
|
||||
line-height: 1.5em;
|
||||
padding: 4px;
|
||||
}
|
||||
}
|
||||
|
|
14
assets/less/manage/classes/form.less
Normal file
14
assets/less/manage/classes/form.less
Normal file
|
@ -0,0 +1,14 @@
|
|||
.form {
|
||||
|
||||
&__label {
|
||||
display: inline-block;
|
||||
background-color: #222;
|
||||
border: 1px solid #333;
|
||||
border-radius: 2px;
|
||||
min-width: 250px;
|
||||
margin: 2px;
|
||||
padding: 2px;
|
||||
min-height: 50px;
|
||||
vertical-align: top;
|
||||
}
|
||||
}
|
9
assets/less/manage/classes/input.less
Normal file
9
assets/less/manage/classes/input.less
Normal file
|
@ -0,0 +1,9 @@
|
|||
.input {
|
||||
background: #333;
|
||||
border: 1px solid #444;
|
||||
border-radius: 2px;
|
||||
padding: 2px;
|
||||
color: #fff;
|
||||
width: 100%;
|
||||
vertical-align: top;
|
||||
}
|
|
@ -3,15 +3,22 @@
|
|||
flex-direction: column;
|
||||
|
||||
&__entry {
|
||||
border-right: 4px solid #a00;
|
||||
border-right: 4px solid #666;
|
||||
padding-right: 1px;
|
||||
display: block;
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
|
||||
&:not(:last-child) {
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
&__selector {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
&__content {
|
||||
padding: 2px;
|
||||
width: 100%;
|
||||
background-color: #333;
|
||||
min-height: 50px;
|
||||
|
|
|
@ -4,13 +4,12 @@
|
|||
justify-content: center;
|
||||
|
||||
&__entry {
|
||||
min-width: 296px;
|
||||
margin: 2px;
|
||||
min-width: 296px;
|
||||
|
||||
&__content {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
padding: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
@manage-font: 'Open Sans', sans-serif;
|
||||
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
@ -13,13 +15,16 @@ body {
|
|||
|
||||
.manage {
|
||||
background-color: #222;
|
||||
font: 12px/20px 'Open Sans', sans-serif;
|
||||
font: 12px/20px @manage-font;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
@import "classes/button";
|
||||
@import "classes/container";
|
||||
@import "classes/footer";
|
||||
@import "classes/form";
|
||||
@import "classes/header";
|
||||
@import "classes/input";
|
||||
@import "classes/listing";
|
||||
@import "classes/pagination";
|
||||
|
||||
|
|
18
misuzu.php
18
misuzu.php
|
@ -17,21 +17,29 @@ if (PHP_SAPI !== 'cli') {
|
|||
exit;
|
||||
}
|
||||
|
||||
if (isset($_COOKIE['msz_uid'], $_COOKIE['msz_sid'])) {
|
||||
$app->startSession((int)$_COOKIE['msz_uid'], $_COOKIE['msz_sid']);
|
||||
}
|
||||
|
||||
if (!$app->inDebugMode()) {
|
||||
ob_start('ob_gzhandler');
|
||||
}
|
||||
|
||||
if ($app->config->get('Auth', 'lockdown', 'bool', false)) {
|
||||
http_response_code(503);
|
||||
$app->startTemplating();
|
||||
$app->templating->addPath('auth', __DIR__ . '/views/auth');
|
||||
echo $app->templating->render('lockdown');
|
||||
exit;
|
||||
}
|
||||
|
||||
if (isset($_COOKIE['msz_uid'], $_COOKIE['msz_sid'])) {
|
||||
$app->startSession((int)$_COOKIE['msz_uid'], $_COOKIE['msz_sid']);
|
||||
}
|
||||
|
||||
$manage_mode = starts_with($_SERVER['REQUEST_URI'], '/manage');
|
||||
|
||||
$app->startTemplating();
|
||||
$app->templating->addPath('mio', __DIR__ . '/views/mio');
|
||||
|
||||
if ($manage_mode) {
|
||||
if (Application::getInstance()->getSession() === null) {
|
||||
if (Application::getInstance()->getSession() === null || $_SERVER['HTTP_HOST'] !== 'misuzu.misaka.nl') {
|
||||
http_response_code(403);
|
||||
echo $app->templating->render('errors.403');
|
||||
exit;
|
||||
|
|
|
@ -4,6 +4,7 @@ use Illuminate\Database\Eloquent\ModelNotFoundException;
|
|||
use Misuzu\Application;
|
||||
use Misuzu\Database;
|
||||
use Misuzu\Net\IPAddress;
|
||||
use Misuzu\Users\Role;
|
||||
use Misuzu\Users\User;
|
||||
use Misuzu\Users\Session;
|
||||
use Misuzu\Users\LoginAttempt;
|
||||
|
@ -166,7 +167,8 @@ switch ($mode) {
|
|||
break;
|
||||
}
|
||||
|
||||
User::createUser($username, $password, $email);
|
||||
$user = User::createUser($username, $password, $email);
|
||||
$user->addRole(Role::find(1), true);
|
||||
$app->templating->var('auth_register_message', 'Welcome to Flashii! You may now log in.');
|
||||
break;
|
||||
}
|
||||
|
|
110
public/manage/users-roles.php
Normal file
110
public/manage/users-roles.php
Normal file
|
@ -0,0 +1,110 @@
|
|||
<?php
|
||||
use Misuzu\Application;
|
||||
use Misuzu\Colour;
|
||||
use Misuzu\Users\Role;
|
||||
|
||||
require_once __DIR__ . '/../../misuzu.php';
|
||||
|
||||
$role_mode = (string)($_GET['m'] ?? 'list');
|
||||
$role_id = (int)($_GET['i'] ?? 0);
|
||||
|
||||
while ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
if (!tmp_csrf_verify($_POST['csrf'] ?? '')) {
|
||||
echo 'csrf err';
|
||||
break;
|
||||
}
|
||||
|
||||
if (!in_array($role_mode, ['create', 'edit'], true)) {
|
||||
echo 'invalid mode';
|
||||
break;
|
||||
}
|
||||
|
||||
if (!isset($_POST['role'])) {
|
||||
echo 'no';
|
||||
break;
|
||||
}
|
||||
|
||||
$role_name = $_POST['role']['name'] ?? '';
|
||||
$role_name_length = strlen($role_name);
|
||||
|
||||
if ($role_name_length < 1 || $role_name_length > 255) {
|
||||
echo 'invalid name length';
|
||||
break;
|
||||
}
|
||||
|
||||
$role_secret = !empty($_POST['role']['secret']);
|
||||
|
||||
$role_hierarchy = (int)($_POST['role']['hierarchy'] ?? -1);
|
||||
|
||||
if ($role_hierarchy < 1 || $role_hierarchy > 100) {
|
||||
echo 'Invalid hierarchy value.';
|
||||
break;
|
||||
}
|
||||
|
||||
$role_colour = Colour::none();
|
||||
$role_colour->setInherit(!empty($_POST['role']['colour']['inherit']));
|
||||
|
||||
if (!$role_colour->getInherit()) {
|
||||
foreach (['red', 'green', 'blue'] as $key) {
|
||||
$value = (int)($_POST['role']['colour'][$key] ?? -1);
|
||||
$setter = 'set' . ucfirst($key);
|
||||
|
||||
if ($value < 0 || $value > 0xFF) {
|
||||
echo 'invalid colour value';
|
||||
break 2;
|
||||
}
|
||||
|
||||
$role_colour->{$setter}($value);
|
||||
}
|
||||
}
|
||||
|
||||
$role_description = $_POST['role']['description'] ?? '';
|
||||
|
||||
if (strlen($role_description) > 1000) {
|
||||
echo 'description is too long';
|
||||
break;
|
||||
}
|
||||
|
||||
$edit_role = $role_id < 1 ? new Role : Role::find($role_id);
|
||||
$edit_role->role_name = $role_name;
|
||||
$edit_role->role_hierarchy = $role_hierarchy;
|
||||
$edit_role->role_secret = $role_secret;
|
||||
$edit_role->role_colour = $role_colour;
|
||||
$edit_role->role_description = $role_description;
|
||||
$edit_role->save();
|
||||
|
||||
header('Location: ?m=list');
|
||||
break;
|
||||
}
|
||||
|
||||
switch ($role_mode) {
|
||||
case 'list':
|
||||
$users_page = (int)($_GET['p'] ?? 1);
|
||||
$manage_roles = Role::paginate(32, ['*'], 'p', $users_page);
|
||||
$app->templating->vars(compact('manage_roles'));
|
||||
|
||||
echo $app->templating->render('@manage.users.roles');
|
||||
break;
|
||||
|
||||
case 'edit':
|
||||
if (!isset($edit_role)) {
|
||||
if ($role_id < 1) {
|
||||
echo 'no';
|
||||
break;
|
||||
}
|
||||
|
||||
$edit_role = Role::find($role_id);
|
||||
}
|
||||
|
||||
if ($edit_role === null) {
|
||||
echo 'invalid role';
|
||||
break;
|
||||
}
|
||||
|
||||
$app->templating->vars(compact('edit_role'));
|
||||
// no break
|
||||
|
||||
case 'create':
|
||||
echo $app->templating->render('@manage.users.roles_create');
|
||||
break;
|
||||
}
|
|
@ -9,81 +9,69 @@ class Colour
|
|||
|
||||
private $rawValue = 0;
|
||||
|
||||
public function __get(string $name)
|
||||
public function getRaw(): int
|
||||
{
|
||||
switch ($name) {
|
||||
case 'raw':
|
||||
return $this->rawValue;
|
||||
|
||||
case 'inherit':
|
||||
return ($this->rawValue & self::INHERIT) > 0;
|
||||
|
||||
case 'red':
|
||||
return $this->rawValue >> 16 & 0xFF;
|
||||
|
||||
case 'green':
|
||||
return $this->rawValue >> 8 & 0xFF;
|
||||
|
||||
case 'blue':
|
||||
return $this->rawValue & 0xFF;
|
||||
|
||||
case 'hex':
|
||||
return dechex_pad($this->red) . dechex_pad($this->green) . dechex_pad($this->blue);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function __set(string $name, $value): void
|
||||
public function setRaw(int $raw): void
|
||||
{
|
||||
switch ($name) {
|
||||
case 'raw':
|
||||
if (!is_int32($value) && !is_uint32($value)) {
|
||||
break;
|
||||
$this->rawValue = $raw;
|
||||
}
|
||||
|
||||
$this->rawValue = $value;
|
||||
break;
|
||||
|
||||
case 'inherit':
|
||||
if (!is_bool($value)) {
|
||||
break;
|
||||
public function getInherit(): bool
|
||||
{
|
||||
return ($this->rawValue & self::INHERIT) > 0;
|
||||
}
|
||||
|
||||
if ($value) {
|
||||
public function setInherit(bool $state): void
|
||||
{
|
||||
if ($state) {
|
||||
$this->rawValue |= self::INHERIT;
|
||||
} else {
|
||||
$this->rawValue &= ~self::INHERIT;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'red':
|
||||
if (!is_byte($value)) {
|
||||
break;
|
||||
}
|
||||
|
||||
public function getRed(): int
|
||||
{
|
||||
return $this->rawValue >> 16 & 0xFF;
|
||||
}
|
||||
|
||||
public function setRed(int $red): void
|
||||
{
|
||||
$red = $red & 0xFF;
|
||||
$this->rawValue &= ~0xFF0000;
|
||||
$this->rawValue |= $value << 16;
|
||||
break;
|
||||
|
||||
case 'green':
|
||||
if (!is_byte($value)) {
|
||||
break;
|
||||
$this->rawValue |= $red << 16;
|
||||
}
|
||||
|
||||
public function getGreen(): int
|
||||
{
|
||||
return $this->rawValue >> 8 & 0xFF;
|
||||
}
|
||||
|
||||
public function setGreen(int $green): void
|
||||
{
|
||||
$green = $green & 0xFF;
|
||||
$this->rawValue &= ~0xFF00;
|
||||
$this->rawValue |= $value << 8;
|
||||
break;
|
||||
|
||||
case 'blue':
|
||||
if (!is_byte($value)) {
|
||||
break;
|
||||
$this->rawValue |= $green << 8;
|
||||
}
|
||||
|
||||
public function getBlue(): int
|
||||
{
|
||||
return $this->rawValue & 0xFF;
|
||||
}
|
||||
|
||||
public function setBlue(int $blue): void
|
||||
{
|
||||
$blue = $blue & 0xFF;
|
||||
$this->rawValue &= ~0xFF;
|
||||
$this->rawValue |= $value;
|
||||
break;
|
||||
$this->rawValue |= $blue;
|
||||
}
|
||||
|
||||
public function getHex(): string
|
||||
{
|
||||
return dechex_pad($this->getRed()) . dechex_pad($this->getGreen()) . dechex_pad($this->getBlue());
|
||||
}
|
||||
|
||||
public function __construct(?int $raw)
|
||||
|
@ -125,6 +113,6 @@ class Colour
|
|||
|
||||
public function __toString()
|
||||
{
|
||||
return "#{$this->hex}";
|
||||
return "#{$this->getHex()}";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,8 @@ class Directory
|
|||
*/
|
||||
private $path;
|
||||
|
||||
public const SEPARATOR = DIRECTORY_SEPARATOR;
|
||||
|
||||
public function getPath(): string
|
||||
{
|
||||
return $this->path;
|
||||
|
@ -58,12 +60,12 @@ class Directory
|
|||
}
|
||||
|
||||
return realpath($path);
|
||||
}, glob($this->path . '/' . $pattern));
|
||||
}, glob($this->path . self::SEPARATOR . $pattern));
|
||||
}
|
||||
|
||||
public function filename(string $filename): string
|
||||
{
|
||||
return $this->getPath() . '/' . $filename;
|
||||
return $this->getPath() . self::SEPARATOR . $filename;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -78,11 +80,12 @@ class Directory
|
|||
throw new DirectoryExistsException;
|
||||
}
|
||||
|
||||
$split_path = explode('/', $path);
|
||||
$existing_path = '/';
|
||||
$path = Directory::fixSlashes($path);
|
||||
$split_path = explode(self::SEPARATOR, $path);
|
||||
$existing_path = running_on_windows() ? '' : self::SEPARATOR;
|
||||
|
||||
foreach ($split_path as $path_part) {
|
||||
$existing_path .= $path_part . '/';
|
||||
$existing_path .= $path_part . self::SEPARATOR;
|
||||
|
||||
if (!Directory::exists($existing_path)) {
|
||||
mkdir($existing_path);
|
||||
|
@ -146,8 +149,8 @@ class Directory
|
|||
* @param string $path
|
||||
* @return string
|
||||
*/
|
||||
public static function fixSlashes(string $path): string
|
||||
public static function fixSlashes(string $path, string $separator = self::SEPARATOR): string
|
||||
{
|
||||
return str_replace(['/', '\\'], DIRECTORY_SEPARATOR, $path);
|
||||
return str_replace(['/', '\\'], $separator, $path);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,6 +46,26 @@ class Role extends Model
|
|||
return $user->hasRole($this);
|
||||
}
|
||||
|
||||
public function getRoleColourAttribute(int $colour): Colour
|
||||
{
|
||||
return new Colour($colour);
|
||||
}
|
||||
|
||||
public function setRoleColourAttribute(Colour $colour): void
|
||||
{
|
||||
$this->attributes['role_colour'] = $colour->getRaw();
|
||||
}
|
||||
|
||||
public function getRoleDescriptionAttribute(?string $description): string
|
||||
{
|
||||
return empty($description) ? '' : $description;
|
||||
}
|
||||
|
||||
public function setRoleDescriptionAttribute(string $description): void
|
||||
{
|
||||
$this->attributes['role_description'] = empty($description) ? null : $description;
|
||||
}
|
||||
|
||||
public function users()
|
||||
{
|
||||
return $this->hasMany(UserRole::class, 'role_id');
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
namespace Misuzu\Users;
|
||||
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Misuzu\Colour;
|
||||
use Misuzu\Database;
|
||||
use Misuzu\Model;
|
||||
use Misuzu\Net\IPAddress;
|
||||
|
@ -109,6 +110,12 @@ class User extends Model
|
|||
return '';
|
||||
}
|
||||
|
||||
public function getDisplayColour(): Colour
|
||||
{
|
||||
$role = Role::find($this->display_role);
|
||||
return $role === null ? Colour::none() : $role->role_colour;
|
||||
}
|
||||
|
||||
public function addRole(Role $role, bool $setDisplay = false): void
|
||||
{
|
||||
$relation = new UserRole;
|
||||
|
|
|
@ -25,72 +25,72 @@ class ColourTest extends TestCase
|
|||
{
|
||||
$colour = Colour::none();
|
||||
|
||||
$this->assertTrue($colour->inherit);
|
||||
$this->assertEquals($colour->raw, 0x40000000);
|
||||
$this->assertEquals($colour->red, 0);
|
||||
$this->assertEquals($colour->green, 0);
|
||||
$this->assertEquals($colour->blue, 0);
|
||||
$this->assertEquals($colour->hex, '000000');
|
||||
$this->assertTrue($colour->getInherit());
|
||||
$this->assertEquals($colour->getRaw(), 0x40000000);
|
||||
$this->assertEquals($colour->getRed(), 0);
|
||||
$this->assertEquals($colour->getGreen(), 0);
|
||||
$this->assertEquals($colour->getBlue(), 0);
|
||||
$this->assertEquals($colour->getHex(), '000000');
|
||||
}
|
||||
|
||||
public function testNull()
|
||||
{
|
||||
$colour = new Colour(null);
|
||||
|
||||
$this->assertTrue($colour->inherit);
|
||||
$this->assertEquals($colour->raw, 0x40000000);
|
||||
$this->assertEquals($colour->red, 0);
|
||||
$this->assertEquals($colour->green, 0);
|
||||
$this->assertEquals($colour->blue, 0);
|
||||
$this->assertEquals($colour->hex, '000000');
|
||||
$this->assertTrue($colour->getInherit());
|
||||
$this->assertEquals($colour->getRaw(), 0x40000000);
|
||||
$this->assertEquals($colour->getRed(), 0);
|
||||
$this->assertEquals($colour->getGreen(), 0);
|
||||
$this->assertEquals($colour->getBlue(), 0);
|
||||
$this->assertEquals($colour->getHex(), '000000');
|
||||
}
|
||||
|
||||
public function testFromRaw()
|
||||
{
|
||||
$colour = new Colour(static::RAW_HEX6);
|
||||
|
||||
$this->assertEquals($colour->hex, static::STR_HEX6);
|
||||
$this->assertEquals($colour->raw, static::RAW_HEX6);
|
||||
$this->assertEquals($colour->red, static::RED_HEX6);
|
||||
$this->assertEquals($colour->green, static::GREEN_HEX6);
|
||||
$this->assertEquals($colour->blue, static::BLUE_HEX6);
|
||||
$this->assertFalse($colour->inherit);
|
||||
$this->assertEquals($colour->getHex(), static::STR_HEX6);
|
||||
$this->assertEquals($colour->getRaw(), static::RAW_HEX6);
|
||||
$this->assertEquals($colour->getRed(), static::RED_HEX6);
|
||||
$this->assertEquals($colour->getGreen(), static::GREEN_HEX6);
|
||||
$this->assertEquals($colour->getBlue(), static::BLUE_HEX6);
|
||||
$this->assertFalse($colour->getInherit());
|
||||
}
|
||||
|
||||
public function testFromRGB()
|
||||
{
|
||||
$colour = Colour::fromRGB(static::RED_HEX6, static::GREEN_HEX6, static::BLUE_HEX6);
|
||||
|
||||
$this->assertEquals($colour->hex, static::STR_HEX6);
|
||||
$this->assertEquals($colour->raw, static::RAW_HEX6);
|
||||
$this->assertEquals($colour->red, static::RED_HEX6);
|
||||
$this->assertEquals($colour->green, static::GREEN_HEX6);
|
||||
$this->assertEquals($colour->blue, static::BLUE_HEX6);
|
||||
$this->assertFalse($colour->inherit);
|
||||
$this->assertEquals($colour->getHex(), static::STR_HEX6);
|
||||
$this->assertEquals($colour->getRaw(), static::RAW_HEX6);
|
||||
$this->assertEquals($colour->getRed(), static::RED_HEX6);
|
||||
$this->assertEquals($colour->getGreen(), static::GREEN_HEX6);
|
||||
$this->assertEquals($colour->getBlue(), static::BLUE_HEX6);
|
||||
$this->assertFalse($colour->getInherit());
|
||||
}
|
||||
|
||||
public function testFromHex()
|
||||
{
|
||||
$colour = Colour::fromHex(static::SSTR_HEX6);
|
||||
|
||||
$this->assertEquals($colour->hex, static::STR_HEX6);
|
||||
$this->assertEquals($colour->raw, static::RAW_HEX6);
|
||||
$this->assertEquals($colour->red, static::RED_HEX6);
|
||||
$this->assertEquals($colour->green, static::GREEN_HEX6);
|
||||
$this->assertEquals($colour->blue, static::BLUE_HEX6);
|
||||
$this->assertFalse($colour->inherit);
|
||||
$this->assertEquals($colour->getHex(), static::STR_HEX6);
|
||||
$this->assertEquals($colour->getRaw(), static::RAW_HEX6);
|
||||
$this->assertEquals($colour->getRed(), static::RED_HEX6);
|
||||
$this->assertEquals($colour->getGreen(), static::GREEN_HEX6);
|
||||
$this->assertEquals($colour->getBlue(), static::BLUE_HEX6);
|
||||
$this->assertFalse($colour->getInherit());
|
||||
}
|
||||
|
||||
public function testFromHex3()
|
||||
{
|
||||
$colour = Colour::fromHex(static::SSTR_HEX3);
|
||||
|
||||
$this->assertEquals($colour->hex, static::STR_HEX3);
|
||||
$this->assertEquals($colour->raw, static::RAW_HEX3);
|
||||
$this->assertEquals($colour->red, static::RED_HEX3);
|
||||
$this->assertEquals($colour->green, static::GREEN_HEX3);
|
||||
$this->assertEquals($colour->blue, static::BLUE_HEX3);
|
||||
$this->assertFalse($colour->inherit);
|
||||
$this->assertEquals($colour->getHex(), static::STR_HEX3);
|
||||
$this->assertEquals($colour->getRaw(), static::RAW_HEX3);
|
||||
$this->assertEquals($colour->getRed(), static::RED_HEX3);
|
||||
$this->assertEquals($colour->getGreen(), static::GREEN_HEX3);
|
||||
$this->assertEquals($colour->getBlue(), static::BLUE_HEX3);
|
||||
$this->assertFalse($colour->getInherit());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
39
utility.php
39
utility.php
|
@ -202,42 +202,7 @@ function create_pagination($paginator)
|
|||
return \Illuminate\Pagination\UrlWindow::make($paginator);
|
||||
}
|
||||
|
||||
function is_int_ex($value, int $boundary_low, int $boundary_high): bool
|
||||
function running_on_windows(): bool
|
||||
{
|
||||
return is_int($value) && $value >= $boundary_low && $value <= $boundary_high;
|
||||
}
|
||||
|
||||
function is_sbyte($value): bool
|
||||
{
|
||||
return is_int_ex($value, -0x80, 0x7F);
|
||||
}
|
||||
|
||||
function is_byte($value): bool
|
||||
{
|
||||
return is_int_ex($value, 0x0, 0xFF);
|
||||
}
|
||||
|
||||
function is_int16($value): bool
|
||||
{
|
||||
return is_int_ex($value, -0x8000, 0x7FFF);
|
||||
}
|
||||
|
||||
function is_uint16($value): bool
|
||||
{
|
||||
return is_int_ex($value, 0x0, 0xFFFF);
|
||||
}
|
||||
|
||||
function is_int32($value): bool
|
||||
{
|
||||
return is_int_ex($value, -0x80000000, 0x7FFFFFFF);
|
||||
}
|
||||
|
||||
function is_uint32($value): bool
|
||||
{
|
||||
return is_int_ex($value, 0x0, 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
function is_int64($value): bool
|
||||
{
|
||||
return is_int_ex($value, -0x8000000000000000, 0x7FFFFFFFFFFFFFFF);
|
||||
return starts_with(strtolower(PHP_OS), 'win');
|
||||
}
|
||||
|
|
9
views/auth/lockdown.twig
Normal file
9
views/auth/lockdown.twig
Normal file
|
@ -0,0 +1,9 @@
|
|||
{% extends '@auth/master.twig' %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container logout">
|
||||
<div class="logout__message">
|
||||
<p class="logout__paragraph">The site is currently unavailable, try again later.</p>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
|
@ -14,10 +14,10 @@
|
|||
{% endfor %}
|
||||
{% endmacro %}
|
||||
|
||||
{% macro paginate(paginator, base_url, className) %}
|
||||
{% from _self import pagination_segment %}
|
||||
{% macro paginate(paginator, base_url, className, alwaysRender) %}
|
||||
{% set alwaysRender = alwaysRender|default(false) %}
|
||||
|
||||
{% set url_window = paginator|create_pagination %}
|
||||
{% if alwaysRender or paginator.hasMorePages %}
|
||||
{% set separator = '%3F' in base_url|default('')|url_encode ? '&' : '?' %}
|
||||
{% set base_url = base_url ~ separator %}
|
||||
|
||||
|
@ -38,6 +38,9 @@
|
|||
|
||||
<li class="pagination__separator"></li>
|
||||
|
||||
{% from _self import pagination_segment %}
|
||||
{% set url_window = paginator|create_pagination %}
|
||||
|
||||
{% if url_window.first is iterable %}
|
||||
{{ pagination_segment(url_window.first, base_url, paginator.currentPage) }}
|
||||
<li class="pagination__separator"></li>
|
||||
|
@ -67,4 +70,5 @@
|
|||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
|
|
|
@ -4,12 +4,13 @@
|
|||
{% block content %}
|
||||
<div class="container listing user-listing">
|
||||
{% for user in manage_users %}
|
||||
<label class="listing__entry user-listing__entry">
|
||||
<label class="listing__entry user-listing__entry"{% if not user.displayColour.inherit %} style="border-color: {{ user.displayColour }}"{% endif %}>
|
||||
<div class="listing__entry__content user-listing__entry__content">
|
||||
<input type="checkbox">
|
||||
<input class="listing__entry__selector" type="checkbox">
|
||||
<a href="/profile.php?u={{ user.user_id }}" class="listing__entry__column user-listing__entry__column user-listing__entry__column--username">
|
||||
{{ user.username }}
|
||||
</a>
|
||||
<div class="user-listing__avatar" style="background-image:url('/profile.php?u={{ user.user_id }}&m=avatar');"></div>
|
||||
</div>
|
||||
</label>
|
||||
{% endfor %}
|
||||
|
|
23
views/manage/users/roles.twig
Normal file
23
views/manage/users/roles.twig
Normal file
|
@ -0,0 +1,23 @@
|
|||
{% extends '@manage/users/master.twig' %}
|
||||
{% from '@manage/macros.twig' import paginate %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container">
|
||||
<a href="?m=create" class="button">Create new Role</a>
|
||||
</div>
|
||||
|
||||
<div class="container listing role-listing">
|
||||
{% for role in manage_roles %}
|
||||
<a href="?m=edit&i={{ role.role_id }}" class="listing__entry role-listing__entry"{% if not role.role_colour.inherit %} style="border-color: {{ role.role_colour }}"{% endif %}>
|
||||
<div class="listing__entry__content role-listing__entry__content">
|
||||
{{ role.role_name }}
|
||||
{{ role.users.count }} users
|
||||
</div>
|
||||
</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<div class="container container--center">
|
||||
{{ paginate(manage_roles) }}
|
||||
</div>
|
||||
{% endblock %}
|
73
views/manage/users/roles_create.twig
Normal file
73
views/manage/users/roles_create.twig
Normal file
|
@ -0,0 +1,73 @@
|
|||
{% extends '@manage/users/master.twig' %}
|
||||
|
||||
{% block content %}
|
||||
<form action="?m={{ edit_role is defined ? 'edit&i=' ~ edit_role.role_id : 'create' }}" method="post">
|
||||
<div class="container">
|
||||
<h1 class="container__title container__title">Creating a new Role</h1>
|
||||
|
||||
<label class="form__label">
|
||||
<div class="form__label__text">Role Name</div>
|
||||
<div class="form__label__input">
|
||||
<input class="input input--text" type="text" value="{{ edit_role is defined ? edit_role.role_name : '' }}" name="role[name]" maxlength="255">
|
||||
</div>
|
||||
</label>
|
||||
|
||||
<label class="form__label">
|
||||
<div class="form__label__text">Hide Rank</div>
|
||||
<div class="form__label__input">
|
||||
<input class="input" type="checkbox" name="role[secret]"{% if edit_role is defined and edit_role.role_secret %} checked{% endif %}>
|
||||
</div>
|
||||
</label>
|
||||
|
||||
<label class="form__label">
|
||||
<div class="form__label__text">Hierarchy</div>
|
||||
<div class="form__label__input">
|
||||
<input class="input input--number" type="number" value="{{ edit_role is defined ? edit_role.role_hierarchy : '1' }}" min="1" max="100" name="role[hierarchy]">
|
||||
</div>
|
||||
</label>
|
||||
|
||||
<h2 class="container__subtitle">Colour</h2>
|
||||
|
||||
<label class="form__label">
|
||||
<div class="form__label__text">Inherit Colour</div>
|
||||
<div class="form__label__input">
|
||||
<input class="input" type="checkbox" name="role[colour][inherit]"{% if edit_role is defined and edit_role.role_colour.inherit %} checked{% endif %}>
|
||||
</div>
|
||||
</label>
|
||||
|
||||
<label class="form__label">
|
||||
<div class="form__label__text">Red</div>
|
||||
<div class="form__label__input">
|
||||
<input class="input input--number" type="number" value="{{ edit_role is defined ? edit_role.role_colour.red : '0' }}" min="0" max="255" name="role[colour][red]">
|
||||
</div>
|
||||
</label>
|
||||
|
||||
<label class="form__label">
|
||||
<div class="form__label__text">Green</div>
|
||||
<div class="form__label__input">
|
||||
<input class="input input--number" type="number" value="{{ edit_role is defined ? edit_role.role_colour.green : '0' }}" min="0" max="255" name="role[colour][green]">
|
||||
</div>
|
||||
</label>
|
||||
|
||||
<label class="form__label">
|
||||
<div class="form__label__text">Blue</div>
|
||||
<div class="form__label__input">
|
||||
<input class="input input--number" type="number" value="{{ edit_role is defined ? edit_role.role_colour.blue : '0' }}" min="0" max="255" name="role[colour][blue]">
|
||||
</div>
|
||||
</label>
|
||||
|
||||
<h2 class="container__subtitle">Additional</h2>
|
||||
|
||||
<label class="form__label">
|
||||
<div class="form__label__text">Description</div>
|
||||
<div class="form__label__input">
|
||||
<textarea class="input input--textarea" name="role[description]" maxlength="1000">{{ edit_role is defined ? edit_role.role_description : '' }}</textarea>
|
||||
</div>
|
||||
</label>
|
||||
|
||||
<div>
|
||||
<button class="button" name="csrf" value="{{ csrf_token() }}">{{ edit_role is defined ? 'Update role' : 'Create role' }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
|
@ -64,10 +64,10 @@
|
|||
{{ link('https://github.com/flashwave/misuzu/tree/' ~ git_branch(), git_branch(), 'mio__footer__copyright__link') }} # {{ link('https://github.com/flashwave/misuzu/commit/' ~ git_hash(true), git_hash(), 'mio__footer__copyright__link') }}
|
||||
</div>
|
||||
<div class="mio__footer__links">
|
||||
{{ link('#', 'Terms of Service', 'mio__footer__links__link') }}
|
||||
{{ link('#', 'Rules', 'mio__footer__links__link') }}
|
||||
{{ link('#', 'Contact', 'mio__footer__links__link') }}
|
||||
{{ link('#', 'Status', 'mio__footer__links__link') }}
|
||||
{{ link('#', 'Terms of Service', 'mio__footer__links__link') }} |
|
||||
{{ link('#', 'Rules', 'mio__footer__links__link') }} |
|
||||
{{ link('#', 'Contact', 'mio__footer__links__link') }} |
|
||||
{{ link('#', 'Status', 'mio__footer__links__link') }} |
|
||||
{{ link('https://twitter.com/flashiinet', 'Twitter', 'mio__footer__links__link') }}
|
||||
</div>
|
||||
</footer>
|
||||
|
|
Loading…
Add table
Reference in a new issue