diff --git a/database/2018_01_16_063812_initial_users_table.php b/database/2018_01_16_063812_initial_users_table.php index e7b9f859..424db497 100644 --- a/database/2018_01_16_063812_initial_users_table.php +++ b/database/2018_01_16_063812_initial_users_table.php @@ -1,7 +1,7 @@ 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'); } } diff --git a/database/2018_02_10_222914_create_sessions_table.php b/database/2018_02_10_222914_create_sessions_table.php index e32f85ad..b8a7f76e 100644 --- a/database/2018_02_10_222914_create_sessions_table.php +++ b/database/2018_02_10_222914_create_sessions_table.php @@ -1,7 +1,7 @@ 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') diff --git a/database/2018_02_11_135554_create_roles_tables.php b/database/2018_02_11_135554_create_roles_tables.php index 2d3e5891..ef976862 100644 --- a/database/2018_02_11_135554_create_roles_tables.php +++ b/database/2018_02_11_135554_create_roles_tables.php @@ -1,7 +1,7 @@ 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']); diff --git a/database/2018_03_22_040816_create_login_attempts_table.php b/database/2018_03_22_040816_create_login_attempts_table.php index d1dbb0a7..f2f961b1 100644 --- a/database/2018_03_22_040816_create_login_attempts_table.php +++ b/database/2018_03_22_040816_create_login_attempts_table.php @@ -1,7 +1,7 @@ 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'); } } diff --git a/database/2018_03_22_201221_add_session_country_and_login_user_agent.php b/database/2018_03_22_201221_add_session_country_and_login_user_agent.php index d7d78584..506958f4 100644 --- a/database/2018_03_22_201221_add_session_country_and_login_user_agent.php +++ b/database/2018_03_22_201221_add_session_country_and_login_user_agent.php @@ -1,7 +1,7 @@ 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'); }); diff --git a/database/2018_03_22_232723_add_profile_fields_to_users.php b/database/2018_03_22_232723_add_profile_fields_to_users.php index 86521459..4d6a1607 100644 --- a/database/2018_03_22_232723_add_profile_fields_to_users.php +++ b/database/2018_03_22_232723_add_profile_fields_to_users.php @@ -1,7 +1,7 @@ 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', diff --git a/database/2018_04_13_140000_create_news_tables.php b/database/2018_04_13_140000_create_news_tables.php index bd29c9fb..1c6a8d18 100644 --- a/database/2018_04_13_140000_create_news_tables.php +++ b/database/2018_04_13_140000_create_news_tables.php @@ -1,7 +1,7 @@ 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'); } diff --git a/database/2018_04_17_221700_add_last_seen_and_user_title.php b/database/2018_04_17_221700_add_last_seen_and_user_title.php index 723bc368..327a02ac 100644 --- a/database/2018_04_17_221700_add_last_seen_and_user_title.php +++ b/database/2018_04_17_221700_add_last_seen_and_user_title.php @@ -1,7 +1,7 @@ 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', diff --git a/misuzu.php b/misuzu.php index 2945027b..a692949f 100644 --- a/misuzu.php +++ b/misuzu.php @@ -1,7 +1,9 @@ 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')); diff --git a/public/manage/users.php b/public/manage/users.php index b0609e35..1f6ebfeb 100644 --- a/public/manage/users.php +++ b/public/manage/users.php @@ -1,5 +1,4 @@ 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); } } diff --git a/src/Application.php b/src/Application.php index 6545821f..3e5fe8ce 100644 --- a/src/Application.php +++ b/src/Application.php @@ -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']); diff --git a/src/Colour.php b/src/Colour.php index e39aa01e..4f158a77 100644 --- a/src/Colour.php +++ b/src/Colour.php @@ -1,194 +1,112 @@ 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; } diff --git a/src/Database.php b/src/Database.php index f110f5a0..1f3b6d0d 100644 --- a/src/Database.php +++ b/src/Database.php @@ -1,174 +1,152 @@ 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; } } diff --git a/src/DatabaseV1.php b/src/DatabaseV1.php new file mode 100644 index 00000000..d252250e --- /dev/null +++ b/src/DatabaseV1.php @@ -0,0 +1,174 @@ +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); + } +} diff --git a/src/News/NewsPost.php b/src/News/NewsPost.php index 3726220f..abfbd918 100644 --- a/src/News/NewsPost.php +++ b/src/News/NewsPost.php @@ -1,33 +1,17 @@ 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); } } diff --git a/src/Users/Role.php b/src/Users/Role.php index 03eb7f0e..291712fe 100644 --- a/src/Users/Role.php +++ b/src/Users/Role.php @@ -1,7 +1,6 @@ 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 diff --git a/src/Users/User.php b/src/Users/User.php index 33d00428..5391dd4c 100644 --- a/src/Users/User.php +++ b/src/Users/User.php @@ -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') diff --git a/src/Zalgo.php b/src/Zalgo.php index 235122f7..914447c2 100644 --- a/src/Zalgo.php +++ b/src/Zalgo.php @@ -1,208 +1,132 @@ 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; +} diff --git a/src/zalgo.php b/src/zalgo.php new file mode 100644 index 00000000..914447c2 --- /dev/null +++ b/src/zalgo.php @@ -0,0 +1,132 @@ +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')); } } diff --git a/views/manage/master.twig b/views/manage/master.twig index e7a7e488..550ec7a1 100644 --- a/views/manage/master.twig +++ b/views/manage/master.twig @@ -136,7 +136,7 @@
- +
Profile diff --git a/views/manage/users/listing.twig b/views/manage/users/listing.twig index 8f6d8096..fab815eb 100644 --- a/views/manage/users/listing.twig +++ b/views/manage/users/listing.twig @@ -4,7 +4,7 @@ {% block content %}
{% for user in manage_users %} - +
{{ user.username }} diff --git a/views/manage/users/roles.twig b/views/manage/users/roles.twig index d0807818..4ecb1daf 100644 --- a/views/manage/users/roles.twig +++ b/views/manage/users/roles.twig @@ -8,7 +8,7 @@
{% for role in manage_roles %} - +
{{ role.role_name }} {{ role.users.count }} users diff --git a/views/manage/users/roles_create.twig b/views/manage/users/roles_create.twig index 731a23e0..24594d03 100644 --- a/views/manage/users/roles_create.twig +++ b/views/manage/users/roles_create.twig @@ -5,7 +5,7 @@

