Page Menu
Home
DevCentral
Search
Configure Global Search
Log In
Files
F3773089
D1443.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
8 KB
Referenced Files
None
Subscribers
None
D1443.diff
View Options
diff --git a/.gitignore b/.gitignore
new file mode 100644
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+vendor/
+composer.lock
diff --git a/composer.json b/composer.json
new file mode 100644
--- /dev/null
+++ b/composer.json
@@ -0,0 +1,23 @@
+{
+ "name": "nasqueron/saas-service",
+ "description": "Generic library to serve an entry point for SaaS applications",
+ "type": "library",
+ "license": "BSD-2-Clause",
+ "authors": [
+ {
+ "name": "Sébastien Santoro",
+ "email": "dereckson@espace-win.org"
+ }
+ ],
+ "require": {
+ },
+ "autoload": {
+ "psr-4": {
+ "Nasqueron\\SAAS\\": "src/",
+ "Nasqueron\\SAAS\\Tests\\": "tests/"
+ }
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^7.0"
+ }
+}
diff --git a/src/ConfigurationException.php b/src/ConfigurationException.php
new file mode 100644
--- /dev/null
+++ b/src/ConfigurationException.php
@@ -0,0 +1,8 @@
+<?php
+
+namespace Nasqueron\SAAS;
+
+
+class ConfigurationException extends SaaSException {
+
+}
diff --git a/src/InstanceNotFoundException.php b/src/InstanceNotFoundException.php
new file mode 100644
--- /dev/null
+++ b/src/InstanceNotFoundException.php
@@ -0,0 +1,38 @@
+<?php
+
+namespace Nasqueron\SAAS;
+
+use Throwable;
+
+class InstanceNotFoundException extends SaaSException {
+
+ /**
+ * @var string
+ */
+ private $instance;
+
+ /**
+ * @var string
+ */
+ const DEFAULT_MESSAGE = "The specified instance can't been found.";
+
+ public function __construct (string $instance, string $message = "",
+ int $code = 0, Throwable $previous = null) {
+ $this->instance = $instance;
+
+ if ($message === "") {
+ $message = self::DEFAULT_MESSAGE;
+ }
+
+ parent::__construct($message, $code, $previous);
+ }
+
+ public function getInstance () : string {
+ return $this->instance;
+ }
+
+ public function setInstance (string $instance) : void {
+ $this->instance = $instance;
+ }
+
+}
diff --git a/src/SaaSException.php b/src/SaaSException.php
new file mode 100644
--- /dev/null
+++ b/src/SaaSException.php
@@ -0,0 +1,8 @@
+<?php
+
+namespace Nasqueron\SAAS;
+
+
+class SaaSException extends \Exception {
+
+}
diff --git a/src/Service.php b/src/Service.php
new file mode 100644
--- /dev/null
+++ b/src/Service.php
@@ -0,0 +1,106 @@
+<?php
+
+namespace Nasqueron\SAAS;
+
+abstract class Service {
+
+ ///
+ /// Request methods
+ ///
+
+ public function handleNotExistingSite() : Service {
+ if (!$this->isExisting()) {
+ $this->serveNotExistingResponse();
+ }
+
+ return $this;
+ }
+
+ /**
+ * @throws SaasException where the URI can't be found
+ */
+ public function handleAliveRequest() : Service {
+ // Handles /status requests
+ if (self::isAliveRequest()) {
+ $this->serveAliveResponse();
+ }
+
+ return $this;
+ }
+
+ public abstract function run();
+
+ ///
+ /// Default implementation
+ ///
+
+ public function isExisting () : bool {
+ return true;
+ }
+
+ public function serveAliveResponse() : void {
+ die("ALIVE");
+ }
+
+ public function serveNotExistingResponse(): void {
+ header("HTTP/1.0 404 Not Found");
+ die("This site doesn't exist.");
+ }
+
+ ///
+ /// Helper methods
+ ///
+
+ public static function getServerHost() : string {
+ if (isset($_SERVER['HTTP_HOST'])) {
+ return self::extractHost($_SERVER['HTTP_HOST']);
+ }
+
+ return "";
+ }
+
+ /**
+ * Extracts host from a host:port expression
+ *
+ * @param string $expression The host:port expression, e.g. acme.domain.tld:5000
+ * @return string The host expression without the port, e.g. acme.domain.tld
+ */
+ private static function extractHost (string $expression) : string {
+ $position = strpos($expression, ':');
+
+ if ($position === false) {
+ return $expression;
+ }
+
+ return substr ($expression, 0, $position);
+ }
+
+ /**
+ * @throws SaasException when no URL server parameter have been found.
+ */
+ public static function getUri() : string {
+ $sources = [
+ 'DOCUMENT_URI',
+ 'REQUEST_URI',
+ ];
+
+ foreach ($sources as $source) {
+ if (isset($_SERVER[$source])) {
+ return $_SERVER[$source];
+ }
+ }
+
+ throw new SaasException("Can't get URI.");
+ }
+
+ /**
+ * @throws SaasException where the URI can't be found
+ */
+ private static function isAliveRequest() : bool {
+ return
+ ($_SERVER['REQUEST_METHOD'] === 'GET' || $_SERVER['REQUEST_METHOD'] === 'HEAD')
+ &&
+ static::getUri() === '/status';
+ }
+
+}
diff --git a/tests/InstanceNotFoundTest.php b/tests/InstanceNotFoundTest.php
new file mode 100644
--- /dev/null
+++ b/tests/InstanceNotFoundTest.php
@@ -0,0 +1,28 @@
+<?php
+declare(strict_types=1);
+
+namespace Nasqueron\SAAS\Tests;
+
+use Nasqueron\SAAS\InstanceNotFoundException;
+use PHPUnit\Framework\TestCase;
+
+final class InstanceNotFoundTest extends TestCase {
+
+ /**
+ * @var \Nasqueron\SAAS\InstanceNotFoundException
+ */
+ private $exception;
+
+ protected function setUp () {
+ $this->exception = new InstanceNotFoundException("foo");
+ }
+
+ public function testGetInstance () {
+ $this->assertEquals("foo", $this->exception->getInstance());
+ }
+
+ public function testSetInstance () {
+ $this->exception->setInstance("bar");
+ $this->assertEquals("bar", $this->exception->getInstance());
+ }
+}
diff --git a/tests/Mocks/TestService.php b/tests/Mocks/TestService.php
new file mode 100644
--- /dev/null
+++ b/tests/Mocks/TestService.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace Nasqueron\SAAS\Tests\Mocks;
+
+use Nasqueron\SAAS\Service;
+
+class TestService extends Service {
+
+ /**
+ * @var string
+ */
+ private $host;
+
+ public function __construct (string $host = '') {
+ $this->host = $host;
+ }
+
+ public function run () : void {
+ }
+
+ public function isExisting () : bool {
+ return $this->host === "service.acme.tld";
+ }
+
+}
diff --git a/tests/ServiceTest.php b/tests/ServiceTest.php
new file mode 100644
--- /dev/null
+++ b/tests/ServiceTest.php
@@ -0,0 +1,67 @@
+<?php
+declare(strict_types=1);
+
+namespace Nasqueron\SAAS\Tests;
+
+use Nasqueron\SAAS\SaaSException;
+use Nasqueron\SAAS\Service;
+use Nasqueron\SAAS\Tests\Mocks\TestService;
+use PHPUnit\Framework\TestCase;
+
+final class ServiceTest extends TestCase {
+
+ /**
+ * @var \Nasqueron\SAAS\Service
+ */
+ private $service;
+
+ /**
+ * @var \Nasqueron\SAAS\Service
+ */
+ private $notExistingService;
+
+ protected function setUp() {
+ $this->service = new TestService("service.acme.tld");
+ $this->notExistingService = new TestService("bipbip.acme.tld");
+ }
+
+ public function testIsExisting() {
+ $this->assertTrue($this->service->isExisting());
+ $this->assertFalse($this->notExistingService->isExisting());
+ }
+
+ /**
+ * @dataProvider hostProvider
+ */
+ public function testGetServerHost($host, $expected) {
+ $_SERVER["HTTP_HOST"] = $host;
+ $this->assertEquals($expected, Service::getServerHost());
+ }
+
+ public function hostProvider () : iterable {
+ yield ["service.acme.tld", "service.acme.tld"];
+ yield ["service.acme.tld:1234", "service.acme.tld"];
+ yield ["127.0.0.1", "127.0.0.1"];
+ yield ["127.0.0.1:1234", "127.0.0.1"];
+ yield ["", ""];
+ yield [":1234", ""];
+ }
+
+ public function testGetUriForNginxServer () {
+ $_SERVER['REQUEST_URI'] = "/foo";
+ $this->assertEquals("/foo", Service::getUri());
+ }
+
+ public function testGetUriForInternalPHPServer () {
+ $_SERVER['DOCUMENT_URI'] = "/foo";
+ $this->assertEquals("/foo", Service::getUri());
+ }
+
+ public function testGetUriWhenThereIsNot () {
+ unset($_SERVER['DOCUMENT_URI']);
+ unset($_SERVER['REQUEST_URI']);
+
+ $this->expectException(SaasException::class);
+ $a = Service::getUri();
+ }
+}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Nov 25, 05:50 (21 h, 16 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2261985
Default Alt Text
D1443.diff (8 KB)
Attached To
Mode
D1443: Bootstrap base SaaS library
Attached
Detach File
Event Timeline
Log In to Comment