summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/App.php19
-rw-r--r--src/Controllers/KeyController.php22
-rw-r--r--src/Controllers/ServerDiscoveryController.php25
-rw-r--r--src/Controllers/ServerImplementationController.php19
-rw-r--r--src/DB.php22
-rw-r--r--src/Router.php52
-rw-r--r--src/Singleton.php17
-rw-r--r--src/routes.php26
8 files changed, 202 insertions, 0 deletions
diff --git a/src/App.php b/src/App.php
new file mode 100644
index 0000000..4c67f76
--- /dev/null
+++ b/src/App.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace App;
+
+use Symfony\Component\Dotenv\Dotenv;
+
+class App
+{
+ public function __construct()
+ {
+ $dotenv = new Dotenv();
+ $dotenv->load(dirname(__DIR__) . "/.env");
+ }
+
+ public function run(): void
+ {
+ Router::getInstance()->run()->send();
+ }
+}
diff --git a/src/Controllers/KeyController.php b/src/Controllers/KeyController.php
new file mode 100644
index 0000000..bde1642
--- /dev/null
+++ b/src/Controllers/KeyController.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace App\Controllers;
+
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\HttpFoundation\JsonResponse;
+
+class KeyController
+{
+ public function server(): Response
+ {
+ return new JsonResponse([
+ "server" => [
+ "name" => "Matrix PHP",
+ "version" => "0.1.0",
+ ],
+ ]);
+ }
+
+ public function query(string $serverName): Response
+ {}
+}
diff --git a/src/Controllers/ServerDiscoveryController.php b/src/Controllers/ServerDiscoveryController.php
new file mode 100644
index 0000000..e5fdd31
--- /dev/null
+++ b/src/Controllers/ServerDiscoveryController.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace App\Controllers;
+
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\HttpFoundation\JsonResponse;
+
+class ServerDiscoveryController
+{
+ public function server(): Response
+ {
+ return new JsonResponse([
+ "m.server" => "$_ENV[DOMAIN]:443",
+ ]);
+ }
+
+ public function client(): Response
+ {
+ return new JsonResponse([
+ "m.homeserver" => [
+ "base_url" => "https://$_ENV[DOMAIN]",
+ ],
+ ]);
+ }
+}
diff --git a/src/Controllers/ServerImplementationController.php b/src/Controllers/ServerImplementationController.php
new file mode 100644
index 0000000..4531ce5
--- /dev/null
+++ b/src/Controllers/ServerImplementationController.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace App\Controllers;
+
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\HttpFoundation\JsonResponse;
+
+class ServerImplementationController
+{
+ public function version(): Response
+ {
+ return new JsonResponse([
+ "server" => [
+ "name" => "Matrix PHP",
+ "version" => "0.1.0",
+ ],
+ ]);
+ }
+}
diff --git a/src/DB.php b/src/DB.php
new file mode 100644
index 0000000..b536079
--- /dev/null
+++ b/src/DB.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace App;
+
+class DB
+{
+ use Singleton;
+
+ private \PDO $connection;
+
+ public function __construct()
+ {
+ $driver = $_ENV['DB_DRIVER'] ?? 'pgsql';
+ $host = $_ENV['DB_HOST'] ?? 'localhost';
+ $port = $_ENV['DB_PORT'] ?? 5432;
+ $dbname = $_ENV['DB_NAME'];
+ $user = $_ENV['DB_USER'];
+ $password = $_ENV['DB_PASSWORD'];
+
+ $this->connection = new \PDO("$driver:host=$host;port=$port;dbname=$dbname", $user, $password);
+ }
+}
diff --git a/src/Router.php b/src/Router.php
new file mode 100644
index 0000000..deb852e
--- /dev/null
+++ b/src/Router.php
@@ -0,0 +1,52 @@
+<?php
+
+namespace App;
+
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\Routing\Loader\Configurator\RouteConfigurator;
+use Symfony\Component\Routing\Matcher\UrlMatcher;
+use Symfony\Component\Routing\RequestContext;
+use Symfony\Component\Routing\RouteCollection;
+
+class Router
+{
+ use Singleton;
+
+ private RouteCollection $routes;
+ private RouteConfigurator $configurator;
+
+ public function __construct()
+ {
+ $this->routes = new RouteCollection();
+ $this->configurator = new RouteConfigurator($this->routes, $this->routes);
+
+ $this->addRoutes();
+ }
+
+ public function run(): Response
+ {
+ $request = Request::createFromGlobals();
+
+ $context = new RequestContext();
+ $context->fromRequest($request);
+
+ try {
+ $matcher = new UrlMatcher($this->routes, $context);
+ $match = $matcher->matchRequest($request);
+
+ $class = $match["_controller"][0];
+ $method = $match["_controller"][1];
+
+ return (new $class)->$method();
+ } catch (\Exception $exception) {
+ return new Response("500: " . $exception->getMessage(), 500);
+ }
+ }
+
+ private function addRoutes(): void
+ {
+ $routes = include_once(__DIR__ . "/routes.php");
+ $routes($this->configurator);
+ }
+}
diff --git a/src/Singleton.php b/src/Singleton.php
new file mode 100644
index 0000000..b4d4598
--- /dev/null
+++ b/src/Singleton.php
@@ -0,0 +1,17 @@
+<?php
+
+namespace App;
+
+trait Singleton
+{
+ private static self $instance;
+
+ public static function getInstance(): self
+ {
+ if (! isset(self::$instance)) {
+ self::$instance = new self();
+ }
+
+ return self::$instance;
+ }
+}
diff --git a/src/routes.php b/src/routes.php
new file mode 100644
index 0000000..ff16ecc
--- /dev/null
+++ b/src/routes.php
@@ -0,0 +1,26 @@
+<?php
+
+namespace App;
+
+use App\Controllers\ServerDiscoveryController;
+use App\Controllers\ServerImplementationController;
+use Symfony\Component\Routing\Loader\Configurator\RouteConfigurator;
+
+return function (RouteConfigurator $routes): void
+{
+ $routes
+ ->add("well_known_matrix_server", "/.well-known/matrix/server")
+ ->controller([ServerDiscoveryController::class, "server"]);
+
+ $routes
+ ->add("well_known_matrix_client", "/.well-known/matrix/client")
+ ->controller([ServerDiscoveryController::class, "client"]);
+
+ $routes
+ ->add("matrix_federation_version", "/_matrix/federation/v1/version")
+ ->controller([ServerImplementationController::class, "version"]);
+
+ # /_matrix/key/v2/server
+ # /_matrix/key/v2/query
+ # /_matrix/key/v2/query/{serverName}
+};