mirror of
https://github.com/Part-DB/Part-DB-server.git
synced 2025-06-20 17:15:51 +02:00
Use DatetimeImmutable instead of DateTime wherever possible
This commit is contained in:
parent
eebc373734
commit
235d572f8c
39 changed files with 222 additions and 112 deletions
|
@ -9,10 +9,17 @@ doctrine:
|
|||
# either here or in the DATABASE_URL env var (see .env file)
|
||||
|
||||
types:
|
||||
# UTC datetimes
|
||||
datetime:
|
||||
class: App\Doctrine\Types\UTCDateTimeType
|
||||
date:
|
||||
class: App\Doctrine\Types\UTCDateTimeType
|
||||
|
||||
datetime_immutable:
|
||||
class: App\Doctrine\Types\UTCDateTimeImmutableType
|
||||
date_immutable:
|
||||
class: App\Doctrine\Types\UTCDateTimeImmutableType
|
||||
|
||||
big_decimal:
|
||||
class: App\Doctrine\Types\BigDecimalType
|
||||
tinyint:
|
||||
|
|
|
@ -75,7 +75,7 @@ class APITokenFixtures extends Fixture implements DependentFixtureInterface
|
|||
$expired_token->setUser($admin_user);
|
||||
$expired_token->setLevel(ApiTokenLevel::FULL);
|
||||
$expired_token->setName('expired');
|
||||
$expired_token->setValidUntil(new \DateTime('-1 day'));
|
||||
$expired_token->setValidUntil(new \DateTimeImmutable('-1 day'));
|
||||
$this->setTokenSecret($expired_token, self::TOKEN_EXPIRED);
|
||||
$manager->persist($expired_token);
|
||||
|
||||
|
|
|
@ -99,7 +99,7 @@ class PartFixtures extends Fixture implements DependentFixtureInterface
|
|||
$part->addPartLot($partLot1);
|
||||
|
||||
$partLot2 = new PartLot();
|
||||
$partLot2->setExpirationDate(new DateTime());
|
||||
$partLot2->setExpirationDate(new \DateTimeImmutable());
|
||||
$partLot2->setComment('Test');
|
||||
$partLot2->setNeedsRefill(true);
|
||||
$partLot2->setStorageLocation($manager->find(StorageLocation::class, 3));
|
||||
|
|
|
@ -47,7 +47,7 @@ class LocaleDateTimeColumn extends AbstractColumn
|
|||
}
|
||||
|
||||
if (!$value instanceof DateTimeInterface) {
|
||||
$value = new DateTime((string) $value);
|
||||
$value = new \DateTimeImmutable((string) $value);
|
||||
}
|
||||
|
||||
$formatValues = [
|
||||
|
|
97
src/Doctrine/Types/UTCDateTimeImmutableType.php
Normal file
97
src/Doctrine/Types/UTCDateTimeImmutableType.php
Normal file
|
@ -0,0 +1,97 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||
*
|
||||
* Copyright (C) 2019 - 2022 Jan Böhmer (https://github.com/jbtronics)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published
|
||||
* by the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Doctrine\Types;
|
||||
|
||||
use DateTime;
|
||||
use DateTimeInterface;
|
||||
use DateTimeZone;
|
||||
use Doctrine\DBAL\Platforms\AbstractPlatform;
|
||||
use Doctrine\DBAL\Types\ConversionException;
|
||||
use Doctrine\DBAL\Types\DateTimeImmutableType;
|
||||
use Doctrine\DBAL\Types\DateTimeType;
|
||||
use Doctrine\DBAL\Types\Exception\InvalidFormat;
|
||||
|
||||
/**
|
||||
* This DateTimeImmutableType all dates to UTC, so it can be later used with the timezones.
|
||||
* Taken (and adapted) from here: https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/cookbook/working-with-datetime.html.
|
||||
*/
|
||||
class UTCDateTimeImmutableType extends DateTimeImmutableType
|
||||
{
|
||||
private static ?DateTimeZone $utc_timezone = null;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @param T $value
|
||||
*
|
||||
* @return (T is null ? null : string)
|
||||
*
|
||||
* @template T
|
||||
*/
|
||||
public function convertToDatabaseValue($value, AbstractPlatform $platform): ?string
|
||||
{
|
||||
if (!self::$utc_timezone instanceof \DateTimeZone) {
|
||||
self::$utc_timezone = new DateTimeZone('UTC');
|
||||
}
|
||||
|
||||
if ($value instanceof \DateTimeImmutable) {
|
||||
$value = $value->setTimezone(self::$utc_timezone);
|
||||
}
|
||||
|
||||
return parent::convertToDatabaseValue($value, $platform);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @param T $value
|
||||
*
|
||||
* @template T
|
||||
*/
|
||||
public function convertToPHPValue($value, AbstractPlatform $platform): ?\DateTimeImmutable
|
||||
{
|
||||
if (!self::$utc_timezone instanceof \DateTimeZone) {
|
||||
self::$utc_timezone = new DateTimeZone('UTC');
|
||||
}
|
||||
|
||||
if (null === $value || $value instanceof \DateTimeImmutable) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
$converted = \DateTimeImmutable::createFromFormat(
|
||||
$platform->getDateTimeFormatString(),
|
||||
$value,
|
||||
self::$utc_timezone
|
||||
);
|
||||
|
||||
if (!$converted) {
|
||||
throw InvalidFormat::new(
|
||||
$value,
|
||||
static::class,
|
||||
$platform->getDateTimeFormatString(),
|
||||
);
|
||||
}
|
||||
|
||||
return $converted;
|
||||
}
|
||||
}
|
|
@ -185,9 +185,9 @@ abstract class Attachment extends AbstractNamedDBElement
|
|||
protected ?AttachmentType $attachment_type = null;
|
||||
|
||||
#[Groups(['attachment:read'])]
|
||||
protected ?\DateTime $addedDate = null;
|
||||
protected ?\DateTimeImmutable $addedDate = null;
|
||||
#[Groups(['attachment:read'])]
|
||||
protected ?\DateTime $lastModified = null;
|
||||
protected ?\DateTimeImmutable $lastModified = null;
|
||||
|
||||
|
||||
public function __construct()
|
||||
|
|
|
@ -135,9 +135,9 @@ class AttachmentType extends AbstractStructuralDBElement
|
|||
protected Collection $attachments_with_type;
|
||||
|
||||
#[Groups(['attachment_type:read'])]
|
||||
protected ?\DateTime $addedDate = null;
|
||||
protected ?\DateTimeImmutable $addedDate = null;
|
||||
#[Groups(['attachment_type:read'])]
|
||||
protected ?\DateTime $lastModified = null;
|
||||
protected ?\DateTimeImmutable $lastModified = null;
|
||||
|
||||
|
||||
public function __construct()
|
||||
|
|
|
@ -41,9 +41,9 @@ use Symfony\Component\Validator\Constraints as Assert;
|
|||
abstract class AbstractCompany extends AbstractPartsContainingDBElement
|
||||
{
|
||||
#[Groups(['company:read'])]
|
||||
protected ?\DateTime $addedDate = null;
|
||||
protected ?\DateTimeImmutable $addedDate = null;
|
||||
#[Groups(['company:read'])]
|
||||
protected ?\DateTime $lastModified = null;
|
||||
protected ?\DateTimeImmutable $lastModified = null;
|
||||
|
||||
/**
|
||||
* @var string The address of the company
|
||||
|
|
|
@ -34,28 +34,28 @@ use Symfony\Component\Serializer\Annotation\Groups;
|
|||
trait TimestampTrait
|
||||
{
|
||||
/**
|
||||
* @var \DateTime|null the date when this element was modified the last time
|
||||
* @var \DateTimeImmutable|null the date when this element was modified the last time
|
||||
*/
|
||||
#[Groups(['extended', 'full'])]
|
||||
#[ApiProperty(writable: false)]
|
||||
#[ORM\Column(name: 'last_modified', type: Types::DATETIME_MUTABLE, options: ['default' => 'CURRENT_TIMESTAMP'])]
|
||||
protected ?\DateTime $lastModified = null;
|
||||
#[ORM\Column(name: 'last_modified', type: Types::DATETIME_IMMUTABLE, options: ['default' => 'CURRENT_TIMESTAMP'])]
|
||||
protected ?\DateTimeImmutable $lastModified = null;
|
||||
|
||||
/**
|
||||
* @var \DateTime|null the date when this element was created
|
||||
* @var \DateTimeImmutable|null the date when this element was created
|
||||
*/
|
||||
#[Groups(['extended', 'full'])]
|
||||
#[ApiProperty(writable: false)]
|
||||
#[ORM\Column(name: 'datetime_added', type: Types::DATETIME_MUTABLE, options: ['default' => 'CURRENT_TIMESTAMP'])]
|
||||
protected ?\DateTime $addedDate = null;
|
||||
#[ORM\Column(name: 'datetime_added', type: Types::DATETIME_IMMUTABLE, options: ['default' => 'CURRENT_TIMESTAMP'])]
|
||||
protected ?\DateTimeImmutable $addedDate = null;
|
||||
|
||||
/**
|
||||
* Returns the last time when the element was modified.
|
||||
* Returns null if the element was not yet saved to DB yet.
|
||||
*
|
||||
* @return \DateTimeInterface|null the time of the last edit
|
||||
* @return \DateTimeImmutable|null the time of the last edit
|
||||
*/
|
||||
public function getLastModified(): ?\DateTimeInterface
|
||||
public function getLastModified(): ?\DateTimeImmutable
|
||||
{
|
||||
return $this->lastModified;
|
||||
}
|
||||
|
@ -64,9 +64,9 @@ trait TimestampTrait
|
|||
* Returns the date/time when the element was created.
|
||||
* Returns null if the element was not yet saved to DB yet.
|
||||
*
|
||||
* @return \DateTimeInterface|null the creation time of the part
|
||||
* @return \DateTimeImmutable|null the creation time of the part
|
||||
*/
|
||||
public function getAddedDate(): ?\DateTimeInterface
|
||||
public function getAddedDate(): ?\DateTimeImmutable
|
||||
{
|
||||
return $this->addedDate;
|
||||
}
|
||||
|
@ -78,9 +78,9 @@ trait TimestampTrait
|
|||
#[ORM\PreUpdate]
|
||||
public function updateTimestamps(): void
|
||||
{
|
||||
$this->lastModified = new DateTime('now');
|
||||
$this->lastModified = new \DateTimeImmutable('now');
|
||||
if (null === $this->addedDate) {
|
||||
$this->addedDate = new DateTime('now');
|
||||
$this->addedDate = new \DateTimeImmutable('now');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ namespace App\Entity\LogSystem;
|
|||
use Doctrine\DBAL\Types\Types;
|
||||
use App\Entity\Base\AbstractDBElement;
|
||||
use App\Entity\UserSystem\User;
|
||||
use DateTime;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use App\Repository\LogEntryRepository;
|
||||
|
||||
|
@ -56,10 +56,10 @@ abstract class AbstractLogEntry extends AbstractDBElement
|
|||
protected string $username = '';
|
||||
|
||||
/**
|
||||
* @var \DateTimeInterface The datetime the event associated with this log entry has occured
|
||||
* @var \DateTimeImmutable The datetime the event associated with this log entry has occured
|
||||
*/
|
||||
#[ORM\Column(name: 'datetime', type: Types::DATETIME_MUTABLE)]
|
||||
protected \DateTimeInterface $timestamp;
|
||||
#[ORM\Column(name: 'datetime', type: Types::DATETIME_IMMUTABLE)]
|
||||
protected \DateTimeImmutable $timestamp;
|
||||
|
||||
/**
|
||||
* @var LogLevel The priority level of the associated level. 0 is highest, 7 lowest
|
||||
|
@ -90,7 +90,7 @@ abstract class AbstractLogEntry extends AbstractDBElement
|
|||
|
||||
public function __construct()
|
||||
{
|
||||
$this->timestamp = new DateTime();
|
||||
$this->timestamp = new \DateTimeImmutable();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -165,7 +165,7 @@ abstract class AbstractLogEntry extends AbstractDBElement
|
|||
/**
|
||||
* Returns the timestamp when the event that caused this log entry happened.
|
||||
*/
|
||||
public function getTimestamp(): \DateTimeInterface
|
||||
public function getTimestamp(): \DateTimeImmutable
|
||||
{
|
||||
return $this->timestamp;
|
||||
}
|
||||
|
@ -175,7 +175,7 @@ abstract class AbstractLogEntry extends AbstractDBElement
|
|||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setTimestamp(\DateTime $timestamp): self
|
||||
public function setTimestamp(\DateTimeImmutable $timestamp): self
|
||||
{
|
||||
$this->timestamp = $timestamp;
|
||||
|
||||
|
|
|
@ -92,7 +92,7 @@ class OAuthToken extends AbstractNamedDBElement implements AccessTokenInterface
|
|||
return $this->token;
|
||||
}
|
||||
|
||||
public function getExpirationDate(): ?\DateTimeInterface
|
||||
public function getExpirationDate(): ?\DateTimeImmutable
|
||||
{
|
||||
return $this->expires_at;
|
||||
}
|
||||
|
|
|
@ -183,9 +183,9 @@ class Category extends AbstractPartsContainingDBElement
|
|||
protected Collection $parameters;
|
||||
|
||||
#[Groups(['category:read'])]
|
||||
protected ?\DateTime $addedDate = null;
|
||||
protected ?\DateTimeImmutable $addedDate = null;
|
||||
#[Groups(['category:read'])]
|
||||
protected ?\DateTime $lastModified = null;
|
||||
protected ?\DateTimeImmutable $lastModified = null;
|
||||
|
||||
#[Assert\Valid]
|
||||
#[ORM\Embedded(class: EDACategoryInfo::class)]
|
||||
|
|
|
@ -134,9 +134,9 @@ class Footprint extends AbstractPartsContainingDBElement
|
|||
protected Collection $parameters;
|
||||
|
||||
#[Groups(['footprint:read'])]
|
||||
protected ?\DateTime $addedDate = null;
|
||||
protected ?\DateTimeImmutable $addedDate = null;
|
||||
#[Groups(['footprint:read'])]
|
||||
protected ?\DateTime $lastModified = null;
|
||||
protected ?\DateTimeImmutable $lastModified = null;
|
||||
|
||||
#[Assert\Valid]
|
||||
#[ORM\Embedded(class: EDAFootprintInfo::class)]
|
||||
|
|
|
@ -54,9 +54,9 @@ class InfoProviderReference
|
|||
#[Groups(['provider_reference:read'])]
|
||||
private ?string $provider_url = null;
|
||||
|
||||
#[Column(type: Types::DATETIME_MUTABLE, nullable: true, options: ['default' => null])]
|
||||
#[Column(type: Types::DATETIME_IMMUTABLE, nullable: true, options: ['default' => null])]
|
||||
#[Groups(['provider_reference:read'])]
|
||||
private ?\DateTime $last_updated = null;
|
||||
private ?\DateTimeImmutable $last_updated = null;
|
||||
|
||||
/**
|
||||
* Constructing is forbidden from outside.
|
||||
|
@ -95,9 +95,8 @@ class InfoProviderReference
|
|||
|
||||
/**
|
||||
* Gets the time, when the part was last time updated by the provider.
|
||||
* @return \DateTimeInterface|null
|
||||
*/
|
||||
public function getLastUpdated(): ?\DateTimeInterface
|
||||
public function getLastUpdated(): ?\DateTimeImmutable
|
||||
{
|
||||
return $this->last_updated;
|
||||
}
|
||||
|
@ -140,7 +139,7 @@ class InfoProviderReference
|
|||
$ref->provider_key = $provider_key;
|
||||
$ref->provider_id = $provider_id;
|
||||
$ref->provider_url = $provider_url;
|
||||
$ref->last_updated = new \DateTime();
|
||||
$ref->last_updated = new \DateTimeImmutable();
|
||||
return $ref;
|
||||
}
|
||||
|
||||
|
@ -155,7 +154,7 @@ class InfoProviderReference
|
|||
$ref->provider_key = $dto->provider_key;
|
||||
$ref->provider_id = $dto->provider_id;
|
||||
$ref->provider_url = $dto->provider_url;
|
||||
$ref->last_updated = new \DateTime();
|
||||
$ref->last_updated = new \DateTimeImmutable();
|
||||
return $ref;
|
||||
}
|
||||
}
|
|
@ -156,9 +156,9 @@ class MeasurementUnit extends AbstractPartsContainingDBElement
|
|||
protected Collection $parameters;
|
||||
|
||||
#[Groups(['measurement_unit:read'])]
|
||||
protected ?\DateTime $addedDate = null;
|
||||
protected ?\DateTimeImmutable $addedDate = null;
|
||||
#[Groups(['measurement_unit:read'])]
|
||||
protected ?\DateTime $lastModified = null;
|
||||
protected ?\DateTimeImmutable $lastModified = null;
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
@ -154,9 +154,9 @@ class Part extends AttachmentContainingDBElement
|
|||
protected ?Attachment $master_picture_attachment = null;
|
||||
|
||||
#[Groups(['part:read'])]
|
||||
protected ?\DateTime $addedDate = null;
|
||||
protected ?\DateTimeImmutable $addedDate = null;
|
||||
#[Groups(['part:read'])]
|
||||
protected ?\DateTime $lastModified = null;
|
||||
protected ?\DateTimeImmutable $lastModified = null;
|
||||
|
||||
|
||||
public function __construct()
|
||||
|
|
|
@ -105,13 +105,13 @@ class PartLot extends AbstractDBElement implements TimeStampableInterface, Named
|
|||
protected string $comment = '';
|
||||
|
||||
/**
|
||||
* @var \DateTime|null Set a time until when the lot must be used.
|
||||
* @var \DateTimeImmutable|null Set a time until when the lot must be used.
|
||||
* Set to null, if the lot can be used indefinitely.
|
||||
*/
|
||||
#[Groups(['extended', 'full', 'import', 'part_lot:read', 'part_lot:write'])]
|
||||
#[ORM\Column(name: 'expiration_date', type: Types::DATETIME_MUTABLE, nullable: true)]
|
||||
#[ORM\Column(name: 'expiration_date', type: Types::DATETIME_IMMUTABLE, nullable: true)]
|
||||
#[Year2038BugWorkaround]
|
||||
protected ?\DateTime $expiration_date = null;
|
||||
protected ?\DateTimeImmutable $expiration_date = null;
|
||||
|
||||
/**
|
||||
* @var StorageLocation|null The storelocation of this lot
|
||||
|
@ -194,7 +194,7 @@ class PartLot extends AbstractDBElement implements TimeStampableInterface, Named
|
|||
}
|
||||
|
||||
//Check if the expiration date is bigger then current time
|
||||
return $this->expiration_date < new DateTime('now');
|
||||
return $this->expiration_date < new \DateTimeImmutable('now');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -236,7 +236,7 @@ class PartLot extends AbstractDBElement implements TimeStampableInterface, Named
|
|||
/**
|
||||
* Gets the expiration date for the part lot. Returns null, if no expiration date was set.
|
||||
*/
|
||||
public function getExpirationDate(): ?\DateTimeInterface
|
||||
public function getExpirationDate(): ?\DateTimeImmutable
|
||||
{
|
||||
return $this->expiration_date;
|
||||
}
|
||||
|
@ -246,7 +246,7 @@ class PartLot extends AbstractDBElement implements TimeStampableInterface, Named
|
|||
*
|
||||
*
|
||||
*/
|
||||
public function setExpirationDate(?\DateTime $expiration_date): self
|
||||
public function setExpirationDate(?\DateTimeImmutable $expiration_date): self
|
||||
{
|
||||
$this->expiration_date = $expiration_date;
|
||||
|
||||
|
|
|
@ -170,9 +170,9 @@ class StorageLocation extends AbstractPartsContainingDBElement
|
|||
protected ?Attachment $master_picture_attachment = null;
|
||||
|
||||
#[Groups(['location:read'])]
|
||||
protected ?\DateTime $addedDate = null;
|
||||
protected ?\DateTimeImmutable $addedDate = null;
|
||||
#[Groups(['location:read'])]
|
||||
protected ?\DateTime $lastModified = null;
|
||||
protected ?\DateTimeImmutable $lastModified = null;
|
||||
|
||||
|
||||
/********************************************************************************
|
||||
|
|
|
@ -156,9 +156,9 @@ class Currency extends AbstractStructuralDBElement
|
|||
protected Collection $pricedetails;
|
||||
|
||||
#[Groups(['currency:read'])]
|
||||
protected ?\DateTime $addedDate = null;
|
||||
protected ?\DateTimeImmutable $addedDate = null;
|
||||
#[Groups(['currency:read'])]
|
||||
protected ?\DateTime $lastModified = null;
|
||||
protected ?\DateTimeImmutable $lastModified = null;
|
||||
|
||||
|
||||
public function __construct()
|
||||
|
|
|
@ -46,7 +46,7 @@ use App\Entity\Contracts\NamedElementInterface;
|
|||
use App\Entity\Contracts\TimeStampableInterface;
|
||||
use App\Entity\Parts\Part;
|
||||
use App\Entity\Parts\Supplier;
|
||||
use DateTime;
|
||||
use DateTimeImmutable;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
@ -173,9 +173,9 @@ class Orderdetail extends AbstractDBElement implements TimeStampableInterface, N
|
|||
#[ORM\PreUpdate]
|
||||
public function updateTimestamps(): void
|
||||
{
|
||||
$this->lastModified = new DateTime('now');
|
||||
$this->lastModified = new DateTimeImmutable('now');
|
||||
if (!$this->addedDate instanceof \DateTimeInterface) {
|
||||
$this->addedDate = new DateTime('now');
|
||||
$this->addedDate = new DateTimeImmutable('now');
|
||||
}
|
||||
|
||||
if ($this->part instanceof Part) {
|
||||
|
|
|
@ -38,7 +38,7 @@ use App\Validator\Constraints\BigDecimal\BigDecimalPositive;
|
|||
use App\Validator\Constraints\Selectable;
|
||||
use Brick\Math\BigDecimal;
|
||||
use Brick\Math\RoundingMode;
|
||||
use DateTime;
|
||||
use DateTimeImmutable;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
|
||||
use Symfony\Component\Serializer\Annotation\Groups;
|
||||
|
@ -141,9 +141,9 @@ class Pricedetail extends AbstractDBElement implements TimeStampableInterface
|
|||
#[ORM\PreUpdate]
|
||||
public function updateTimestamps(): void
|
||||
{
|
||||
$this->lastModified = new DateTime('now');
|
||||
$this->lastModified = new DateTimeImmutable('now');
|
||||
if (!$this->addedDate instanceof \DateTimeInterface) {
|
||||
$this->addedDate = new DateTime('now');
|
||||
$this->addedDate = new DateTimeImmutable('now');
|
||||
}
|
||||
|
||||
if ($this->orderdetail instanceof Orderdetail) {
|
||||
|
|
|
@ -158,9 +158,9 @@ class Project extends AbstractStructuralDBElement
|
|||
protected Collection $parameters;
|
||||
|
||||
#[Groups(['project:read'])]
|
||||
protected ?\DateTime $addedDate = null;
|
||||
protected ?\DateTimeImmutable $addedDate = null;
|
||||
#[Groups(['project:read'])]
|
||||
protected ?\DateTime $lastModified = null;
|
||||
protected ?\DateTimeImmutable $lastModified = null;
|
||||
|
||||
|
||||
/********************************************************************************
|
||||
|
|
|
@ -75,10 +75,10 @@ class ApiToken implements TimeStampableInterface
|
|||
#[Groups('token:read')]
|
||||
private ?User $user = null;
|
||||
|
||||
#[ORM\Column(type: Types::DATETIME_MUTABLE, nullable: true)]
|
||||
#[ORM\Column(type: Types::DATETIME_IMMUTABLE, nullable: true)]
|
||||
#[Groups('token:read')]
|
||||
#[Year2038BugWorkaround]
|
||||
private ?\DateTime $valid_until;
|
||||
private ?\DateTimeImmutable $valid_until;
|
||||
|
||||
#[ORM\Column(length: 68, unique: true)]
|
||||
private string $token;
|
||||
|
@ -87,9 +87,9 @@ class ApiToken implements TimeStampableInterface
|
|||
#[Groups('token:read')]
|
||||
private ApiTokenLevel $level = ApiTokenLevel::READ_ONLY;
|
||||
|
||||
#[ORM\Column(type: Types::DATETIME_MUTABLE, nullable: true)]
|
||||
#[ORM\Column(type: Types::DATETIME_IMMUTABLE, nullable: true)]
|
||||
#[Groups('token:read')]
|
||||
private ?\DateTime $last_time_used = null;
|
||||
private ?\DateTimeImmutable $last_time_used = null;
|
||||
|
||||
public function __construct(ApiTokenType $tokenType = ApiTokenType::PERSONAL_ACCESS_TOKEN)
|
||||
{
|
||||
|
@ -97,7 +97,7 @@ class ApiToken implements TimeStampableInterface
|
|||
$this->token = $tokenType->getTokenPrefix() . bin2hex(random_bytes(32));
|
||||
|
||||
//By default, tokens are valid for 1 year.
|
||||
$this->valid_until = new \DateTime('+1 year');
|
||||
$this->valid_until = new \DateTimeImmutable('+1 year');
|
||||
}
|
||||
|
||||
public function getTokenType(): ApiTokenType
|
||||
|
@ -116,7 +116,7 @@ class ApiToken implements TimeStampableInterface
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function getValidUntil(): ?\DateTimeInterface
|
||||
public function getValidUntil(): ?\DateTimeImmutable
|
||||
{
|
||||
return $this->valid_until;
|
||||
}
|
||||
|
@ -127,10 +127,10 @@ class ApiToken implements TimeStampableInterface
|
|||
*/
|
||||
public function isValid(): bool
|
||||
{
|
||||
return $this->valid_until === null || $this->valid_until > new \DateTime();
|
||||
return $this->valid_until === null || $this->valid_until > new \DateTimeImmutable();
|
||||
}
|
||||
|
||||
public function setValidUntil(?\DateTime $valid_until): ApiToken
|
||||
public function setValidUntil(?\DateTimeImmutable $valid_until): ApiToken
|
||||
{
|
||||
$this->valid_until = $valid_until;
|
||||
return $this;
|
||||
|
@ -159,19 +159,17 @@ class ApiToken implements TimeStampableInterface
|
|||
|
||||
/**
|
||||
* Gets the last time the token was used to authenticate or null if it was never used.
|
||||
* @return \DateTimeInterface|null
|
||||
*/
|
||||
public function getLastTimeUsed(): ?\DateTimeInterface
|
||||
public function getLastTimeUsed(): ?\DateTimeImmutable
|
||||
{
|
||||
return $this->last_time_used;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the last time the token was used to authenticate.
|
||||
* @param \DateTime|null $last_time_used
|
||||
* @return ApiToken
|
||||
*/
|
||||
public function setLastTimeUsed(?\DateTime $last_time_used): ApiToken
|
||||
public function setLastTimeUsed(?\DateTimeImmutable $last_time_used): ApiToken
|
||||
{
|
||||
$this->last_time_used = $last_time_used;
|
||||
return $this;
|
||||
|
|
|
@ -117,10 +117,10 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe
|
|||
protected ?int $id = null;
|
||||
|
||||
#[Groups(['user:read'])]
|
||||
protected ?\DateTime $lastModified = null;
|
||||
protected ?\DateTimeImmutable $lastModified = null;
|
||||
|
||||
#[Groups(['user:read'])]
|
||||
protected ?\DateTime $addedDate = null;
|
||||
protected ?\DateTimeImmutable $addedDate = null;
|
||||
|
||||
/**
|
||||
* @var bool Determines if the user is disabled (user can not log in)
|
||||
|
@ -277,11 +277,11 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe
|
|||
#[Groups(['user:read', 'user:write'])]
|
||||
protected ?Attachment $master_picture_attachment = null;
|
||||
|
||||
/** @var \DateTimeInterface|null The time when the backup codes were generated
|
||||
/** @var \DateTimeImmutable|null The time when the backup codes were generated
|
||||
*/
|
||||
#[Groups(['full'])]
|
||||
#[ORM\Column(type: Types::DATETIME_MUTABLE, nullable: true)]
|
||||
protected ?\DateTimeInterface $backupCodesGenerationDate = null;
|
||||
#[ORM\Column(type: Types::DATETIME_IMMUTABLE, nullable: true)]
|
||||
protected ?\DateTimeImmutable $backupCodesGenerationDate = null;
|
||||
|
||||
/** @var Collection<int, LegacyU2FKeyInterface>
|
||||
*/
|
||||
|
@ -318,10 +318,10 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe
|
|||
protected ?PermissionData $permissions = null;
|
||||
|
||||
/**
|
||||
* @var \DateTime|null the time until the password reset token is valid
|
||||
* @var \DateTimeImmutable|null the time until the password reset token is valid
|
||||
*/
|
||||
#[ORM\Column(type: Types::DATETIME_MUTABLE, nullable: true)]
|
||||
protected ?\DateTime $pw_reset_expires = null;
|
||||
#[ORM\Column(type: Types::DATETIME_IMMUTABLE, nullable: true)]
|
||||
protected ?\DateTimeImmutable $pw_reset_expires = null;
|
||||
|
||||
/**
|
||||
* @var bool True if the user was created by a SAML provider (and therefore cannot change its password)
|
||||
|
@ -528,7 +528,7 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe
|
|||
/**
|
||||
* Gets the datetime when the password reset token expires.
|
||||
*/
|
||||
public function getPwResetExpires(): \DateTimeInterface|null
|
||||
public function getPwResetExpires(): \DateTimeImmutable|null
|
||||
{
|
||||
return $this->pw_reset_expires;
|
||||
}
|
||||
|
@ -536,7 +536,7 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe
|
|||
/**
|
||||
* Sets the datetime when the password reset token expires.
|
||||
*/
|
||||
public function setPwResetExpires(\DateTime $pw_reset_expires): self
|
||||
public function setPwResetExpires(\DateTimeImmutable $pw_reset_expires): self
|
||||
{
|
||||
$this->pw_reset_expires = $pw_reset_expires;
|
||||
|
||||
|
@ -897,7 +897,7 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe
|
|||
public function setBackupCodes(array $codes): self
|
||||
{
|
||||
$this->backupCodes = $codes;
|
||||
$this->backupCodesGenerationDate = $codes === [] ? null : new DateTime();
|
||||
$this->backupCodesGenerationDate = $codes === [] ? null : new \DateTimeImmutable();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
@ -905,7 +905,7 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe
|
|||
/**
|
||||
* Return the date when the backup codes were generated.
|
||||
*/
|
||||
public function getBackupCodesGenerationDate(): ?\DateTimeInterface
|
||||
public function getBackupCodesGenerationDate(): ?\DateTimeImmutable
|
||||
{
|
||||
return $this->backupCodesGenerationDate;
|
||||
}
|
||||
|
|
|
@ -82,9 +82,8 @@ class WebauthnKey extends BasePublicKeyCredentialSource implements TimeStampable
|
|||
|
||||
/**
|
||||
* Retrieve the last time when the key was used.
|
||||
* @return \DateTimeInterface|null
|
||||
*/
|
||||
public function getLastTimeUsed(): ?\DateTimeInterface
|
||||
public function getLastTimeUsed(): ?\DateTimeImmutable
|
||||
{
|
||||
return $this->last_time_used;
|
||||
}
|
||||
|
|
|
@ -84,7 +84,7 @@ class LabelResponse extends Response
|
|||
*/
|
||||
public function setAutoLastModified(): LabelResponse
|
||||
{
|
||||
$this->setLastModified(new DateTime());
|
||||
$this->setLastModified(new \DateTimeImmutable());
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
|
|
@ -75,7 +75,7 @@ class ApiTokenAuthenticator implements AuthenticatorInterface
|
|||
|
||||
$old_time = $token->getLastTimeUsed();
|
||||
//Set the last used date of the token
|
||||
$token->setLastTimeUsed(new \DateTime());
|
||||
$token->setLastTimeUsed(new \DateTimeImmutable());
|
||||
//Only flush the token if the last used date change is more than 10 minutes
|
||||
//For performance reasons we don't want to flush the token every time it is used, but only if it is used more than 10 minutes after the last time it was used
|
||||
//If a flush is later in the code we don't want to flush the token again
|
||||
|
|
|
@ -225,7 +225,7 @@ trait PKImportHelperTrait
|
|||
protected function setCreationDate(TimeStampableInterface $entity, ?string $datetime_str): void
|
||||
{
|
||||
if ($datetime_str !== null && $datetime_str !== '' && $datetime_str !== '0000-00-00 00:00:00') {
|
||||
$date = new \DateTime($datetime_str);
|
||||
$date = new \DateTimeImmutable($datetime_str);
|
||||
} else {
|
||||
$date = null; //Null means "now" at persist time
|
||||
}
|
||||
|
|
|
@ -97,7 +97,7 @@ final class LabelExampleElementsGenerator
|
|||
|
||||
$lot->setDescription('Example Lot');
|
||||
$lot->setComment('Lot comment');
|
||||
$lot->setExpirationDate(new DateTime('+1 days'));
|
||||
$lot->setExpirationDate(new \DateTimeImmutable('+1 day'));
|
||||
$lot->setStorageLocation($this->getStructuralData(StorageLocation::class));
|
||||
$lot->setAmount(123);
|
||||
$lot->setOwner($this->getUser());
|
||||
|
|
|
@ -81,7 +81,7 @@ final class GlobalProviders implements PlaceholderProviderInterface
|
|||
return 'anonymous';
|
||||
}
|
||||
|
||||
$now = new DateTime();
|
||||
$now = new \DateTimeImmutable();
|
||||
|
||||
if ('[[DATETIME]]' === $placeholder) {
|
||||
$formatter = IntlDateFormatter::create(
|
||||
|
|
|
@ -42,7 +42,6 @@ declare(strict_types=1);
|
|||
namespace App\Services\LabelSystem\PlaceholderProviders;
|
||||
|
||||
use App\Entity\Contracts\TimeStampableInterface;
|
||||
use DateTime;
|
||||
use IntlDateFormatter;
|
||||
use Locale;
|
||||
|
||||
|
@ -57,11 +56,11 @@ final class TimestampableElementProvider implements PlaceholderProviderInterface
|
|||
$formatter = new IntlDateFormatter(Locale::getDefault(), IntlDateFormatter::SHORT, IntlDateFormatter::SHORT);
|
||||
|
||||
if ('[[LAST_MODIFIED]]' === $placeholder) {
|
||||
return $formatter->format($label_target->getLastModified() ?? new DateTime());
|
||||
return $formatter->format($label_target->getLastModified() ?? new \DateTimeImmutable());
|
||||
}
|
||||
|
||||
if ('[[CREATION_DATE]]' === $placeholder) {
|
||||
return $formatter->format($label_target->getAddedDate() ?? new DateTime());
|
||||
return $formatter->format($label_target->getAddedDate() ?? new \DateTimeImmutable());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -136,7 +136,7 @@ class LogDataFormatter
|
|||
}
|
||||
|
||||
try {
|
||||
$dateTime = new \DateTime($date, new \DateTimeZone($timezone));
|
||||
$dateTime = new \DateTimeImmutable($date, new \DateTimeZone($timezone));
|
||||
} catch (\Exception) {
|
||||
return '<i>unknown DateTime format</i>';
|
||||
}
|
||||
|
|
|
@ -34,11 +34,13 @@ use App\Repository\LogEntryRepository;
|
|||
use Brick\Math\BigDecimal;
|
||||
use DateTime;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\DBAL\Types\Types;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\Mapping\ClassMetadata;
|
||||
use Doctrine\ORM\Mapping\MappingException;
|
||||
use Exception;
|
||||
use InvalidArgumentException;
|
||||
use PHPUnit\Util\Type;
|
||||
use ReflectionClass;
|
||||
|
||||
class TimeTravel
|
||||
|
@ -171,17 +173,26 @@ class TimeTravel
|
|||
/**
|
||||
* This function decodes the array which is created during the json_encode of a datetime object and returns a DateTime object.
|
||||
* @param array $input
|
||||
* @return DateTime
|
||||
* @return \DateTimeInterface
|
||||
* @throws Exception
|
||||
*/
|
||||
private function dateTimeDecode(?array $input): ?\DateTime
|
||||
private function dateTimeDecode(?array $input, string $doctrineType): ?\DateTimeInterface
|
||||
{
|
||||
//Allow null values
|
||||
if ($input === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new \DateTime($input['date'], new \DateTimeZone($input['timezone']));
|
||||
//Mutable types
|
||||
if (in_array($doctrineType, [Types::DATETIME_MUTABLE, Types::DATE_MUTABLE], true)) {
|
||||
return new \DateTime($input['date'], new \DateTimeZone($input['timezone']));
|
||||
}
|
||||
//Immutable types
|
||||
if (in_array($doctrineType, [Types::DATETIME_IMMUTABLE, Types::DATE_IMMUTABLE], true)) {
|
||||
return new \DateTimeImmutable($input['date'], new \DateTimeZone($input['timezone']));
|
||||
}
|
||||
|
||||
throw new InvalidArgumentException('The given doctrine type is not a datetime type!');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -208,8 +219,10 @@ class TimeTravel
|
|||
$data = BigDecimal::of($data);
|
||||
}
|
||||
|
||||
if (!$data instanceof DateTime && ('datetime' === $metadata->getFieldMapping($field)['type'])) {
|
||||
$data = $this->dateTimeDecode($data);
|
||||
if (!$data instanceof \DateTimeInterface
|
||||
&& (in_array($metadata->getFieldMapping($field)['type'],
|
||||
[Types::DATETIME_IMMUTABLE, Types::DATETIME_IMMUTABLE, Types::DATE_MUTABLE, Types::DATETIME_IMMUTABLE], true))) {
|
||||
$data = $this->dateTimeDecode($data, $metadata->getFieldMapping($field)['type']);
|
||||
}
|
||||
|
||||
$this->setField($element, $field, $data);
|
||||
|
|
|
@ -49,7 +49,7 @@ final class SidebarTreeUpdater
|
|||
//This tag and therfore this whole cache gets cleared by TreeCacheInvalidationListener when a structural element is changed
|
||||
$item->tag('sidebar_tree_update');
|
||||
|
||||
return new \DateTime();
|
||||
return new \DateTimeImmutable();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,8 +59,7 @@ class PasswordResetManager
|
|||
$user->setPwResetToken($this->passwordEncoder->hash($unencrypted_token));
|
||||
|
||||
//Determine the expiration datetime of
|
||||
$expiration_date = new DateTime();
|
||||
$expiration_date->add(date_interval_create_from_date_string('1 day'));
|
||||
$expiration_date = new \DateTimeImmutable("+1 day");
|
||||
$user->setPwResetExpires($expiration_date);
|
||||
|
||||
if ($user->getEmail() !== null && $user->getEmail() !== '') {
|
||||
|
@ -105,7 +104,7 @@ class PasswordResetManager
|
|||
}
|
||||
|
||||
//Check if token is expired yet
|
||||
if ($user->getPwResetExpires() < new DateTime()) {
|
||||
if ($user->getPwResetExpires() < new \DateTimeImmutable()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -119,7 +118,7 @@ class PasswordResetManager
|
|||
|
||||
//Remove token
|
||||
$user->setPwResetToken(null);
|
||||
$user->setPwResetExpires(new DateTime());
|
||||
$user->setPwResetExpires(new \DateTimeImmutable());
|
||||
|
||||
//Save to DB
|
||||
$this->em->flush();
|
||||
|
|
|
@ -33,12 +33,11 @@ class PartLotTest extends TestCase
|
|||
$lot = new PartLot();
|
||||
$this->assertNull($lot->isExpired(), 'Lot must be return null when no Expiration date is set!');
|
||||
|
||||
$datetime = new DateTime();
|
||||
|
||||
$lot->setExpirationDate($datetime->setTimestamp(strtotime('now +1 hour')));
|
||||
$lot->setExpirationDate(new \DateTimeImmutable('+1 hour'));
|
||||
$this->assertFalse($lot->isExpired(), 'Lot with expiration date in the future must not be expired!');
|
||||
|
||||
$lot->setExpirationDate($datetime->setTimestamp(strtotime('now -1 hour')));
|
||||
$lot->setExpirationDate(new \DateTimeImmutable('-1 hour'));
|
||||
$this->assertTrue($lot->isExpired(), 'Lot with expiration date in the past must be expired!');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -95,7 +95,7 @@ class PartTest extends TestCase
|
|||
$part->addPartLot(
|
||||
(new PartLot())
|
||||
->setAmount(6)
|
||||
->setExpirationDate($datetime->setTimestamp(strtotime('now -1 hour')))
|
||||
->setExpirationDate(new \DateTimeImmutable('-1 hour'))
|
||||
);
|
||||
|
||||
$this->assertEqualsWithDelta(13.0, $part->getAmountSum(), PHP_FLOAT_EPSILON);
|
||||
|
|
|
@ -73,7 +73,7 @@ class UserTest extends TestCase
|
|||
$codes = ['test', 'invalid', 'test'];
|
||||
$user->setBackupCodes($codes);
|
||||
// Backup Codes generation date must be changed!
|
||||
$this->assertInstanceOf(\DateTime::class, $user->getBackupCodesGenerationDate());
|
||||
$this->assertNotNull($user->getBackupCodesGenerationDate());
|
||||
$this->assertSame($codes, $user->getBackupCodes());
|
||||
|
||||
//Test what happens if we delete the backup keys
|
||||
|
|
|
@ -65,7 +65,7 @@ class PartLotProviderTest extends WebTestCase
|
|||
$this->target = new PartLot();
|
||||
$this->target->setDescription('Lot description');
|
||||
$this->target->setComment('Lot comment');
|
||||
$this->target->setExpirationDate(new \DateTime('1999-04-13'));
|
||||
$this->target->setExpirationDate(new \DateTimeImmutable('1999-04-13'));
|
||||
$this->target->setInstockUnknown(true);
|
||||
|
||||
$location = new StorageLocation();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue