diff --git a/src/View/Helper/CrudViewHelper.php b/src/View/Helper/CrudViewHelper.php index 9133e11..a7a7c59 100644 --- a/src/View/Helper/CrudViewHelper.php +++ b/src/View/Helper/CrudViewHelper.php @@ -10,6 +10,7 @@ use Cake\Datasource\SchemaInterface; use Cake\Utility\Inflector; use Cake\Utility\Text; +use Cake\View\Form\EntityContext; use Cake\View\Helper; use UnitEnum; use function Cake\Core\h; @@ -30,11 +31,11 @@ class CrudViewHelper extends Helper protected array $helpers = ['Form', 'Html', 'Time']; /** - * Context + * Entity context * - * @var \Cake\Datasource\EntityInterface + * @var \Cake\View\Form\EntityContext */ - protected EntityInterface $_context; + protected EntityContext $_context; /** * Default config. @@ -53,15 +54,15 @@ class CrudViewHelper extends Helper */ public function setContext(EntityInterface $record): void { - $this->_context = $record; + $this->_context = new EntityContext(['entity' => $record]); } /** * Get context * - * @return \Cake\Datasource\EntityInterface + * @return \Cake\View\Form\EntityContext */ - public function getContext(): EntityInterface + public function getContext(): EntityContext { return $this->_context; } @@ -78,11 +79,11 @@ public function process(string $field, EntityInterface $data, array $options = [ { $this->setContext($data); - $value = $this->fieldValue($data, $field); + $value = $this->getContext()->val($field, ['schemaDefault' => false]); $options += ['formatter' => null]; if ($options['formatter'] === 'element') { - $context = $this->getContext(); + $context = $this->getContext()->entity(); return $this->_View->element($options['element'], compact('context', 'field', 'value', 'options')); } @@ -95,7 +96,7 @@ public function process(string $field, EntityInterface $data, array $options = [ } if (is_callable($options['formatter'])) { - return $options['formatter']($field, $value, $this->getContext(), $options, $this->getView()); + return $options['formatter']($field, $value, $this->getContext()->entity(), $options, $this->getView()); } $value = $this->introspect($field, $value, $options); @@ -112,8 +113,8 @@ public function process(string $field, EntityInterface $data, array $options = [ */ public function fieldValue(?EntityInterface $data, string $field): mixed { - if (empty($data)) { - $data = $this->getContext(); + if ($data === null) { + return $this->getContext()->val($field, ['schemaDefault' => false]); } return $data->get($field); @@ -140,7 +141,7 @@ public function introspect(string $field, mixed $value, array $options = []): ar if (isset($fieldFormatters[$type])) { /** @psalm-suppress PossiblyNullArrayOffset */ if (is_callable($fieldFormatters[$type])) { - return $fieldFormatters[$type]($field, $value, $this->getContext(), $options, $this->getView()); + return $fieldFormatters[$type]($field, $value, $this->getContext()->entity(), $options, $this->getView()); } /** @psalm-suppress PossiblyNullArrayOffset */ @@ -180,9 +181,7 @@ public function introspect(string $field, mixed $value, array $options = []): ar */ public function columnType(string $field): ?string { - $schema = $this->schema(); - - return $schema->getColumnType($field); + return $this->getContext()->type($field); } /** @@ -295,7 +294,7 @@ public function relation(string $field): mixed return false; } - $data = $this->getContext(); + $data = $this->getContext()->entity(); foreach ($associations['manyToOne'] as $alias => $details) { if ($field !== $details['foreignKey']) { @@ -396,7 +395,7 @@ public function createViewLink(string $title, array $options = []): string { return $this->Html->link( $title, - ['action' => 'view', $this->getContext()->get($this->getViewVar('primaryKey'))], + ['action' => 'view', $this->getContext()->entity()->get($this->getViewVar('primaryKey'))], $options ); } diff --git a/templates/element/index/table.php b/templates/element/index/table.php index 2e6cd25..58876b1 100644 --- a/templates/element/index/table.php +++ b/templates/element/index/table.php @@ -1,3 +1,6 @@ +
@@ -10,7 +13,7 @@
Paginator->sort($field, $options['title'] ?? null, $options); } diff --git a/tests/Fixture/BlogsFixture.php b/tests/Fixture/BlogsFixture.php index 8ac126f..b7102c4 100644 --- a/tests/Fixture/BlogsFixture.php +++ b/tests/Fixture/BlogsFixture.php @@ -8,10 +8,10 @@ class BlogsFixture extends TestFixture { public array $records = [ - ['name' => '1st post', 'body' => '1st post body', 'user_id' => 1], - ['name' => '2nd post', 'body' => '2nd post body', 'user_id' => 1], - ['name' => '3rd post', 'body' => '3rd post body', 'user_id' => 1], - ['name' => '4th post', 'body' => '4th post body', 'user_id' => 1], - ['name' => '5th post', 'body' => '5th post body', 'user_id' => 1], + ['name' => '1st post', 'body' => '1st post body', 'user_id' => 1, 'created' => '2024-09-03 00:00:00'], + ['name' => '2nd post', 'body' => '2nd post body', 'user_id' => 1, 'created' => '2024-09-04 00:00:00'], + ['name' => '3rd post', 'body' => '3rd post body', 'user_id' => 1, 'created' => '2024-09-05 00:00:00'], + ['name' => '4th post', 'body' => '4th post body', 'user_id' => 1, 'created' => '2024-09-06 00:00:00'], + ['name' => '5th post', 'body' => '5th post body', 'user_id' => 1, 'created' => '2024-09-07 00:00:00'], ]; } diff --git a/tests/Fixture/UsersFixture.php b/tests/Fixture/UsersFixture.php new file mode 100644 index 0000000..9248a6e --- /dev/null +++ b/tests/Fixture/UsersFixture.php @@ -0,0 +1,13 @@ + 'ADmad', 'birth_date' => '2000-01-01'], + ]; +} diff --git a/tests/TestCase/View/Helper/CrudViewHelperTest.php b/tests/TestCase/View/Helper/CrudViewHelperTest.php index e5380c2..6acec89 100644 --- a/tests/TestCase/View/Helper/CrudViewHelperTest.php +++ b/tests/TestCase/View/Helper/CrudViewHelperTest.php @@ -4,7 +4,6 @@ namespace CrudView\Test\TestCase\View\Helper; use Cake\I18n\DateTime; -use Cake\ORM\Entity; use Cake\TestSuite\TestCase; use Cake\View\View; use CrudView\View\Helper\CrudViewHelper; @@ -14,12 +13,11 @@ */ class CrudViewHelperTest extends TestCase { + protected array $fixtures = ['plugin.CrudView.Blogs', 'plugin.CrudView.Users']; + protected CrudViewHelper $CrudView; - /** - * @var \Cake\View\View&\PHPUnit\Framework\MockObject\MockObject - */ - protected $View; + protected View $View; /** * setUp method @@ -36,28 +34,21 @@ public function setUp(): void ], ]); + $this->CrudView = new CrudViewHelper($this->View); + + $this->fetchTable('Blogs')->belongsTo('Users'); + static::setAppNamespace(); } public function testIntrospect() { - $this->CrudView = $this->getMockBuilder(CrudViewHelper::class) - ->setConstructorArgs([$this->View]) - ->onlyMethods(['columnType', 'getContext']) - ->getMock(); - - $this->CrudView - ->expects($this->any()) - ->method('getContext') - ->willReturn(new Entity()); - - $this->CrudView - ->expects($this->any()) - ->method('columnType') - ->with('created') - ->willReturn('datetime'); - - $value = new DateTime(); + $entity = $this->fetchTable('Blogs')->find()->first(); + $entity->created = new DateTime(); + + $this->CrudView->setContext($entity); + + $value = $entity->created; $result = $this->CrudView->introspect('created', $value); $this->assertEquals('just now', $result); @@ -81,4 +72,16 @@ public function testIntrospect() $result = $this->CrudView->introspect('created', $value); $this->assertEquals('formatted time', $result); } + + public function testProcess() + { + $entity = $this->fetchTable('Blogs')->find() + ->contain('Users') + ->first(); + + $this->assertSame( + 'on 1/1/00', + $this->CrudView->process('user.birth_date', $entity) + ); + } } diff --git a/tests/schema.php b/tests/schema.php index 9715345..9367b23 100644 --- a/tests/schema.php +++ b/tests/schema.php @@ -10,6 +10,16 @@ 'name' => ['type' => 'string', 'length' => 255, 'null' => false], 'body' => ['type' => 'text', 'null' => false], 'user_id' => ['type' => 'integer'], + 'created' => ['type' => 'datetime', 'null' => false], + ], + 'constraints' => ['primary' => ['type' => 'primary', 'columns' => ['id']]], + ], + [ + 'table' => 'users', + 'columns' => [ + 'id' => ['type' => 'integer'], + 'username' => ['type' => 'string', 'length' => 20, 'null' => false], + 'birth_date' => ['type' => 'date', 'null' => false], ], 'constraints' => ['primary' => ['type' => 'primary', 'columns' => ['id']]], ],