diff --git a/src/Tqdev/PhpCrudUi/Client/CrudApi.php b/src/Tqdev/PhpCrudUi/Client/CrudApi.php index 7d168be..424a6ef 100644 --- a/src/Tqdev/PhpCrudUi/Client/CrudApi.php +++ b/src/Tqdev/PhpCrudUi/Client/CrudApi.php @@ -1,4 +1,5 @@ getPrimaryKey($table, 'read'); return $record[$primaryKey]; } - } diff --git a/src/Tqdev/PhpCrudUi/Config.php b/src/Tqdev/PhpCrudUi/Config.php index 376c466..8e8da16 100644 --- a/src/Tqdev/PhpCrudUi/Config.php +++ b/src/Tqdev/PhpCrudUi/Config.php @@ -1,4 +1,5 @@ service->_list($table, $action, $field, $id, $name, $params); return $this->responder->success($result); } - } diff --git a/src/Tqdev/PhpCrudUi/Controller/TemplateResponder.php b/src/Tqdev/PhpCrudUi/Controller/TemplateResponder.php index 8885a39..47e962f 100644 --- a/src/Tqdev/PhpCrudUi/Controller/TemplateResponder.php +++ b/src/Tqdev/PhpCrudUi/Controller/TemplateResponder.php @@ -1,4 +1,5 @@ setTemplatePath($this->templatePath); return ResponseFactory::fromHtml(ResponseFactory::OK, $result); } - } diff --git a/src/Tqdev/PhpCrudUi/Document/TemplateDocument.php b/src/Tqdev/PhpCrudUi/Document/TemplateDocument.php index 78b5364..731f0b7 100644 --- a/src/Tqdev/PhpCrudUi/Document/TemplateDocument.php +++ b/src/Tqdev/PhpCrudUi/Document/TemplateDocument.php @@ -1,4 +1,5 @@ masterTemplate = $masterTemplate; $this->contentTemplate = $contentTemplate; $this->variables = $variables; - $this->template = new Template('html',$this->getFunctions()); + $this->template = new Template('html', $this->getFunctions()); $this->templatePath = ''; } private function getFunctions(): array { return array( - 'lt' => function ($a, $b) {return $a < $b;}, - 'gt' => function ($a, $b) {return $a > $b;}, - 'le' => function ($a, $b) {return $a <= $b;}, - 'ge' => function ($a, $b) {return $a >= $b;}, - 'eq' => function ($a, $b) {return $a == $b;}, - 'add' => function ($a, $b) {return $a + $b;}, - 'sub' => function ($a, $b) {return $a - $b;}, + 'lt' => function ($a, $b) { + return $a < $b; + }, + 'gt' => function ($a, $b) { + return $a > $b; + }, + 'le' => function ($a, $b) { + return $a <= $b; + }, + 'ge' => function ($a, $b) { + return $a >= $b; + }, + 'eq' => function ($a, $b) { + return $a == $b; + }, + 'add' => function ($a, $b) { + return $a + $b; + }, + 'sub' => function ($a, $b) { + return $a - $b; + }, ); } @@ -40,7 +55,7 @@ public function addVariables(array $variables)/*: void*/ public function setTemplatePath(string $path)/*: void*/ { - $this->templatePath = rtrim($path,'/'); + $this->templatePath = rtrim($path, '/'); } private function getHtmlFileContents(string $template): string diff --git a/src/Tqdev/PhpCrudUi/Record/CrudService.php b/src/Tqdev/PhpCrudUi/Record/CrudService.php index 9ccb93a..01f33d6 100644 --- a/src/Tqdev/PhpCrudUi/Record/CrudService.php +++ b/src/Tqdev/PhpCrudUi/Record/CrudService.php @@ -1,4 +1,5 @@ $table, 'action' => $action, diff --git a/src/Tqdev/PhpCrudUi/Template/Template.php b/src/Tqdev/PhpCrudUi/Template/Template.php index ba688bd..275dd48 100644 --- a/src/Tqdev/PhpCrudUi/Template/Template.php +++ b/src/Tqdev/PhpCrudUi/Template/Template.php @@ -1,4 +1,5 @@ explode('|', $node->expression); $path = array_shift($parts); @@ -195,7 +196,7 @@ private function renderIfNode(/*object*/ $node, array $data): string return $result; } - private function renderElseIfNode(/*object*/ $node, array $ifNodes, array $data): string + private function renderElseIfNode(/*object*/$node, array $ifNodes, array $data): string { if (count($ifNodes) < 1 || $ifNodes[0]->type != 'if') { return $this->escape("{{elseif!!could not find matching `if`}}"); @@ -222,7 +223,7 @@ private function renderElseIfNode(/*object*/ $node, array $ifNodes, array $data) return $result; } - private function renderElseNode(/*object*/ $node, array $ifNodes, array $data): string + private function renderElseNode(/*object*/$node, array $ifNodes, array $data): string { if (count($ifNodes) < 1 || $ifNodes[0]->type != 'if') { return $this->escape("{{else!!could not find matching `if`}}"); @@ -238,7 +239,7 @@ private function renderElseNode(/*object*/ $node, array $ifNodes, array $data): return $result; } - private function renderForNode(/*object*/ $node, array $data): string + private function renderForNode(/*object*/$node, array $data): string { $parts = $this->explode('|', $node->expression); $pathParts = $this->explode(':', array_shift($parts), 3); @@ -267,7 +268,7 @@ private function renderForNode(/*object*/ $node, array $data): string return $result; } - private function renderVarNode(/*object*/ $node, array $data): string + private function renderVarNode(/*object*/$node, array $data): string { $parts = $this->explode('|', $node->expression); $path = array_shift($parts); @@ -295,7 +296,7 @@ private function resolvePath(string $path, array $data)/*: object*/ return $current; } - private function applyFunctions(/*object*/ $value, array $parts, array $data)/*: object*/ + private function applyFunctions(/*object*/$value, array $parts, array $data)/*: object*/ { foreach ($parts as $part) { $function = $this->explode('(', rtrim($part, ')'), 2); @@ -320,5 +321,4 @@ private function applyFunctions(/*object*/ $value, array $parts, array $data)/*: } return $value; } - } diff --git a/src/Tqdev/PhpCrudUi/Template/TemplateString.php b/src/Tqdev/PhpCrudUi/Template/TemplateString.php index 31bb593..d029ee7 100644 --- a/src/Tqdev/PhpCrudUi/Template/TemplateString.php +++ b/src/Tqdev/PhpCrudUi/Template/TemplateString.php @@ -1,4 +1,5 @@ db = $db; $this->cache = $cache; $this->ttl = $ttl; - $this->database = null; + $this->database = $this->loadDatabase(true); $this->tables = []; } - private function database(): ReflectedDatabase - { - if (!$this->database) { - $this->database = $this->loadDatabase(true); - } - return $this->database; - } - private function loadDatabase(bool $useCache): ReflectedDatabase { - $key = sprintf('%s-ReflectedDatabase', $this->db->getCacheKey()); - $data = $useCache ? $this->cache->get($key) : ''; + $data = $useCache ? $this->cache->get('ReflectedDatabase') : ''; if ($data != '') { $database = ReflectedDatabase::fromJson(json_decode(gzuncompress($data))); } else { $database = ReflectedDatabase::fromReflection($this->db->reflection()); $data = gzcompress(json_encode($database, JSON_UNESCAPED_UNICODE)); - $this->cache->set($key, $data, $this->ttl); + $this->cache->set('ReflectedDatabase', $data, $this->ttl); } return $database; } private function loadTable(string $tableName, bool $useCache): ReflectedTable { - $key = sprintf('%s-ReflectedTable(%s)', $this->db->getCacheKey(), $tableName); - $data = $useCache ? $this->cache->get($key) : ''; + $data = $useCache ? $this->cache->get("ReflectedTable($tableName)") : ''; if ($data != '') { $table = ReflectedTable::fromJson(json_decode(gzuncompress($data))); } else { - $tableType = $this->database()->getType($tableName); + $tableType = $this->database->getType($tableName); $table = ReflectedTable::fromReflection($this->db->reflection(), $tableName, $tableType); $data = gzcompress(json_encode($table, JSON_UNESCAPED_UNICODE)); - $this->cache->set($key, $data, $this->ttl); + $this->cache->set("ReflectedTable($tableName)", $data, $this->ttl); } return $table; } @@ -4155,12 +4145,12 @@ public function refreshTable(string $tableName) public function hasTable(string $tableName): bool { - return $this->database()->hasTable($tableName); + return $this->database->hasTable($tableName); } public function getType(string $tableName): string { - return $this->database()->getType($tableName); + return $this->database->getType($tableName); } public function getTable(string $tableName): ReflectedTable @@ -4173,19 +4163,20 @@ public function getTable(string $tableName): ReflectedTable public function getTableNames(): array { - return $this->database()->getTableNames(); + return $this->database->getTableNames(); } public function getDatabaseName(): string { - return $this->database()->getName(); + return $this->database->getName(); } public function removeTable(string $tableName): bool { unset($this->tables[$tableName]); - return $this->database()->removeTable($tableName); + return $this->database->removeTable($tableName); } + } } @@ -5159,8 +5150,6 @@ public function convertColumnValues(ReflectedTable $table, array &$columnValues) } } } - } -} // file: src/Tqdev/PhpCrudApi/Database/GenericDB.php namespace Tqdev\PhpCrudApi\Database { @@ -5173,11 +5162,7 @@ public function convertColumnValues(ReflectedTable $table, array &$columnValues) class GenericDB { private $driver; - private $address; - private $port; private $database; - private $username; - private $password; private $pdo; private $reflection; private $definition; @@ -5185,33 +5170,28 @@ class GenericDB private $columns; private $converter; - private function getDsn(): string + private function getDsn(string $address, int $port, string $database): string { switch ($this->driver) { - case 'mysql': - return "$this->driver:host=$this->address;port=$this->port;dbname=$this->database;charset=utf8mb4"; - case 'pgsql': - return "$this->driver:host=$this->address port=$this->port dbname=$this->database options='--client_encoding=UTF8'"; - case 'sqlsrv': - return "$this->driver:Server=$this->address,$this->port;Database=$this->database"; + case 'mysql':return "$this->driver:host=$address;port=$port;dbname=$database;charset=utf8mb4"; + case 'pgsql':return "$this->driver:host=$address port=$port dbname=$database options='--client_encoding=UTF8'"; + case 'sqlsrv':return "$this->driver:Server=$address,$port;Database=$database"; } } private function getCommands(): array { switch ($this->driver) { - case 'mysql': - return [ + case 'mysql':return [ 'SET SESSION sql_warnings=1;', 'SET NAMES utf8mb4;', 'SET SESSION sql_mode = "ANSI,TRADITIONAL";', ]; - case 'pgsql': - return [ + case 'pgsql':return [ "SET NAMES 'UTF8';", ]; - case 'sqlsrv': - return []; + case 'sqlsrv':return [ + ]; } } @@ -5222,80 +5202,41 @@ private function getOptions(): array \PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC, ); switch ($this->driver) { - case 'mysql': - return $options + [ + case 'mysql':return $options + [ \PDO::ATTR_EMULATE_PREPARES => false, \PDO::MYSQL_ATTR_FOUND_ROWS => true, \PDO::ATTR_PERSISTENT => true, ]; - case 'pgsql': - return $options + [ + case 'pgsql':return $options + [ \PDO::ATTR_EMULATE_PREPARES => false, \PDO::ATTR_PERSISTENT => true, ]; - case 'sqlsrv': - return $options + [ + case 'sqlsrv':return $options + [ \PDO::SQLSRV_ATTR_DIRECT_QUERY => false, \PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE => true, ]; } } - private function initPdo(): bool - { - if ($this->pdo) { - $result = $this->pdo->reconstruct($this->getDsn(), $this->username, $this->password, $this->getOptions()); - } else { - $this->pdo = new LazyPdo($this->getDsn(), $this->username, $this->password, $this->getOptions()); - $result = true; - } - $commands = $this->getCommands(); - foreach ($commands as $command) { - $this->pdo->addInitCommand($command); - } - $this->reflection = new GenericReflection($this->pdo, $this->driver, $this->database); - $this->definition = new GenericDefinition($this->pdo, $this->driver, $this->database); - $this->conditions = new ConditionsBuilder($this->driver); - $this->columns = new ColumnsBuilder($this->driver); - $this->converter = new DataConverter($this->driver); - return $result; - } - public function __construct(string $driver, string $address, int $port, string $database, string $username, string $password) { $this->driver = $driver; - $this->address = $address; - $this->port = $port; $this->database = $database; - $this->username = $username; - $this->password = $password; - $this->initPdo(); - } - - public function reconstruct(string $driver, string $address, int $port, string $database, string $username, string $password): bool - { - if ($driver) { - $this->driver = $driver; - } - if ($address) { - $this->address = $address; - } - if ($port) { - $this->port = $port; - } - if ($database) { - $this->database = $database; - } - if ($username) { - $this->username = $username; - } - if ($password) { - $this->password = $password; + $dsn = $this->getDsn($address, $port, $database); + $options = $this->getOptions(); + $this->pdo = new \PDO($dsn, $username, $password, $options); + $commands = $this->getCommands(); + foreach ($commands as $command) { + $this->pdo->query($command); } - return $this->initPdo(); + $this->reflection = new GenericReflection($this->pdo, $driver, $database); + $this->definition = new GenericDefinition($this->pdo, $driver, $database); + $this->conditions = new ConditionsBuilder($driver); + $this->columns = new ColumnsBuilder($driver); + $this->converter = new DataConverter($driver); } - public function pdo(): LazyPdo + public function pdo(): \PDO { return $this->pdo; } @@ -5469,17 +5410,6 @@ private function query(string $sql, array $parameters): \PDOStatement $stmt->execute($parameters); return $stmt; } - - public function getCacheKey(): string - { - return md5(json_encode([ - $this->driver, - $this->address, - $this->port, - $this->database, - $this->username - ])); - } } } @@ -5488,7 +5418,6 @@ public function getCacheKey(): string use Tqdev\PhpCrudApi\Column\Reflection\ReflectedColumn; use Tqdev\PhpCrudApi\Column\Reflection\ReflectedTable; - use Tqdev\PhpCrudApi\Database\LazyPdo; class GenericDefinition { @@ -5498,7 +5427,7 @@ class GenericDefinition private $typeConverter; private $reflection; - public function __construct(LazyPdo $pdo, string $driver, string $database) + public function __construct(\PDO $pdo, string $driver, string $database) { $this->pdo = $pdo; $this->driver = $driver; @@ -5911,8 +5840,6 @@ private function query(string $sql): bool // file: src/Tqdev/PhpCrudApi/Database/GenericReflection.php namespace Tqdev\PhpCrudApi\Database { - use Tqdev\PhpCrudApi\Database\LazyPdo; - class GenericReflection { private $pdo; @@ -5920,7 +5847,7 @@ class GenericReflection private $database; private $typeConverter; - public function __construct(LazyPdo $pdo, string $driver, string $database) + public function __construct(\PDO $pdo, string $driver, string $database) { $this->pdo = $pdo; $this->driver = $driver; @@ -6050,131 +5977,6 @@ private function query(string $sql, array $parameters): array } } -// file: src/Tqdev/PhpCrudApi/Database/LazyPdo.php -namespace Tqdev\PhpCrudApi\Database { - - class LazyPdo extends \PDO - { - private $dsn; - private $user; - private $password; - private $options; - private $commands; - - private $pdo = null; - - public function __construct(string $dsn, /*?string*/ $user = null, /*?string*/ $password = null, array $options = array()) - { - $this->dsn = $dsn; - $this->user = $user; - $this->password = $password; - $this->options = $options; - $this->commands = array(); - // explicitly NOT calling super::__construct - } - - public function addInitCommand(string $command)/*: void*/ - { - $this->commands[] = $command; - } - - private function pdo() - { - if (!$this->pdo) { - $this->pdo = new \PDO($this->dsn, $this->user, $this->password, $this->options); - foreach ($this->commands as $command) { - $this->pdo->query($command); - } - } - return $this->pdo; - } - - public function reconstruct(string $dsn, /*?string*/ $user = null, /*?string*/ $password = null, array $options = array()): bool - { - $this->dsn = $dsn; - $this->user = $user; - $this->password = $password; - $this->options = $options; - $this->commands = array(); - if ($this->pdo) { - $this->pdo = null; - return true; - } - return false; - } - - public function inTransaction(): bool - { - // Do not call parent method if there is no pdo object - return $this->pdo && parent::inTransaction(); - } - - public function setAttribute($attribute, $value): bool - { - if ($this->pdo) { - return $this->pdo()->setAttribute($attribute, $value); - } - $this->options[$attribute] = $value; - return true; - } - - public function getAttribute($attribute): mixed - { - return $this->pdo()->getAttribute($attribute); - } - - public function beginTransaction(): bool - { - return $this->pdo()->beginTransaction(); - } - - public function commit(): bool - { - return $this->pdo()->commit(); - } - - public function rollBack(): bool - { - return $this->pdo()->rollBack(); - } - - public function errorCode(): mixed - { - return $this->pdo()->errorCode(); - } - - public function errorInfo(): array - { - return $this->pdo()->errorInfo(); - } - - public function exec($query): int - { - return $this->pdo()->exec($query); - } - - public function prepare($statement, $options = array()) - { - return $this->pdo()->prepare($statement, $options); - } - - public function quote($string, $parameter_type = null): string - { - return $this->pdo()->quote($string, $parameter_type); - } - - public function lastInsertId(/* ?string */$name = null): string - { - return $this->pdo()->lastInsertId($name); - } - - public function query(string $statement): \PDOStatement - { - return call_user_func_array(array($this->pdo(), 'query'), func_get_args()); - } - } -} - // file: src/Tqdev/PhpCrudApi/Database/TypeConverter.php namespace Tqdev\PhpCrudApi\Database { @@ -6963,6 +6765,11 @@ private function handleRecords(string $operation, string $tableName) /*: void*/ $condition = $filters->getCombinedConditions($table, $params); VariableStore::set("authorization.conditions.$tableName", $condition); } + if ($path == 'openapi') { + VariableStore::set('authorization.tableHandler', $this->getProperty('tableHandler', '')); + VariableStore::set('authorization.columnHandler', $this->getProperty('columnHandler', '')); + } + return $next->handle($request); } public function process(ServerRequestInterface $request, RequestHandlerInterface $next): ResponseInterface @@ -7795,100 +7602,6 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface } } -// file: src/Tqdev/PhpCrudApi/Middleware/ReconnectMiddleware.php -namespace Tqdev\PhpCrudApi\Middleware { - - use Psr\Http\Message\ResponseInterface; - use Psr\Http\Message\ServerRequestInterface; - use Psr\Http\Server\RequestHandlerInterface; - use Tqdev\PhpCrudApi\Column\ReflectionService; - use Tqdev\PhpCrudApi\Controller\Responder; - use Tqdev\PhpCrudApi\Database\GenericDB; - use Tqdev\PhpCrudApi\Middleware\Base\Middleware; - use Tqdev\PhpCrudApi\Middleware\Router\Router; - - class ReconnectMiddleware extends Middleware - { - private $reflection; - private $db; - - public function __construct(Router $router, Responder $responder, array $properties, ReflectionService $reflection, GenericDB $db) - { - parent::__construct($router, $responder, $properties); - $this->reflection = $reflection; - $this->db = $db; - } - - private function getDriver(): string - { - $driverHandler = $this->getProperty('driverHandler', ''); - if ($driverHandler) { - return call_user_func($driverHandler); - } - return ''; - } - - private function getAddress(): string - { - $addressHandler = $this->getProperty('addressHandler', ''); - if ($addressHandler) { - return call_user_func($addressHandler); - } - return ''; - } - - private function getPort(): int - { - $portHandler = $this->getProperty('portHandler', ''); - if ($portHandler) { - return call_user_func($portHandler); - } - return 0; - } - - private function getDatabase(): string - { - $databaseHandler = $this->getProperty('databaseHandler', ''); - if ($databaseHandler) { - return call_user_func($databaseHandler); - } - return ''; - } - - private function getUsername(): string - { - $usernameHandler = $this->getProperty('usernameHandler', ''); - if ($usernameHandler) { - return call_user_func($usernameHandler); - } - return ''; - } - - private function getPassword(): string - { - $passwordHandler = $this->getProperty('passwordHandler', ''); - if ($passwordHandler) { - return call_user_func($passwordHandler); - } - return ''; - } - - public function process(ServerRequestInterface $request, RequestHandlerInterface $next): ResponseInterface - { - $driver = $this->getDriver(); - $address = $this->getAddress(); - $port = $this->getPort(); - $database = $this->getDatabase(); - $username = $this->getUsername(); - $password = $this->getPassword(); - if ($driver || $address || $port || $database || $username || $password) { - $this->db->reconstruct($driver, $address, $port, $database, $username, $password); - } - return $next->handle($request); - } - } -} - // file: src/Tqdev/PhpCrudApi/Middleware/SanitationMiddleware.php namespace Tqdev\PhpCrudApi\Middleware { @@ -9673,7 +9386,6 @@ private function setHabtmValues(ReflectedTable $t1, ReflectedTable $t2, array &$ use Tqdev\PhpCrudApi\Middleware\IpAddressMiddleware; use Tqdev\PhpCrudApi\Middleware\JoinLimitsMiddleware; use Tqdev\PhpCrudApi\Middleware\JwtAuthMiddleware; - use Tqdev\PhpCrudApi\Middleware\ReconnectMiddleware; use Tqdev\PhpCrudApi\Middleware\MultiTenancyMiddleware; use Tqdev\PhpCrudApi\Middleware\PageLimitsMiddleware; use Tqdev\PhpCrudApi\Middleware\Router\SimpleRouter; @@ -9701,7 +9413,7 @@ public function __construct(Config $config) $config->getUsername(), $config->getPassword() ); - $prefix = sprintf('phpcrudapi-%s-', substr(md5(__FILE__), 0, 8)); + $prefix = sprintf('phpcrudapi-%s-%s-%s-', $config->getDriver(), $config->getDatabase(), substr(md5(__FILE__), 0, 8)); $cache = CacheFactory::create($config->getCacheType(), $prefix, $config->getCachePath()); $reflection = new ReflectionService($db, $cache, $config->getCacheTime()); $responder = new JsonResponder(); @@ -9723,9 +9435,6 @@ public function __construct(Config $config) case 'dbAuth': new DbAuthMiddleware($router, $responder, $properties, $reflection, $db); break; - case 'reconnect': - new ReconnectMiddleware($router, $responder, $properties, $reflection, $db); - break; case 'validation': new ValidationMiddleware($router, $responder, $properties, $reflection); break;