Skip to content

Commit

Permalink
Merge branch '2.11.x' into 3.0.x
Browse files Browse the repository at this point in the history
* 2.11.x:
  Use EntityManagerInterface in type declarations (doctrine#9325)
  Add errors caused by the lexer update to the baselines (doctrine#9360)
  Generated/Virtual Columns: Insertable / Updateable (doctrine#9118)
  Remove the composer/package-versions-deprecated package
  Relax assertion to include null as possible outcome (doctrine#9355)
  • Loading branch information
derrabus committed Jan 12, 2022
2 parents 9624129 + ee59119 commit 0025878
Show file tree
Hide file tree
Showing 76 changed files with 1,006 additions and 238 deletions.
10 changes: 8 additions & 2 deletions UPGRADE.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,13 @@ Use `toIterable()` instead.

# Upgrade to 2.11

## Rename `AbstractIdGenerator::generate()` to `generateId()`

Implementations of `AbstractIdGenerator` have to override the method
`generateId()` without calling the parent implementation. Not doing so is
deprecated. Calling `generate()` on any `AbstractIdGenerator` implementation
is deprecated.

## PSR-6-based second level cache

The second level cache has been reworked to consume a PSR-6 cache. Using a
Expand Down Expand Up @@ -352,8 +359,7 @@ These methods have been deprecated:
## Deprecated `Doctrine\ORM\Version`

The `Doctrine\ORM\Version` class is now deprecated and will be removed in Doctrine ORM 3.0:
please refrain from checking the ORM version at runtime or use
[ocramius/package-versions](https://github.com/Ocramius/PackageVersions/).
please refrain from checking the ORM version at runtime or use Composer's [runtime API](https://getcomposer.org/doc/07-runtime.md#knowing-whether-package-x-is-installed-in-version-y).

## Deprecated `EntityManager#merge()` method

Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@
},
"require": {
"php": "^8.0",
"composer-runtime-api": "^2",
"ext-ctype": "*",
"ext-pdo": "*",
"composer/package-versions-deprecated": "^1.8",
"doctrine/cache": "^1.12.1 || ^2.1.1",
"doctrine/collections": "^1.5",
"doctrine/common": "^3.0.3",
Expand Down
19 changes: 19 additions & 0 deletions docs/en/reference/annotations-reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,18 @@ Optional attributes:

- **nullable**: Determines if NULL values allowed for this column. If not specified, default value is false.

- **insertable**: Boolean value to determine if the column should be
included when inserting a new row into the underlying entities table.
If not specified, default value is true.

- **updatable**: Boolean value to determine if the column should be
included when updating the row of the underlying entities table.
If not specified, default value is true.

- **generated**: An enum with the possible values ALWAYS, INSERT, NEVER. Is
used after an INSERT or UPDATE statement to determine if the database
generated this value and it needs to be fetched using a SELECT statement.

- **options**: Array of additional options:

- ``default``: The default value to set for the column if no value
Expand Down Expand Up @@ -193,6 +205,13 @@ Examples:
*/
protected $loginCount;
/**
* Generated column
* @Column(type="string", name="user_fullname", insertable=false, updatable=false)
* MySQL example: full_name char(41) GENERATED ALWAYS AS (concat(firstname,' ',lastname)),
*/
protected $fullname;
.. _annref_column_result:

@ColumnResult
Expand Down
21 changes: 21 additions & 0 deletions docs/en/reference/attributes-reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,18 @@ Optional parameters:
- **nullable**: Determines if NULL values allowed for this column.
If not specified, default value is ``false``.

- **insertable**: Boolean value to determine if the column should be
included when inserting a new row into the underlying entities table.
If not specified, default value is true.

- **updatable**: Boolean value to determine if the column should be
included when updating the row of the underlying entities table.
If not specified, default value is true.

- **generated**: An enum with the possible values ALWAYS, INSERT, NEVER. Is
used after an INSERT or UPDATE statement to determine if the database
generated this value and it needs to be fetched using a SELECT statement.

- **options**: Array of additional options:

- ``default``: The default value to set for the column if no value
Expand Down Expand Up @@ -248,6 +260,15 @@ Examples:
)]
protected $loginCount;
// MySQL example: full_name char(41) GENERATED ALWAYS AS (concat(firstname,' ',lastname)),
#[Column(
type: "string",
name: "user_fullname",
insertable: false,
updatable: false
)]
protected $fullname;
.. _attrref_cache:

#[Cache]
Expand Down
4 changes: 4 additions & 0 deletions docs/en/reference/basic-mapping.rst
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,10 @@ list:
unique key.
- ``nullable``: (optional, default FALSE) Whether the database
column is nullable.
- ``insertable``: (optional, default TRUE) Whether the database
column should be inserted.
- ``updatable``: (optional, default TRUE) Whether the database
column should be updated.
- ``enumType``: (optional, requires PHP 8.1 and ORM 2.11) The PHP enum type
name to convert the database value into.
- ``precision``: (optional, default 0) The precision for a decimal
Expand Down
5 changes: 5 additions & 0 deletions docs/en/reference/xml-mapping.rst
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,11 @@ Optional attributes:
table? Defaults to false.
- nullable - Should this field allow NULL as a value? Defaults to
false.
- insertable - Should this field be inserted? Defaults to true.
- updatable - Should this field be updated? Defaults to true.
- generated - Enum of the values ALWAYS, INSERT, NEVER that determines if
generated value must be fetched from database after INSERT or UPDATE.
Defaults to "NEVER".
- version - Should this field be used for optimistic locking? Only
works on fields with type integer or datetime.
- scale - Scale of a decimal type.
Expand Down
13 changes: 13 additions & 0 deletions doctrine-mapping.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,14 @@
</xs:restriction>
</xs:simpleType>

<xs:simpleType name="generated-type">
<xs:restriction base="xs:token">
<xs:enumeration value="NEVER"/>
<xs:enumeration value="INSERT"/>
<xs:enumeration value="ALWAYS"/>
</xs:restriction>
</xs:simpleType>

<xs:complexType name="field">
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="options" type="orm:options" minOccurs="0" />
Expand All @@ -299,6 +307,9 @@
<xs:attribute name="length" type="xs:NMTOKEN" />
<xs:attribute name="unique" type="xs:boolean" default="false" />
<xs:attribute name="nullable" type="xs:boolean" default="false" />
<xs:attribute name="insertable" type="xs:boolean" default="true" />
<xs:attribute name="updatable" type="xs:boolean" default="true" />
<xs:attribute name="generated" type="orm:generated-type" default="NEVER" />
<xs:attribute name="enum-type" type="xs:string" />
<xs:attribute name="version" type="xs:boolean" />
<xs:attribute name="column-definition" type="xs:string" />
Expand Down Expand Up @@ -623,6 +634,8 @@
<xs:attribute name="length" type="xs:NMTOKEN" />
<xs:attribute name="unique" type="xs:boolean" default="false" />
<xs:attribute name="nullable" type="xs:boolean" default="false" />
<xs:attribute name="insertable" type="xs:boolean" default="true" />
<xs:attribute name="updateable" type="xs:boolean" default="true" />
<xs:attribute name="version" type="xs:boolean" />
<xs:attribute name="column-definition" type="xs:string" />
<xs:attribute name="precision" type="xs:integer" use="optional" />
Expand Down
12 changes: 10 additions & 2 deletions lib/Doctrine/ORM/Cache/DefaultEntityHydrator.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,16 @@ public function buildCacheEntry(ClassMetadata $metadata, EntityCacheKey $key, $e
$data = $this->uow->getOriginalEntityData($entity);
$data = array_merge($data, $metadata->getIdentifierValues($entity)); // why update has no identifier values ?
if ($metadata->isVersioned) {
$data[$metadata->versionField] = $metadata->getFieldValue($entity, $metadata->versionField);
if ($metadata->requiresFetchAfterChange) {
if ($metadata->isVersioned) {
$data[$metadata->versionField] = $metadata->getFieldValue($entity, $metadata->versionField);
}

foreach ($metadata->fieldMappings as $name => $fieldMapping) {
if (isset($fieldMapping['generated'])) {
$data[$name] = $metadata->getFieldValue($entity, $name);
}
}
}

foreach ($metadata->associationMappings as $name => $assoc) {
Expand Down
4 changes: 2 additions & 2 deletions lib/Doctrine/ORM/EntityRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class EntityRepository implements ObjectRepository, Selectable
/** @var string */
protected $_entityName;

/** @var EntityManager */
/** @var EntityManagerInterface */
protected $_em;

/** @var ClassMetadata */
Expand Down Expand Up @@ -282,7 +282,7 @@ public function getClassName()
}

/**
* @return EntityManager
* @return EntityManagerInterface
*/
protected function getEntityManager()
{
Expand Down
4 changes: 2 additions & 2 deletions lib/Doctrine/ORM/Event/LifecycleEventArgs.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace Doctrine\ORM\Event;

use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\Persistence\Event\LifecycleEventArgs as BaseLifecycleEventArgs;

/**
Expand All @@ -28,7 +28,7 @@ public function getEntity()
/**
* Retrieves associated EntityManager.
*
* @return EntityManager
* @return EntityManagerInterface
*/
public function getEntityManager()
{
Expand Down
6 changes: 3 additions & 3 deletions lib/Doctrine/ORM/Event/LoadClassMetadataEventArgs.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,22 @@

namespace Doctrine\ORM\Event;

use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\Persistence\Event\LoadClassMetadataEventArgs as BaseLoadClassMetadataEventArgs;

/**
* Class that holds event arguments for a loadMetadata event.
*
* @method __construct(ClassMetadata $classMetadata, EntityManager $objectManager)
* @method __construct(ClassMetadata $classMetadata, EntityManagerInterface $objectManager)
* @method ClassMetadata getClassMetadata()
*/
class LoadClassMetadataEventArgs extends BaseLoadClassMetadataEventArgs
{
/**
* Retrieve associated EntityManager.
*
* @return EntityManager
* @return EntityManagerInterface
*/
public function getEntityManager()
{
Expand Down
5 changes: 2 additions & 3 deletions lib/Doctrine/ORM/Event/PostFlushEventArgs.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
namespace Doctrine\ORM\Event;

use Doctrine\Common\EventArgs;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityManagerInterface;

/**
Expand All @@ -15,7 +14,7 @@
*/
class PostFlushEventArgs extends EventArgs
{
/** @var EntityManager */
/** @var EntityManagerInterface */
private $em;

public function __construct(EntityManagerInterface $em)
Expand All @@ -26,7 +25,7 @@ public function __construct(EntityManagerInterface $em)
/**
* Retrieves associated EntityManager.
*
* @return EntityManager
* @return EntityManagerInterface
*/
public function getEntityManager()
{
Expand Down
5 changes: 2 additions & 3 deletions lib/Doctrine/ORM/Event/PreFlushEventArgs.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
namespace Doctrine\ORM\Event;

use Doctrine\Common\EventArgs;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityManagerInterface;

/**
Expand All @@ -15,7 +14,7 @@
*/
class PreFlushEventArgs extends EventArgs
{
/** @var EntityManager */
/** @var EntityManagerInterface */
private $em;

public function __construct(EntityManagerInterface $em)
Expand All @@ -24,7 +23,7 @@ public function __construct(EntityManagerInterface $em)
}

/**
* @return EntityManager
* @return EntityManagerInterface
*/
public function getEntityManager()
{
Expand Down
61 changes: 60 additions & 1 deletion lib/Doctrine/ORM/Id/AbstractIdGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,77 @@

namespace Doctrine\ORM\Id;

use Doctrine\Deprecations\Deprecation;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityManagerInterface;
use InvalidArgumentException;
use LogicException;

use function get_debug_type;
use function sprintf;

abstract class AbstractIdGenerator
{
/** @var bool */
private $alreadyDelegatedToGenerateId = false;

/**
* Generates an identifier for an entity.
*
* @deprecated Call {@see generateId()} instead.
*
* @param object|null $entity
*
* @return mixed
*/
public function generate(EntityManager $em, $entity)
{
if ($this->alreadyDelegatedToGenerateId) {
throw new LogicException(sprintf(
'Endless recursion detected in %s. Please implement generateId() without calling the parent implementation.',
get_debug_type($this)
));
}

Deprecation::trigger(
'doctrine/orm',
'https://github.com/doctrine/orm/pull/9325',
'%s::generate() is deprecated, call generateId() instead.',
get_debug_type($this)
);

$this->alreadyDelegatedToGenerateId = true;

try {
return $this->generateId($em, $entity);
} finally {
$this->alreadyDelegatedToGenerateId = false;
}
}

/**
* Generates an identifier for an entity.
*
* @param object|null $entity
*
* @return mixed
*/
abstract public function generate(EntityManager $em, $entity);
public function generateId(EntityManagerInterface $em, $entity)
{
Deprecation::trigger(
'doctrine/orm',
'https://github.com/doctrine/orm/pull/9325',
'Not implementing %s in %s is deprecated.',
__FUNCTION__,
get_debug_type($this)
);

if (! $em instanceof EntityManager) {
throw new InvalidArgumentException('Unsupported entity manager implementation.');
}

return $this->generate($em, $entity);
}

/**
* Gets whether this generator is a post-insert generator which means that
Expand Down
6 changes: 3 additions & 3 deletions lib/Doctrine/ORM/Id/AssignedGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace Doctrine\ORM\Id;

use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Exception\EntityMissingAssignedId;

use function get_class;
Expand All @@ -17,11 +17,11 @@ class AssignedGenerator extends AbstractIdGenerator
/**
* Returns the identifier assigned to the given entity.
*
* {@inheritDoc}
* {@inheritdoc}
*
* @throws EntityMissingAssignedId
*/
public function generate(EntityManager $em, $entity)
public function generateId(EntityManagerInterface $em, $entity)
{
$class = $em->getClassMetadata(get_class($entity));
$idFields = $class->getIdentifierFieldNames();
Expand Down
Loading

0 comments on commit 0025878

Please sign in to comment.