Поле даты и времени Symfony 4 Entity возвращает текущую дату вместо базы данных.
У меня есть образ Entity, в котором дата обновления хранится в поле с именем updatedAt.
<?php /** @noinspection PhpFullyQualifiedNameUsageInspection */
namespace App\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\HttpFoundation\File\File;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
/**
* @ORM\Entity(repositoryClass = "App\Repository\ImageRepository")
* @Vich\Uploadable
*/
class Image
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type = "integer")
*/
private $id;
/**
* @var File
* @Vich\UploadableField(mapping = "images", fileNameProperty = "name")
*/
private $file;
/**
* @var string
* @ORM\Column(type = "string", length=255)"
*/
private $name;
/**
* @var \DateTime
* @ORM\Column(type = "datetime")
*/
private $updatedAt;
/**
* @ORM\ManyToMany(targetEntity = "App\Entity\Tag", inversedBy = "images", cascade = {"persist"})
*/
private $tags;
public function __construct()
{
$this->updatedAt = new \DateTime();
$this->tags = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getFile(): ?File
{
return $this->file;
}
public function setFile(?File $file = null): void
{
$this->file = $file;
if ($file !== null) {
// It is required that at least one field changes if you are using doctrine
// otherwise the event listeners won't be called and the file is lost
$this->updatedAt = new \DateTime();
}
}
public function getName(): ?string
{
return $this->name;
}
public function setName(?string $name): self
{
$this->name = $name;
return $this;
}
public function getUpdatedAt(): ?\DateTimeInterface
{
return $this->updatedAt;
}
public function setUpdatedAt(\DateTimeInterface $updatedAt): self
{
$this->updatedAt = $updatedAt;
return $this;
}
}
Но когда я получаю его из базы данных, поле updatedAt показывает текущее время данных, как показано ниже:
Image {#646 ▼
-id: 27
-file: File {#698 ▶}
-name: "kPRHHeCVrT.jpg"
-updatedAt: DateTime @1558609804 {#706 ▼
date: 2019-05-23 11:10:04.486082 UTC (+00:00)
}
-tags: PersistentCollection {#686 ▶}
}
и var_dump($this->updatedAt) в методе getUpdatedAt показывает это:
object(DateTime)#626 (3) { ["date"]=> string(26) "2019-05-19 21:17:48.000000" ["timezone_type"]=> int(3) ["timezone"]=> string(3) "UTC" }
object(DateTime)#680 (3) { ["date"]=> string(26) "2019-05-23 11:24:12.746548" ["timezone_type"]=> int(3) ["timezone"]=> string(3) "UTC" }
обратите внимание на 2 разных объекта. Я не понимаю, почему это так.
код для сеттера выше.
И все, что вы делаете, это просто $imageRepo->find($id) сразу после чего следует dump($image) ? Конечно, похоже, что вы где-то обновляете изображение или, возможно, у вас есть какой-то пользовательский прослушиватель событий доктрины. (Не по теме, но Функция дампа Symfony обычно лучше, чем встроенная функция php var_dump).
Да, я пробовал встроенную функцию дампа, и она печатает тот же результат. но в любом случае я извлекаю объект с помощью ParameterConverter, также с функцией findAll. Я использую VichUploader с параметрами CurrentDateTimeDirectoryNamer: directory_namer: service: Vich\UploaderBundle\Naming\CurrentDateTimeDirectoryNamer options: date_time_format: 'Y/d/m' date_time_property: uploadTimestamp






Как говорится в комментариях в вашем коде (поскольку вы сохранили его от официального VichUploaderBundle документация):
public function setFile(?File $file = null): void
{
$this->file = $file;
if ($file !== null) {
// It is required that at least one field changes if you are using doctrine
// otherwise the event listeners won't be called and the file is lost
$this->updatedAt = new \DateTime();
}
}
Таким образом, это означает, что каждый раз, когда вы вызываете свой метод установить файл (), вы назначаете текущую дату своему свойству $this->updatedAt. Метод вызывается каждый раз, когда вы создаете/обновляете объект изображения, поэтому он всегда будет содержать текущую дату. Это также могло произойти из-за того, что для параметра inject_on_load установлено значение true в yaml-файле конфигурации vich.
Я предлагаю вам добавить новое свойство с именем vichUpdatedAt() и использовать его вместо updatedAt() :
БОНУС: Я рекомендую вам установить эти расширения: https://symfony.com/doc/current/bundles/StofDoctrineExtensionsBundle/index.html Это позволит вам легко добавлять свойства udpatedAt и createdAt в любом месте.
Активируйте желаемое расширение (в /config/packages/stof_doctrine_extensions.yaml), так что для нас прямо сейчас это будет расширение с отметкой времени:
stof_doctrine_extensions:
default_locale: en_US
orm:
default:
timestampable: true
Затем в вашем классе изображений просто добавьте:
use Gedmo\Timestampable\Traits\TimestampableEntity;
class Image {
use TimestampableEntity;
....
}
И вот, бесплатные свойства updatedAt и createdAt, больше ничего не нужно делать, это просто работает.
Я использовал ту же логику в другом проекте, и я просто сделал то же самое, что и раньше. Это должно быть что-то, чего нам не хватает, также обратите внимание на новый DateTime() в конструкторе, который я делал из dacates.
Забыл сказать вам, что основная проблема заключается в том, что пакет не может отображать актив, поскольку он сохраняется с использованием currentDateDirectoryNamer, который, конечно, будет использовать текущую дату, а не updatedAt, и поэтому я не получаю актив
@SalimBenAissa Вы используете inject_on_load: true ? (в vich_uploader.yaml)
Ind yes и изменение его на false решило проблему. Но я больше не могу получить доступ к файлу из объекта, я думаю, что лучший вариант - я следую вашему демарху или просто удаляю обновление в setFile, так как обычно я не буду изменять файл, а скорее удалю его и загружу другой.
вместо этого вы можете загрузить свое изображение вручную в службу, вызываемую вашим контроллером, если у вас для inject_on_load установлено значение false, но да, это еще больше работы!
@SalimBenAissa обычно возникает вопрос, если включена функция inject_on_load, setFile() следует вызывать при обновлении или создавать не в методе получения. Итак, вопрос, почему setFile называется?
Можете ли вы показать, как вы устанавливаете дату? Потому что кажется, что вы сохраняете значение по умолчанию для своей даты