From bfa360ce2499e062395631c2475d20ea1472aa72 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Sat, 9 Mar 2019 18:53:33 +0100 Subject: [PATCH 1/4] Get subdomain --- DataStorage/File/JsonBuilder.php | 1159 ++++++++++++++++++++ DataStorage/File/JsonGrammar.php | 5 + DataStorage/File/QueryType.php | 34 + Uri/Http.php | 19 + tests/DataStorage/File/JsonBuilderTest.php | 153 +++ tests/DataStorage/File/testDb1.json | 36 + tests/DataStorage/File/testDb2.json | 47 + 7 files changed, 1453 insertions(+) create mode 100644 DataStorage/File/JsonBuilder.php create mode 100644 DataStorage/File/JsonGrammar.php create mode 100644 DataStorage/File/QueryType.php create mode 100644 tests/DataStorage/File/JsonBuilderTest.php create mode 100644 tests/DataStorage/File/testDb1.json create mode 100644 tests/DataStorage/File/testDb2.json diff --git a/DataStorage/File/JsonBuilder.php b/DataStorage/File/JsonBuilder.php new file mode 100644 index 000000000..25961948f --- /dev/null +++ b/DataStorage/File/JsonBuilder.php @@ -0,0 +1,1159 @@ +', + '<=', + '>=', + '<>', + '!=', + 'like', + 'like binary', + 'not like', + 'between', + 'ilike', + '&', + '|', + '^', + '<<', + '>>', + 'rlike', + 'regexp', + 'not regexp', + '~', + '~*', + '!~', + '!~*', + 'similar to', + 'not similar to', + 'in', + ]; + + /** + * Json grammar. + * + * @var JsonGrammar + * @since 1.0.0 + */ + private $grammar = null; + + /** + * Constructor. + * + * @param bool $readOnly Query is read only + * + * @since 1.0.0 + */ + public function __construct(bool $readOnly = false) + { + $this->isReadOnly = $readOnly; + $this->grammar = new JsonGrammar(); + } + + /** + * Select. + * + * @param array ...$columns Columns + * + * @return JsonBuilder + * + * @todo Closure is not working this way, needs to be evaluated befor assigning + * + * @since 1.0.0 + */ + public function select(...$columns) : self + { + $this->type = QueryType::SELECT; + + foreach ($columns as $key => $column) { + if (\is_string($column) || $column instanceof \Closure) { + $this->selects[] = $column; + } else { + throw new \InvalidArgumentException(); + } + } + + return $this; + } + + /** + * Select. + * + * @param array ...$columns Columns + * + * @return JsonBuilder + * + * @todo Closure is not working this way, needs to be evaluated befor assigning + * + * @since 1.0.0 + */ + public function random(...$columns) : self + { + $this->select(...$columns); + + $this->type = QueryType::RANDOM; + + return $this; + } + + /** + * Bind parameter. + * + * @param mixed $binds Binds + * + * @return JsonBuilder + * + * @since 1.0.0 + */ + public function bind($binds) : self + { + if (\is_array($binds)) { + $this->binds += $binds; + } elseif (\is_string($binds) || $binds instanceof \Closure) { + $this->binds[] = $binds; + } else { + throw new \InvalidArgumentException(); + } + + return $this; + } + + /** + * Creating new. + * + * @return JsonBuilder + * + * @since 1.0.0 + */ + public function newQuery() : self + { + return new static($this->connection, $this->isReadOnly); + } + + /** + * Is distinct. + * + * @return JsonBuilder + * + * @since 1.0.0 + */ + public function distinct() : self + { + $this->distinct = true; + + return $this; + } + + /** + * From. + * + * @param array ...$tables Tables + * + * @return JsonBuilder + * + * @since 1.0.0 + */ + public function from(...$tables) : self + { + foreach ($tables as $key => $table) { + if (\is_string($table) || $table instanceof \Closure) { + $this->from[] = $table; + } else { + throw new \InvalidArgumentException(); + } + } + + return $this; + } + + /** + * Where. + * + * @param array|\Closure|string|Where $columns Columns + * @param array|string $operator Operator + * @param mixed $values Values + * @param array|string $boolean Boolean condition + * + * @return JsonBuilder + * + * @throws \InvalidArgumentException + * + * @since 1.0.0 + */ + public function where($columns, $operator = null, $values = null, $boolean = 'and') : self + { + if (!\is_array($columns)) { + $columns = [$columns]; + $operator = [$operator]; + $values = [$values]; + $boolean = [$boolean]; + } + + $i = 0; + foreach ($columns as $key => $column) { + if (isset($operator[$i]) && !\in_array(\strtolower($operator[$i]), self::OPERATORS)) { + throw new \InvalidArgumentException('Unknown operator.'); + } + + $this->wheres[$column][] = [ + 'column' => $column, + 'operator' => $operator[$i], + 'value' => $values[$i], + 'boolean' => $boolean[$i], + ]; + + ++$i; + } + + return $this; + } + + /** + * Get column of where condition + * + * One column can have multiple where conditions. + * TODO: maybe think about a case where there is a where condition but no column but some other identifier? + * + * @param mixed $column Column + * + * @return null|array + * + * @since 1.0.0 + */ + public function getWhereByColumn($column) : ?array + { + return $this->wheres[$column] ?? null; + } + + /** + * Where and sub condition. + * + * @param array|\Closure|string|Where $where Where sub condition + * @param mixed $operator Operator + * @param mixed $values Values + * + * @return JsonBuilder + * + * @since 1.0.0 + */ + public function andWhere($where, $operator = null, $values = null) : self + { + return $this->where($where, $operator, $values, 'and'); + } + + /** + * Where or sub condition. + * + * @param array|\Closure|string|Where $where Where sub condition + * @param mixed $operator Operator + * @param mixed $values Values + * + * @return JsonBuilder + * + * @since 1.0.0 + */ + public function orWhere($where, $operator = null, $values = null) : self + { + return $this->where($where, $operator, $values, 'or'); + } + + /** + * Where in. + * + * @param array|\Closure|string|Where $column Column + * @param mixed $values Values + * @param string $boolean Boolean condition + * + * @return JsonBuilder + * + * @since 1.0.0 + */ + public function whereIn($column, $values = null, string $boolean = 'and') : self + { + $this->where($column, 'in', $values, $boolean); + + return $this; + } + + /** + * Where null. + * + * @param array|\Closure|string|Where $column Column + * @param string $boolean Boolean condition + * + * @return JsonBuilder + * + * @since 1.0.0 + */ + public function whereNull($column, string $boolean = 'and') : self + { + $this->where($column, '=', null, $boolean); + + return $this; + } + + /** + * Where not null. + * + * @param array|\Closure|string|Where $column Column + * @param string $boolean Boolean condition + * + * @return JsonBuilder + * + * @since 1.0.0 + */ + public function whereNotNull($column, string $boolean = 'and') : self + { + $this->where($column, '!=', null, $boolean); + + return $this; + } + + /** + * Group by. + * + * @param array|\Closure|string ...$columns Grouping result + * + * @return JsonBuilder + * + * @since 1.0.0 + */ + public function groupBy(...$columns) : self + { + foreach ($columns as $key => $column) { + if (\is_string($column) || $column instanceof \Closure) { + $this->groups[] = $column; + } else { + throw new \InvalidArgumentException(); + } + } + + return $this; + } + + /** + * Order by newest. + * + * @param \Closure|string $column Column + * + * @return JsonBuilder + * + * @since 1.0.0 + */ + public function newest($column) : self + { + $this->orderBy($column, 'DESC'); + + return $this; + } + + /** + * Order by oldest. + * + * @param \Closure|string $column Column + * + * @return JsonBuilder + * + * @since 1.0.0 + */ + public function oldest($column) : self + { + $this->orderBy($column, 'ASC'); + + return $this; + } + + /** + * Order by oldest. + * + * @param array|\Closure|string $columns Columns + * @param string|string[] $order Orders + * + * @return JsonBuilder + * + * @since 1.0.0 + */ + public function orderBy($columns, $order = 'DESC') : self + { + if (\is_string($columns) || $columns instanceof \Closure) { + if (!\is_string($order)) { + throw new \InvalidArgumentException(); + } + + if (!isset($this->orders[$order])) { + $this->orders[$order] = []; + } + + $this->orders[$order][] = $columns; + } elseif (\is_array($columns)) { + foreach ($columns as $key => $column) { + $this->orders[\is_string($order) ? $order : $order[$key]][] = $column; + } + } else { + throw new \InvalidArgumentException(); + } + + return $this; + } + + /** + * Offset. + * + * @param int $offset Offset + * + * @return JsonBuilder + * + * @since 1.0.0 + */ + public function offset(int $offset) : self + { + $this->offset = $offset; + + return $this; + } + + /** + * Limit. + * + * @param int $limit Limit + * + * @return JsonBuilder + * + * @since 1.0.0 + */ + public function limit(int $limit) : self + { + $this->limit = $limit; + + return $this; + } + + /** + * Union. + * + * @param mixed $query Query + * + * @return JsonBuilder + * + * @since 1.0.0 + */ + public function union($query) : self + { + if (!\is_array($query)) { + $this->unions[] = $query; + } else { + $this->unions += $query; + } + + return $this; + } + + /** + * Lock query. + * + * @return void + * + * @since 1.0.0 + */ + public function lock() : void + { + } + + /** + * Lock for update query. + * + * @return void + * + * @since 1.0.0 + */ + public function lockUpdate() : void + { + } + + /** + * Find query. + * + * @return void + * + * @since 1.0.0 + */ + public function find() : void + { + } + + /** + * Count results. + * + * @param string $table Table to count the result set + * + * @return JsonBuilder + * + * @since 1.0.0 + */ + public function count(string $table = '*') : self + { + // todo: don't do this as string, create new object new \count(); this can get handled by the grammar parser WAY better + return $this->select('COUNT(' . $table . ')'); + } + + /** + * Select minimum. + * + * @return void + * + * @since 1.0.0 + */ + public function min() : void + { + } + + /** + * Select maximum. + * + * @return void + * + * @since 1.0.0 + */ + public function max() : void + { + } + + /** + * Select sum. + * + * @return void + * + * @since 1.0.0 + */ + public function sum() : void + { + } + + /** + * Select average. + * + * @return void + * + * @since 1.0.0 + */ + public function avg() : void + { + } + + /** + * Insert into columns. + * + * @param array ...$columns Columns + * + * @return JsonBuilder + * + * @throws \Exception + * + * @since 1.0.0 + */ + public function insert(...$columns) : self + { + if ($this->isReadOnly) { + throw new \Exception(); + } + + $this->type = QueryType::INSERT; + + foreach ($columns as $key => $column) { + $this->inserts[] = $column; + } + + return $this; + } + + /** + * Table to insert into. + * + * @param \Closure|string $table Table + * + * @return JsonBuilder + * + * @since 1.0.0 + */ + public function into($table) : self + { + $this->into = $table; + + return $this; + } + + /** + * Values to insert. + * + * @param array ...$values Values + * + * @return JsonBuilder + * + * @since 1.0.0 + */ + public function values(...$values) : self + { + $this->values[] = $values; + + return $this; + } + + /** + * Get insert values + * + * @return array + * + * @since 1.0.0 + */ + public function getValues() : array + { + return $this->values; + } + + /** + * Values to insert. + * + * @param mixed $value Values + * + * @return JsonBuilder + * + * @since 1.0.0 + */ + public function value($value) : self + { + \end($this->values); + $key = \key($this->values); + + if (\is_array($value)) { + $this->values[$key] = $value; + } else { + $this->values[$key][] = $value; + } + + \reset($this->values); + + return $this; + } + + /** + * Values to insert. + * + * @param array ...$sets Values + * + * @return JsonBuilder + * + * @since 1.0.0 + */ + public function sets(...$sets) : self + { + $this->sets[$sets[0]] = $sets[1] ?? null; + + return $this; + } + + /** + * Values to insert. + * + * @param mixed $set Values + * + * @return JsonBuilder + * + * @since 1.0.0 + */ + public function set($set) : self + { + $this->sets[\key($set)] = \current($set); + + return $this; + } + + /** + * Update columns. + * + * @param array ...$tables Column names to update + * + * @return JsonBuilder + * + * @throws \Exception + * + * @since 1.0.0 + */ + public function update(...$tables) : self + { + if ($this->isReadOnly) { + throw new \Exception(); + } + + $this->type = QueryType::UPDATE; + + foreach ($tables as $key => $table) { + if (\is_string($table) || $table instanceof \Closure) { + $this->updates[] = $table; + } else { + throw new \InvalidArgumentException(); + } + } + + return $this; + } + + /** + * Delete query + * + * @return JsonBuilder + * + * @since 1.0.0 + */ + public function delete() : self + { + if ($this->isReadOnly) { + throw new \Exception(); + } + + $this->type = QueryType::DELETE; + + return $this; + } + + /** + * Increment value. + * + * @return void + * + * @since 1.0.0 + */ + public function increment() : void + { + } + + /** + * Decrement value. + * + * @return void + * + * @since 1.0.0 + */ + public function decrement() : void + { + } + + /** + * Join. + * + * @return JsonBuilder + * + * @since 1.0.0 + */ + public function join($table, string $type = JoinType::JOIN) : self + { + if (\is_string($table) || $table instanceof \Closure) { + $this->joins[] = ['type' => $type, 'table' => $table]; + } else { + throw new \InvalidArgumentException(); + } + + return $this; + } + + /** + * Join. + * + * @return JsonBuilder + * + * @since 1.0.0 + */ + public function leftJoin($column) : self + { + return $this->join($column, JoinType::LEFT_JOIN); + } + + /** + * Join. + * + * @return JsonBuilder + * + * @since 1.0.0 + */ + public function leftOuterJoin($column) : self + { + return $this->join($column, JoinType::LEFT_OUTER_JOIN); + } + + /** + * Join. + * + * @return JsonBuilder + * + * @since 1.0.0 + */ + public function leftInnerJoin($column) : self + { + return $this->join($column, JoinType::LEFT_INNER_JOIN); + } + + /** + * Join. + * + * @return JsonBuilder + * + * @since 1.0.0 + */ + public function rightJoin($column) : self + { + return $this->join($column, JoinType::RIGHT_JOIN); + } + + /** + * Join. + * + * @return JsonBuilder + * + * @since 1.0.0 + */ + public function rightOuterJoin($column) : self + { + return $this->join($column, JoinType::RIGHT_OUTER_JOIN); + } + + /** + * Join. + * + * @return JsonBuilder + * + * @since 1.0.0 + */ + public function rightInnerJoin($column) : self + { + return $this->join($column, JoinType::RIGHT_INNER_JOIN); + } + + /** + * Join. + * + * @return JsonBuilder + * + * @since 1.0.0 + */ + public function outerJoin($column) : self + { + return $this->join($column, JoinType::OUTER_JOIN); + } + + /** + * Join. + * + * @return JsonBuilder + * + * @since 1.0.0 + */ + public function innerJoin($column) : self + { + return $this->join($column, JoinType::INNER_JOIN); + } + + /** + * Join. + * + * @return JsonBuilder + * + * @since 1.0.0 + */ + public function crossJoin($column) : self + { + return $this->join($column, JoinType::CROSS_JOIN); + } + + /** + * Join. + * + * @return JsonBuilder + * + * @since 1.0.0 + */ + public function fullJoin($column) : self + { + return $this->join($column, JoinType::FULL_JOIN); + } + + /** + * Join. + * + * @return JsonBuilder + * + * @since 1.0.0 + */ + public function fullOuterJoin($column) : self + { + return $this->join($column, JoinType::FULL_OUTER_JOIN); + } + + /** + * On. + * + * @return JsonBuilder + * + * @since 1.0.0 + */ + public function on($columns, $operator = null, $values = null, $boolean = 'and') : self + { + if ($operator !== null && !\is_array($operator) && !\in_array(\strtolower($operator), self::OPERATORS)) { + throw new \InvalidArgumentException('Unknown operator.'); + } + + if (!\is_array($columns)) { + $columns = [$columns]; + $operator = [$operator]; + $values = [$values]; + $boolean = [$boolean]; + } + + $joinCount = \count($this->joins) - 1; + $i = 0; + + foreach ($columns as $key => $column) { + if (isset($operator[$i]) && !\in_array(\strtolower($operator[$i]), self::OPERATORS)) { + throw new \InvalidArgumentException('Unknown operator.'); + } + + $this->ons[$joinCount][] = [ + 'column' => $column, + 'operator' => $operator[$i], + 'value' => $values[$i], + 'boolean' => $boolean[$i], + ]; + + ++$i; + } + + return $this; + } + + /** + * On. + * + * @return JsonBuilder + * + * @since 1.0.0 + */ + public function orOn($columns, $operator = null, $values = null) : self + { + return $this->on($columns, $operator, $values, 'or'); + } + + /** + * On. + * + * @return JsonBuilder + * + * @since 1.0.0 + */ + public function andOn($columns, $operator = null, $values = null) : self + { + return $this->on($columns, $operator, $values, 'and'); + } + + /** + * Execute query. + * + * @return mixed + * + * @since 1.0.0 + */ + public function execute() + { + return $this->grammar->compileQuery($this); + } +} \ No newline at end of file diff --git a/DataStorage/File/JsonGrammar.php b/DataStorage/File/JsonGrammar.php new file mode 100644 index 000000000..f34697c32 --- /dev/null +++ b/DataStorage/File/JsonGrammar.php @@ -0,0 +1,5 @@ +host; } + /** + * Return the subdomain of a host + * + * @return string + * + * @since 1.0.0 + */ + public function getSubdomain() : string + { + $host = explode('.', $this->host); + $length = \count($host) - 2; + + if ($length < 1) { + return ''; + } + + return \array_slice($host, 0, $length); + } + /** * {@inheritdoc} */ diff --git a/tests/DataStorage/File/JsonBuilderTest.php b/tests/DataStorage/File/JsonBuilderTest.php new file mode 100644 index 000000000..ef386ad00 --- /dev/null +++ b/tests/DataStorage/File/JsonBuilderTest.php @@ -0,0 +1,153 @@ +table1 = \json_decode(\file_get_contents(__DIR__ . '/testDb1.json'), true); + $this->table2 = \json_decode(\file_get_contents(__DIR__ . '/testDb2.json'), true); + } + + public function testJsonSelect() : void + { + $this->markTestSkipped(); + + $query = new JsonBuilder(); + self::assertEquals('acc1', $query->select('/0/account/*/name')->from($this->table1, $this->table2)->where('/0/account/*/id', '=', 1)->execute()['name']); + self::assertEquals('acc6', $query->select('/1/account/*/name')->from($this->table1, $this->table2)->where('/1/account/*/id', '=', 2)->execute()['name']); + + //$query = new JsonBuilder(); + //self::assertEquals($sql, $query->select('a.test')->distinct()->from('a')->where('a.test', '=', 1)->execute()); + + $query = new JsonBuilder(); + $datetime = new \DateTime('1999-31-12'); + self::assertEquals('dog2', $query->select('/0/animals/dog')->from($this->table2)->where('/0/animals/dog/created', '>', $datetime)->execute()['name']); + + $table = $this->table2; + $query = new JsonBuilder(); + self::assertEquals(['dog1', 'dog2', 'cat2'], $query->select('/0/animals/dog/*/name', function () { + return '/0/animals/cat/*/name'; + })->from(function () use ($table) { + return $table; + })->where(['/0/animals/cat/*/owner', '/0/animals/dog/*/owner'], ['=', '='], [1, 4], ['and', 'or'])->execute()); + } + + public function testJsonOrder() : void + { + $this->markTestSkipped(); + + $query = new JsonBuilder(); + self::assertEquals(['acc2', 'acc1', 'acc4'], + $query->select('/0/account/*/name') + ->from($this->table1) + ->where('/0/account/*/id', '>', 0) + ->orderBy('/0/account/status', 'ASC') + ->execute() + ); + } + + public function testJsonOffsetLimit() : void + { + $this->markTestSkipped(); + + $query = new JsonBuilder(); + self::assertEquals(['acc2', 'acc1'], + $query->select('/0/account/*/name') + ->from($this->table1) + ->where('/0/account/*/id', '>', 0) + ->orderBy('/0/account/status', 'ASC') + ->limit(2) + ->execute() + ); + } + + /** + * @expectedException \Exception + */ + public function testReadOnlyInsert() : void + { + $query = new JsonBuilder(true); + $query->insert('test'); + } + + /** + * @expectedException \Exception + */ + public function testReadOnlyUpdate() : void + { + $query = new JsonBuilder(true); + $query->update(); + } + + /** + * @expectedException \Exception + */ + public function testReadOnlyDelete() : void + { + $query = new JsonBuilder(true); + $query->delete(); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testInvalidWhereOperator() : void + { + $query = new JsonBuilder(true); + $query->where('a', 'invalid', 'b'); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testInvalidJoinTable() : void + { + $query = new JsonBuilder(true); + $query->join(null); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testInvalidJoinOperator() : void + { + $query = new JsonBuilder(true); + $query->join('b')->on('a', 'invalid', 'b'); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testInvalidOrOrderType() : void + { + $query = new JsonBuilder(true); + $query->orderBy('a', 1); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testInvalidOrColumnType() : void + { + $query = new JsonBuilder(true); + $query->orderBy(null, 'DESC'); + } +} \ No newline at end of file diff --git a/tests/DataStorage/File/testDb1.json b/tests/DataStorage/File/testDb1.json new file mode 100644 index 000000000..aaa8d86f4 --- /dev/null +++ b/tests/DataStorage/File/testDb1.json @@ -0,0 +1,36 @@ +{ + "account": [ + { + "id": 1, + "name": "acc1", + "status": 2 + }, + { + "id": 2, + "name": "acc2", + "status": 1 + }, + { + "id": 4, + "name": "acc4", + "status": 2 + } + ], + "news": [ + { + "id": 1, + "title": "news1", + "by": 2 + }, + { + "id": 2, + "title": "news2", + "by": 4 + }, + { + "id": 4, + "title": "news4", + "by": 2 + } + ] +} \ No newline at end of file diff --git a/tests/DataStorage/File/testDb2.json b/tests/DataStorage/File/testDb2.json new file mode 100644 index 000000000..27702750e --- /dev/null +++ b/tests/DataStorage/File/testDb2.json @@ -0,0 +1,47 @@ +{ + "account": [ + { + "id": 1, + "name": "acc5", + "status": 2 + }, + { + "id": 2, + "name": "acc6", + "status": 1 + }, + { + "id": 4, + "name": "acc7", + "status": 2 + } + ], + "animals": { + "dog": [ + { + "id": 1, + "name": "dog1", + "owner": 4, + "created": "1999-01-01" + }, + { + "id": 2, + "name": "dog2", + "owner": 1, + "created": "2000-01-01" + } + ], + "cat": { + "1": { + "id": 1, + "name": "cat1", + "owner": 2 + }, + "2": { + "id": 2, + "name": "cat2", + "owner": 1 + } + } + } +} \ No newline at end of file From 89c14a69b83843cc69a3eed67df6f242b6da7e0a Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Sat, 9 Mar 2019 19:33:25 +0100 Subject: [PATCH 2/4] Add better uri creation from current --- Message/Http/Request.php | 2 +- Uri/Http.php | 14 +++++++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/Message/Http/Request.php b/Message/Http/Request.php index 99d4fd75c..e6bca7e94 100644 --- a/Message/Http/Request.php +++ b/Message/Http/Request.php @@ -108,7 +108,7 @@ final class Request extends RequestAbstract */ private function initCurrentRequest() : void { - $this->uri = new Http(Http::getCurrent()); + $this->uri = Http::fromCurrent(); $this->data = $_GET ?? []; $this->files = $_FILES ?? []; $this->header->getL11n()->setLanguage($this->loadRequestLanguage()); diff --git a/Uri/Http.php b/Uri/Http.php index 61619e171..eaaab587c 100644 --- a/Uri/Http.php +++ b/Uri/Http.php @@ -193,6 +193,18 @@ final class Http implements UriInterface . '://' . ($_SERVER['HTTP_HOST'] ?? ''). ($_SERVER['REQUEST_URI'] ?? ''); } + /** + * Create uri from current url + * + * @return Http Returns the current uri + * + * @since 1.0.0 + */ + public static function fromCurrent() : self + { + return new self(self::getCurrent()); + } + /** * {@inheritdoc} */ @@ -250,7 +262,7 @@ final class Http implements UriInterface return ''; } - return \array_slice($host, 0, $length); + return \implode('.', \array_slice($host, 0, $length)); } /** From b9a82ea08dfad231f3cbe2df56e294f1dff19f04 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Sat, 9 Mar 2019 21:42:21 +0100 Subject: [PATCH 3/4] Improve localization --- ApplicationAbstract.php | 9 +++++++++ DataStorage/Cookie/CookieJar.php | 14 ++++++++++++++ Localization/Localization.php | 4 ++++ Message/Http/Request.php | 31 +++++++++++++++++++++++++------ 4 files changed, 52 insertions(+), 6 deletions(-) diff --git a/ApplicationAbstract.php b/ApplicationAbstract.php index 41413c512..58620425b 100644 --- a/ApplicationAbstract.php +++ b/ApplicationAbstract.php @@ -27,6 +27,7 @@ namespace phpOMS; * @property \phpOMS\Localization\L11nManager $l11nManager * @property \phpOMS\Router\Router $router * @property \phpOMS\DataStorage\Session\SessionInterface $sessionManager + * @property \phpOMS\DataStorage\Cookie\CookieJar $cookieJar * @property \phpOMS\Module\ModuleManager $moduleManager * @property \phpOMS\Dispatcher\Dispatcher $dispatcher * @property \phpOMS\DataStorage\Cache\CachePool $cachePool @@ -123,6 +124,14 @@ class ApplicationAbstract */ protected $sessionManager = null; + /** + * Cookie instance. + * + * @var \phpOMS\DataStorage\Cookie\CookieJar + * @since 1.0.0 + */ + protected $cookieJar = null; + /** * Server localization. * diff --git a/DataStorage/Cookie/CookieJar.php b/DataStorage/Cookie/CookieJar.php index a6d8484cf..1404f4319 100644 --- a/DataStorage/Cookie/CookieJar.php +++ b/DataStorage/Cookie/CookieJar.php @@ -111,6 +111,20 @@ final class CookieJar return false; } + /** + * Get cookie value + * + * @param string $id Cookie id + * + * @return mixed + * + * @since 1.0.0 + */ + public function get(string $id) + { + return $this->cookies[$id] ?? null; + } + /** * Delete already set cookie * diff --git a/Localization/Localization.php b/Localization/Localization.php index 9a6b9373a..d24f3d04a 100644 --- a/Localization/Localization.php +++ b/Localization/Localization.php @@ -162,6 +162,10 @@ class Localization throw new InvalidEnumValue($langCode); } + if ($countryCode !== '*' && !\file_exists(__DIR__ . '/../Localization/Defaults/Definitions/' . $langCode . '_' . $countryCode . '.json')) { + $countryCode = '*'; + } + $files = \glob(__DIR__ . '/../Localization/Defaults/Definitions/' . $langCode . '_' . $countryCode); foreach ($files as $file) { diff --git a/Message/Http/Request.php b/Message/Http/Request.php index e6bca7e94..2e498d86c 100644 --- a/Message/Http/Request.php +++ b/Message/Http/Request.php @@ -111,7 +111,7 @@ final class Request extends RequestAbstract $this->uri = Http::fromCurrent(); $this->data = $_GET ?? []; $this->files = $_FILES ?? []; - $this->header->getL11n()->setLanguage($this->loadRequestLanguage()); + $this->header->getL11n()->setLanguage($this->getRequestLanguage()); $this->initNonGetData(); } @@ -155,23 +155,42 @@ final class Request extends RequestAbstract } /** - * Load request language + * Get request language * * @return string * * @since 1.0.0 */ - private function loadRequestLanguage() : string + public function getRequestLanguage() : string { if (!isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { - return 'EN'; + return 'en'; } $components = \explode(';', $_SERVER['HTTP_ACCEPT_LANGUAGE']); $locals = \stripos($components[0], ',') !== false ? $locals = \explode(',', $components[0]) : $components; $firstLocalComponents = \explode('-', $locals[0]); - return $firstLocalComponents[0]; + return \strtolower($firstLocalComponents[0]); + } + + /** + * Get request locale + * + * @return string + * + * @since 1.0.0 + */ + public function getLocale() : string + { + if (!isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { + return 'en_US'; + } + + $components = \explode(';', $_SERVER['HTTP_ACCEPT_LANGUAGE']); + $locals = \stripos($components[0], ',') !== false ? $locals = \explode(',', $components[0]) : $components; + + return \str_replace('-', '_', $locals[0]); } /** @@ -253,7 +272,7 @@ final class Request extends RequestAbstract $paths[] = $pathArray[$i]; } - $this->hash[] = sha1(\implode('', $paths)); + $this->hash[] = \sha1(\implode('', $paths)); } } From 632322fa88a4f83bc158fc68e01da9450d2c28b4 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Sat, 9 Mar 2019 23:18:21 +0100 Subject: [PATCH 4/4] Fix bugs --- DataStorage/File/JsonBuilder.php | 1 + DataStorage/File/JsonGrammar.php | 32 +++++++++++++++++++++- Math/Matrix/SingularValueDecomposition.php | 6 ++-- Message/RequestAbstract.php | 2 +- 4 files changed, 35 insertions(+), 6 deletions(-) diff --git a/DataStorage/File/JsonBuilder.php b/DataStorage/File/JsonBuilder.php index 25961948f..2123f2020 100644 --- a/DataStorage/File/JsonBuilder.php +++ b/DataStorage/File/JsonBuilder.php @@ -15,6 +15,7 @@ declare(strict_types=1); namespace phpOMS\DataStorage\File; use phpOMS\DataStorage\File\QueryType; +use phpOMS\DataStorage\Database\Query\JoinType; /** * Json query Jsonbuilder. diff --git a/DataStorage/File/JsonGrammar.php b/DataStorage/File/JsonGrammar.php index f34697c32..00ce90215 100644 --- a/DataStorage/File/JsonGrammar.php +++ b/DataStorage/File/JsonGrammar.php @@ -2,4 +2,34 @@ // where create sub array // order // select data from where -// limit \ No newline at end of file +// limit + +/** + * Orange Management + * + * PHP Version 7.2 + * + * @package phpOMS\DataStorage\File + * @copyright Dennis Eichhorn + * @license OMS License 1.0 + * @version 1.0.0 + * @link http://website.orange-management.de + */ +declare(strict_types=1); + +namespace phpOMS\DataStorage\File; + +use phpOMS\DataStorage\File\QueryType; + +/** + * Json query JsonGrammar. + * + * @package phpOMS\DataStorage\File + * @license OMS License 1.0 + * @link http://website.orange-management.de + * @since 1.0.0 + */ +final class JsonGrammar +{ + +} diff --git a/Math/Matrix/SingularValueDecomposition.php b/Math/Matrix/SingularValueDecomposition.php index 8474efce9..14fcd3937 100644 --- a/Math/Matrix/SingularValueDecomposition.php +++ b/Math/Matrix/SingularValueDecomposition.php @@ -254,13 +254,11 @@ final class SingularValueDecomposition $pp = $p - 1; $iter = 0; - while (true) { + while ($p > 0) { for ($k = $p - 2; $k >= -1; --$k) { if ($k === -1) { break; - } - - if (\abs($e[$k]) <= $eps * (\abs($this->S[$k]) + \abs($this->S[$k + 1]))) { + } elseif (\abs($e[$k]) <= $eps * (\abs($this->S[$k]) + \abs($this->S[$k + 1]))) { $e[$k] = 0.0; break; } diff --git a/Message/RequestAbstract.php b/Message/RequestAbstract.php index 2d5582e56..f01b32079 100644 --- a/Message/RequestAbstract.php +++ b/Message/RequestAbstract.php @@ -196,7 +196,7 @@ abstract class RequestAbstract implements MessageInterface return []; } - $json = \json_decode($this->data[$key]); + $json = \json_decode($this->data[$key], true); return $json === false ? [] : $json; }