diff --git a/Neos.Cache/Classes/Backend/PdoBackend.php b/Neos.Cache/Classes/Backend/PdoBackend.php
index 99ef0e8dac..839d098ba2 100644
--- a/Neos.Cache/Classes/Backend/PdoBackend.php
+++ b/Neos.Cache/Classes/Backend/PdoBackend.php
@@ -526,7 +526,7 @@ protected function createCacheTables(): void
{
$this->connect();
try {
- PdoHelper::importSql($this->databaseHandle, $this->pdoDriver, __DIR__ . '/../../Resources/Private/DDL.sql');
+ PdoHelper::importSql($this->databaseHandle, $this->pdoDriver, __DIR__ . '/../../Resources/Private/DDL.sql', ['###CACHE_TABLE_NAME###' => $this->cacheTableName, '###TAGS_TABLE_NAME###' => $this->tagsTableName]);
} catch (\PDOException $exception) {
throw new Exception('Could not create cache tables with DSN "' . $this->dataSourceName . '". PDO error: ' . $exception->getMessage(), 1259576985);
}
@@ -648,6 +648,7 @@ public function setup(): Result
$this->connect();
} catch (Exception $exception) {
$result->addError(new Error($exception->getMessage(), (int)$exception->getCode(), [], 'Failed'));
+ return $result;
}
if ($this->pdoDriver === 'sqlite') {
$result->addNotice(new Notice('SQLite database tables are created automatically and don\'t need to be set up'));
diff --git a/Neos.Cache/Classes/Backend/TaggableMultiBackend.php b/Neos.Cache/Classes/Backend/TaggableMultiBackend.php
index 0e3915ad71..4c1c0a0489 100644
--- a/Neos.Cache/Classes/Backend/TaggableMultiBackend.php
+++ b/Neos.Cache/Classes/Backend/TaggableMultiBackend.php
@@ -43,17 +43,17 @@ protected function buildSubBackend(string $backendClassName, array $backendOptio
public function flushByTag(string $tag): int
{
$this->prepareBackends();
- $count = 0;
+ $flushed = 0;
foreach ($this->backends as $backend) {
try {
- $count |= $backend->flushByTag($tag);
+ $flushed += $backend->flushByTag($tag);
} catch (Throwable $throwable) {
$this->logger?->error('Failed flushing cache by tag using backend ' . get_class($backend) . ' in ' . get_class($this) . ': ' . $this->throwableStorage?->logThrowable($throwable), LogEnvironment::fromMethodName(__METHOD__));
$this->handleError($throwable);
$this->removeUnhealthyBackend($backend);
}
}
- return $count;
+ return $flushed;
}
/**
diff --git a/Neos.Cache/Classes/Psr/Cache/CachePool.php b/Neos.Cache/Classes/Psr/Cache/CachePool.php
index 16a989319b..998b0f4653 100644
--- a/Neos.Cache/Classes/Psr/Cache/CachePool.php
+++ b/Neos.Cache/Classes/Psr/Cache/CachePool.php
@@ -27,7 +27,7 @@ class CachePool implements CacheItemPoolInterface
/**
* Pattern an entry identifier must match.
*/
- const PATTERN_ENTRYIDENTIFIER = '/^[a-zA-Z0-9_%\-&]{1,250}$/';
+ const PATTERN_ENTRYIDENTIFIER = '/^[a-zA-Z0-9_%\-&\.]{1,250}$/';
/**
* @var BackendInterface
diff --git a/Neos.Cache/Resources/Private/DDL.sql b/Neos.Cache/Resources/Private/DDL.sql
index c19211d534..5e8967256d 100644
--- a/Neos.Cache/Resources/Private/DDL.sql
+++ b/Neos.Cache/Resources/Private/DDL.sql
@@ -1,6 +1,6 @@
BEGIN;
-CREATE TABLE "cache" (
+CREATE TABLE "###CACHE_TABLE_NAME###" (
"identifier" VARCHAR(250) NOT NULL,
"cache" VARCHAR(250) NOT NULL,
"context" VARCHAR(150) NOT NULL,
@@ -10,13 +10,13 @@ CREATE TABLE "cache" (
PRIMARY KEY ("identifier", "cache", "context")
);
-CREATE TABLE "tags" (
+CREATE TABLE "###TAGS_TABLE_NAME###" (
"identifier" VARCHAR(250) NOT NULL,
"cache" VARCHAR(250) NOT NULL,
"context" VARCHAR(150) NOT NULL,
"tag" VARCHAR(250) NOT NULL
);
-CREATE INDEX "identifier" ON "tags" ("identifier", "cache", "context");
-CREATE INDEX "tag" ON "tags" ("tag");
+CREATE INDEX "identifier" ON "###TAGS_TABLE_NAME###" ("identifier", "cache", "context");
+CREATE INDEX "tag" ON "###TAGS_TABLE_NAME###" ("tag");
COMMIT;
diff --git a/Neos.Cache/Resources/Private/mysql.DDL.sql b/Neos.Cache/Resources/Private/mysql.DDL.sql
index 89576116cd..6be26bf5e8 100644
--- a/Neos.Cache/Resources/Private/mysql.DDL.sql
+++ b/Neos.Cache/Resources/Private/mysql.DDL.sql
@@ -1,6 +1,6 @@
BEGIN;
-CREATE TABLE "cache" (
+CREATE TABLE "###CACHE_TABLE_NAME###" (
"identifier" VARCHAR(250) NOT NULL,
"cache" VARCHAR(250) NOT NULL,
"context" VARCHAR(150) NOT NULL,
@@ -10,7 +10,7 @@ CREATE TABLE "cache" (
PRIMARY KEY ("identifier", "cache", "context")
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-CREATE TABLE "tags" (
+CREATE TABLE "###TAGS_TABLE_NAME###" (
"pk" INT NOT NULL AUTO_INCREMENT,
"identifier" VARCHAR(250) NOT NULL,
"cache" VARCHAR(250) NOT NULL,
@@ -18,7 +18,7 @@ CREATE TABLE "tags" (
"tag" VARCHAR(250) NOT NULL,
PRIMARY KEY ("pk")
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-CREATE INDEX "identifier" ON tags ("identifier", "cache", "context");
-CREATE INDEX "tag" ON "tags" ("tag");
+CREATE INDEX "identifier" ON ###TAGS_TABLE_NAME### ("identifier", "cache", "context");
+CREATE INDEX "tag" ON "###TAGS_TABLE_NAME###" ("tag");
COMMIT;
diff --git a/Neos.Cache/Resources/Private/pgsql.DDL.sql b/Neos.Cache/Resources/Private/pgsql.DDL.sql
index aa5be82ca5..96e310cac9 100644
--- a/Neos.Cache/Resources/Private/pgsql.DDL.sql
+++ b/Neos.Cache/Resources/Private/pgsql.DDL.sql
@@ -1,6 +1,6 @@
BEGIN;
-CREATE TABLE "cache" (
+CREATE TABLE "###CACHE_TABLE_NAME###" (
"identifier" VARCHAR(250) NOT NULL,
"cache" VARCHAR(250) NOT NULL,
"context" VARCHAR(150) NOT NULL,
@@ -10,13 +10,13 @@ CREATE TABLE "cache" (
PRIMARY KEY ("identifier", "cache", "context")
);
-CREATE TABLE "tags" (
+CREATE TABLE "###TAGS_TABLE_NAME###" (
"identifier" VARCHAR(250) NOT NULL,
"cache" VARCHAR(250) NOT NULL,
"context" VARCHAR(150) NOT NULL,
"tag" VARCHAR(250) NOT NULL
);
-CREATE INDEX "identifier" ON "tags" ("identifier", "cache", "context");
-CREATE INDEX "tag" ON "tags" ("tag");
+CREATE INDEX "identifier" ON "###TAGS_TABLE_NAME###" ("identifier", "cache", "context");
+CREATE INDEX "tag" ON "###TAGS_TABLE_NAME###" ("tag");
COMMIT;
diff --git a/Neos.Cache/Tests/Unit/Backend/TaggableMultiBackendTest.php b/Neos.Cache/Tests/Unit/Backend/TaggableMultiBackendTest.php
new file mode 100644
index 0000000000..f99d99d010
--- /dev/null
+++ b/Neos.Cache/Tests/Unit/Backend/TaggableMultiBackendTest.php
@@ -0,0 +1,48 @@
+getMockBuilder(NullBackend::class);
+ $firstNullBackendMock = $mockBuilder->getMock();
+ $secondNullBackendMock = $mockBuilder->getMock();
+ $thirdNullBackendMock = $mockBuilder->getMock();
+
+ $firstNullBackendMock->expects(self::once())->method('flushByTag')->with('foo')->willReturn(2);
+ $secondNullBackendMock->expects(self::once())->method('flushByTag')->with('foo')->willThrowException(new \RuntimeException());
+ $thirdNullBackendMock->expects(self::once())->method('flushByTag')->with('foo')->willReturn(3);
+
+ $multiBackend = new TaggableMultiBackend($this->getEnvironmentConfiguration(), []);
+ $this->inject($multiBackend, 'backends', [$firstNullBackendMock, $secondNullBackendMock, $thirdNullBackendMock]);
+ $this->inject($multiBackend, 'initialized', true);
+
+ $result = $multiBackend->flushByTag('foo');
+ self::assertSame(5, $result);
+ }
+
+ /**
+ * @return EnvironmentConfiguration
+ */
+ public function getEnvironmentConfiguration(): EnvironmentConfiguration
+ {
+ return new EnvironmentConfiguration(
+ __DIR__ . '~Testing',
+ 'vfs://Foo/',
+ 255
+ );
+ }
+}
diff --git a/Neos.Cache/Tests/Unit/Psr/Cache/CachePoolTest.php b/Neos.Cache/Tests/Unit/Psr/Cache/CachePoolTest.php
index 578a2d395f..5ca532204c 100644
--- a/Neos.Cache/Tests/Unit/Psr/Cache/CachePoolTest.php
+++ b/Neos.Cache/Tests/Unit/Psr/Cache/CachePoolTest.php
@@ -12,6 +12,7 @@
*/
use Neos\Cache\Backend\AbstractBackend;
+use Neos\Cache\Backend\BackendInterface;
use Neos\Cache\Psr\Cache\CachePool;
use Neos\Cache\Psr\Cache\CacheItem;
use Neos\Cache\Psr\InvalidArgumentException;
@@ -23,6 +24,57 @@
*/
class CachePoolTest extends BaseTestCase
{
+ public function validIdentifiersDataProvider(): array
+ {
+ return [
+ ['short'],
+ ['SomeValidIdentifier'],
+ ['withNumbers0123456789'],
+ ['withUnder_score'],
+ ['with.dot'],
+
+ // The following tests exceed the minimum requirements of the PSR-6 keys (@see https://www.php-fig.org/psr/psr-6/#definitions)
+ ['dashes-are-allowed'],
+ ['percent%sign'],
+ ['amper&sand'],
+ ['a-string-that-exceeds-the-psr-minimum-maxlength-of-sixtyfour-but-is-shorter-than-twohundredandfifty-characters'],
+ ];
+ }
+
+ /**
+ * @test
+ * @dataProvider validIdentifiersDataProvider
+ */
+ public function validIdentifiers(string $identifier): void
+ {
+ $mockBackend = $this->getMockBuilder(BackendInterface::class)->getMock();
+ $cachePool = new CachePool($identifier, $mockBackend);
+ self::assertInstanceOf(CachePool::class, $cachePool);
+ }
+
+ public function invalidIdentifiersDataProvider(): array
+ {
+ return [
+ [''],
+ ['späcialcharacters'],
+ ['a-string-that-exceeds-the-maximum-allowed-length-of-twohundredandfifty-characters-which-is-pretty-large-as-it-turns-out-so-i-repeat-a-string-that-exceeds-the-maximum-allowed-length-of-twohundredandfifty-characters-still-not-there-wow-crazy-flow-rocks-though'],
+ ];
+ }
+
+ /**
+ * @test
+ * @dataProvider invalidIdentifiersDataProvider
+ */
+ public function invalidIdentifiers(string $identifier): void
+ {
+ $mockBackend = $this->getMockBuilder(BackendInterface::class)->getMock();
+
+ $this->expectException(\InvalidArgumentException::class);
+ new CachePool($identifier, $mockBackend);
+ }
+
+
+
/**
* @test
*/
diff --git a/Neos.Flow/Classes/Core/Booting/Scripts.php b/Neos.Flow/Classes/Core/Booting/Scripts.php
index 3c8214eda3..9b352de3c6 100644
--- a/Neos.Flow/Classes/Core/Booting/Scripts.php
+++ b/Neos.Flow/Classes/Core/Booting/Scripts.php
@@ -60,6 +60,9 @@
*/
class Scripts
{
+ /** @var string */
+ protected static $builtPhpCommand = null;
+
/**
* Initializes the Class Loader
*
@@ -773,6 +776,10 @@ protected static function buildSubprocessCommand(string $commandIdentifier, arra
*/
public static function buildPhpCommand(array $settings): string
{
+ if (isset(static::$builtPhpCommand)) {
+ return static::$builtPhpCommand;
+ }
+
$subRequestEnvironmentVariables = [
'FLOW_ROOTPATH' => FLOW_PATH_ROOT,
'FLOW_PATH_TEMPORARY_BASE' => FLOW_PATH_TEMPORARY_BASE,
@@ -810,7 +817,7 @@ public static function buildPhpCommand(array $settings): string
static::ensureWebSubrequestsUseCurrentlyRunningPhpVersion($command);
- return $command;
+ return static::$builtPhpCommand = $command;
}
/**
@@ -867,8 +874,13 @@ protected static function ensureCLISubrequestsUseCurrentlyRunningPhpBinary($phpB
);
}
- exec(PHP_BINARY . ' -r "echo realpath(PHP_BINARY);"', $output);
- $realPhpBinary = $output[0];
+ // stfu to avoid possible open_basedir restriction https://github.com/neos/flow-development-collection/pull/2491
+ $realPhpBinary = @realpath(PHP_BINARY);
+ if ($realPhpBinary === false) {
+ // bypass with exec open_basedir restriction
+ exec(PHP_BINARY . ' -r "echo realpath(PHP_BINARY);"', $output);
+ $realPhpBinary = $output[0];
+ }
if (strcmp($realPhpBinary, $configuredPhpBinaryPathAndFilename) !== 0) {
throw new Exception\SubProcessException(sprintf(
'You are running the Flow CLI with a PHP binary different from the one Flow is configured to use internally. ' .
diff --git a/Neos.Flow/Classes/Mvc/Dispatcher.php b/Neos.Flow/Classes/Mvc/Dispatcher.php
index ebd9552960..b3ba774fbd 100644
--- a/Neos.Flow/Classes/Mvc/Dispatcher.php
+++ b/Neos.Flow/Classes/Mvc/Dispatcher.php
@@ -27,6 +27,7 @@
use Neos\Flow\Security\Exception\AccessDeniedException;
use Neos\Flow\Security\Exception\AuthenticationRequiredException;
use Neos\Flow\Security\Exception\MissingConfigurationException;
+use Psr\Log\LoggerInterface;
/**
* Dispatches requests to the controller which was specified by the request and
@@ -105,7 +106,7 @@ public function dispatch(ActionRequest $request, ActionResponse $response)
// Rethrow as the SecurityEntryPoint middleware will take care of the rest
throw $exception->attachInterceptedRequest($request);
} catch (AccessDeniedException $exception) {
- /** @var PsrLoggerFactoryInterface $securityLogger */
+ /** @var LoggerInterface $securityLogger */
$securityLogger = $this->objectManager->get(PsrLoggerFactoryInterface::class)->get('securityLogger');
$securityLogger->warning('Access denied', LogEnvironment::fromMethodName(__METHOD__));
throw $exception;
diff --git a/Neos.Flow/Classes/Mvc/Routing/Dto/RouteTags.php b/Neos.Flow/Classes/Mvc/Routing/Dto/RouteTags.php
index 6853915aca..44a1833079 100644
--- a/Neos.Flow/Classes/Mvc/Routing/Dto/RouteTags.php
+++ b/Neos.Flow/Classes/Mvc/Routing/Dto/RouteTags.php
@@ -71,7 +71,9 @@ public static function createFromTag(string $tag): self
*/
public static function createFromArray(array $tags): self
{
- array_walk($tags, 'static::validateTag');
+ foreach ($tags as $tag) {
+ self::validateTag($tag);
+ }
return new static($tags);
}
diff --git a/Neos.Flow/Classes/ObjectManagement/DependencyInjection/ProxyClassBuilder.php b/Neos.Flow/Classes/ObjectManagement/DependencyInjection/ProxyClassBuilder.php
index 848fca8471..4e5dec36e2 100644
--- a/Neos.Flow/Classes/ObjectManagement/DependencyInjection/ProxyClassBuilder.php
+++ b/Neos.Flow/Classes/ObjectManagement/DependencyInjection/ProxyClassBuilder.php
@@ -291,7 +291,7 @@ protected function buildConstructorInjectionCode(Configuration $objectConfigurat
} else {
if (strpos($argumentValue, '.') !== false) {
$settingPath = explode('.', $argumentValue);
- $settings = Arrays::getValueByPath($this->configurationManager->getConfiguration(ConfigurationManager::CONFIGURATION_TYPE_SETTINGS), array_shift($settingPath));
+ $settings = $this->configurationManager->getConfiguration(ConfigurationManager::CONFIGURATION_TYPE_SETTINGS, array_shift($settingPath));
$argumentValue = Arrays::getValueByPath($settings, $settingPath);
}
if (!isset($this->objectConfigurations[$argumentValue])) {
@@ -629,7 +629,7 @@ protected function buildMethodParametersCode(array $argumentConfigurations)
} else {
if (strpos($argumentValue, '.') !== false) {
$settingPath = explode('.', $argumentValue);
- $settings = Arrays::getValueByPath($this->configurationManager->getConfiguration(ConfigurationManager::CONFIGURATION_TYPE_SETTINGS), array_shift($settingPath));
+ $settings = $this->configurationManager->getConfiguration(ConfigurationManager::CONFIGURATION_TYPE_SETTINGS, array_shift($settingPath));
$argumentValue = Arrays::getValueByPath($settings, $settingPath);
}
$preparedArguments[] = '\Neos\Flow\Core\Bootstrap::$staticObjectManager->get(\'' . $argumentValue . '\')';
diff --git a/Neos.Flow/Classes/Persistence/Doctrine/ObjectValidationAndDeDuplicationListener.php b/Neos.Flow/Classes/Persistence/Doctrine/ObjectValidationAndDeDuplicationListener.php
index 3e9f7a746c..9b6eb1c186 100644
--- a/Neos.Flow/Classes/Persistence/Doctrine/ObjectValidationAndDeDuplicationListener.php
+++ b/Neos.Flow/Classes/Persistence/Doctrine/ObjectValidationAndDeDuplicationListener.php
@@ -1,4 +1,5 @@
getObjectManager();
+ $unitOfWork = $entityManager->getUnitOfWork();
+ $objectToPersist = $eventArgs->getObject();
+
+ $classMetadata = $entityManager->getClassMetadata(get_class($objectToPersist));
+ $className = $classMetadata->rootEntityName;
+
+ $classSchema = $this->reflectionService->getClassSchema($className);
+ $identityMapOfClassName = $unitOfWork->getIdentityMap()[$className] ?? [];
+
+ if ($classSchema !== null && $classSchema->getModelType() === ClassSchema::MODELTYPE_VALUEOBJECT) {
+ foreach ($identityMapOfClassName as $objectInIdentityMap) {
+ if ($this->persistenceManager->getIdentifierByObject($objectInIdentityMap) === $this->persistenceManager->getIdentifierByObject($objectToPersist)) {
+ $unitOfWork->removeFromIdentityMap($objectInIdentityMap);
+ }
+ }
+ }
+ }
+
/**
* An onFlush event listener used to act upon persistence.
*
diff --git a/Neos.Flow/Configuration/Settings.Persistence.yaml b/Neos.Flow/Configuration/Settings.Persistence.yaml
index 2b3766c60c..4bf261f976 100644
--- a/Neos.Flow/Configuration/Settings.Persistence.yaml
+++ b/Neos.Flow/Configuration/Settings.Persistence.yaml
@@ -44,7 +44,7 @@ Neos:
events: ['onFlush']
listener: 'Neos\Flow\Persistence\Doctrine\AllowedObjectsListener'
'Neos\Flow\Persistence\Doctrine\ObjectValidationAndDeDuplicationListener':
- events: ['onFlush']
+ events: ['onFlush', 'prePersist']
listener: 'Neos\Flow\Persistence\Doctrine\ObjectValidationAndDeDuplicationListener'
# Doctrine ORM Second Level Cache configuration.
diff --git a/Neos.Flow/Resources/Private/Translations/de/ValidationErrors.xlf b/Neos.Flow/Resources/Private/Translations/de/ValidationErrors.xlf
index 4f81d1844d..d22df2f48a 100644
--- a/Neos.Flow/Resources/Private/Translations/de/ValidationErrors.xlf
+++ b/Neos.Flow/Resources/Private/Translations/de/ValidationErrors.xlf
@@ -130,9 +130,9 @@
Eine gültige Dezimalzahl wird erwartet
-
+
- Der Wert entspricht nicht den Muster. Erhalten: {0}
+ Der Wert entspricht nicht dem Muster. Erhalten: {0}
diff --git a/Neos.Flow/Tests/Unit/Core/Booting/ScriptsTest.php b/Neos.Flow/Tests/Unit/Core/Booting/ScriptsTest.php
index 2db985361e..3088f3fe4a 100644
--- a/Neos.Flow/Tests/Unit/Core/Booting/ScriptsTest.php
+++ b/Neos.Flow/Tests/Unit/Core/Booting/ScriptsTest.php
@@ -37,6 +37,8 @@ protected static function ensureWebSubrequestsUseCurrentlyRunningPhpVersion($php
public static function buildSubprocessCommand(string $commandIdentifier, array $settings, array $commandArguments = []): string
{
+ // clear cache for testing
+ static::$builtPhpCommand = null;
return parent::buildSubprocessCommand($commandIdentifier, $settings, $commandArguments);
}
}
diff --git a/Neos.Utility.Arrays/Classes/Arrays.php b/Neos.Utility.Arrays/Classes/Arrays.php
index d09777dba4..984c5a4b3a 100644
--- a/Neos.Utility.Arrays/Classes/Arrays.php
+++ b/Neos.Utility.Arrays/Classes/Arrays.php
@@ -194,12 +194,12 @@ public static function array_reduce(array $array, string $function, $initial = n
/**
* Returns the value of a nested array by following the specifed path.
*
- * @param array &$array The array to traverse as a reference
+ * @param array $array The array to traverse
* @param array|string $path The path to follow. Either a simple array of keys or a string in the format 'foo.bar.baz'
* @return mixed The value found, NULL if the path didn't exist (note there is no way to distinguish between a found NULL value and "path not found")
* @throws \InvalidArgumentException
*/
- public static function getValueByPath(array &$array, $path)
+ public static function getValueByPath(array $array, $path)
{
if (is_string($path)) {
$path = explode('.', $path);
diff --git a/Neos.Utility.Pdo/Classes/PdoHelper.php b/Neos.Utility.Pdo/Classes/PdoHelper.php
index 4836bb8854..873ef34621 100644
--- a/Neos.Utility.Pdo/Classes/PdoHelper.php
+++ b/Neos.Utility.Pdo/Classes/PdoHelper.php
@@ -33,9 +33,10 @@ abstract class PdoHelper
* @param \PDO $databaseHandle
* @param string $pdoDriver
* @param string $pathAndFilename
+ * @param array $replacePairs every key in this array will be replaced with the corresponding value in the loaded SQL (example: ['###CACHE_TABLE_NAME###' => 'caches', '###TAGS_TABLE_NAME###' => 'tags'])
* @return void
*/
- public static function importSql(\PDO $databaseHandle, string $pdoDriver, string $pathAndFilename)
+ public static function importSql(\PDO $databaseHandle, string $pdoDriver, string $pathAndFilename, array $replacePairs = [])
{
$path = dirname($pathAndFilename);
$filename = basename($pathAndFilename);
@@ -52,7 +53,7 @@ public static function importSql(\PDO $databaseHandle, string $pdoDriver, string
$statement = '';
foreach ($sql as $line) {
- $statement .= ' ' . trim($line);
+ $statement .= ' ' . trim(strtr($line, $replacePairs));
if (substr($statement, -1) === ';') {
$databaseHandle->exec($statement);
$statement = '';
diff --git a/composer.json b/composer.json
index 175f1c1b71..ddfb8a4abe 100644
--- a/composer.json
+++ b/composer.json
@@ -22,7 +22,7 @@
"psr/http-server-handler": "^1.0",
"psr/http-client": "^1.0",
"ramsey/uuid": "^3.0 || ^4.0",
- "doctrine/orm": "^2.9.3 <2.16.0",
+ "doctrine/orm": "^2.9.3",
"doctrine/migrations": "^3.0",
"doctrine/dbal": "^2.13",
"doctrine/common": "^3.0.3",