Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't use datetime field type as editable #6144

Merged
merged 1 commit into from
Jul 25, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions src/Action/SetObjectFieldValueAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

use Sonata\AdminBundle\Admin\FieldDescriptionInterface;
use Sonata\AdminBundle\Admin\Pool;
use Sonata\AdminBundle\Templating\TemplateRegistry;
use Sonata\AdminBundle\Twig\Extension\SonataAdminExtension;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
Expand Down Expand Up @@ -119,8 +120,8 @@ public function __invoke(Request $request): JsonResponse
$propertyPath = new PropertyPath($field);
}

// Handle date and datetime types have setter expecting a DateTime object
if ('' !== $value && \in_array($fieldDescription->getType(), ['date', 'datetime'], true)) {
// Handle date type has setter expect a DateTime object
if ('' !== $value && TemplateRegistry::TYPE_DATE === $fieldDescription->getType()) {
$inputTimezone = new \DateTimeZone(date_default_timezone_get());
$outputTimezone = $fieldDescription->getOption('timezone');

Expand All @@ -133,13 +134,13 @@ public function __invoke(Request $request): JsonResponse
}

// Handle boolean type transforming the value into a boolean
if ('' !== $value && 'boolean' === $fieldDescription->getType()) {
if ('' !== $value && TemplateRegistry::TYPE_BOOLEAN === $fieldDescription->getType()) {
$value = filter_var($value, FILTER_VALIDATE_BOOLEAN);
}

// Handle entity choice association type, transforming the value into entity
if ('' !== $value
&& 'choice' === $fieldDescription->getType()
&& TemplateRegistry::TYPE_CHOICE === $fieldDescription->getType()
&& null !== $fieldDescription->getOption('class')
// NEXT_MAJOR: Replace this call with "$fieldDescription->getOption('class') === $fieldDescription->getTargetModel()".
&& $this->hasFieldDescriptionAssociationWithClass($fieldDescription, $fieldDescription->getOption('class'))
Expand Down
4 changes: 4 additions & 0 deletions src/Resources/views/CRUD/base_list_field.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ file that was distributed with this source code.
) %}

{% if field_description.type == constant('Sonata\\AdminBundle\\Templating\\TemplateRegistry::TYPE_DATE') and value is not empty %}
{# it is a x-editable format https://vitalets.github.io/x-editable/docs.html#date #}
peter-gribanov marked this conversation as resolved.
Show resolved Hide resolved
{% set data_value = value|date('Y-m-d', options.timezone|default(null)) %}
{% elseif field_description.type == constant('Sonata\\AdminBundle\\Templating\\TemplateRegistry::TYPE_BOOLEAN') and value is empty %}
{% set data_value = 0 %}
Expand All @@ -70,6 +71,9 @@ file that was distributed with this source code.
{% if field_description.label is not same as(false) %}
data-title="{{ field_description.label|trans({}, field_description.translationDomain) }}"
{% endif %}
{% if field_description.type == constant('Sonata\\AdminBundle\\Templating\\TemplateRegistry::TYPE_DATE') %}
data-format="yyyy-mm-dd"
{% endif %}
data-pk="{{ admin.id(object) }}"
data-url="{{ url }}" {% endblock %}>
{{ block('field') }}
Expand Down
59 changes: 0 additions & 59 deletions tests/Action/SetObjectFieldValueActionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -200,65 +200,6 @@ public function testSetObjectFieldValueActionWithDate($timezone, \DateTimeZone $
$this->assertSame($defaultTimezone->getName(), $object->getDateProp()->getTimezone()->getName());
}

/**
* @dataProvider getTimeZones
*/
public function testSetObjectFieldValueActionWithDateTime($timezone, \DateTimeZone $expectedTimezone): void
{
$object = new Bafoo();
peter-gribanov marked this conversation as resolved.
Show resolved Hide resolved
$request = new Request([
'code' => 'sonata.post.admin',
'objectId' => 42,
'field' => 'datetimeProp',
'value' => '2020-12-12 23:11:23',
'context' => 'list',
], [], [], [], [], ['REQUEST_METHOD' => Request::METHOD_POST, 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest']);

$fieldDescription = $this->prophesize(FieldDescriptionInterface::class);
$pool = $this->prophesize(Pool::class);
$translator = $this->prophesize(TranslatorInterface::class);
$propertyAccessor = new PropertyAccessor();
$templateRegistry = $this->prophesize(TemplateRegistryInterface::class);
$container = $this->prophesize(ContainerInterface::class);

$this->admin->getObject(42)->willReturn($object);
$this->admin->getCode()->willReturn('sonata.post.admin');
$this->admin->hasAccess('edit', $object)->willReturn(true);
$this->admin->getListFieldDescription('datetimeProp')->willReturn($fieldDescription->reveal());
$this->admin->update($object)->shouldBeCalled();

$this->admin->getTemplate('base_list_field')->willReturn('admin_template');
$templateRegistry->getTemplate('base_list_field')->willReturn('admin_template');
$container->get('sonata.post.admin.template_registry')->willReturn($templateRegistry->reveal());
$this->pool->getPropertyAccessor()->willReturn($propertyAccessor);
$this->twig->addExtension(new SonataAdminExtension(
$pool->reveal(),
null,
$translator->reveal(),
$container->reveal()
));
$fieldDescription->getOption('editable')->willReturn(true);
$fieldDescription->getOption('timezone')->willReturn($timezone);
$fieldDescription->getAdmin()->willReturn($this->admin->reveal());
$fieldDescription->getType()->willReturn('datetime');
$fieldDescription->getTemplate()->willReturn('field_template');
$fieldDescription->getValue(Argument::cetera())->willReturn('some value');

$this->validator->validate($object)->willReturn(new ConstraintViolationList([]));

$response = ($this->action)($request);

$this->assertSame(Response::HTTP_OK, $response->getStatusCode());

$defaultTimezone = new \DateTimeZone(date_default_timezone_get());
$expectedDate = new \DateTime($request->query->get('value'), $expectedTimezone);
$expectedDate->setTimezone($defaultTimezone);

$this->assertInstanceOf(\DateTime::class, $object->getDatetimeProp());
$this->assertSame($expectedDate->format('Y-m-d H:i:s'), $object->getDatetimeProp()->format('Y-m-d H:i:s'));
$this->assertSame($defaultTimezone->getName(), $object->getDatetimeProp()->getTimezone()->getName());
}

public function testSetObjectFieldValueActionOnARelationField(): void
{
$object = new Baz();
Expand Down