From 9932a3fb8c1ce1a3270687e1b4d5bcb1cc4eb7a0 Mon Sep 17 00:00:00 2001 From: ryu818 Date: Wed, 27 Nov 2024 10:20:49 +0900 Subject: [PATCH 1/2] fix: Error Messages Not Displayed for Nested Array Fields in Form Inputs https://github.com/cakephp/elastic-search/issues/323 --- src/View/Form/DocumentContext.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/View/Form/DocumentContext.php b/src/View/Form/DocumentContext.php index b642fcc..d614c5f 100644 --- a/src/View/Form/DocumentContext.php +++ b/src/View/Form/DocumentContext.php @@ -421,7 +421,7 @@ public function error(string $field): array $errors = $entity->getError(array_pop($parts)); } - if (!$errors && $entityErrors && !is_array($entity)) { + if (!$errors && $entityErrors) { $errors = Hash::extract($entityErrors, $field) ?: []; } From b9da325dabf0e2ce16849444cc74bb0d3dd51f0a Mon Sep 17 00:00:00 2001 From: Mark Story Date: Sat, 7 Dec 2024 12:32:18 -0500 Subject: [PATCH 2/2] Add tests and fix implementatino for nested array fields. --- src/View/Form/DocumentContext.php | 13 +++++- .../View/Form/DocumentContextTest.php | 41 ++++++++++++++++++- tests/bootstrap.php | 2 +- 3 files changed, 51 insertions(+), 5 deletions(-) diff --git a/src/View/Form/DocumentContext.php b/src/View/Form/DocumentContext.php index d614c5f..df14e52 100644 --- a/src/View/Form/DocumentContext.php +++ b/src/View/Form/DocumentContext.php @@ -417,11 +417,20 @@ public function error(string $field): array $entityErrors = $this->_context['entity']->getErrors(); } + $tailField = array_pop($parts); if ($entity instanceof Document) { - $errors = $entity->getError(array_pop($parts)); + $errors = $entity->getError($tailField); } - if (!$errors && $entityErrors) { + // If errors couldn't be read from $entity and $entity + // is either not an array, or the tail field is not Document + // we want to extract errors from the root entity as we could + // have nested validators, or structured fields. + if ( + !$errors && + $entityErrors && + (!is_array($entity) || !($entity[$tailField] instanceof Document)) + ) { $errors = Hash::extract($entityErrors, $field) ?: []; } diff --git a/tests/TestCase/View/Form/DocumentContextTest.php b/tests/TestCase/View/Form/DocumentContextTest.php index 02a20b6..9f35b02 100644 --- a/tests/TestCase/View/Form/DocumentContextTest.php +++ b/tests/TestCase/View/Form/DocumentContextTest.php @@ -473,10 +473,10 @@ public function testNestedValidatorErrors() $expected = [ 'username' => [ 'Required' ] ]; $this->assertEquals($expected, $context->error('user')); - $expected = [ 'Required' ]; + $expected = ['Required']; $this->assertEquals($expected, $context->error('user.username')); - $expected = [ 'Required' ]; + $expected = ['Required']; $this->assertEquals([], $context->error('comments.0')); $this->assertEquals($expected, $context->error('comments.0.comment')); $this->assertEquals($expected, $context->error('comments.2.comment')); @@ -523,6 +523,43 @@ public function testErrorAssociatedHasMany() $this->assertEquals([], $context->error('comments.1.article_id')); } + /** + * Test errors for structured fields. + * + * @return void + */ + public function testErrorNestedFields() + { + $row = new Article([ + 'name' => [ + 'ja' => [ + ['family_name' => 'XX', 'given_name' => 'YY'], + ], + 'en' => [ + ['family_name' => 'ZZ', 'given_name' => 'AA'], + ] + ] + ]); + $row->setError('name', [ + 'ja' => [ + ['family_name' => ['_empty' => 'Invalid value']] + ] + ]); + + $articles = $this->setupIndex(); + $context = new DocumentContext( + $this->request, + [ + 'entity' => $row, + 'table' => $articles, + 'validator' => 'default', + ] + ); + $this->assertEquals(['_empty' => 'Invalid value'], $context->error('name.ja.0.family_name')); + $this->assertEquals([], $context->error('name.derp.0.family_name')); + $this->assertEquals([], $context->error('name.derp.0.undefined')); + } + /** * Test getting fieldnames. * diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 2d714e7..cff35f7 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -51,8 +51,8 @@ putenv('DB_URL=Cake\ElasticSearch\Datasource\Connection://127.0.0.1:9200?driver=Cake\ElasticSearch\Datasource\Connection'); } -ConnectionManager::setConfig('elastic', ['url' => getenv('DB_URL')]); ConnectionManager::setConfig('test', ['url' => getenv('DB_URL')]); +ConnectionManager::setConfig('test_elastic', ['url' => getenv('DB_URL')]); $schema = new MappingGenerator('./tests/mappings.php', 'test'); $schema->reload();