From 2c9b2b7d4fd2fd8b2c3dfc442d047983bca5e4d6 Mon Sep 17 00:00:00 2001 From: Matthew Baggett Date: Sat, 18 Jun 2022 02:40:26 +0200 Subject: [PATCH] Fixup --- Makefile | 2 +- src/Components/Entity.php | 2 + src/Components/Model.php | 6 +++ src/Connection/Database.php | 23 ++++++++++++ .../ApiEndpoints/tests.endpoints.php.twig | 36 ++++++++++++------ .../Controllers/basecontroller.php.twig | 37 +++++++++++++++++++ .../Templates/Models/basemodel.php.twig | 2 +- src/Laminator.php | 11 ++---- 8 files changed, 98 insertions(+), 21 deletions(-) diff --git a/Makefile b/Makefile index a74ba45..6c85e29 100644 --- a/Makefile +++ b/Makefile @@ -21,4 +21,4 @@ clean: ${DC_RUN} test vendor/bin/php-cs-fixer fix test: clear setup migrate regen clean - ${DC_RUN} test vendor/bin/phpunit \ No newline at end of file + ${DC_RUN} test vendor/bin/phpunit --stop-on-error --stop-on-failure \ No newline at end of file diff --git a/src/Components/Entity.php b/src/Components/Entity.php index ae40207..c81bc6f 100644 --- a/src/Components/Entity.php +++ b/src/Components/Entity.php @@ -18,6 +18,7 @@ class Entity protected CaseTransformer $transCamel2Snake; protected CaseTransformer $transField2Property; protected CaseTransformer $transCamel2ScreamingSnake; + protected CaseTransformer $transStudly2Snake; private Laminator $Laminator; public function __construct() @@ -31,6 +32,7 @@ class Entity $this->transSnake2Spinal = new CaseTransformer(new Format\SnakeCase(), new Format\SpinalCase()); $this->transCamel2Snake = new CaseTransformer(new Format\CamelCase(), new Format\SnakeCase()); $this->transCamel2ScreamingSnake = new CaseTransformer(new Format\CamelCase(), new Format\ScreamingSnakeCase()); + $this->transStudly2Snake = new CaseTransformer(new Format\StudlyCaps(), new Format\SnakeCase()); $this->transField2Property = $this->transCamel2Camel; } diff --git a/src/Components/Model.php b/src/Components/Model.php index 74f9b6c..1a817cf 100644 --- a/src/Components/Model.php +++ b/src/Components/Model.php @@ -128,6 +128,11 @@ class Model extends Entity return $this->transStudly2Studly->transform($this->getTableSanitised()); } + public function getEndpointName(): string + { + return $this->transStudly2Snake->transform($this->getClassName()); + } + /** * Get the table name, sanitised by removing any prefixes as per Laminator.yml. * @@ -343,6 +348,7 @@ class Model extends Entity 'app_core' => $this->getLaminator()->getBenzineConfig()->getCore(), //'app_container' => $this->getLaminator()->getBenzineConfig()->getAppContainer(), 'class_name' => $this->getClassName(), + 'endpoint_name' => $this->getEndpointName(), 'variable_name' => $this->transStudly2Camel->transform($this->getClassName()), 'name' => $this->getClassName(), 'object_name_plural' => Inflect::pluralize($this->getClassName()), diff --git a/src/Connection/Database.php b/src/Connection/Database.php index 585f3c4..82e6b76 100644 --- a/src/Connection/Database.php +++ b/src/Connection/Database.php @@ -16,6 +16,7 @@ class Database private string $password; private string $database; private string $charset = 'utf8mb4'; + private array $ignoredTables = []; /** @var callable[] */ private array $onConnect; @@ -45,6 +46,9 @@ class Database if (isset($config['charset'])) { $this->setCharset($config['charset']); } + if (isset($config['skip_tables'])){ + $this->setIgnoredTables($config['skip_tables']); + } } public function onConnect(callable $function): self @@ -155,6 +159,25 @@ class Database return new Metadata($this->getAdapter()); } + /** + * @return array + */ + public function getIgnoredTables(): array + { + return $this->ignoredTables; + } + + /** + * @param array $ignoredTables + * @return Database + */ + public function setIgnoredTables(array $ignoredTables): Database + { + $this->ignoredTables = $ignoredTables; + return $this; + } + + public function getArray(): array { return [ diff --git a/src/Generator/Templates/ApiEndpoints/tests.endpoints.php.twig b/src/Generator/Templates/ApiEndpoints/tests.endpoints.php.twig index 59b076b..a66f159 100644 --- a/src/Generator/Templates/ApiEndpoints/tests.endpoints.php.twig +++ b/src/Generator/Templates/ApiEndpoints/tests.endpoints.php.twig @@ -5,7 +5,7 @@ namespace {{ namespace }}\Test\Api\Generated; use {{ app_core }} as App; use {{ namespace }}\Models\{{ class_name }}Model; use {{ namespace }}\Services\{{ class_name }}Service; -use Benzine\Tests\RoutesTestCase; +use Benzine\Tests\AbstractRoutesTestCase; /** * @covers \{{ namespace }}\Controllers\{{ class_name }}Controller @@ -15,7 +15,7 @@ use Benzine\Tests\RoutesTestCase; * @group api * @internal */ -class {{ class_name }}EndpointTest extends RoutesTestCase +class {{ class_name }}EndpointTest extends AbstractRoutesTestCase { public const MODEL_NAME = '{{ class_name }}'; @@ -34,7 +34,7 @@ class {{ class_name }}EndpointTest extends RoutesTestCase $new{{ class_name }}Array = $new{{ class_name }}->__toArray(); $method = 'PUT'; - $uri = '/v1/{{ controller_route}}'; + $uri = '/api/crud/{{ controller_route}}'; $response = $this->request( $method, @@ -84,7 +84,7 @@ class {{ class_name }}EndpointTest extends RoutesTestCase 'Okay', $responseJson['Status'], sprintf( - "Verify that request to PUT /v1/{{ controller_route }} returns an \"Status: Okay\" response.\n This failed because %s", + "Verify that request to PUT /api/crud/{{ controller_route }} returns an \"Status: Okay\" response.\n This failed because %s", isset($responseJson['Reason']) ? 'Reason: '.$responseJson['Reason'] : 'No Reason Given' ) ); @@ -110,7 +110,7 @@ class {{ class_name }}EndpointTest extends RoutesTestCase '{{ column.field }}' => null, {% endfor %} ]; - $response = $this->request('PUT', '/v1/{{ controller_route}}', $new{{ class_name }}); + $response = $this->request('PUT', '/api/crud/{{ controller_route}}', $new{{ class_name }}); $this->waypoint('API PUT REST REQUEST'); $body = (string) $response->getBody(); $this->assertTrue( @@ -145,8 +145,11 @@ class {{ class_name }}EndpointTest extends RoutesTestCase */ public function test{{ class_name }}Get($id) { + $method = "GET"; + $uri = "/api/crud/{{ controller_route}}/{$id}"; + $this->waypoint('Begin'); - $response = $this->request('GET', '/v1/{{ controller_route}}/{$id}'); + $response = $this->request($method, $uri); $this->waypoint('API GET REST REQUEST'); $body = (string) $response->getBody(); $this->assertTrue( @@ -159,6 +162,7 @@ class {{ class_name }}EndpointTest extends RoutesTestCase true ), "Response was not expected 200 or 400.\n". + "Request: {$method} => {$uri}\n". "Response body is: \n". " ******************************\n{$body}\n ******************************\n" ); @@ -169,7 +173,7 @@ class {{ class_name }}EndpointTest extends RoutesTestCase $responseJson = json_decode((string) $body, true); $this->waypoint('JSON DECODE'); $this->assertArrayHasKey('Status', $responseJson); - $this->assertEquals('Okay', $responseJson['Status'], 'Verify that request to GET /v1/{{ controller_route }}/{$id} returns an "Status: Okay" response. This failed. '.(isset($responseJson['Reason']) ? 'Reason: '.$responseJson['Reason'] : 'No Reason Given')); + $this->assertEquals('Okay', $responseJson['Status'], 'Verify that request to GET /api/crud/{{ controller_route }}/{$id} returns an "Status: Okay" response. This failed. '.(isset($responseJson['Reason']) ? 'Reason: '.$responseJson['Reason'] : 'No Reason Given')); $this->assertArrayHasKey('{{ object_name_singular }}', $responseJson); $this->waypoint('Some assertions'); @@ -182,8 +186,11 @@ class {{ class_name }}EndpointTest extends RoutesTestCase */ public function test{{ class_name }}List() { + $method = "GET"; + $uri = "/api/crud/{{ controller_route}}"; + $this->waypoint('Begin'); - $response = $this->request('GET', '/v1/{{ controller_route}}'); + $response = $this->request($method, $uri); $this->waypoint('API REST REQUEST'); $body = (string) $response->getBody(); $this->assertTrue( @@ -196,6 +203,7 @@ class {{ class_name }}EndpointTest extends RoutesTestCase true ), "Response was not expected 200 or 400.\n". + "Request: {$method} => {$uri}\n". "Response body is: \n". " ******************************\n{$body}\n ******************************\n" ); @@ -206,7 +214,7 @@ class {{ class_name }}EndpointTest extends RoutesTestCase $responseJson = json_decode((string) $body, true); $this->waypoint('JSON DECODE'); $this->assertArrayHasKey('Status', $responseJson); - $this->assertEquals('Okay', $responseJson['Status'], 'Verify that request to GET /v1/{{ controller_route }} returns an "Status: Okay" response. This failed. '.(isset($responseJson['Reason']) ? 'Reason: '.$responseJson['Reason'] : 'No Reason Given')); + $this->assertEquals('Okay', $responseJson['Status'], 'Verify that request to GET /api/crud/{{ controller_route }} returns an "Status: Okay" response. This failed. '.(isset($responseJson['Reason']) ? 'Reason: '.$responseJson['Reason'] : 'No Reason Given')); $this->assertArrayHasKey('{{ object_name_plural }}', $responseJson); $this->waypoint('Some assertions'); $this->validate{{ class_name }}Object(reset($responseJson['{{ object_name_plural }}'])); @@ -222,7 +230,10 @@ class {{ class_name }}EndpointTest extends RoutesTestCase */ public function test{{ class_name }}Delete($id) { - $response = $this->request('DELETE', '/v1/{{ controller_route}}/{$id}'); + $method = "DELETE"; + $uri = "/api/crud/{{ controller_route}}/{$id}"; + + $response = $this->request($method, $uri); $body = (string) $response->getBody(); $this->assertTrue( in_array( @@ -234,12 +245,13 @@ class {{ class_name }}EndpointTest extends RoutesTestCase true ), "Response was not expected 200 or 400.\n". + "Request: {$method} => {$uri}\n". "Response body is: \n". " ******************************\n{$body}\n ******************************\n" ); $responseJson = json_decode((string) $body, true); $this->assertArrayHasKey('Status', $responseJson); - $this->assertEquals('Okay', $responseJson['Status'], 'Verify that request to DELETE /v1/{{ controller_route }}/{$id} returns an "Status: Okay" response. This failed. '.(isset($responseJson['Reason']) ? 'Reason: '.$responseJson['Reason'] : 'No Reason Given')); + $this->assertEquals('Okay', $responseJson['Status'], 'Verify that request to DELETE /api/crud/{{ controller_route }}/{$id} returns an "Status: Okay" response. This failed. '.(isset($responseJson['Reason']) ? 'Reason: '.$responseJson['Reason'] : 'No Reason Given')); $this->assertEquals('DELETE', $responseJson['Action']); $this->assertArrayHasKey('{{ object_name_singular }}', $responseJson); $this->validate{{ class_name }}Object($responseJson['{{ class_name }}']); @@ -254,7 +266,7 @@ class {{ class_name }}EndpointTest extends RoutesTestCase */ public function test{{ class_name }}DeleteVerify($id) { - $response = $this->request('GET', "/v1/{{ controller_route}}/{$id}"); + $response = $this->request('GET', "/api/crud/{{ controller_route}}/{$id}"); $body = (string) $response->getBody(); $this->assertNotNull( json_decode((string) $body), diff --git a/src/Generator/Templates/Controllers/basecontroller.php.twig b/src/Generator/Templates/Controllers/basecontroller.php.twig index e9ee088..bbfec21 100644 --- a/src/Generator/Templates/Controllers/basecontroller.php.twig +++ b/src/Generator/Templates/Controllers/basecontroller.php.twig @@ -4,6 +4,9 @@ namespace {{ namespace }}\Controllers\Base; use {{ namespace }}\Services; use Benzine\Controllers\AbstractCrudController; +use Slim\Psr7\Request; +use Slim\Psr7\Response; +use Benzine\Annotations\Route; {% include '_overwrite_warning.twig' %} @@ -19,4 +22,38 @@ abstract class AbstractBase{{ class_name }}Controller extends AbstractCrudContro { return $this->service; } + + /** + * @Route(methods={"GET"},path="/api/crud/{{ endpoint_name }}") + */ + public function listRequest(Request $request, Response $response): Response + { + return parent::listRequest($request,$response); + } + + /** + * @Route(methods={"GET"},path="/api/crud/{{ endpoint_name }}/{id}") + */ + public function getRequest(Request $request, Response $response, $args): Response + { + return parent::getRequest($request, $response, $args); + } + + /** + * @Route(methods={"PUT"},path="/api/crud/{{ endpoint_name }}") + * @Route(methods={"PUT"},path="/api/crud/{{ endpoint_name }}/{id}") + */ + public function createRequest(Request $request, Response $response, $args): Response + { + return parent::createRequest($request, $response, $args); + } + + /** + * @Route(methods={"DELETE"},path="/api/crud/{{ endpoint_name }}/{id}") + */ + public function deleteRequest(Request $request, Response $response, $args): Response + { + return parent::deleteRequest($request, $response, $args); + } + } diff --git a/src/Generator/Templates/Models/basemodel.php.twig b/src/Generator/Templates/Models/basemodel.php.twig index 91cdde7..db5b56e 100644 --- a/src/Generator/Templates/Models/basemodel.php.twig +++ b/src/Generator/Templates/Models/basemodel.php.twig @@ -455,7 +455,7 @@ abstract class AbstractBase{{ class_name }}Model extends AbstractModel implement {% if column.getDbType in ['datetime', 'timestamp'] %} $this->{{ column.getFieldSanitised }} = ${{ column.getDbField() }} !== null - ? DateTime::createFromFormat("Y-m-d H:i:s", ${{ column.getDbField() }}) + ? new DateTime(${{ column.getDbField() }}) : null ; {% else %} $this->{{ column.getFieldSanitised }} = ${{ column.getDbField() }}; diff --git a/src/Laminator.php b/src/Laminator.php index 852a293..d49e3f9 100644 --- a/src/Laminator.php +++ b/src/Laminator.php @@ -47,7 +47,6 @@ class Laminator private TwigFileSystemLoader $loader; private TwigEnvironment $twig; private Databases $databases; - private array $ignoredTables = []; private \SimpleXMLElement $coverageReport; private bool $waitForKeypressEnabled = true; @@ -104,11 +103,6 @@ class Laminator $fct = new \Twig\TwigFunction('var_export', 'var_export'); $this->twig->addFunction($fct); - // Skip tables specified in configuration. - if (isset($this->config['database'], $this->config['database']['skip_tables'])) { - $this->ignoredTables = $this->config['database']['skip_tables']; - } - $this->transSnake2Studly = new CaseTransformer(new Format\SnakeCase(), new Format\StudlyCaps()); $this->transStudly2Camel = new CaseTransformer(new Format\StudlyCaps(), new Format\CamelCase()); $this->transStudly2Studly = new CaseTransformer(new Format\StudlyCaps(), new Format\StudlyCaps()); @@ -298,7 +292,7 @@ class Laminator echo 'Collecting '.count($tables)." entities data.\n"; foreach ($tables as $table) { - if (in_array($table->getName(), $this->ignoredTables, true)) { + if (in_array($table->getName(), $database->getIgnoredTables(), true)) { continue; } $oModel = Components\Model::Factory($this) @@ -321,6 +315,9 @@ class Laminator /** @var Database $database */ $tables = $database->getMetadata()->getTables(); foreach ($tables as $table) { + if (in_array($table->getName(), $database->getIgnoredTables(), true)) { + continue; + } $key = $keys[$database->getAdapter()->getCurrentSchema().'::'.$table->getName()]; $models[$key] ->computeColumns($table->getColumns())