diff --git a/Core/API/Parameter/IntegerType.class.php b/Core/API/Parameter/IntegerType.class.php
new file mode 100644
index 0000000..898fe45
--- /dev/null
+++ b/Core/API/Parameter/IntegerType.class.php
@@ -0,0 +1,57 @@
+minValue = $minValue;
+ $this->maxValue = $maxValue;
+ parent::__construct($name, Parameter::TYPE_INT, $optional, $defaultValue, $choices);
+ }
+
+ public function parseParam($value): bool {
+ if (!parent::parseParam($value)) {
+ return false;
+ }
+
+ $this->value = $value;
+ if ($this->value < $this->minValue || $this->value > $this->maxValue) {
+ return false;
+ }
+
+ return true;
+ }
+
+ public function getTypeName(): string {
+ $typeName = parent::getTypeName();
+ $hasMin = $this->minValue > PHP_INT_MIN;
+ $hasMax = $this->maxValue < PHP_INT_MAX;
+
+ if ($hasMin || $hasMax) {
+ if ($hasMin && $hasMax) {
+ $typeName .= " ($this->minValue - $this->maxValue)";
+ } else if ($hasMin) {
+ $typeName .= " (> $this->minValue)";
+ } else if ($hasMax) {
+ $typeName .= " (< $this->maxValue)";
+ }
+ }
+
+ return $typeName;
+ }
+
+ public function toString(): string {
+ $typeName = $this->getTypeName();
+ $str = "$typeName $this->name";
+ $defaultValue = (is_null($this->value) ? 'NULL' : $this->value);
+ if ($this->optional) {
+ $str = "[$str = $defaultValue]";
+ }
+
+ return $str;
+ }
+}
\ No newline at end of file
diff --git a/Core/API/Parameter/Parameter.class.php b/Core/API/Parameter/Parameter.class.php
index 3b1afe7..f1e3076 100644
--- a/Core/API/Parameter/Parameter.class.php
+++ b/Core/API/Parameter/Parameter.class.php
@@ -17,12 +17,10 @@ class Parameter {
// only internal access
const TYPE_RAW = 8;
- // only json will work here I guess
- // nope. also name[]=value
const TYPE_ARRAY = 9;
const TYPE_MIXED = 10;
- const names = array('Integer', 'Float', 'Boolean', 'String', 'Date', 'Time', 'DateTime', 'E-Mail', 'Raw', 'Array', 'Mixed');
+ const names = ['Integer', 'Float', 'Boolean', 'String', 'Date', 'Time', 'DateTime', 'E-Mail', 'Raw', 'Array', 'Mixed'];
const DATE_FORMAT = "Y-m-d";
const TIME_FORMAT = "H:i:s";
@@ -47,12 +45,12 @@ class Parameter {
$this->typeName = $this->getTypeName();
}
- public function reset() {
+ public function reset(): void {
$this->value = $this->defaultValue;
}
public function getSwaggerTypeName(): string {
- $typeName = strtolower(($this->type >= 0 && $this->type < count(Parameter::names)) ? Parameter::names[$this->type] : "invalid");
+ $typeName = strtolower(Parameter::names[$this->type] ?? "invalid");
if ($typeName === "mixed" || $typeName === "raw") {
return "object";
}
diff --git a/Core/API/Parameter/RegexType.class.php b/Core/API/Parameter/RegexType.class.php
new file mode 100644
index 0000000..7338b13
--- /dev/null
+++ b/Core/API/Parameter/RegexType.class.php
@@ -0,0 +1,36 @@
+pattern = $pattern;
+
+ if (!startsWith($this->pattern, "/") || !endsWith($this->pattern, "/")) {
+ $this->pattern = "/" . $this->pattern . "/";
+ }
+
+ parent::__construct($name, -1, $optional, $defaultValue);
+ }
+
+ public function parseParam($value): bool {
+ if (!parent::parseParam($value)) {
+ return false;
+ }
+
+ $matches = [];
+ if (!preg_match($this->pattern, $this->value, $matches)) {
+ return false;
+ }
+
+ return strlen($matches[0]) === strlen($this->value);
+ }
+
+ public function getTypeName(): string {
+ return parent::getTypeName() . " ($this->pattern)";
+ }
+}
\ No newline at end of file
diff --git a/Core/API/Parameter/StringType.class.php b/Core/API/Parameter/StringType.class.php
index c3878c1..e27e1e4 100644
--- a/Core/API/Parameter/StringType.class.php
+++ b/Core/API/Parameter/StringType.class.php
@@ -7,7 +7,8 @@ class StringType extends Parameter {
const UNLIMITED = -1;
public int $maxLength;
- public function __construct(string $name, int $maxLength = self::UNLIMITED, bool $optional = FALSE, ?string $defaultValue = NULL, ?array $choices = NULL) {
+ public function __construct(string $name, int $maxLength = self::UNLIMITED, bool $optional = FALSE,
+ ?string $defaultValue = NULL, ?array $choices = NULL) {
$this->maxLength = $maxLength;
parent::__construct($name, Parameter::TYPE_STRING, $optional, $defaultValue, $choices);
}
diff --git a/Core/Documents/Install.class.php b/Core/Documents/Install.class.php
index f63759e..cbdb93b 100644
--- a/Core/Documents/Install.class.php
+++ b/Core/Documents/Install.class.php
@@ -268,7 +268,7 @@ namespace Documents\Install {
$success = false;
}
- $requiredVersion = '8.1';
+ $requiredVersion = "8.2";
if (version_compare(PHP_VERSION, $requiredVersion, '<')) {
$failedRequirements[] = "PHP Version >= $requiredVersion is required. Got: " . PHP_VERSION . "";
$success = false;
@@ -290,7 +290,7 @@ namespace Documents\Install {
$this->errorString = $msg;
}
- return array("success" => $success, "msg" => $msg);
+ return ["success" => $success, "msg" => $msg];
}
private function installDependencies(): array {
@@ -348,7 +348,7 @@ namespace Documents\Install {
$missingInputs[] = "Type";
}
- $supportedTypes = array("mysql", "postgres");
+ $supportedTypes = ["mysql", "postgres"];
if (!$success) {
$msg = "Please fill out the following inputs:
" .
$this->createUnorderedList($missingInputs);
diff --git a/test/Parameter.test.php b/test/Parameter.test.php
index 61c165b..18e508c 100644
--- a/test/Parameter.test.php
+++ b/test/Parameter.test.php
@@ -29,12 +29,16 @@ class ParameterTest extends \PHPUnit\Framework\TestCase {
$this->assertTrue($random->parseParam($data));
$this->assertEquals($data, $random->value);
- // test data types
+ // test data types: we cast the values to string
+ $this->assertTrue($random->parseParam(1));
+ $this->assertTrue($random->parseParam(2.5));
+ $this->assertTrue($random->parseParam(true));
+ $this->assertTrue($random->parseParam(false));
+
+ // null values only allowed, when parameter is optional
$this->assertFalse($random->parseParam(null));
- $this->assertFalse($random->parseParam(1));
- $this->assertFalse($random->parseParam(2.5));
- $this->assertFalse($random->parseParam(true));
- $this->assertFalse($random->parseParam(false));
+
+ // arrays cannot be cast to string (easily)
$this->assertFalse($random->parseParam(["key" => 1]));
}
@@ -64,12 +68,6 @@ class ParameterTest extends \PHPUnit\Framework\TestCase {
}
public function testParseType() {
- // int
- $this->assertEquals(Parameter::TYPE_INT, Parameter::parseType(1));
- $this->assertEquals(Parameter::TYPE_INT, Parameter::parseType(1.0));
- $this->assertEquals(Parameter::TYPE_INT, Parameter::parseType("1"));
- $this->assertEquals(Parameter::TYPE_INT, Parameter::parseType("1.0"));
-
// array
$this->assertEquals(Parameter::TYPE_ARRAY, Parameter::parseType([1, true]));
@@ -106,4 +104,53 @@ class ParameterTest extends \PHPUnit\Framework\TestCase {
// string, everything else
$this->assertEquals(Parameter::TYPE_STRING, Parameter::parseType("test"));
}
+
+ public function testIntegerType() {
+ // int
+ $this->assertEquals(Parameter::TYPE_INT, Parameter::parseType(1));
+ $this->assertEquals(Parameter::TYPE_INT, Parameter::parseType(1.0));
+ $this->assertEquals(Parameter::TYPE_INT, Parameter::parseType("1"));
+ $this->assertEquals(Parameter::TYPE_INT, Parameter::parseType("1.0"));
+
+ // test min value
+ $min = new \Core\API\Parameter\IntegerType("test_has_min_value", 10);
+ $this->assertTrue($min->parseParam(10));
+ $this->assertTrue($min->parseParam(11));
+ $this->assertFalse($min->parseParam(9));
+
+ // test max value
+ $max = new \Core\API\Parameter\IntegerType("test_has_min_value", PHP_INT_MIN, 100);
+ $this->assertTrue($max->parseParam(99));
+ $this->assertTrue($max->parseParam(100));
+ $this->assertFalse($max->parseParam(101));
+
+ // test min and max value
+ $minmax = new \Core\API\Parameter\IntegerType("test_has_min_value", 10, 100);
+ $this->assertTrue($minmax->parseParam(10));
+ $this->assertTrue($minmax->parseParam(11));
+ $this->assertFalse($minmax->parseParam(9));
+ $this->assertTrue($minmax->parseParam(99));
+ $this->assertTrue($minmax->parseParam(100));
+ $this->assertFalse($minmax->parseParam(101));
+ }
+
+ public function testRegexType() {
+ $onlyLowercase = new \Core\API\Parameter\RegexType("only_lowercase", "/[a-z]+/");
+ $this->assertTrue($onlyLowercase->parseParam("abcdefghiklmnopqrstuvwxyz"));
+ $this->assertFalse($onlyLowercase->parseParam("0123456789"));
+
+ $onlyLowercaseOneChar = new \Core\API\Parameter\RegexType("only_lowercase_one_char", "/^[a-z]$/");
+ $this->assertFalse($onlyLowercaseOneChar->parseParam("abcdefghiklmnopqrstuvwxyz"));
+ $this->assertTrue($onlyLowercaseOneChar->parseParam("a"));
+
+ $regexWithoutSlashes = new \Core\API\Parameter\RegexType("regex_no_slash", "[a-z]+");
+ $this->assertTrue($regexWithoutSlashes->parseParam("abcdefghiklmnopqrstuvwxyz"));
+ $this->assertFalse($regexWithoutSlashes->parseParam("0123456789"));
+
+ $integerRegex = new \Core\API\Parameter\RegexType("integer_regex", "[1-9][0-9]*");
+ $this->assertTrue($integerRegex->parseParam("12"));
+ $this->assertTrue($integerRegex->parseParam(12));
+ $this->assertFalse($integerRegex->parseParam("012"));
+ $this->assertFalse($integerRegex->parseParam("1.2"));
+ }
}
\ No newline at end of file
diff --git a/test/Request.test.php b/test/Request.test.php
index 8c5bacc..417f950 100644
--- a/test/Request.test.php
+++ b/test/Request.test.php
@@ -102,7 +102,8 @@ class RequestTest extends \PHPUnit\Framework\TestCase {
$this->assertFalse($this->simulateRequest($allMethodsAllowed, "NONEXISTENT"), $allMethodsAllowed->getLastError());
$this->assertTrue($this->simulateRequest($allMethodsAllowed, "OPTIONS"), $allMethodsAllowed->getLastError());
$this->assertEquals(204, self::$SENT_STATUS_CODE);
- $this->assertEquals(["Allow" => "OPTIONS, GET, POST"], self::$SENT_HEADERS);
+ $this->assertArrayHasKey("Allow", self::$SENT_HEADERS);
+ $this->assertEquals(["OPTIONS", "GET", "POST"], explode(", ", self::$SENT_HEADERS["Allow"]));
}
public function testOnlyPost() {
@@ -114,7 +115,8 @@ class RequestTest extends \PHPUnit\Framework\TestCase {
$this->assertTrue($this->simulateRequest($onlyPostAllowed, "POST"), $onlyPostAllowed->getLastError());
$this->assertTrue($this->simulateRequest($onlyPostAllowed, "OPTIONS"), $onlyPostAllowed->getLastError());
$this->assertEquals(204, self::$SENT_STATUS_CODE);
- $this->assertEquals(["Allow" => "OPTIONS, POST"], self::$SENT_HEADERS);
+ $this->assertArrayHasKey("Allow", self::$SENT_HEADERS);
+ $this->assertEquals(["OPTIONS", "POST"], explode(", ", self::$SENT_HEADERS["Allow"]));
}
public function testPrivate() {