Permalink
Browse files

Merge pull request #4 from flashwave/master

Update release branch!
  • Loading branch information...
flashwave committed Jan 5, 2018
2 parents 8e8822e + 4b005b5 commit f8229b8e4ce677f06b7b4a072c8b8d60b3fbaa1f
@@ -1,9 +1,5 @@
; Example configuration for Misuzu
[Database]
default = mysql_example
connections = mysql_example sqlite_example postgres_example sqlsrv_example
[Database.mysql_example]
driver = mysql
host = localhost
View
@@ -3,6 +3,8 @@
require_once 'vendor/autoload.php';
$app = Application::start(__DIR__ . '/config/config.ini');
$app->debug(IO\Directory::exists(__DIR__ . '/vendor/phpunit/phpunit'));
$app = Application::start(
__DIR__ . '/config/config.ini',
IO\Directory::exists(__DIR__ . '/vendor/phpunit/phpunit')
);
$app->startDatabase();
View
@@ -3,64 +3,38 @@
use Aitemu\RouteCollection;
use Misuzu\Config\ConfigManager;
use UnexpectedValueException;
use InvalidArgumentException;
class Application
/**
* Handles the set up procedures.
*/
class Application extends ApplicationBase
{
private static $instance = null;
public static function getInstance(): Application
{
if (is_null(static::$instance) || !(static::$instance instanceof Application)) {
throw new \Exception('Invalid instance type.');
}
return static::$instance;
}
public static function start(...$params): Application
{
if (!is_null(static::$instance) || static::$instance instanceof Application) {
throw new \Exception('An Application has already been set up.');
}
static::$instance = new Application(...$params);
return static::getInstance();
}
public static function gitCommitInfo(string $format): string
{
return trim(shell_exec(sprintf('git log --pretty="%s" -n1 HEAD', $format)));
}
public static function gitCommitHash(bool $long = false): string
{
return self::gitCommitInfo($long ? '%H' : '%h');
}
public static function gitBranch(): string
{
return trim(shell_exec('git rev-parse --abbrev-ref HEAD'));
}
private $modules = [];
public function __get($name)
{
if (starts_with($name, 'has') && strlen($name) > 3 && ctype_upper($name[3])) {
$name = lcfirst(substr($name, 3));
return $this->hasModule($name);
}
if ($this->hasModule($name)) {
return $this->modules[$name];
}
/**
* Whether the application is in debug mode, this should only be set in the constructor and never altered.
* @var bool
*/
private $debugMode = false;
throw new \Exception('Invalid property.');
}
/**
* Array of database connection names, first in the list is assumed to be the default.
*/
private const DATABASE_CONNECTIONS = [
'mysql-main',
//'mysql-ayase',
];
protected function __construct($configFile = null)
/**
* Constructor, called by ApplicationBase::start() which also passes the arguments through.
* @param ?string $configFile
* @param bool $debug
*/
protected function __construct(?string $configFile = null, bool $debug = false)
{
$this->debugMode = $debug;
ExceptionHandler::register();
ExceptionHandler::debug($this->debugMode);
$this->addModule('config', new ConfigManager($configFile));
}
@@ -73,45 +47,72 @@ public function __destruct()
ExceptionHandler::unregister();
}
/**
* Sets up the database module.
*/
public function startDatabase(): void
{
if ($this->hasDatabase) {
throw new \Exception('Database module has already been started.');
throw new UnexpectedValueException('Database module has already been started.');
}
$this->addModule('database', new Database($this->config, self::DATABASE_CONNECTIONS[0]));
$this->loadDatabaseConnections();
}
/**
* Sets up the required database connections defined in the DATABASE_CONNECTIONS constant.
*/
private function loadDatabaseConnections(): void
{
$config = $this->config;
$database = $this->database;
foreach (self::DATABASE_CONNECTIONS as $name) {
$section = 'Database.' . $name;
$this->addModule('database', new Database(
$config,
$config->get('Database', 'default', 'string', 'default')
));
if (!$config->contains($section)) {
throw new InvalidArgumentException("Database {$name} is not configured.");
}
$this->loadConfigDatabaseConnections();
$database->addConnectionFromConfig($section, $name);
}
}
/**
* Sets up the templating engine module.
*/
public function startTemplating(): void
{
if ($this->hasTemplating) {
throw new \Exception('Templating module has already been started.');
throw new UnexpectedValueException('Templating module has already been started.');
}
$this->addModule('templating', $twig = new TemplateEngine);
$twig->debug($this->debugMode);
$twig->addFilter('json_decode');
$twig->addFilter('byte_symbol');
$twig->addFunction('byte_symbol');
$twig->addFunction('session_id');
$twig->addFunction('config', [$this->config, 'get']);
$twig->addFunction('route', [$this->router, 'url']);
$twig->addFunction('git_hash', [Application::class, 'gitCommitHash']);
$twig->addFunction('git_branch', [Application::class, 'gitBranch']);
$twig->vars(['app' => $this]);
$twig->addPath('nova', __DIR__ . '/../views/nova');
}
/**
* Sets up the router module.
*/
public function startRouter(array $routes = null): void
{
if ($this->hasRouter) {
throw new \Exception('Router module has already been started.');
throw new UnexpectedValueException('Router module has already been started.');
}
$this->addModule('router', $router = new RouteCollection);
@@ -120,53 +121,4 @@ public function startRouter(array $routes = null): void
$router->add($routes);
}
}
/**
* @todo Instead of reading a connections variable from the config,
* the expected connections should be defined somewhere in this class.
*/
private function loadConfigDatabaseConnections(): void
{
$config = $this->config;
$database = $this->database;
if ($config->contains('Database', 'connections')) {
$connections = explode(' ', $config->get('Database', 'connections'));
foreach ($connections as $name) {
$section = 'Database.' . $name;
if (!$config->contains($section)) {
continue;
}
$database->addConnectionFromConfig($section, $name);
}
} else {
throw new \Exception('No database connections have been configured.');
}
}
public function debug(bool $mode): void
{
ExceptionHandler::debug($mode);
if ($this->hasTemplating) {
$this->templating->debug($mode);
}
}
public function addModule(string $name, $module): void
{
if ($this->hasModule($name)) {
throw new \Exception('This module has already been registered.');
}
$this->modules[$name] = $module;
}
public function hasModule(string $name): bool
{
return array_key_exists($name, $this->modules) && !is_null($this->modules[$name]);
}
}
View
@@ -0,0 +1,118 @@
<?php
namespace Misuzu;
use InvalidArgumentException;
use UnexpectedValueException;
/**
* Contains all non-specific methods, for possibly using Misuzu as a framework for other things.
*/
abstract class ApplicationBase
{
/**
* Things extending ApplicationBase are single instance, this property contains the active one.
* @var ApplicationBase
*/
private static $instance = null;
/**
* Holds all the loaded modules.
* @var array
*/
private $modules = [];
/**
* Gets the currently active instance of ApplicationBase
* @return ApplicationBase
*/
public static function getInstance(): ApplicationBase
{
if (is_null(self::$instance) || !(self::$instance instanceof ApplicationBase)) {
throw new UnexpectedValueException('Invalid instance type.');
}
return self::$instance;
}
/**
* Creates an instance of whichever class extends ApplicationBase.
* I have no idea how to make a param for the ... thingy so ech.
* @return ApplicationBase
*/
public static function start(...$params): ApplicationBase
{
if (!is_null(self::$instance) || self::$instance instanceof ApplicationBase) {
throw new UnexpectedValueException('An Application has already been set up.');
}
self::$instance = new static(...$params);
return self::getInstance();
}
/**
* Gets info from the current git commit.
* @param string $format Follows the format of the pretty flag on the git log command
* @return string
*/
public static function gitCommitInfo(string $format): string
{
return trim(shell_exec(sprintf('git log --pretty="%s" -n1 HEAD', $format)));
}
/**
* Gets the hash of the current commit.
* @param bool $long Whether to fetch the long hash or the shorter one.
* @return string
*/
public static function gitCommitHash(bool $long = false): string
{
return self::gitCommitInfo($long ? '%H' : '%h');
}
/**
* Gets the name of the current branch.
* @return string
*/
public static function gitBranch(): string
{
return trim(shell_exec('git rev-parse --abbrev-ref HEAD'));
}
public function __get($name)
{
if (starts_with($name, 'has') && strlen($name) > 3 && ctype_upper($name[3])) {
$name = lcfirst(substr($name, 3));
return $this->hasModule($name);
}
if ($this->hasModule($name)) {
return $this->modules[$name];
}
throw new InvalidArgumentException('Invalid property.');
}
/**
* Adds a module to this application.
* @param string $name
* @param mixed $module
*/
public function addModule(string $name, $module): void
{
if ($this->hasModule($name)) {
throw new InvalidArgumentException('This module has already been registered.');
}
$this->modules[$name] = $module;
}
/**
* Checks if a module is registered.
* @param string $name
* @return bool
*/
public function hasModule(string $name): bool
{
return array_key_exists($name, $this->modules) && !is_null($this->modules[$name]);
}
}
View
@@ -1,6 +1,8 @@
<?php
namespace Misuzu;
use InvalidArgumentException;
class Colour
{
private const INHERIT = 0x40000000;
@@ -106,7 +108,7 @@ public static function fromHex(string $hex): Colour
if ($hex_length === 3) {
$hex = $hex[0] . $hex[0] . $hex[1] . $hex[1] . $hex[2] . $hex[2];
} elseif ($hex_length != 6) {
throw new \Exception('Invalid hex colour format! (find a more appropiate exception type)');
throw new InvalidArgumentException('Invalid hex colour format!');
}
return static::fromRGB(
@@ -3,7 +3,6 @@
use Misuzu\Application;
use Misuzu\Database;
use Misuzu\AyaseUser;
class HomeController extends Controller
{
Oops, something went wrong.

0 comments on commit f8229b8

Please sign in to comment.