Skip to content

Commit

Permalink
Fix introspection of field of associated records
Browse files Browse the repository at this point in the history
  • Loading branch information
ADmad committed Sep 8, 2024
1 parent 458a531 commit a9c7a70
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 45 deletions.
33 changes: 16 additions & 17 deletions src/View/Helper/CrudViewHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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.
Expand All @@ -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;
}
Expand All @@ -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'));
}
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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 */
Expand Down Expand Up @@ -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);
}

/**
Expand Down Expand Up @@ -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']) {
Expand Down Expand Up @@ -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
);
}
Expand Down
5 changes: 4 additions & 1 deletion templates/element/index/table.php
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
<?php
use Cake\Utility\Inflector;
?>
<div class="table-responsive">
<table class="table table-hover table-sm">
<thead>
Expand All @@ -10,7 +13,7 @@
<th>
<?php
if (!empty($options['disableSort'])) {
echo $options['title'] ?? \Cake\Utility\Inflector::humanize($field);
echo $options['title'] ?? Inflector::humanize(str_replace('.', '_', $field));
} else {
echo $this->Paginator->sort($field, $options['title'] ?? null, $options);
}
Expand Down
10 changes: 5 additions & 5 deletions tests/Fixture/BlogsFixture.php
Original file line number Diff line number Diff line change
Expand Up @@ -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'],
];
}
13 changes: 13 additions & 0 deletions tests/Fixture/UsersFixture.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php
declare(strict_types=1);

namespace CrudView\Test\Fixture;

use Cake\TestSuite\Fixture\TestFixture;

class UsersFixture extends TestFixture
{
public array $records = [
['username' => 'ADmad', 'birth_date' => '2000-01-01'],
];
}
47 changes: 25 additions & 22 deletions tests/TestCase/View/Helper/CrudViewHelperTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
Expand All @@ -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);

Expand All @@ -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)
);
}
}
10 changes: 10 additions & 0 deletions tests/schema.php
Original file line number Diff line number Diff line change
Expand Up @@ -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']]],
],
Expand Down

0 comments on commit a9c7a70

Please sign in to comment.