{% if edit_role is defined %} - Editing {{ edit_role.role_name }} ({{ edit_role.role_id }}) + Editing {{ edit_role.role_name }} ({{ edit_role.role_id }}) {% else %} Creating a new Role {% endif %} @@ -37,28 +37,28 @@ diff --git a/views/manage/users/view.twig b/views/manage/users/view.twig index 6b539241..885c2292 100644 --- a/views/manage/users/view.twig +++ b/views/manage/users/view.twig @@ -3,7 +3,7 @@ {% block content %}

- Viewing {{ view_user.username }} ({{ view_user.user_id }}) + Viewing {{ view_user.username }} ({{ view_user.user_id }})

Featured News
- {% for post in featured_news %} + {% for post in featuredNews %} {{ news_preview(post) }} {% endfor %}
diff --git a/views/mio/news/macros.twig b/views/mio/news/macros.twig index fe83fa5a..a4568316 100644 --- a/views/mio/news/macros.twig +++ b/views/mio/news/macros.twig @@ -13,7 +13,7 @@ {{ post.created_at }}
-
+
{{ post.user.username }}
diff --git a/views/mio/news/post.twig b/views/mio/news/post.twig index 35ebaf95..ee089dbc 100644 --- a/views/mio/news/post.twig +++ b/views/mio/news/post.twig @@ -17,7 +17,7 @@
-
{{ post.user.username }}
+
{{ post.user.username }}
diff --git a/views/mio/user/view.twig b/views/mio/user/view.twig index cf09b8bf..408a0636 100644 --- a/views/mio/user/view.twig +++ b/views/mio/user/view.twig @@ -74,7 +74,7 @@
{% if profile.userTitle is not empty %}
-
+
{{ profile.userTitle }}