From 51720fd6a61c887214c5337377bbf7164010f17d Mon Sep 17 00:00:00 2001 From: Marien Fressinaud Date: Mon, 4 May 2020 15:37:54 +0200 Subject: [PATCH] Setup a basic application based on Minz --- .gitmodules | 3 ++ Makefile | 10 ++++ autoload.php | 24 ++++++++++ configuration/environment_development.php | 22 +++++++++ configuration/environment_test.php | 24 ++++++++++ env.sample | 9 ++++ lib/Minz | 1 + public/index.php | 36 ++++++++++++++ src/Application.php | 57 +++++++++++++++++++++++ src/Pages.php | 24 ++++++++++ src/views/pages/home.phtml | 3 ++ tests/HelloWorldTest.php | 15 ------ tests/PagesTest.php | 19 ++++++++ tests/bootstrap.php | 6 +++ 14 files changed, 238 insertions(+), 15 deletions(-) create mode 100644 .gitmodules create mode 100644 autoload.php create mode 100644 configuration/environment_development.php create mode 100644 configuration/environment_test.php create mode 100644 env.sample create mode 160000 lib/Minz create mode 100644 src/Application.php create mode 100644 src/Pages.php create mode 100644 src/views/pages/home.phtml delete mode 100644 tests/HelloWorldTest.php create mode 100644 tests/PagesTest.php diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..6a57cd85 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "lib/Minz"] + path = lib/Minz + url = https://github.com/flusio/Minz.git diff --git a/Makefile b/Makefile index f263295c..c0c7bcff 100644 --- a/Makefile +++ b/Makefile @@ -23,6 +23,13 @@ stop: ## Stop and clean Docker server install: ## Install the dependencies $(COMPOSER) install +.PHONY: setup +setup: .env ## Setup the application system + $(PHP) ./cli --request /system/setup + +.PHONY: update +update: setup ## Update the application + .PHONY: test test: ## Run the test suite $(PHP) ./vendor/bin/phpunit --coverage-text --whitelist ./src --bootstrap ./tests/bootstrap.php --testdox ./tests @@ -38,3 +45,6 @@ lint-fix: ## Fix the errors detected by the linter .PHONY: help help: @grep -h -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' + +.env: + @cp env.sample .env diff --git a/autoload.php b/autoload.php new file mode 100644 index 00000000..e8f01c18 --- /dev/null +++ b/autoload.php @@ -0,0 +1,24 @@ + + * @license http://www.gnu.org/licenses/agpl-3.0.en.html AGPL + */ + +spl_autoload_register( + function ($class_name) { + $app_name = 'flusio'; + $app_path = __DIR__; + $lib_path = $app_path . '/lib'; + + if (strpos($class_name, 'Minz') === 0) { + include $lib_path . '/Minz/autoload.php'; + } elseif (strpos($class_name, $app_name) === 0) { + $class_name = substr($class_name, strlen($app_name) + 1); + $class_path = str_replace('\\', '/', $class_name) . '.php'; + include $app_path . '/src/' . $class_path; + } + } +); diff --git a/configuration/environment_development.php b/configuration/environment_development.php new file mode 100644 index 00000000..f0759d7b --- /dev/null +++ b/configuration/environment_development.php @@ -0,0 +1,22 @@ +pop('DB_HOST'); +$db_port = $dotenv->pop('DB_PORT'); +$db_name = 'flusio_development'; + +return [ + 'app_name' => 'flusio', + + 'secret_key' => $dotenv->pop('APP_SECRET_KEY'), + + 'url_options' => [ + 'host' => $dotenv->pop('APP_HOST'), + 'port' => intval($dotenv->pop('APP_PORT')), + ], + + 'database' => [ + 'dsn' => "pgsql:host={$db_host};port={$db_port};dbname={$db_name}", + 'username' => $dotenv->pop('DB_USERNAME'), + 'password' => $dotenv->pop('DB_PASSWORD'), + ], +]; diff --git a/configuration/environment_test.php b/configuration/environment_test.php new file mode 100644 index 00000000..915038a2 --- /dev/null +++ b/configuration/environment_test.php @@ -0,0 +1,24 @@ +pop('DB_HOST'); +$db_port = $dotenv->pop('DB_PORT'); +$db_name = 'flusio_test'; + +return [ + 'app_name' => 'flusio', + + 'secret_key' => $dotenv->pop('APP_SECRET_KEY'), + + 'url_options' => [ + 'host' => 'test.flus.io', + 'protocol' => 'https', + ], + + 'database' => [ + 'dsn' => "pgsql:host={$db_host};port={$db_port};dbname={$db_name}", + 'username' => $dotenv->pop('DB_USERNAME'), + 'password' => $dotenv->pop('DB_PASSWORD'), + ], + + 'no_syslog' => !getenv('APP_SYSLOG_ENABLED'), +]; diff --git a/env.sample b/env.sample new file mode 100644 index 00000000..136f816a --- /dev/null +++ b/env.sample @@ -0,0 +1,9 @@ +APP_ENVIRONMENT=development +APP_SECRET_KEY=change-me +APP_HOST=localhost +APP_PORT=8000 + +DB_HOST=database +DB_PORT=5432 +DB_USERNAME=postgres +DB_PASSWORD=postgres diff --git a/lib/Minz b/lib/Minz new file mode 160000 index 00000000..a12d64ca --- /dev/null +++ b/lib/Minz @@ -0,0 +1 @@ +Subproject commit a12d64ca0e6f557e9316a914840f5c4a5e76b503 diff --git a/public/index.php b/public/index.php index e69de29b..4d25e972 100644 --- a/public/index.php +++ b/public/index.php @@ -0,0 +1,36 @@ + + * @license http://www.gnu.org/licenses/agpl-3.0.en.html AGPL + */ + +// Setup the Minz framework +$app_path = realpath(__DIR__ . '/..'); + +include $app_path . '/autoload.php'; +\Minz\Configuration::load('dotenv', $app_path); +\Minz\Environment::initialize(); +\Minz\Environment::startSession(); + +// Get the http information and create a Request +$request_method = strtolower($_SERVER['REQUEST_METHOD']); +$http_method = $request_method === 'head' ? 'get' : $request_method; +$http_uri = $_SERVER['REQUEST_URI']; +$http_parameters = array_merge($_GET, $_POST); + +$request = new \Minz\Request($http_method, $http_uri, $http_parameters, $_SERVER); + +// Initialize the Application and execute the request to get a Response +$application = new \flusio\Application(); +$response = $application->run($request); + +// Generate the HTTP headers and output +http_response_code($response->code()); +foreach ($response->headers() as $header) { + header($header); +} + +if ($request_method !== 'head') { + echo $response->render(); +} diff --git a/src/Application.php b/src/Application.php new file mode 100644 index 00000000..490084c4 --- /dev/null +++ b/src/Application.php @@ -0,0 +1,57 @@ +run($request); + * echo $response->render(); + * + * @author Marien Fressinaud + * @license http://www.gnu.org/licenses/agpl-3.0.en.html AGPL + */ +class Application +{ + /** @var \Minz\Engine **/ + private $engine; + + /** + * Setup a Router and declare its routes. + */ + public function __construct() + { + // Initialize the routes + $router = new \Minz\Router(); + $router->addRoute('get', '/', 'Pages#home', 'home'); + + $this->engine = new \Minz\Engine($router); + \Minz\Url::setRouter($router); + } + + /** + * Declare global View variables and execute a request. + * + * @param \Minz\Request $request + * + * @return \Minz\Response + */ + public function run($request) + { + \Minz\Output\View::declareDefaultVariables([ + 'environment' => \Minz\Configuration::$environment, + 'errors' => [], + 'error' => null, + ]); + + return $this->engine->run($request); + } +} diff --git a/src/Pages.php b/src/Pages.php new file mode 100644 index 00000000..ab5dc138 --- /dev/null +++ b/src/Pages.php @@ -0,0 +1,24 @@ + + * @license http://www.gnu.org/licenses/agpl-3.0.en.html AGPL + */ +class Pages +{ + /** + * Show the home page. + * + * @return \Minz\Response + */ + public function home() + { + return Response::ok('pages/home.phtml'); + } +} diff --git a/src/views/pages/home.phtml b/src/views/pages/home.phtml new file mode 100644 index 00000000..48b7258d --- /dev/null +++ b/src/views/pages/home.phtml @@ -0,0 +1,3 @@ +

+ Hello World! +

diff --git a/tests/HelloWorldTest.php b/tests/HelloWorldTest.php deleted file mode 100644 index e5b5eedf..00000000 --- a/tests/HelloWorldTest.php +++ /dev/null @@ -1,15 +0,0 @@ -assertSame('Hello World', $string); - } -} diff --git a/tests/PagesTest.php b/tests/PagesTest.php new file mode 100644 index 00000000..83b74b19 --- /dev/null +++ b/tests/PagesTest.php @@ -0,0 +1,19 @@ +run($request); + + $this->assertResponse($response, 200, 'Hello World!'); + $pointer = $response->output()->pointer(); + $this->assertSame('pages/home.phtml', $pointer); + } +} diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 0d4f296a..cf25f4fc 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -1,3 +1,9 @@