something, do not look
This commit is contained in:
parent
85ebfef072
commit
b9f0e88f25
31 changed files with 915 additions and 669 deletions
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Misuzu\Database;
|
||||
use Misuzu\DatabaseV1;
|
||||
|
||||
// phpcs:disable
|
||||
class InitialUsersTable extends Migration
|
||||
|
@ -11,7 +11,7 @@ class InitialUsersTable extends Migration
|
|||
*/
|
||||
public function up()
|
||||
{
|
||||
$schema = Database::connection()->getSchemaBuilder();
|
||||
$schema = DatabaseV1::connection()->getSchemaBuilder();
|
||||
$schema->create('users', function (Blueprint $table) {
|
||||
$table->increments('user_id');
|
||||
|
||||
|
@ -46,7 +46,7 @@ class InitialUsersTable extends Migration
|
|||
*/
|
||||
public function down()
|
||||
{
|
||||
$schema = Database::connection()->getSchemaBuilder();
|
||||
$schema = DatabaseV1::connection()->getSchemaBuilder();
|
||||
$schema->drop('users');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Misuzu\Database;
|
||||
use Misuzu\DatabaseV1;
|
||||
|
||||
// phpcs:disable
|
||||
class CreateSessionsTable extends Migration
|
||||
|
@ -11,7 +11,7 @@ class CreateSessionsTable extends Migration
|
|||
*/
|
||||
public function up()
|
||||
{
|
||||
$schema = Database::connection()->getSchemaBuilder();
|
||||
$schema = DatabaseV1::connection()->getSchemaBuilder();
|
||||
$schema->create('sessions', function (Blueprint $table) {
|
||||
$table->increments('session_id');
|
||||
|
||||
|
@ -50,7 +50,7 @@ class CreateSessionsTable extends Migration
|
|||
*/
|
||||
public function down()
|
||||
{
|
||||
$schema = Database::connection()->getSchemaBuilder();
|
||||
$schema = DatabaseV1::connection()->getSchemaBuilder();
|
||||
|
||||
$schema->table('users', function (Blueprint $table) {
|
||||
$table->integer('user_registered')
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Misuzu\Database;
|
||||
use Misuzu\DatabaseV1;
|
||||
|
||||
// phpcs:disable
|
||||
class CreateRolesTables extends Migration
|
||||
|
@ -11,7 +11,7 @@ class CreateRolesTables extends Migration
|
|||
*/
|
||||
public function up()
|
||||
{
|
||||
$schema = Database::connection()->getSchemaBuilder();
|
||||
$schema = DatabaseV1::connection()->getSchemaBuilder();
|
||||
$schema->create('roles', function (Blueprint $table) {
|
||||
$table->increments('role_id');
|
||||
|
||||
|
@ -77,7 +77,7 @@ class CreateRolesTables extends Migration
|
|||
*/
|
||||
public function down()
|
||||
{
|
||||
$schema = Database::connection()->getSchemaBuilder();
|
||||
$schema = DatabaseV1::connection()->getSchemaBuilder();
|
||||
|
||||
$schema->table('users', function (Blueprint $table) {
|
||||
$table->dropForeign(['display_role']);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Misuzu\Database;
|
||||
use Misuzu\DatabaseV1;
|
||||
|
||||
// phpcs:disable
|
||||
class CreateLoginAttemptsTable extends Migration
|
||||
|
@ -11,7 +11,7 @@ class CreateLoginAttemptsTable extends Migration
|
|||
*/
|
||||
public function up()
|
||||
{
|
||||
$schema = Database::connection()->getSchemaBuilder();
|
||||
$schema = DatabaseV1::connection()->getSchemaBuilder();
|
||||
$schema->create('login_attempts', function (Blueprint $table) {
|
||||
$table->increments('attempt_id');
|
||||
|
||||
|
@ -42,7 +42,7 @@ class CreateLoginAttemptsTable extends Migration
|
|||
*/
|
||||
public function down()
|
||||
{
|
||||
$schema = Database::connection()->getSchemaBuilder();
|
||||
$schema = DatabaseV1::connection()->getSchemaBuilder();
|
||||
$schema->drop('login_attempts');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Misuzu\Database;
|
||||
use Misuzu\DatabaseV1;
|
||||
|
||||
// phpcs:disable
|
||||
class AddSessionCountryAndLoginUserAgent extends Migration
|
||||
|
@ -11,7 +11,7 @@ class AddSessionCountryAndLoginUserAgent extends Migration
|
|||
*/
|
||||
public function up()
|
||||
{
|
||||
$schema = Database::connection()->getSchemaBuilder();
|
||||
$schema = DatabaseV1::connection()->getSchemaBuilder();
|
||||
$schema->table('sessions', function (Blueprint $table) {
|
||||
$table->char('session_country', 2)
|
||||
->default('XX');
|
||||
|
@ -27,7 +27,7 @@ class AddSessionCountryAndLoginUserAgent extends Migration
|
|||
*/
|
||||
public function down()
|
||||
{
|
||||
$schema = Database::connection()->getSchemaBuilder();
|
||||
$schema = DatabaseV1::connection()->getSchemaBuilder();
|
||||
$schema->table('sessions', function (Blueprint $table) {
|
||||
$table->dropColumn('session_country');
|
||||
});
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Misuzu\Database;
|
||||
use Misuzu\DatabaseV1;
|
||||
|
||||
// phpcs:disable
|
||||
class AddProfileFieldsToUsers extends Migration
|
||||
|
@ -11,7 +11,7 @@ class AddProfileFieldsToUsers extends Migration
|
|||
*/
|
||||
public function up()
|
||||
{
|
||||
$schema = Database::connection()->getSchemaBuilder();
|
||||
$schema = DatabaseV1::connection()->getSchemaBuilder();
|
||||
$schema->table('users', function (Blueprint $table) {
|
||||
$table->string('user_website', 255)
|
||||
->default('');
|
||||
|
@ -50,7 +50,7 @@ class AddProfileFieldsToUsers extends Migration
|
|||
*/
|
||||
public function down()
|
||||
{
|
||||
$schema = Database::connection()->getSchemaBuilder();
|
||||
$schema = DatabaseV1::connection()->getSchemaBuilder();
|
||||
$schema->table('users', function (Blueprint $table) {
|
||||
$table->dropColumn([
|
||||
'user_website',
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Misuzu\Database;
|
||||
use Misuzu\DatabaseV1;
|
||||
|
||||
// phpcs:disable
|
||||
class CreateNewsTables extends Migration
|
||||
|
@ -11,7 +11,7 @@ class CreateNewsTables extends Migration
|
|||
*/
|
||||
public function up()
|
||||
{
|
||||
$schema = Database::connection()->getSchemaBuilder();
|
||||
$schema = DatabaseV1::connection()->getSchemaBuilder();
|
||||
|
||||
$schema->create('news_categories', function (Blueprint $table) {
|
||||
$table->increments('category_id');
|
||||
|
@ -52,7 +52,7 @@ class CreateNewsTables extends Migration
|
|||
*/
|
||||
public function down()
|
||||
{
|
||||
$schema = Database::connection()->getSchemaBuilder();
|
||||
$schema = DatabaseV1::connection()->getSchemaBuilder();
|
||||
$schema->drop('news_posts');
|
||||
$schema->drop('news_categories');
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Misuzu\Database;
|
||||
use Misuzu\DatabaseV1;
|
||||
|
||||
// phpcs:disable
|
||||
class AddLastSeenAndUserTitle extends Migration
|
||||
|
@ -11,7 +11,7 @@ class AddLastSeenAndUserTitle extends Migration
|
|||
*/
|
||||
public function up()
|
||||
{
|
||||
$schema = Database::connection()->getSchemaBuilder();
|
||||
$schema = DatabaseV1::connection()->getSchemaBuilder();
|
||||
$schema->table('users', function (Blueprint $table) {
|
||||
$table->string('user_title', 64)
|
||||
->nullable()
|
||||
|
@ -28,7 +28,7 @@ class AddLastSeenAndUserTitle extends Migration
|
|||
*/
|
||||
public function down()
|
||||
{
|
||||
$schema = Database::connection()->getSchemaBuilder();
|
||||
$schema = DatabaseV1::connection()->getSchemaBuilder();
|
||||
$schema->table('users', function (Blueprint $table) {
|
||||
$table->dropColumn([
|
||||
'user_title',
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
<?php
|
||||
namespace Misuzu;
|
||||
|
||||
require_once 'vendor/autoload.php';
|
||||
require_once __DIR__ . '/vendor/autoload.php';
|
||||
require_once __DIR__ . '/src/colour.php';
|
||||
require_once __DIR__ . '/src/zalgo.php';
|
||||
|
||||
$app = new Application(
|
||||
__DIR__ . '/config/config.ini',
|
||||
|
|
|
@ -1,8 +1,33 @@
|
|||
<?php
|
||||
use Misuzu\Database;
|
||||
use Misuzu\News\NewsPost;
|
||||
|
||||
require_once __DIR__ . '/../misuzu.php';
|
||||
|
||||
$featured_news = NewsPost::where('is_featured', true)->orderBy('created_at', 'desc')->take(3)->get();
|
||||
//$featured_news = NewsPost::where('is_featured', true)->orderBy('created_at', 'desc')->take(3)->get();
|
||||
$featuredNews = [];
|
||||
|
||||
echo $app->getTemplating()->render('home.landing', compact('featured_news'));
|
||||
$fetchNews = Database::connection()
|
||||
->query('
|
||||
SELECT
|
||||
p.`post_id`, p.`post_title`, p.`post_text`, p.`created_at`,
|
||||
u.`user_id`, u.`username`,
|
||||
COALESCE(r.`role_colour`, CAST(0x40000000 AS UNSIGNED)) as `display_colour`
|
||||
FROM `msz_news_posts` as p
|
||||
LEFT JOIN `msz_users` as u
|
||||
ON p.`user_id` = u.`user_id`
|
||||
LEFT JOIN `msz_roles` as r
|
||||
ON u.`display_role` = r.`role_id`
|
||||
WHERE p.`is_featured` = true
|
||||
ORDER BY p.`created_at` DESC
|
||||
LIMIT 3
|
||||
');
|
||||
|
||||
while (($newsPost = $fetchNews->fetchObject(NewsPost::class)) !== false) {
|
||||
$featuredNews['post'] = $newsPost;
|
||||
}
|
||||
|
||||
var_dump($featuredNews);
|
||||
|
||||
|
||||
echo $app->getTemplating()->render('home.landing', compact('featuredNews'));
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
use Misuzu\Colour;
|
||||
use Misuzu\Users\Role;
|
||||
use Misuzu\Users\User;
|
||||
|
||||
|
@ -73,20 +72,21 @@ switch ($_GET['v'] ?? null) {
|
|||
break;
|
||||
}
|
||||
|
||||
$role_colour = Colour::none();
|
||||
$role_colour->setInherit(!empty($_POST['role']['colour']['inherit']));
|
||||
$role_colour = colour_create();
|
||||
|
||||
if (!$role_colour->getInherit()) {
|
||||
if (!empty($_POST['role']['colour']['inherit'])) {
|
||||
colour_set_inherit($role_colour);
|
||||
} else {
|
||||
foreach (['red', 'green', 'blue'] as $key) {
|
||||
$value = (int)($_POST['role']['colour'][$key] ?? -1);
|
||||
$setter = 'set' . ucfirst($key);
|
||||
$func = 'colour_set_' . ucfirst($key);
|
||||
|
||||
if ($value < 0 || $value > 0xFF) {
|
||||
echo 'invalid colour value';
|
||||
break 2;
|
||||
}
|
||||
|
||||
$role_colour->{$setter}($value);
|
||||
$func($role_colour, $value);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,10 +35,16 @@ class Application extends ApplicationBase
|
|||
|
||||
/**
|
||||
* Database instance.
|
||||
* @var \Misuzu\Database
|
||||
* @var \Misuzu\DatabaseV1
|
||||
*/
|
||||
private $databaseInstance = null;
|
||||
|
||||
/**
|
||||
* Database instance.
|
||||
* @var \Misuzu\Database
|
||||
*/
|
||||
private $database;
|
||||
|
||||
/**
|
||||
* ConfigManager instance.
|
||||
* @var \Misuzu\Config\ConfigManager
|
||||
|
@ -200,15 +206,16 @@ class Application extends ApplicationBase
|
|||
throw new UnexpectedValueException('Database module has already been started.');
|
||||
}
|
||||
|
||||
$this->databaseInstance = new Database($this->configInstance, self::DATABASE_CONNECTIONS[0]);
|
||||
$this->database = new Database($this->configInstance, self::DATABASE_CONNECTIONS[0]);
|
||||
$this->databaseInstance = new DatabaseV1($this->configInstance, self::DATABASE_CONNECTIONS[0]);
|
||||
$this->loadDatabaseConnections();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the active database instance.
|
||||
* @return Database
|
||||
* @return DatabaseV1
|
||||
*/
|
||||
public function getDatabase(): Database
|
||||
public function getDatabase(): DatabaseV1
|
||||
{
|
||||
if (is_null($this->databaseInstance)) {
|
||||
throw new UnexpectedValueException('Internal database instance is null, did you run startDatabase yet?');
|
||||
|
@ -261,6 +268,11 @@ class Application extends ApplicationBase
|
|||
$this->templatingInstance->addFilter('flip', 'array_flip');
|
||||
$this->templatingInstance->addFilter('create_pagination');
|
||||
$this->templatingInstance->addFilter('first_paragraph');
|
||||
$this->templatingInstance->addFilter('colour_get_css');
|
||||
$this->templatingInstance->addFilter('colour_get_inherit');
|
||||
$this->templatingInstance->addFilter('colour_get_red');
|
||||
$this->templatingInstance->addFilter('colour_get_green');
|
||||
$this->templatingInstance->addFilter('colour_get_blue');
|
||||
|
||||
$this->templatingInstance->addFunction('git_hash', [Application::class, 'gitCommitHash']);
|
||||
$this->templatingInstance->addFunction('git_branch', [Application::class, 'gitBranch']);
|
||||
|
|
298
src/Colour.php
298
src/Colour.php
|
@ -1,194 +1,112 @@
|
|||
<?php
|
||||
namespace Misuzu;
|
||||
define('MSZ_COLOUR_INHERIT', 0x40000000);
|
||||
|
||||
use InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* Class Colour
|
||||
* @package Misuzu
|
||||
*/
|
||||
class Colour
|
||||
function colour_create(): int
|
||||
{
|
||||
/**
|
||||
* Flag to set when this this should inherit a parent's colour.
|
||||
*/
|
||||
private const INHERIT = 0x40000000;
|
||||
|
||||
/**
|
||||
* Raw colour value, 32-bit integer (although only 25 bits are used).
|
||||
* @var int
|
||||
*/
|
||||
private $rawValue = 0;
|
||||
|
||||
/**
|
||||
* Gets the raw colour value.
|
||||
* @return int
|
||||
*/
|
||||
public function getRaw(): int
|
||||
{
|
||||
return $this->rawValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a raw colour value.
|
||||
* @param int $raw
|
||||
*/
|
||||
public function setRaw(int $raw): void
|
||||
{
|
||||
$this->rawValue = $raw & 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether the inheritance flag is set.
|
||||
* @return bool
|
||||
*/
|
||||
public function getInherit(): bool
|
||||
{
|
||||
return ($this->rawValue & self::INHERIT) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles the inheritance flag.
|
||||
* @param bool $state
|
||||
*/
|
||||
public function setInherit(bool $state): void
|
||||
{
|
||||
if ($state) {
|
||||
$this->rawValue |= self::INHERIT;
|
||||
} else {
|
||||
$this->rawValue &= ~self::INHERIT;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the red colour byte.
|
||||
* @return int
|
||||
*/
|
||||
public function getRed(): int
|
||||
{
|
||||
return $this->rawValue >> 16 & 0xFF;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the red colour byte.
|
||||
* @param int $red
|
||||
*/
|
||||
public function setRed(int $red): void
|
||||
{
|
||||
$red = $red & 0xFF;
|
||||
$this->rawValue &= ~0xFF0000;
|
||||
$this->rawValue |= $red << 16;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the green colour byte.
|
||||
* @return int
|
||||
*/
|
||||
public function getGreen(): int
|
||||
{
|
||||
return $this->rawValue >> 8 & 0xFF;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the green colour byte.
|
||||
* @param int $green
|
||||
*/
|
||||
public function setGreen(int $green): void
|
||||
{
|
||||
$green = $green & 0xFF;
|
||||
$this->rawValue &= ~0xFF00;
|
||||
$this->rawValue |= $green << 8;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the blue colour byte.
|
||||
* @return int
|
||||
*/
|
||||
public function getBlue(): int
|
||||
{
|
||||
return $this->rawValue & 0xFF;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the blue colour byte.
|
||||
* @param int $blue
|
||||
*/
|
||||
public function setBlue(int $blue): void
|
||||
{
|
||||
$blue = $blue & 0xFF;
|
||||
$this->rawValue &= ~0xFF;
|
||||
$this->rawValue |= $blue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the hexidecimal value for this colour, without # prefix.
|
||||
* @return string
|
||||
*/
|
||||
public function getHex(): string
|
||||
{
|
||||
return dechex_pad($this->getRaw() & 0xFFFFFF, 6);
|
||||
}
|
||||
|
||||
/**
|
||||
* Colour constructor.
|
||||
* @param int|null $raw
|
||||
*/
|
||||
public function __construct(?int $raw)
|
||||
{
|
||||
$this->rawValue = $raw ?? self::INHERIT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $red
|
||||
* @param int $green
|
||||
* @param int $blue
|
||||
* @return Colour
|
||||
*/
|
||||
public static function fromRGB(int $red, int $green, int $blue): Colour
|
||||
{
|
||||
$raw = 0;
|
||||
$raw |= ($red & 0xFF) << 16;
|
||||
$raw |= ($green & 0xFF) << 8;
|
||||
$raw |= $blue & 0xFF;
|
||||
return new static($raw);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $hex
|
||||
* @return Colour
|
||||
*/
|
||||
public static function fromHex(string $hex): Colour
|
||||
{
|
||||
$hex = ltrim(strtolower($hex), '#');
|
||||
$hex_length = strlen($hex);
|
||||
|
||||
if ($hex_length === 3) {
|
||||
$hex = $hex[0] . $hex[0] . $hex[1] . $hex[1] . $hex[2] . $hex[2];
|
||||
} elseif ($hex_length != 6) {
|
||||
throw new InvalidArgumentException('Invalid hex colour format!');
|
||||
}
|
||||
|
||||
return static::fromRGB(
|
||||
hexdec(substr($hex, 0, 2)),
|
||||
hexdec(substr($hex, 2, 2)),
|
||||
hexdec(substr($hex, 4, 2))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Colour
|
||||
*/
|
||||
public static function none(): Colour
|
||||
{
|
||||
return new static(static::INHERIT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the hexidecimal value for this colour, with # prefix.
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return "#{$this->getHex()}";
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
function colour_none(): int
|
||||
{
|
||||
return MSZ_COLOUR_INHERIT;
|
||||
}
|
||||
|
||||
function colour_set_inherit(int &$colour): void
|
||||
{
|
||||
$colour |= MSZ_COLOUR_INHERIT;
|
||||
}
|
||||
|
||||
function colour_unset_inherit(int &$colour): void
|
||||
{
|
||||
$colour &= ~MSZ_COLOUR_INHERIT;
|
||||
}
|
||||
|
||||
function colour_get_inherit(int $colour): bool
|
||||
{
|
||||
return ($colour & MSZ_COLOUR_INHERIT) > 0;
|
||||
}
|
||||
|
||||
function colour_get_red(int $colour): int
|
||||
{
|
||||
return ($colour >> 16) & 0xFF;
|
||||
}
|
||||
|
||||
function colour_set_red(int &$colour, int $red): void
|
||||
{
|
||||
$red = $red & 0xFF;
|
||||
$colour &= ~0xFF0000;
|
||||
$colour |= $red << 16;
|
||||
}
|
||||
|
||||
function colour_get_green(int $colour): int
|
||||
{
|
||||
return ($colour >> 8) & 0xFF;
|
||||
}
|
||||
|
||||
function colour_set_green(int &$colour, int $green): void
|
||||
{
|
||||
$green = $green & 0xFF;
|
||||
$colour &= ~0xFF00;
|
||||
$colour |= $green << 8;
|
||||
}
|
||||
|
||||
function colour_get_blue(int $colour): int
|
||||
{
|
||||
return $colour & 0xFF;
|
||||
}
|
||||
|
||||
function colour_set_blue(int &$colour, int $blue): void
|
||||
{
|
||||
$blue = $blue & 0xFF;
|
||||
$colour &= ~0xFF;
|
||||
$colour |= $blue;
|
||||
}
|
||||
|
||||
function colour_get_hex(int $colour, string $format = '#%s'): string
|
||||
{
|
||||
return sprintf(
|
||||
$format,
|
||||
dechex_pad($colour & 0xFFFFFF, 6)
|
||||
);
|
||||
}
|
||||
|
||||
function colour_get_css(int $colour): string
|
||||
{
|
||||
if (colour_get_inherit($colour)) {
|
||||
return 'inherit';
|
||||
}
|
||||
|
||||
return colour_get_hex($colour);
|
||||
}
|
||||
|
||||
function colour_from_rgb(int &$colour, int $red, int $green, int $blue): bool
|
||||
{
|
||||
colour_set_red($colour, $red);
|
||||
colour_set_green($colour, $green);
|
||||
colour_set_blue($colour, $blue);
|
||||
return true;
|
||||
}
|
||||
|
||||
function colour_from_hex(int &$colour, string $hex): bool
|
||||
{
|
||||
if ($hex[0] === '#') {
|
||||
$hex = substr($hex, 1);
|
||||
}
|
||||
|
||||
$length = strlen($hex);
|
||||
|
||||
if ($length === 3) {
|
||||
$hex = $hex[0] . $hex[0] . $hex[1] . $hex[1] . $hex[2] . $hex[2];
|
||||
} elseif ($length !== 6) {
|
||||
return false;
|
||||
}
|
||||
|
||||
colour_from_rgb(
|
||||
$colour,
|
||||
hexdec(substr($hex, 0, 2)),
|
||||
hexdec(substr($hex, 2, 2)),
|
||||
hexdec(substr($hex, 4, 2))
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
232
src/Database.php
232
src/Database.php
|
@ -1,174 +1,152 @@
|
|||
<?php
|
||||
namespace Misuzu;
|
||||
|
||||
use Illuminate\Database\Capsule\Manager as LaravelDatabaseManager;
|
||||
use Misuzu\Config\ConfigManager;
|
||||
use PDO;
|
||||
use InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* Class Database
|
||||
* @package Misuzu
|
||||
*/
|
||||
class Database extends LaravelDatabaseManager
|
||||
final class Database
|
||||
{
|
||||
/**
|
||||
* @var ConfigManager
|
||||
* Array of supported abstraction layers.
|
||||
*/
|
||||
private $configManager;
|
||||
|
||||
/**
|
||||
* Array of supported abstraction layers, primarily depends on what Illuminate\Database supports in reality.
|
||||
*/
|
||||
private const SUPPORTED_DB_ALS = [
|
||||
private const SUPPORTED = [
|
||||
'mysql',
|
||||
'sqlite',
|
||||
'pgsql',
|
||||
'sqlsrv',
|
||||
];
|
||||
|
||||
/**
|
||||
* The default port for MySQL.
|
||||
*/
|
||||
private const DEFAULT_PORT_MYSQL = 3306;
|
||||
|
||||
/**
|
||||
* The default port for PostgreSQL.
|
||||
*/
|
||||
private const DEFAULT_PORT_PGSQL = 5432;
|
||||
|
||||
/**
|
||||
* Default port for Microsoft SQL Server.
|
||||
*/
|
||||
private const DEFAULT_PORT_MSSQL = 1433;
|
||||
|
||||
/**
|
||||
* Default hostname.
|
||||
*/
|
||||
private const DEFAULT_HOST = '127.0.0.1';
|
||||
|
||||
/**
|
||||
* Database constructor.
|
||||
* @param ConfigManager $config
|
||||
* @param string $default
|
||||
* @param bool $startEloquent
|
||||
* @param bool $setAsGlobal
|
||||
* The default port for MySQL.
|
||||
*/
|
||||
public function __construct(
|
||||
ConfigManager $config,
|
||||
string $default = 'default',
|
||||
bool $startEloquent = true,
|
||||
bool $setAsGlobal = true
|
||||
) {
|
||||
$this->configManager = $config;
|
||||
parent::__construct();
|
||||
|
||||
$this->container['config']['database.default'] = $default;
|
||||
|
||||
if ($startEloquent) {
|
||||
$this->bootEloquent();
|
||||
}
|
||||
|
||||
if ($setAsGlobal) {
|
||||
$this->setAsGlobal();
|
||||
}
|
||||
}
|
||||
private const DEFAULT_PORT_MYSQL = 3306;
|
||||
|
||||
/**
|
||||
* Creates a new connection using a ConfigManager instance.
|
||||
* @param string $section
|
||||
* @param string $name
|
||||
* @var Database
|
||||
*/
|
||||
public function addConnectionFromConfig(string $section, string $name = 'default'): void
|
||||
private static $instance;
|
||||
|
||||
/**
|
||||
* @var PDO[]
|
||||
*/
|
||||
private $connections = [];
|
||||
|
||||
/**
|
||||
* @var ConfigManager
|
||||
*/
|
||||
private $configManager;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $default;
|
||||
|
||||
public static function getInstance(): Database
|
||||
{
|
||||
if (!(self::$instance instanceof static)) {
|
||||
throw new \UnexpectedValueException('No instance of Database exists yet.');
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
public function __construct(
|
||||
ConfigManager $config,
|
||||
string $default = 'default'
|
||||
) {
|
||||
if (self::$instance instanceof static) {
|
||||
throw new \UnexpectedValueException('Only one instance of Database may exist.');
|
||||
}
|
||||
|
||||
self::$instance = $this;
|
||||
$this->default = $default;
|
||||
$this->configManager = $config;
|
||||
}
|
||||
|
||||
public static function connection(?string $name = null): PDO
|
||||
{
|
||||
return self::getInstance()->getConnection($name);
|
||||
}
|
||||
|
||||
public function getConnection(?string $name = null): PDO
|
||||
{
|
||||
$name = $name ?? $this->default;
|
||||
return $this->connections[$name] ?? $this->addConnection($name);
|
||||
}
|
||||
|
||||
public function addConnection(string $name): PDO
|
||||
{
|
||||
$section = "Database.{$name}";
|
||||
|
||||
if (!$this->configManager->contains($section, 'driver')) {
|
||||
throw new InvalidArgumentException('Config section not found!');
|
||||
}
|
||||
|
||||
$driver = $this->configManager->get($section, 'driver');
|
||||
|
||||
if (!in_array($driver, self::SUPPORTED_DB_ALS)) {
|
||||
if (!in_array($driver, self::SUPPORTED)) {
|
||||
throw new InvalidArgumentException('Unsupported driver.');
|
||||
}
|
||||
|
||||
$args = [
|
||||
'driver' => $driver,
|
||||
'database' => $this->configManager->get($section, 'database', 'string', 'misuzu'),
|
||||
'prefix' => $this->configManager->contains($section, 'prefix')
|
||||
? $this->configManager->get($section, 'prefix', 'string')
|
||||
: '',
|
||||
$dsn = $driver . ':';
|
||||
$options = [
|
||||
PDO::ATTR_CASE => PDO::CASE_NATURAL,
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||
PDO::ATTR_ORACLE_NULLS => PDO::NULL_NATURAL,
|
||||
PDO::ATTR_STRINGIFY_FETCHES => false,
|
||||
PDO::ATTR_EMULATE_PREPARES => false,
|
||||
];
|
||||
|
||||
switch ($driver) {
|
||||
case 'sqlite':
|
||||
if ($this->configManager->get($section, 'memory', 'bool', false)) {
|
||||
$dsn .= ':memory:';
|
||||
} else {
|
||||
$databasePath = realpath(
|
||||
$this->configManager->get($section, 'database', 'string', __DIR__ . '/../store/misuzu.db')
|
||||
);
|
||||
|
||||
if ($databasePath === false) {
|
||||
throw new \UnexpectedValueException("Database does not exist.");
|
||||
}
|
||||
|
||||
$dsn .= $databasePath . ';';
|
||||
}
|
||||
break;
|
||||
|
||||
case 'mysql':
|
||||
$is_unix_socket = $this->configManager->contains($section, 'unix_socket');
|
||||
|
||||
$args['host'] = $is_unix_socket
|
||||
? ''
|
||||
: $this->configManager->get($section, 'host', 'string', self::DEFAULT_HOST);
|
||||
if ($is_unix_socket) {
|
||||
$dsn .= 'unix_socket=' . $this->configManager->get($section, 'unix_socket', 'string') . ';';
|
||||
} else {
|
||||
$dsn .= 'host=' . $this->configManager->get($section, 'host', 'string', self::DEFAULT_HOST) . ';';
|
||||
$dsn .= 'port=' . $this->configManager->get($section, 'port', 'int', self::DEFAULT_PORT_MYSQL) . ';';
|
||||
}
|
||||
|
||||
$args['port'] = $is_unix_socket
|
||||
? self::DEFAULT_PORT_MYSQL
|
||||
: $this->configManager->get($section, 'port', 'int', self::DEFAULT_PORT_MYSQL);
|
||||
$dsn .= 'charset=' . (
|
||||
$this->configManager->contains($section, 'charset')
|
||||
? $this->configManager->get($section, 'charset', 'string')
|
||||
: 'utf8mb4'
|
||||
) . ';';
|
||||
|
||||
$args['username'] = $this->configManager->get($section, 'username', 'string');
|
||||
$args['password'] = $this->configManager->get($section, 'password', 'string');
|
||||
$args['unix_socket'] = $is_unix_socket
|
||||
? $this->configManager->get($section, 'unix_socket', 'string')
|
||||
: '';
|
||||
$dsn .= 'dbname=' . $this->configManager->get($section, 'database', 'string', 'misuzu') . ';';
|
||||
|
||||
// these should probably be locked to these types
|
||||
$args['charset'] = $this->configManager->contains($section, 'charset')
|
||||
? $this->configManager->get($section, 'charset', 'string')
|
||||
: 'utf8mb4';
|
||||
|
||||
$args['collation'] = $this->configManager->contains($section, 'collation')
|
||||
? $this->configManager->get($section, 'collation', 'string')
|
||||
: 'utf8mb4_bin';
|
||||
|
||||
$args['strict'] = true;
|
||||
$args['engine'] = null;
|
||||
break;
|
||||
|
||||
case 'pgsql':
|
||||
$is_unix_socket = $this->configManager->contains($section, 'unix_socket');
|
||||
|
||||
$args['host'] = $is_unix_socket
|
||||
? ''
|
||||
: $this->configManager->get($section, 'host', 'string', self::DEFAULT_HOST);
|
||||
|
||||
$args['port'] = $is_unix_socket
|
||||
? self::DEFAULT_PORT_PGSQL
|
||||
: $this->configManager->get($section, 'port', 'int', self::DEFAULT_PORT_PGSQL);
|
||||
|
||||
$args['username'] = $this->configManager->get($section, 'username', 'string');
|
||||
$args['password'] = $this->configManager->get($section, 'password', 'string');
|
||||
|
||||
$args['unix_socket'] = $is_unix_socket
|
||||
? $this->configManager->get($section, 'unix_socket', 'string')
|
||||
: '';
|
||||
|
||||
// these should probably be locked to these types
|
||||
$args['charset'] = $this->configManager->contains($section, 'charset')
|
||||
? $this->configManager->get($section, 'charset', 'string')
|
||||
: 'utf8';
|
||||
|
||||
$args['schema'] = 'public';
|
||||
$args['sslmode'] = 'prefer';
|
||||
break;
|
||||
|
||||
case 'sqlsrv':
|
||||
$args['host'] = $this->configManager->get($section, 'host', 'string', self::DEFAULT_HOST);
|
||||
$args['port'] = $this->configManager->get($section, 'port', 'int', self::DEFAULT_PORT_MSSQL);
|
||||
$args['username'] = $this->configManager->get($section, 'username', 'string');
|
||||
$args['password'] = $this->configManager->get($section, 'password', 'string');
|
||||
|
||||
// these should probably be locked to these types
|
||||
$args['charset'] = $this->configManager->contains($section, 'charset')
|
||||
? $this->configManager->get($section, 'charset', 'string')
|
||||
: 'utf8';
|
||||
$options[PDO::MYSQL_ATTR_INIT_COMMAND] = "SET SESSION sql_mode='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'";
|
||||
break;
|
||||
}
|
||||
|
||||
$this->addConnection($args, $name);
|
||||
$connection = new PDO(
|
||||
$dsn,
|
||||
$this->configManager->get($section, 'username', 'string', null),
|
||||
$this->configManager->get($section, 'password', 'string', null),
|
||||
$options
|
||||
);
|
||||
|
||||
return $this->connections[$name] = $connection;
|
||||
}
|
||||
}
|
||||
|
|
174
src/DatabaseV1.php
Normal file
174
src/DatabaseV1.php
Normal file
|
@ -0,0 +1,174 @@
|
|||
<?php
|
||||
namespace Misuzu;
|
||||
|
||||
use Illuminate\Database\Capsule\Manager as LaravelDatabaseManager;
|
||||
use Misuzu\Config\ConfigManager;
|
||||
use InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* Class Database
|
||||
* @package Misuzu
|
||||
*/
|
||||
class DatabaseV1 extends LaravelDatabaseManager
|
||||
{
|
||||
/**
|
||||
* @var ConfigManager
|
||||
*/
|
||||
private $configManager;
|
||||
|
||||
/**
|
||||
* Array of supported abstraction layers, primarily depends on what Illuminate\Database supports in reality.
|
||||
*/
|
||||
private const SUPPORTED_DB_ALS = [
|
||||
'mysql',
|
||||
'sqlite',
|
||||
'pgsql',
|
||||
'sqlsrv',
|
||||
];
|
||||
|
||||
/**
|
||||
* The default port for MySQL.
|
||||
*/
|
||||
private const DEFAULT_PORT_MYSQL = 3306;
|
||||
|
||||
/**
|
||||
* The default port for PostgreSQL.
|
||||
*/
|
||||
private const DEFAULT_PORT_PGSQL = 5432;
|
||||
|
||||
/**
|
||||
* Default port for Microsoft SQL Server.
|
||||
*/
|
||||
private const DEFAULT_PORT_MSSQL = 1433;
|
||||
|
||||
/**
|
||||
* Default hostname.
|
||||
*/
|
||||
private const DEFAULT_HOST = '127.0.0.1';
|
||||
|
||||
/**
|
||||
* Database constructor.
|
||||
* @param ConfigManager $config
|
||||
* @param string $default
|
||||
* @param bool $startEloquent
|
||||
* @param bool $setAsGlobal
|
||||
*/
|
||||
public function __construct(
|
||||
ConfigManager $config,
|
||||
string $default = 'default',
|
||||
bool $startEloquent = true,
|
||||
bool $setAsGlobal = true
|
||||
) {
|
||||
$this->configManager = $config;
|
||||
parent::__construct();
|
||||
|
||||
$this->container['config']['database.default'] = $default;
|
||||
|
||||
if ($startEloquent) {
|
||||
$this->bootEloquent();
|
||||
}
|
||||
|
||||
if ($setAsGlobal) {
|
||||
$this->setAsGlobal();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new connection using a ConfigManager instance.
|
||||
* @param string $section
|
||||
* @param string $name
|
||||
*/
|
||||
public function addConnectionFromConfig(string $section, string $name = 'default'): void
|
||||
{
|
||||
if (!$this->configManager->contains($section, 'driver')) {
|
||||
throw new InvalidArgumentException('Config section not found!');
|
||||
}
|
||||
|
||||
$driver = $this->configManager->get($section, 'driver');
|
||||
|
||||
if (!in_array($driver, self::SUPPORTED_DB_ALS)) {
|
||||
throw new InvalidArgumentException('Unsupported driver.');
|
||||
}
|
||||
|
||||
$args = [
|
||||
'driver' => $driver,
|
||||
'database' => $this->configManager->get($section, 'database', 'string', 'misuzu'),
|
||||
'prefix' => $this->configManager->contains($section, 'prefix')
|
||||
? $this->configManager->get($section, 'prefix', 'string')
|
||||
: '',
|
||||
];
|
||||
|
||||
switch ($driver) {
|
||||
case 'mysql':
|
||||
$is_unix_socket = $this->configManager->contains($section, 'unix_socket');
|
||||
|
||||
$args['host'] = $is_unix_socket
|
||||
? ''
|
||||
: $this->configManager->get($section, 'host', 'string', self::DEFAULT_HOST);
|
||||
|
||||
$args['port'] = $is_unix_socket
|
||||
? self::DEFAULT_PORT_MYSQL
|
||||
: $this->configManager->get($section, 'port', 'int', self::DEFAULT_PORT_MYSQL);
|
||||
|
||||
$args['username'] = $this->configManager->get($section, 'username', 'string');
|
||||
$args['password'] = $this->configManager->get($section, 'password', 'string');
|
||||
$args['unix_socket'] = $is_unix_socket
|
||||
? $this->configManager->get($section, 'unix_socket', 'string')
|
||||
: '';
|
||||
|
||||
// these should probably be locked to these types
|
||||
$args['charset'] = $this->configManager->contains($section, 'charset')
|
||||
? $this->configManager->get($section, 'charset', 'string')
|
||||
: 'utf8mb4';
|
||||
|
||||
$args['collation'] = $this->configManager->contains($section, 'collation')
|
||||
? $this->configManager->get($section, 'collation', 'string')
|
||||
: 'utf8mb4_bin';
|
||||
|
||||
$args['strict'] = true;
|
||||
$args['engine'] = null;
|
||||
break;
|
||||
|
||||
case 'pgsql':
|
||||
$is_unix_socket = $this->configManager->contains($section, 'unix_socket');
|
||||
|
||||
$args['host'] = $is_unix_socket
|
||||
? ''
|
||||
: $this->configManager->get($section, 'host', 'string', self::DEFAULT_HOST);
|
||||
|
||||
$args['port'] = $is_unix_socket
|
||||
? self::DEFAULT_PORT_PGSQL
|
||||
: $this->configManager->get($section, 'port', 'int', self::DEFAULT_PORT_PGSQL);
|
||||
|
||||
$args['username'] = $this->configManager->get($section, 'username', 'string');
|
||||
$args['password'] = $this->configManager->get($section, 'password', 'string');
|
||||
|
||||
$args['unix_socket'] = $is_unix_socket
|
||||
? $this->configManager->get($section, 'unix_socket', 'string')
|
||||
: '';
|
||||
|
||||
// these should probably be locked to these types
|
||||
$args['charset'] = $this->configManager->contains($section, 'charset')
|
||||
? $this->configManager->get($section, 'charset', 'string')
|
||||
: 'utf8';
|
||||
|
||||
$args['schema'] = 'public';
|
||||
$args['sslmode'] = 'prefer';
|
||||
break;
|
||||
|
||||
case 'sqlsrv':
|
||||
$args['host'] = $this->configManager->get($section, 'host', 'string', self::DEFAULT_HOST);
|
||||
$args['port'] = $this->configManager->get($section, 'port', 'int', self::DEFAULT_PORT_MSSQL);
|
||||
$args['username'] = $this->configManager->get($section, 'username', 'string');
|
||||
$args['password'] = $this->configManager->get($section, 'password', 'string');
|
||||
|
||||
// these should probably be locked to these types
|
||||
$args['charset'] = $this->configManager->contains($section, 'charset')
|
||||
? $this->configManager->get($section, 'charset', 'string')
|
||||
: 'utf8';
|
||||
break;
|
||||
}
|
||||
|
||||
$this->addConnection($args, $name);
|
||||
}
|
||||
}
|
|
@ -1,33 +1,17 @@
|
|||
<?php
|
||||
namespace Misuzu\News;
|
||||
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Carbon\Carbon;
|
||||
use Misuzu\Database;
|
||||
use Misuzu\Users\User;
|
||||
use Misuzu\Model;
|
||||
use Parsedown;
|
||||
|
||||
/**
|
||||
* Class NewsPost
|
||||
* @package Misuzu\News
|
||||
* @property-read int $post_id
|
||||
* @property int $category_id
|
||||
* @property bool $is_featured
|
||||
* @property int $user_id
|
||||
* @property string $post_title
|
||||
* @property string $post_text
|
||||
* @property Carbon $scheduled_for
|
||||
* @property Carbon|null $deleted_at
|
||||
* @property-read User $user
|
||||
* @property-read NewsCategory $category
|
||||
*/
|
||||
final class NewsPost extends Model
|
||||
final class NewsPost
|
||||
{
|
||||
use SoftDeletes;
|
||||
|
||||
protected $table = 'news_posts';
|
||||
protected $primaryKey = 'post_id';
|
||||
protected $dates = ['scheduled_for'];
|
||||
|
||||
/**
|
||||
* Parses post_text and returns the final HTML.
|
||||
* @return string
|
||||
|
@ -37,19 +21,21 @@ final class NewsPost extends Model
|
|||
return (new Parsedown)->text($this->post_text);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function user()
|
||||
public function getUser(): ?User
|
||||
{
|
||||
return $this->belongsTo(User::class, 'user_id');
|
||||
if (empty($this->user_id) || $this->user_id < 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return User::find($this->user_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function category()
|
||||
public function getCategory(): ?NewsCategory
|
||||
{
|
||||
return $this->belongsTo(NewsCategory::class, 'category_id');
|
||||
if (empty($this->category_id) || $this->category_id < 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return NewsCategory::find($this->category_id);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
<?php
|
||||
namespace Misuzu\Users;
|
||||
|
||||
use Misuzu\Colour;
|
||||
use Misuzu\Model;
|
||||
|
||||
/**
|
||||
|
@ -13,7 +12,7 @@ use Misuzu\Model;
|
|||
* @property string $role_title
|
||||
* @property string $role_description
|
||||
* @property bool $role_secret
|
||||
* @property Colour $role_colour
|
||||
* @property int $role_colour
|
||||
* @property-read array $users
|
||||
*/
|
||||
class Role extends Model
|
||||
|
@ -27,7 +26,7 @@ class Role extends Model
|
|||
* Creates a new role.
|
||||
* @param string $name
|
||||
* @param int|null $hierarchy
|
||||
* @param Colour|null $colour
|
||||
* @param int|null $colour
|
||||
* @param null|string $title
|
||||
* @param null|string $description
|
||||
* @param bool $secret
|
||||
|
@ -36,13 +35,13 @@ class Role extends Model
|
|||
public static function createRole(
|
||||
string $name,
|
||||
?int $hierarchy = null,
|
||||
?Colour $colour = null,
|
||||
?int $colour = null,
|
||||
?string $title = null,
|
||||
?string $description = null,
|
||||
bool $secret = false
|
||||
): Role {
|
||||
$hierarchy = $hierarchy ?? 1;
|
||||
$colour = $colour ?? Colour::none();
|
||||
$colour = $colour ?? colour_none();
|
||||
|
||||
$role = new Role;
|
||||
$role->role_hierarchy = $hierarchy;
|
||||
|
@ -50,7 +49,7 @@ class Role extends Model
|
|||
$role->role_title = $title;
|
||||
$role->role_description = $description;
|
||||
$role->role_secret = $secret;
|
||||
$role->role_colour = $colour->getRaw();
|
||||
$role->role_colour = $colour;
|
||||
$role->save();
|
||||
|
||||
return $role;
|
||||
|
@ -85,25 +84,6 @@ class Role extends Model
|
|||
return $user->hasRole($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the role_colour attribute.
|
||||
* @param int $colour
|
||||
* @return Colour
|
||||
*/
|
||||
public function getRoleColourAttribute(int $colour): Colour
|
||||
{
|
||||
return new Colour($colour);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the role_colour attribute.
|
||||
* @param Colour $colour
|
||||
*/
|
||||
public function setRoleColourAttribute(Colour $colour): void
|
||||
{
|
||||
$this->attributes['role_colour'] = $colour->getRaw();
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the role_description attribute.
|
||||
* @param null|string $description
|
||||
|
|
|
@ -3,8 +3,7 @@ namespace Misuzu\Users;
|
|||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Misuzu\Colour;
|
||||
use Misuzu\Database;
|
||||
use Misuzu\DatabaseV1;
|
||||
use Misuzu\Model;
|
||||
use Misuzu\Net\IPAddress;
|
||||
|
||||
|
@ -224,12 +223,12 @@ class User extends Model
|
|||
|
||||
/**
|
||||
* Gets the display colour.
|
||||
* @return Colour
|
||||
* @return int
|
||||
*/
|
||||
public function getDisplayColour(): Colour
|
||||
public function getColour(): int
|
||||
{
|
||||
$role = $this->getDisplayRole();
|
||||
return $role === null ? Colour::none() : $role->role_colour;
|
||||
return $role === null ? colour_none() : $role->role_colour;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -333,7 +332,7 @@ class User extends Model
|
|||
if (!$this->displayRoleValidated) {
|
||||
if ($value === null
|
||||
|| UserRole::where('user_id', $this->user_id)->where('role_id', $value)->count() < 1) {
|
||||
$highestRole = Database::table('roles')
|
||||
$highestRole = DatabaseV1::table('roles')
|
||||
->join('user_roles', 'roles.role_id', '=', 'user_roles.role_id')
|
||||
->where('user_id', $this->user_id)
|
||||
->orderBy('roles.role_hierarchy', 'desc')
|
||||
|
|
306
src/Zalgo.php
306
src/Zalgo.php
|
@ -1,208 +1,132 @@
|
|||
<?php
|
||||
namespace Misuzu;
|
||||
define('MSZ_ZALGO_CHARS_UP', [
|
||||
"\u{030d}", "\u{030e}", "\u{0304}", "\u{0305}", "\u{033f}",
|
||||
"\u{0311}", "\u{0306}", "\u{0310}", "\u{0352}", "\u{0357}",
|
||||
"\u{0351}", "\u{0307}", "\u{0308}", "\u{030a}", "\u{0342}",
|
||||
"\u{0344}", "\u{034a}", "\u{034b}", "\u{034c}", "\u{0303}",
|
||||
"\u{0302}", "\u{030c}", "\u{0350}", "\u{0300}", "\u{0301}",
|
||||
"\u{030b}", "\u{030f}", "\u{0312}", "\u{0313}", "\u{0314}",
|
||||
"\u{033d}", "\u{0309}", "\u{0363}", "\u{0364}", "\u{0365}",
|
||||
"\u{0366}", "\u{0367}", "\u{0368}", "\u{0369}", "\u{036a}",
|
||||
"\u{036b}", "\u{036c}", "\u{036d}", "\u{036e}", "\u{036f}",
|
||||
"\u{033e}", "\u{035b}", "\u{0346}", "\u{031a}",
|
||||
]);
|
||||
define('MSZ_ZALGO_CHARS_DOWN', [
|
||||
"\u{0316}", "\u{0317}", "\u{0318}", "\u{0319}", "\u{031c}",
|
||||
"\u{031d}", "\u{031e}", "\u{031f}", "\u{0320}", "\u{0324}",
|
||||
"\u{0325}", "\u{0326}", "\u{0329}", "\u{032a}", "\u{032b}",
|
||||
"\u{032c}", "\u{032d}", "\u{032e}", "\u{032f}", "\u{0330}",
|
||||
"\u{0331}", "\u{0332}", "\u{0333}", "\u{0339}", "\u{033a}",
|
||||
"\u{033b}", "\u{033c}", "\u{0345}", "\u{0347}", "\u{0348}",
|
||||
"\u{0349}", "\u{034d}", "\u{034e}", "\u{0353}", "\u{0354}",
|
||||
"\u{0355}", "\u{0356}", "\u{0359}", "\u{035a}", "\u{0323}",
|
||||
]);
|
||||
define('MSZ_ZALGO_CHARS_MIDDLE', [
|
||||
"\u{0315}", "\u{031b}", "\u{0340}", "\u{0341}", "\u{0358}",
|
||||
"\u{0321}", "\u{0322}", "\u{0327}", "\u{0328}", "\u{0334}",
|
||||
"\u{0335}", "\u{0336}", "\u{034f}", "\u{035c}", "\u{035d}",
|
||||
"\u{035e}", "\u{035f}", "\u{0360}", "\u{0362}", "\u{0338}",
|
||||
"\u{0337}", "\u{0361}", "\u{0489}",
|
||||
]);
|
||||
|
||||
/**
|
||||
* Class Zalgo
|
||||
* @package Misuzu
|
||||
*/
|
||||
class Zalgo
|
||||
define('MSZ_ZALGO_MODE_MINI', 1);
|
||||
define('MSZ_ZALGO_MODE_NORMAL', 2);
|
||||
define('MSZ_ZALGO_MODE_MAX', 3);
|
||||
|
||||
define('MSZ_ZALGO_DIR_UP', 0x1);
|
||||
define('MSZ_ZALGO_DIR_MID', 0x2);
|
||||
define('MSZ_ZALGO_DIR_DOWN', 0x4);
|
||||
|
||||
function zalgo_strip(string $text): string
|
||||
{
|
||||
/**
|
||||
* Characters that crawl upwards.
|
||||
*/
|
||||
private const ZALGO_CHARS_UP = [
|
||||
"\u{030d}", "\u{030e}", "\u{0304}", "\u{0305}", "\u{033f}",
|
||||
"\u{0311}", "\u{0306}", "\u{0310}", "\u{0352}", "\u{0357}",
|
||||
"\u{0351}", "\u{0307}", "\u{0308}", "\u{030a}", "\u{0342}",
|
||||
"\u{0344}", "\u{034a}", "\u{034b}", "\u{034c}", "\u{0303}",
|
||||
"\u{0302}", "\u{030c}", "\u{0350}", "\u{0300}", "\u{0301}",
|
||||
"\u{030b}", "\u{030f}", "\u{0312}", "\u{0313}", "\u{0314}",
|
||||
"\u{033d}", "\u{0309}", "\u{0363}", "\u{0364}", "\u{0365}",
|
||||
"\u{0366}", "\u{0367}", "\u{0368}", "\u{0369}", "\u{036a}",
|
||||
"\u{036b}", "\u{036c}", "\u{036d}", "\u{036e}", "\u{036f}",
|
||||
"\u{033e}", "\u{035b}", "\u{0346}", "\u{031a}",
|
||||
];
|
||||
$text = str_replace(MSZ_ZALGO_CHARS_UP, '', $text);
|
||||
$text = str_replace(MSZ_ZALGO_CHARS_DOWN, '', $text);
|
||||
$text = str_replace(MSZ_ZALGO_CHARS_MIDDLE, '', $text);
|
||||
|
||||
/**
|
||||
* Characters that crawl downwards.
|
||||
*/
|
||||
private const ZALGO_CHARS_DOWN = [
|
||||
"\u{0316}", "\u{0317}", "\u{0318}", "\u{0319}", "\u{031c}",
|
||||
"\u{031d}", "\u{031e}", "\u{031f}", "\u{0320}", "\u{0324}",
|
||||
"\u{0325}", "\u{0326}", "\u{0329}", "\u{032a}", "\u{032b}",
|
||||
"\u{032c}", "\u{032d}", "\u{032e}", "\u{032f}", "\u{0330}",
|
||||
"\u{0331}", "\u{0332}", "\u{0333}", "\u{0339}", "\u{033a}",
|
||||
"\u{033b}", "\u{033c}", "\u{0345}", "\u{0347}", "\u{0348}",
|
||||
"\u{0349}", "\u{034d}", "\u{034e}", "\u{0353}", "\u{0354}",
|
||||
"\u{0355}", "\u{0356}", "\u{0359}", "\u{035a}", "\u{0323}",
|
||||
];
|
||||
return $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Characters that dwell in the middle.
|
||||
*/
|
||||
private const ZALGO_CHARS_MIDDLE = [
|
||||
"\u{0315}", "\u{031b}", "\u{0340}", "\u{0341}", "\u{0358}",
|
||||
"\u{0321}", "\u{0322}", "\u{0327}", "\u{0328}", "\u{0334}",
|
||||
"\u{0335}", "\u{0336}", "\u{034f}", "\u{035c}", "\u{035d}",
|
||||
"\u{035e}", "\u{035f}", "\u{0360}", "\u{0362}", "\u{0338}",
|
||||
"\u{0337}", "\u{0361}", "\u{0489}",
|
||||
];
|
||||
function zalgo_is_char(string $char): bool
|
||||
{
|
||||
return in_array($char, MSZ_ZALGO_CHARS_UP)
|
||||
|| in_array($char, MSZ_ZALGO_CHARS_DOWN)
|
||||
|| in_array($char, MSZ_ZALGO_CHARS_MIDDLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Minimal Zalgo.
|
||||
*/
|
||||
public const ZALGO_MODE_MINI = 1;
|
||||
function zalgo_get_char(array $array): string
|
||||
{
|
||||
return $array[array_rand($array)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Medium Zalgo.
|
||||
*/
|
||||
public const ZALGO_MODE_NORMAL = 2;
|
||||
function zalgo_get_string(array $array, int $length): string
|
||||
{
|
||||
$string = '';
|
||||
|
||||
/**
|
||||
* MAXIMUM ZALGO.
|
||||
*/
|
||||
public const ZALGO_MODE_MAX = 3;
|
||||
for ($i = 0; $i < $length; $i++) {
|
||||
$string .= zalgo_get_char($array);
|
||||
}
|
||||
|
||||
/**
|
||||
* Index of valid modes.
|
||||
*/
|
||||
private const ZALGO_MODES = [
|
||||
self::ZALGO_MODE_MINI,
|
||||
self::ZALGO_MODE_NORMAL,
|
||||
self::ZALGO_MODE_MAX,
|
||||
];
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flag for having characters crawl upwards.
|
||||
*/
|
||||
public const ZALGO_DIR_UP = 0x1;
|
||||
|
||||
/**
|
||||
* Flag for having characters dwell in the middle.
|
||||
*/
|
||||
public const ZALGO_DIR_MID = 0x2;
|
||||
|
||||
/**
|
||||
* Flag for having characters crawl downwards.
|
||||
*/
|
||||
public const ZALGO_DIR_DOWN = 0x4;
|
||||
|
||||
/**
|
||||
* (Try to) restore a Zalgofied string back to normal.
|
||||
* @param string $text
|
||||
* @return string
|
||||
*/
|
||||
public static function strip(string $text): string
|
||||
{
|
||||
$text = str_replace(self::ZALGO_CHARS_UP, '', $text);
|
||||
$text = str_replace(self::ZALGO_CHARS_MIDDLE, '', $text);
|
||||
$text = str_replace(self::ZALGO_CHARS_DOWN, '', $text);
|
||||
function zalgo_run(
|
||||
string $text,
|
||||
int $mode = MSZ_ZALGO_MODE_MINI,
|
||||
int $direction = MSZ_ZALGO_DIR_MID | MSZ_ZALGO_DIR_DOWN
|
||||
): string {
|
||||
$text_length = strlen($text);
|
||||
|
||||
if (!$text_length || !$mode || !$direction) {
|
||||
return $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks a string for Zalgo characters.
|
||||
* @param string $char
|
||||
* @return bool
|
||||
*/
|
||||
private static function isZalgo(string $char): bool
|
||||
{
|
||||
return in_array($char, self::ZALGO_CHARS_UP)
|
||||
|| in_array($char, self::ZALGO_CHARS_MIDDLE)
|
||||
|| in_array($char, self::ZALGO_CHARS_DOWN);
|
||||
$going_up = has_flag($direction, MSZ_ZALGO_DIR_UP);
|
||||
$going_mid = has_flag($direction, MSZ_ZALGO_DIR_MID);
|
||||
$going_down = has_flag($direction, MSZ_ZALGO_DIR_DOWN);
|
||||
|
||||
$str = '';
|
||||
|
||||
for ($i = 0; $i < $text_length; $i++) {
|
||||
$char = $text[$i];
|
||||
|
||||
if (zalgo_is_char($char)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$str .= $char;
|
||||
|
||||
switch ($mode) {
|
||||
case MSZ_ZALGO_MODE_MINI:
|
||||
$num_up = mt_rand(0, 8);
|
||||
$num_mid = mt_rand(0, 2);
|
||||
$num_down = mt_rand(0, 8);
|
||||
break;
|
||||
|
||||
case MSZ_ZALGO_MODE_NORMAL:
|
||||
$num_up = mt_rand(0, 16) / 2 + 1;
|
||||
$num_mid = mt_rand(0, 6) / 2;
|
||||
$num_down = mt_rand(0, 8) / 2 + 1;
|
||||
break;
|
||||
|
||||
case MSZ_ZALGO_MODE_MAX:
|
||||
$num_up = mt_rand(0, 64) / 4 + 3;
|
||||
$num_mid = mt_rand(0, 16) / 4 + 1;
|
||||
$num_down = mt_rand(0, 64) / 4 + 3;
|
||||
break;
|
||||
}
|
||||
|
||||
if ($going_up) {
|
||||
$str .= zalgo_get_string(MSZ_ZALGO_CHARS_UP, $num_up);
|
||||
}
|
||||
|
||||
if ($going_mid) {
|
||||
$str .= zalgo_get_string(MSZ_ZALGO_CHARS_MIDDLE, $num_mid);
|
||||
}
|
||||
|
||||
if ($going_down) {
|
||||
$str .= zalgo_get_string(MSZ_ZALGO_CHARS_DOWN, $num_down);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random Zalgo character.
|
||||
* @param array $array
|
||||
* @param int $length
|
||||
* @return string
|
||||
*/
|
||||
private static function getZalgo(array $array, int $length): string
|
||||
{
|
||||
$string = '';
|
||||
|
||||
for ($i = 0; $i < $length; $i++) {
|
||||
$string .= array_rand_value($array, '');
|
||||
}
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs Zalgo over a string.
|
||||
* @param string $text
|
||||
* @param int $mode
|
||||
* @param int $direction
|
||||
* @return string
|
||||
*/
|
||||
public static function run(
|
||||
string $text,
|
||||
int $mode = self::ZALGO_MODE_MINI,
|
||||
int $direction = self::ZALGO_DIR_MID | self::ZALGO_DIR_DOWN
|
||||
): string {
|
||||
$text_length = strlen($text);
|
||||
|
||||
if (!$text_length || !$mode || !$direction || !in_array($mode, self::ZALGO_MODES)) {
|
||||
return $text;
|
||||
}
|
||||
|
||||
$going_up = has_flag($direction, self::ZALGO_DIR_UP);
|
||||
$going_mid = has_flag($direction, self::ZALGO_DIR_MID);
|
||||
$going_down = has_flag($direction, self::ZALGO_DIR_DOWN);
|
||||
|
||||
if (!$going_up || !$going_mid || !$going_down) {
|
||||
return $text;
|
||||
}
|
||||
|
||||
$str = '';
|
||||
|
||||
for ($i = 0; $i < $text_length; $i++) {
|
||||
$char = $text[$i];
|
||||
|
||||
if (self::isZalgo($char)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$str .= $char;
|
||||
$num_up = 0;
|
||||
$num_mid = 0;
|
||||
$num_down = 0;
|
||||
|
||||
switch ($mode) {
|
||||
case self::ZALGO_MODE_MINI:
|
||||
$num_up = mt_rand(0, 8);
|
||||
$num_mid = mt_rand(0, 2);
|
||||
$num_down = mt_rand(0, 8);
|
||||
break;
|
||||
|
||||
case self::ZALGO_MODE_NORMAL:
|
||||
$num_up = mt_rand(0, 16) / 2 + 1;
|
||||
$num_mid = mt_rand(0, 6) / 2;
|
||||
$num_down = mt_rand(0, 8) / 2 + 1;
|
||||
break;
|
||||
|
||||
case self::ZALGO_MODE_MAX:
|
||||
$num_up = mt_rand(0, 64) / 4 + 3;
|
||||
$num_mid = mt_rand(0, 16) / 4 + 1;
|
||||
$num_down = mt_rand(0, 64) / 4 + 3;
|
||||
break;
|
||||
}
|
||||
|
||||
if ($going_up) {
|
||||
$str .= self::getZalgo(self::ZALGO_CHARS_UP, $num_up);
|
||||
}
|
||||
|
||||
if ($going_mid) {
|
||||
$str .= self::getZalgo(self::ZALGO_CHARS_MIDDLE, $num_mid);
|
||||
}
|
||||
|
||||
if ($going_down) {
|
||||
$str .= self::getZalgo(self::ZALGO_CHARS_DOWN, $num_down);
|
||||
}
|
||||
}
|
||||
|
||||
return $str;
|
||||
}
|
||||
return $str;
|
||||
}
|
||||
|
|
112
src/colour.php
Normal file
112
src/colour.php
Normal file
|
@ -0,0 +1,112 @@
|
|||
<?php
|
||||
define('MSZ_COLOUR_INHERIT', 0x40000000);
|
||||
|
||||
function colour_create(): int
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
function colour_none(): int
|
||||
{
|
||||
return MSZ_COLOUR_INHERIT;
|
||||
}
|
||||
|
||||
function colour_set_inherit(int &$colour): void
|
||||
{
|
||||
$colour |= MSZ_COLOUR_INHERIT;
|
||||
}
|
||||
|
||||
function colour_unset_inherit(int &$colour): void
|
||||
{
|
||||
$colour &= ~MSZ_COLOUR_INHERIT;
|
||||
}
|
||||
|
||||
function colour_get_inherit(int $colour): bool
|
||||
{
|
||||
return ($colour & MSZ_COLOUR_INHERIT) > 0;
|
||||
}
|
||||
|
||||
function colour_get_red(int $colour): int
|
||||
{
|
||||
return ($colour >> 16) & 0xFF;
|
||||
}
|
||||
|
||||
function colour_set_red(int &$colour, int $red): void
|
||||
{
|
||||
$red = $red & 0xFF;
|
||||
$colour &= ~0xFF0000;
|
||||
$colour |= $red << 16;
|
||||
}
|
||||
|
||||
function colour_get_green(int $colour): int
|
||||
{
|
||||
return ($colour >> 8) & 0xFF;
|
||||
}
|
||||
|
||||
function colour_set_green(int &$colour, int $green): void
|
||||
{
|
||||
$green = $green & 0xFF;
|
||||
$colour &= ~0xFF00;
|
||||
$colour |= $green << 8;
|
||||
}
|
||||
|
||||
function colour_get_blue(int $colour): int
|
||||
{
|
||||
return $colour & 0xFF;
|
||||
}
|
||||
|
||||
function colour_set_blue(int &$colour, int $blue): void
|
||||
{
|
||||
$blue = $blue & 0xFF;
|
||||
$colour &= ~0xFF;
|
||||
$colour |= $blue;
|
||||
}
|
||||
|
||||
function colour_get_hex(int $colour, string $format = '#%s'): string
|
||||
{
|
||||
return sprintf(
|
||||
$format,
|
||||
dechex_pad($colour & 0xFFFFFF, 6)
|
||||
);
|
||||
}
|
||||
|
||||
function colour_get_css(int $colour): string
|
||||
{
|
||||
if (colour_get_inherit($colour)) {
|
||||
return 'inherit';
|
||||
}
|
||||
|
||||
return colour_get_hex($colour);
|
||||
}
|
||||
|
||||
function colour_from_rgb(int &$colour, int $red, int $green, int $blue): bool
|
||||
{
|
||||
colour_set_red($colour, $red);
|
||||
colour_set_green($colour, $green);
|
||||
colour_set_blue($colour, $blue);
|
||||
return true;
|
||||
}
|
||||
|
||||
function colour_from_hex(int &$colour, string $hex): bool
|
||||
{
|
||||
if ($hex[0] === '#') {
|
||||
$hex = substr($hex, 1);
|
||||
}
|
||||
|
||||
$length = strlen($hex);
|
||||
|
||||
if ($length === 3) {
|
||||
$hex = $hex[0] . $hex[0] . $hex[1] . $hex[1] . $hex[2] . $hex[2];
|
||||
} elseif ($length !== 6) {
|
||||
return false;
|
||||
}
|
||||
|
||||
colour_from_rgb(
|
||||
$colour,
|
||||
hexdec(substr($hex, 0, 2)),
|
||||
hexdec(substr($hex, 2, 2)),
|
||||
hexdec(substr($hex, 4, 2))
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
132
src/zalgo.php
Normal file
132
src/zalgo.php
Normal file
|
@ -0,0 +1,132 @@
|
|||
<?php
|
||||
define('MSZ_ZALGO_CHARS_UP', [
|
||||
"\u{030d}", "\u{030e}", "\u{0304}", "\u{0305}", "\u{033f}",
|
||||
"\u{0311}", "\u{0306}", "\u{0310}", "\u{0352}", "\u{0357}",
|
||||
"\u{0351}", "\u{0307}", "\u{0308}", "\u{030a}", "\u{0342}",
|
||||
"\u{0344}", "\u{034a}", "\u{034b}", "\u{034c}", "\u{0303}",
|
||||
"\u{0302}", "\u{030c}", "\u{0350}", "\u{0300}", "\u{0301}",
|
||||
"\u{030b}", "\u{030f}", "\u{0312}", "\u{0313}", "\u{0314}",
|
||||
"\u{033d}", "\u{0309}", "\u{0363}", "\u{0364}", "\u{0365}",
|
||||
"\u{0366}", "\u{0367}", "\u{0368}", "\u{0369}", "\u{036a}",
|
||||
"\u{036b}", "\u{036c}", "\u{036d}", "\u{036e}", "\u{036f}",
|
||||
"\u{033e}", "\u{035b}", "\u{0346}", "\u{031a}",
|
||||
]);
|
||||
define('MSZ_ZALGO_CHARS_DOWN', [
|
||||
"\u{0316}", "\u{0317}", "\u{0318}", "\u{0319}", "\u{031c}",
|
||||
"\u{031d}", "\u{031e}", "\u{031f}", "\u{0320}", "\u{0324}",
|
||||
"\u{0325}", "\u{0326}", "\u{0329}", "\u{032a}", "\u{032b}",
|
||||
"\u{032c}", "\u{032d}", "\u{032e}", "\u{032f}", "\u{0330}",
|
||||
"\u{0331}", "\u{0332}", "\u{0333}", "\u{0339}", "\u{033a}",
|
||||
"\u{033b}", "\u{033c}", "\u{0345}", "\u{0347}", "\u{0348}",
|
||||
"\u{0349}", "\u{034d}", "\u{034e}", "\u{0353}", "\u{0354}",
|
||||
"\u{0355}", "\u{0356}", "\u{0359}", "\u{035a}", "\u{0323}",
|
||||
]);
|
||||
define('MSZ_ZALGO_CHARS_MIDDLE', [
|
||||
"\u{0315}", "\u{031b}", "\u{0340}", "\u{0341}", "\u{0358}",
|
||||
"\u{0321}", "\u{0322}", "\u{0327}", "\u{0328}", "\u{0334}",
|
||||
"\u{0335}", "\u{0336}", "\u{034f}", "\u{035c}", "\u{035d}",
|
||||
"\u{035e}", "\u{035f}", "\u{0360}", "\u{0362}", "\u{0338}",
|
||||
"\u{0337}", "\u{0361}", "\u{0489}",
|
||||
]);
|
||||
|
||||
define('MSZ_ZALGO_MODE_MINI', 1);
|
||||
define('MSZ_ZALGO_MODE_NORMAL', 2);
|
||||
define('MSZ_ZALGO_MODE_MAX', 3);
|
||||
|
||||
define('MSZ_ZALGO_DIR_UP', 0x1);
|
||||
define('MSZ_ZALGO_DIR_MID', 0x2);
|
||||
define('MSZ_ZALGO_DIR_DOWN', 0x4);
|
||||
|
||||
function zalgo_strip(string $text): string
|
||||
{
|
||||
$text = str_replace(MSZ_ZALGO_CHARS_UP, '', $text);
|
||||
$text = str_replace(MSZ_ZALGO_CHARS_DOWN, '', $text);
|
||||
$text = str_replace(MSZ_ZALGO_CHARS_MIDDLE, '', $text);
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
function zalgo_is_char(string $char): bool
|
||||
{
|
||||
return in_array($char, MSZ_ZALGO_CHARS_UP)
|
||||
|| in_array($char, MSZ_ZALGO_CHARS_DOWN)
|
||||
|| in_array($char, MSZ_ZALGO_CHARS_MIDDLE);
|
||||
}
|
||||
|
||||
function zalgo_get_char(array $array): string
|
||||
{
|
||||
return $array[array_rand($array)];
|
||||
}
|
||||
|
||||
function zalgo_get_string(array $array, int $length): string
|
||||
{
|
||||
$string = '';
|
||||
|
||||
for ($i = 0; $i < $length; $i++) {
|
||||
$string .= zalgo_get_char($array);
|
||||
}
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
||||
function zalgo_run(
|
||||
string $text,
|
||||
int $mode = MSZ_ZALGO_MODE_MINI,
|
||||
int $direction = MSZ_ZALGO_DIR_MID | MSZ_ZALGO_DIR_DOWN
|
||||
): string {
|
||||
$text_length = strlen($text);
|
||||
|
||||
if (!$text_length || !$mode || !$direction) {
|
||||
return $text;
|
||||
}
|
||||
|
||||
$going_up = has_flag($direction, MSZ_ZALGO_DIR_UP);
|
||||
$going_mid = has_flag($direction, MSZ_ZALGO_DIR_MID);
|
||||
$going_down = has_flag($direction, MSZ_ZALGO_DIR_DOWN);
|
||||
|
||||
$str = '';
|
||||
|
||||
for ($i = 0; $i < $text_length; $i++) {
|
||||
$char = $text[$i];
|
||||
|
||||
if (zalgo_is_char($char)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$str .= $char;
|
||||
|
||||
switch ($mode) {
|
||||
case MSZ_ZALGO_MODE_MINI:
|
||||
$num_up = mt_rand(0, 8);
|
||||
$num_mid = mt_rand(0, 2);
|
||||
$num_down = mt_rand(0, 8);
|
||||
break;
|
||||
|
||||
case MSZ_ZALGO_MODE_NORMAL:
|
||||
$num_up = mt_rand(0, 16) / 2 + 1;
|
||||
$num_mid = mt_rand(0, 6) / 2;
|
||||
$num_down = mt_rand(0, 8) / 2 + 1;
|
||||
break;
|
||||
|
||||
case MSZ_ZALGO_MODE_MAX:
|
||||
$num_up = mt_rand(0, 64) / 4 + 3;
|
||||
$num_mid = mt_rand(0, 16) / 4 + 1;
|
||||
$num_down = mt_rand(0, 64) / 4 + 3;
|
||||
break;
|
||||
}
|
||||
|
||||
if ($going_up) {
|
||||
$str .= zalgo_get_string(MSZ_ZALGO_CHARS_UP, $num_up);
|
||||
}
|
||||
|
||||
if ($going_mid) {
|
||||
$str .= zalgo_get_string(MSZ_ZALGO_CHARS_MIDDLE, $num_mid);
|
||||
}
|
||||
|
||||
if ($going_down) {
|
||||
$str .= zalgo_get_string(MSZ_ZALGO_CHARS_DOWN, $num_down);
|
||||
}
|
||||
}
|
||||
|
||||
return $str;
|
||||
}
|
|
@ -2,7 +2,6 @@
|
|||
namespace MisuzuTests;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Misuzu\Colour;
|
||||
use InvalidArgumentException;
|
||||
|
||||
class ColourTest extends TestCase
|
||||
|
@ -10,95 +9,100 @@ class ColourTest extends TestCase
|
|||
public const RED_HEX6 = 67;
|
||||
public const GREEN_HEX6 = 45;
|
||||
public const BLUE_HEX6 = 23;
|
||||
public const SSTR_HEX6 = '#432d17';
|
||||
public const STR_HEX6 = '432d17';
|
||||
public const STR_HEX6 = '#432d17';
|
||||
public const RAW_HEX6 = 4402455;
|
||||
|
||||
public const RED_HEX3 = 51;
|
||||
public const GREEN_HEX3 = 136;
|
||||
public const BLUE_HEX3 = 221;
|
||||
public const SSTR_HEX3 = '#38d';
|
||||
public const STR_HEX3 = '3388dd';
|
||||
public const STR_HEX3 = '#3388dd';
|
||||
public const RAW_HEX3 = 3377373;
|
||||
|
||||
public function testNone()
|
||||
{
|
||||
$colour = Colour::none();
|
||||
$colour = colour_none();
|
||||
|
||||
$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');
|
||||
$this->assertTrue(colour_get_inherit($colour));
|
||||
$this->assertEquals($colour, 0x40000000);
|
||||
$this->assertEquals(colour_get_red($colour), 0);
|
||||
$this->assertEquals(colour_get_green($colour), 0);
|
||||
$this->assertEquals(colour_get_blue($colour), 0);
|
||||
$this->assertEquals(colour_get_hex($colour), '#000000');
|
||||
$this->assertEquals(colour_get_css($colour), 'inherit');
|
||||
}
|
||||
|
||||
public function testNull()
|
||||
{
|
||||
$colour = new Colour(null);
|
||||
$colour = colour_create();
|
||||
|
||||
$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');
|
||||
$this->assertFalse(colour_get_inherit($colour));
|
||||
$this->assertEquals($colour, 0);
|
||||
$this->assertEquals(colour_get_red($colour), 0);
|
||||
$this->assertEquals(colour_get_green($colour), 0);
|
||||
$this->assertEquals(colour_get_blue($colour), 0);
|
||||
$this->assertEquals(colour_get_hex($colour), '#000000');
|
||||
$this->assertEquals(colour_get_css($colour), '#000000');
|
||||
}
|
||||
|
||||
public function testFromRaw()
|
||||
{
|
||||
$colour = new Colour(static::RAW_HEX6);
|
||||
$colour = static::RAW_HEX6;
|
||||
|
||||
$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());
|
||||
$this->assertFalse(colour_get_inherit($colour));
|
||||
$this->assertEquals($colour, static::RAW_HEX6);
|
||||
$this->assertEquals(colour_get_red($colour), static::RED_HEX6);
|
||||
$this->assertEquals(colour_get_green($colour), static::GREEN_HEX6);
|
||||
$this->assertEquals(colour_get_blue($colour), static::BLUE_HEX6);
|
||||
$this->assertEquals(colour_get_hex($colour), static::STR_HEX6);
|
||||
$this->assertEquals(colour_get_css($colour), static::STR_HEX6);
|
||||
}
|
||||
|
||||
public function testFromRGB()
|
||||
{
|
||||
$colour = Colour::fromRGB(static::RED_HEX6, static::GREEN_HEX6, static::BLUE_HEX6);
|
||||
$colour = colour_create();
|
||||
colour_from_rgb($colour, static::RED_HEX6, static::GREEN_HEX6, static::BLUE_HEX6);
|
||||
|
||||
$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());
|
||||
$this->assertFalse(colour_get_inherit($colour));
|
||||
$this->assertEquals($colour, static::RAW_HEX6);
|
||||
$this->assertEquals(colour_get_red($colour), static::RED_HEX6);
|
||||
$this->assertEquals(colour_get_green($colour), static::GREEN_HEX6);
|
||||
$this->assertEquals(colour_get_blue($colour), static::BLUE_HEX6);
|
||||
$this->assertEquals(colour_get_hex($colour), static::STR_HEX6);
|
||||
$this->assertEquals(colour_get_css($colour), static::STR_HEX6);
|
||||
}
|
||||
|
||||
public function testFromHex()
|
||||
{
|
||||
$colour = Colour::fromHex(static::SSTR_HEX6);
|
||||
$colour = colour_create();
|
||||
colour_from_hex($colour, static::STR_HEX6);
|
||||
|
||||
$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());
|
||||
$this->assertFalse(colour_get_inherit($colour));
|
||||
$this->assertEquals($colour, static::RAW_HEX6);
|
||||
$this->assertEquals(colour_get_red($colour), static::RED_HEX6);
|
||||
$this->assertEquals(colour_get_green($colour), static::GREEN_HEX6);
|
||||
$this->assertEquals(colour_get_blue($colour), static::BLUE_HEX6);
|
||||
$this->assertEquals(colour_get_hex($colour), static::STR_HEX6);
|
||||
$this->assertEquals(colour_get_css($colour), static::STR_HEX6);
|
||||
}
|
||||
|
||||
public function testFromHex3()
|
||||
{
|
||||
$colour = Colour::fromHex(static::SSTR_HEX3);
|
||||
$colour = colour_create();
|
||||
colour_from_hex($colour, static::SSTR_HEX3);
|
||||
|
||||
$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());
|
||||
$this->assertFalse(colour_get_inherit($colour));
|
||||
$this->assertEquals($colour, static::RAW_HEX3);
|
||||
$this->assertEquals(colour_get_red($colour), static::RED_HEX3);
|
||||
$this->assertEquals(colour_get_green($colour), static::GREEN_HEX3);
|
||||
$this->assertEquals(colour_get_blue($colour), static::BLUE_HEX3);
|
||||
$this->assertEquals(colour_get_hex($colour), static::STR_HEX3);
|
||||
$this->assertEquals(colour_get_css($colour), static::STR_HEX3);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException InvalidArgumentException
|
||||
* @expectedExceptionMessage Invalid hex colour format!
|
||||
*/
|
||||
public function testHexException()
|
||||
{
|
||||
Colour::fromHex('invalid hex code');
|
||||
$colour = colour_create();
|
||||
$this->assertFalse(colour_from_hex($colour, 'invalid hex code'));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -136,7 +136,7 @@
|
|||
<div class="header__user">
|
||||
<div class="header__menu">
|
||||
<input type="checkbox" id="menu-user-state" class="header__menu__state">
|
||||
<label for="menu-user-state" class="header__menu__toggle header__menu__toggle--profile" style="background-image:url('/profile.php?u={{ app.session.user.user_id }}&m=avatar');color:{{ app.session.user.displayColour.inherit ? 'inherit' : app.session.user.displayColour }}">{{ app.session.user.username }}</label>
|
||||
<label for="menu-user-state" class="header__menu__toggle header__menu__toggle--profile" style="background-image:url('/profile.php?u={{ app.session.user.user_id }}&m=avatar');color:{{ app.session.user.colour|colour_get_css }}">{{ app.session.user.username }}</label>
|
||||
<div class="header__menu__options header__menu__options--user">
|
||||
<div class="header__menu__section">
|
||||
<a class="header__menu__link" href="/profile.php?u={{ app.session.user.user_id }}">Profile</a>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
{% block content %}
|
||||
<div class="container listing user-listing">
|
||||
{% for user in manage_users %}
|
||||
<a href="?v=view&u={{ user.user_id }}" class="listing__entry user-listing__entry"{% if not user.displayColour.inherit %} style="border-color: {{ user.displayColour }}"{% endif %}>
|
||||
<a href="?v=view&u={{ user.user_id }}" class="listing__entry user-listing__entry"{% if not user.colour|colour_get_inherit %} style="border-color: {{ user.colour|colour_get_css }}"{% endif %}>
|
||||
<div class="listing__entry__content user-listing__entry__content">
|
||||
<div class="listing__entry__column user-listing__entry__column user-listing__entry__column--username">
|
||||
{{ user.username }}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
<div class="container listing role-listing">
|
||||
{% for role in manage_roles %}
|
||||
<a href="?v=role&r={{ role.role_id }}" class="listing__entry role-listing__entry"{% if not role.role_colour.inherit %} style="border-color: {{ role.role_colour }}"{% endif %}>
|
||||
<a href="?v=role&r={{ role.role_id }}" class="listing__entry role-listing__entry"{% if not role.role_colour|colour_get_inherit %} style="border-color: {{ role.role_colour|colour_get_css }}"{% endif %}>
|
||||
<div class="listing__entry__content role-listing__entry__content">
|
||||
{{ role.role_name }}
|
||||
{{ role.users.count }} users
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<div class="container">
|
||||
<h1 class="container__title">
|
||||
{% if edit_role is defined %}
|
||||
Editing <span style="color:{{ edit_role.role_colour.inherit ? 'inherit' : edit_role.role_colour }}">{{ edit_role.role_name }}</span> ({{ edit_role.role_id }})
|
||||
Editing <span style="color:{{ edit_role.role_colour|colour_get_css }}">{{ edit_role.role_name }}</span> ({{ edit_role.role_id }})
|
||||
{% else %}
|
||||
Creating a new Role
|
||||
{% endif %}
|
||||
|
@ -37,28 +37,28 @@
|
|||
<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 %}>
|
||||
<input class="input" type="checkbox" name="role[colour][inherit]"{% if edit_role is defined and edit_role.role_colour|colour_get_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]">
|
||||
<input class="input input--number" type="number" value="{{ edit_role is defined ? edit_role.role_colour|colour_get_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]">
|
||||
<input class="input input--number" type="number" value="{{ edit_role is defined ? edit_role.role_colour|colour_get_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]">
|
||||
<input class="input input--number" type="number" value="{{ edit_role is defined ? edit_role.role_colour|colour_get_blue : '0' }}" min="0" max="255" name="role[colour][blue]">
|
||||
</div>
|
||||
</label>
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
{% block content %}
|
||||
<div class="container">
|
||||
<h1 class="container__title">
|
||||
Viewing <span style="color:{{ view_user.displayColour.inherit ? 'inherit' : view_user.displayColour }}">{{ view_user.username }}</span> ({{ view_user.user_id }})
|
||||
Viewing <span style="color:{{ view_user.colour|colour_get_css }}">{{ view_user.username }}</span> ({{ view_user.user_id }})
|
||||
</h1>
|
||||
|
||||
<label class="form__label">
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
<a class="container__title container__title--link" href="/news.php">Featured News</a>
|
||||
<div class="container__content news__container__content">
|
||||
<div class="news__preview__listing">
|
||||
{% for post in featured_news %}
|
||||
{% for post in featuredNews %}
|
||||
{{ news_preview(post) }}
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
{{ post.created_at }}
|
||||
</div>
|
||||
<a class="news__preview__user" href="/profile.php?u={{ post.user.user_id }}">
|
||||
<div class="news__preview__user__name"{% if not post.user.displayColour.inherit %} style="color:{{ post.user.displayColour }}"{% endif %}>
|
||||
<div class="news__preview__user__name" style="color:{{ post.user.colour|colour_get_css }}">
|
||||
{{ post.user.username }}
|
||||
</div>
|
||||
<div class="avatar news__preview__user__avatar" style="background-image:url('/profile.php?u={{ post.user.user_id }}&m=avatar')"></div>
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
<div class="news__sidebar news__post__details">
|
||||
<a class="news__post__detail news__post__user" href="/profile.php?u={{ post.user.user_id }}">
|
||||
<div class="news__post__username">{{ post.user.username }}</div>
|
||||
<div class="news__post__username" style="color:post.user.colour|colour_get_css">{{ post.user.username }}</div>
|
||||
<div class="avatar news__post__avatar" style="background-image:url('/profile.php?u={{ post.user.user_id }}&m=avatar');"></div>
|
||||
</a>
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@
|
|||
<div class="profile__info__block">
|
||||
{% if profile.userTitle is not empty %}
|
||||
<div class="profile__info__row">
|
||||
<div class="profile__info__column profile__info__column--user-title"{% if not profile.displayColour.inherit %} style="color:{{ profile.displayColour }}"{% endif %}>
|
||||
<div class="profile__info__column profile__info__column--user-title" style="color:{{ profile.colour|colour_get_css }}">
|
||||
{{ profile.userTitle }}
|
||||
</div>
|
||||
</div>
|
||||
|
|
Loading…
Reference in a new issue