Skip to content

Commit

Permalink
fix: do not cast BackedEnum identifiers
Browse files Browse the repository at this point in the history
  • Loading branch information
Gwemox committed Nov 28, 2022
1 parent 139896f commit 8e2f83c
Show file tree
Hide file tree
Showing 4 changed files with 190 additions and 2 deletions.
10 changes: 8 additions & 2 deletions src/Proxy/ProxyGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -940,12 +940,18 @@ private function generateMethods(ClassMetadata $class)
if ($this->isShortIdentifierGetter($method, $class)) {
$identifier = lcfirst(substr($name, 3));
$fieldType = $class->getTypeOfField($identifier);
$cast = in_array($fieldType, ['integer', 'smallint'], true) ? '(int) ' : '';
$castToInt = in_array($fieldType, ['integer', 'smallint'], true);

$methods .= ' if ($this->__isInitialized__ === false) {' . "\n";
$methods .= ' ';
$methods .= $this->shouldProxiedMethodReturn($method) ? 'return ' : '';
$methods .= $cast . ' parent::' . $method->getName() . "();\n";

if ($castToInt) {
$methods .= '! parent::' . $method->getName() . '() instanceof \BackedEnum ';
$methods .= '? (int) parent::' . $method->getName() . '() : ';
}

$methods .= 'parent::' . $method->getName() . "();\n";
$methods .= ' }' . "\n\n";
}

Expand Down
24 changes: 24 additions & 0 deletions tests/Common/Proxy/LazyLoadableObjectWithPHP81EnumIntType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

namespace Doctrine\Tests\Common\Proxy;

class LazyLoadableObjectWithPHP81EnumIntType
{
private LazyLoadableObjectWithPHP81EnumIntTypeIdentfier $identifierFieldEnumIntType;

public function getIdentifierFieldEnumIntType(): LazyLoadableObjectWithPHP81EnumIntTypeIdentfier
{
return $this->identifierFieldEnumIntType;
}

public static function getFooIdentifier(): LazyLoadableObjectWithPHP81EnumIntTypeIdentfier
{
return LazyLoadableObjectWithPHP81EnumIntTypeIdentfier::FOO;
}
}

enum LazyLoadableObjectWithPHP81EnumIntTypeIdentfier: int
{
case FOO = 1;
case BAR = 2;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
<?php
declare(strict_types=1);

namespace Doctrine\Tests\Common\Proxy;

use BadMethodCallException;
use Doctrine\Persistence\Mapping\ClassMetadata;
use ReflectionClass;
use function array_keys;

class LazyLoadableObjectWithPHP81EnumIntTypeClassMetadata implements ClassMetadata
{
/** @var ReflectionClass */
protected $reflectionClass;

/** @var array<string,bool> */
protected $identifier = [
'identifierFieldEnumIntType' => true,
];

/** @var array<string,bool> */
protected $fields = [
'identifierFieldEnumIntType' => true,
];

/**
* {@inheritDoc}
*/
public function getName()
{
return $this->getReflectionClass()->getName();
}

/**
* {@inheritDoc}
*/
public function getIdentifier()
{
return array_keys($this->identifier);
}

/**
* {@inheritDoc}
*/
public function getReflectionClass()
{
if ($this->reflectionClass === null) {
$this->reflectionClass = new ReflectionClass(__NAMESPACE__ . '\LazyLoadableObjectWithPHP81EnumIntType');
}

return $this->reflectionClass;
}

/**
* {@inheritDoc}
*/
public function isIdentifier($fieldName)
{
return isset($this->identifier[$fieldName]);
}

/**
* {@inheritDoc}
*/
public function hasField($fieldName)
{
return isset($this->fields[$fieldName]);
}

/**
* {@inheritDoc}
*/
public function hasAssociation($fieldName)
{
return false;
}

/**
* {@inheritDoc}
*/
public function isSingleValuedAssociation($fieldName)
{
throw new BadMethodCallException('not implemented');
}

/**
* {@inheritDoc}
*/
public function isCollectionValuedAssociation($fieldName)
{
throw new BadMethodCallException('not implemented');
}

/**
* {@inheritDoc}
*/
public function getFieldNames()
{
return array_keys($this->fields);
}

/**
* {@inheritDoc}
*/
public function getIdentifierFieldNames()
{
return $this->getIdentifier();
}

/**
* {@inheritDoc}
*/
public function getAssociationNames()
{
return [];
}

/**
* {@inheritDoc}
*/
public function getTypeOfField($fieldName)
{
return 'integer';
}

/**
* {@inheritDoc}
*/
public function getAssociationTargetClass($assocName)
{
throw new BadMethodCallException('not implemented');
}

/**
* {@inheritDoc}
*/
public function isAssociationInverseSide($assocName)
{
throw new BadMethodCallException('not implemented');
}

/**
* {@inheritDoc}
*/
public function getAssociationMappedByTargetField($assocName)
{
throw new BadMethodCallException('not implemented');
}

/**
* {@inheritDoc}
*/
public function getIdentifierValues($object)
{
throw new BadMethodCallException('not implemented');
}
}
1 change: 1 addition & 0 deletions tests/Common/Proxy/ProxyLogicIdentifierGetterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ public function methodsForWhichLazyLoadingShouldBeDisabled()
}

if (PHP_VERSION_ID >= 80100) {
$data[] = [new LazyLoadableObjectWithPHP81EnumIntTypeClassMetadata(), 'identifierFieldEnumIntType', LazyLoadableObjectWithPHP81EnumIntType::getFooIdentifier()];
$data[] = [new LazyLoadableObjectWithPHP81IntersectionTypeClassMetadata(), 'identifierFieldIntersectionType', new class extends \stdClass implements \Stringable {
public function __toString(): string
{
Expand Down

0 comments on commit 8e2f83c

Please sign in to comment.