TYPO3 v15 dev-main snapshot ()
This commit is contained in:
@@ -0,0 +1,149 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
namespace TYPO3\CMS\Core\DataHandling\Model;
|
||||
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* CorrelationId representation
|
||||
*
|
||||
* @todo Check internal state during v10 development
|
||||
* @internal
|
||||
*/
|
||||
class CorrelationId implements \JsonSerializable
|
||||
{
|
||||
protected const DEFAULT_VERSION = 1;
|
||||
protected const PATTERN_V1 = '#^(?P<flags>[[:xdigit:]]{4})\$(?:(?P<scope>[[:alnum:]_-]+):)?(?P<subject>[[:alnum:]_-]+)(?P<aspects>(?:\/[[:alnum:]._-]+)*)$#';
|
||||
protected int $version = self::DEFAULT_VERSION;
|
||||
protected ?string $scope = null;
|
||||
protected int $capabilities = 0;
|
||||
protected ?string $subject = null;
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
protected array $aspects = [];
|
||||
|
||||
public static function forScope(string $scope): self
|
||||
{
|
||||
$target = static::create();
|
||||
$target->scope = $scope;
|
||||
return $target;
|
||||
}
|
||||
|
||||
public static function forSubject(string $subject, string ...$aspects): self
|
||||
{
|
||||
return static::create()
|
||||
->withSubject($subject)
|
||||
->withAspects(...$aspects);
|
||||
}
|
||||
|
||||
public static function fromString(string $correlationId): self
|
||||
{
|
||||
if (!preg_match(self::PATTERN_V1, $correlationId, $matches, PREG_UNMATCHED_AS_NULL)) {
|
||||
throw new \InvalidArgumentException('Unknown format', 1569620858);
|
||||
}
|
||||
|
||||
$flags = hexdec($matches['flags']);
|
||||
$aspects = $matches['aspects'] === '' ? [] : explode('/', ltrim($matches['aspects'], '/'));
|
||||
$target = static::create()
|
||||
->withSubject($matches['subject'])
|
||||
->withAspects(...$aspects);
|
||||
$target->scope = $matches['scope'] ?? null;
|
||||
$target->version = $flags >> 10;
|
||||
$target->capabilities = $flags & ((1 << 10) - 1);
|
||||
return $target;
|
||||
}
|
||||
|
||||
protected static function create(): self
|
||||
{
|
||||
return GeneralUtility::makeInstance(static::class);
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
if ($this->subject === null) {
|
||||
throw new \LogicException('Cannot serialize for empty subject', 1569668681);
|
||||
}
|
||||
return $this->serialize();
|
||||
}
|
||||
|
||||
public function jsonSerialize(): string
|
||||
{
|
||||
return (string)$this;
|
||||
}
|
||||
|
||||
public function withSubject(string $subject): self
|
||||
{
|
||||
if ($this->subject === $subject) {
|
||||
return $this;
|
||||
}
|
||||
$target = clone $this;
|
||||
$target->subject = $subject;
|
||||
return $target;
|
||||
}
|
||||
|
||||
public function withAspects(string ...$aspects): self
|
||||
{
|
||||
if ($this->aspects === $aspects) {
|
||||
return $this;
|
||||
}
|
||||
$target = clone $this;
|
||||
$target->aspects = $aspects;
|
||||
return $target;
|
||||
}
|
||||
|
||||
public function getScope(): ?string
|
||||
{
|
||||
return $this->scope;
|
||||
}
|
||||
|
||||
public function getSubject(): ?string
|
||||
{
|
||||
return $this->subject;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getAspects(): array
|
||||
{
|
||||
return $this->aspects;
|
||||
}
|
||||
|
||||
/**
|
||||
* v1 specs (eBNF)
|
||||
* + FLAGS "$" [ SCOPE ":" ] SUBJECT { "/" ASPECT }
|
||||
* + FLAGS ::= XDIGIT (* 16-bit integer big-endian)
|
||||
* + SCOPE ::= ALNUM { ALNUM }
|
||||
* + SUBJECT ::= ALNUM { ALNUM }
|
||||
* + ASPECT ::= ( ALNUM | '.' | '_' | '-' ) { ( ALNUM | '.' | '_' | '-' ) }
|
||||
*/
|
||||
protected function serialize(): string
|
||||
{
|
||||
// 6-bit version 10-bit capabilities
|
||||
$flags = $this->version << 10 + $this->capabilities;
|
||||
return sprintf(
|
||||
'%s$%s%s%s',
|
||||
bin2hex(pack('n', $flags)),
|
||||
$this->scope ? $this->scope . ':' : '',
|
||||
$this->subject,
|
||||
$this->aspects ? '/' . implode('/', $this->aspects) : ''
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
namespace TYPO3\CMS\Core\DataHandling\Model;
|
||||
|
||||
/**
|
||||
* Represents the context of an entity
|
||||
*
|
||||
* A context defines a "variant" of an entity, currently by its language and workspace assignment. The EntityContext
|
||||
* is bound to a RecordState.
|
||||
*/
|
||||
class EntityContext
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $workspaceId = 0;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $languageId = 0;
|
||||
|
||||
public function getWorkspaceId(): int
|
||||
{
|
||||
return $this->workspaceId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return static
|
||||
*/
|
||||
public function withWorkspaceId(int $workspaceId): self
|
||||
{
|
||||
if ($this->workspaceId === $workspaceId) {
|
||||
return $this;
|
||||
}
|
||||
$target = clone $this;
|
||||
$target->workspaceId = $workspaceId;
|
||||
return $target;
|
||||
}
|
||||
|
||||
public function getLanguageId(): int
|
||||
{
|
||||
return $this->languageId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return static
|
||||
*/
|
||||
public function withLanguageId(int $languageId): self
|
||||
{
|
||||
if ($this->languageId === $languageId) {
|
||||
return $this;
|
||||
}
|
||||
$target = clone $this;
|
||||
$target->languageId = $languageId;
|
||||
return $target;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
namespace TYPO3\CMS\Core\DataHandling\Model;
|
||||
|
||||
/**
|
||||
* Interface describing pointers to an entity
|
||||
*/
|
||||
interface EntityPointer
|
||||
{
|
||||
public function getName(): string;
|
||||
|
||||
public function getIdentifier(): string;
|
||||
|
||||
public function isNode(): bool;
|
||||
|
||||
public function isEqualTo(EntityPointer $other): bool;
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
namespace TYPO3\CMS\Core\DataHandling\Model;
|
||||
|
||||
/**
|
||||
* An EntityPointerLink is used to connect EntityPointer instances
|
||||
*/
|
||||
class EntityPointerLink
|
||||
{
|
||||
/**
|
||||
* @var EntityPointer
|
||||
*/
|
||||
protected $subject;
|
||||
|
||||
/**
|
||||
* @var EntityPointerLink|null
|
||||
*/
|
||||
protected $ancestor;
|
||||
|
||||
public function __construct(EntityPointer $subject)
|
||||
{
|
||||
$this->subject = $subject;
|
||||
}
|
||||
|
||||
public function getSubject(): EntityPointer
|
||||
{
|
||||
return $this->subject;
|
||||
}
|
||||
|
||||
public function getHead(): EntityPointerLink
|
||||
{
|
||||
$head = $this;
|
||||
while ($head->ancestor !== null) {
|
||||
$head = $head->ancestor;
|
||||
}
|
||||
return $head;
|
||||
}
|
||||
|
||||
public function getAncestor(): ?EntityPointerLink
|
||||
{
|
||||
return $this->ancestor;
|
||||
}
|
||||
|
||||
public function withAncestor(EntityPointerLink $ancestor): self
|
||||
{
|
||||
if ($this->ancestor === $ancestor) {
|
||||
return $this;
|
||||
}
|
||||
$target = clone $this;
|
||||
$target->ancestor = $ancestor;
|
||||
return $target;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
namespace TYPO3\CMS\Core\DataHandling\Model;
|
||||
|
||||
/**
|
||||
* The EntityUidPointer represents the concrete origin of the entity
|
||||
*/
|
||||
class EntityUidPointer implements EntityPointer
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $name;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $identifier;
|
||||
|
||||
public function __construct(string $name, string $identifier)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->identifier = $identifier;
|
||||
}
|
||||
|
||||
public function getName(): string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function getIdentifier(): string
|
||||
{
|
||||
return $this->identifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return static
|
||||
*/
|
||||
public function withUid(string $identifier): self
|
||||
{
|
||||
if ($this->identifier === $identifier) {
|
||||
return $this;
|
||||
}
|
||||
$target = clone $this;
|
||||
$target->identifier = $identifier;
|
||||
return $target;
|
||||
}
|
||||
|
||||
public function isNode(): bool
|
||||
{
|
||||
return $this->name === 'pages';
|
||||
}
|
||||
|
||||
public function isEqualTo(EntityPointer $other): bool
|
||||
{
|
||||
return $this->identifier === $other->getIdentifier()
|
||||
&& $this->name === $other->getName();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
namespace TYPO3\CMS\Core\DataHandling\Model;
|
||||
|
||||
use TYPO3\CMS\Core\Utility\MathUtility;
|
||||
|
||||
/**
|
||||
* A RecordState is an abstract description of a record that consists of
|
||||
*
|
||||
* - an EntityContext describing the "variant" of a record
|
||||
* - an EntityPointer that describes the node where the record is stored
|
||||
* - an EntityUidPointer of the record the RecordState instance represents
|
||||
*
|
||||
* Instances of this class are created by the RecordStateFactory.
|
||||
*/
|
||||
class RecordState
|
||||
{
|
||||
/**
|
||||
* @var EntityContext
|
||||
*/
|
||||
protected $context;
|
||||
|
||||
/**
|
||||
* @var EntityPointer
|
||||
*/
|
||||
protected $node;
|
||||
|
||||
/**
|
||||
* @var EntityUidPointer
|
||||
*/
|
||||
protected $subject;
|
||||
|
||||
/**
|
||||
* @var EntityPointerLink|null
|
||||
*/
|
||||
protected $languageLink;
|
||||
|
||||
/**
|
||||
* @var EntityPointerLink|null
|
||||
*/
|
||||
protected $versionLink;
|
||||
|
||||
public function __construct(EntityContext $context, EntityPointer $node, EntityUidPointer $subject)
|
||||
{
|
||||
$this->context = $context;
|
||||
$this->node = $node;
|
||||
$this->subject = $subject;
|
||||
}
|
||||
|
||||
public function getContext(): EntityContext
|
||||
{
|
||||
return $this->context;
|
||||
}
|
||||
|
||||
public function getNode(): EntityPointer
|
||||
{
|
||||
return $this->node;
|
||||
}
|
||||
|
||||
public function getSubject(): EntityUidPointer
|
||||
{
|
||||
return $this->subject;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return EntityPointerLink
|
||||
*/
|
||||
public function getLanguageLink(): ?EntityPointerLink
|
||||
{
|
||||
return $this->languageLink;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return static
|
||||
*/
|
||||
public function withLanguageLink(?EntityPointerLink $languageLink): self
|
||||
{
|
||||
if ($this->languageLink === $languageLink) {
|
||||
return $this;
|
||||
}
|
||||
$target = clone $this;
|
||||
$target->languageLink = $languageLink;
|
||||
return $target;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return EntityPointerLink
|
||||
*/
|
||||
public function getVersionLink(): ?EntityPointerLink
|
||||
{
|
||||
return $this->versionLink;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return static
|
||||
*/
|
||||
public function withVersionLink(?EntityPointerLink $versionLink): self
|
||||
{
|
||||
if ($this->versionLink === $versionLink) {
|
||||
return $this;
|
||||
}
|
||||
$target = clone $this;
|
||||
$target->versionLink = $versionLink;
|
||||
return $target;
|
||||
}
|
||||
|
||||
public function isNew(): bool
|
||||
{
|
||||
return !MathUtility::canBeInterpretedAsInteger(
|
||||
$this->subject->getIdentifier()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves node identifier (`pid`) of current subject. For translated pages
|
||||
* that would result in the `uid` of the outer-most language parent page
|
||||
* otherwise it's the `pid` of the current subject.
|
||||
*
|
||||
* Example:
|
||||
* + pages: uid: 10, pid: 5, sys_language_uid: 0, l10n_parent: 0 -> returns 5
|
||||
* + pages: uid: 11, pid: 5, sys_language_uid: 1, l10n_parent: 10 -> returns 10
|
||||
* + other: uid: 12, pid: 10 -> returns 10
|
||||
*/
|
||||
public function resolveNodeIdentifier(): string
|
||||
{
|
||||
if ($this->subject->isNode()
|
||||
&& $this->context->getLanguageId() > 0
|
||||
&& $this->languageLink !== null
|
||||
) {
|
||||
return $this->languageLink->getHead()->getSubject()->getIdentifier();
|
||||
}
|
||||
return $this->node->getIdentifier();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves node identifier used as aggregate for current subject. For translated
|
||||
* pages that would result in the `uid` of the outer-most language parent page,
|
||||
* for pages it's the identifier of the current subject, otherwise it's
|
||||
* the `pid` of the current subject.
|
||||
*
|
||||
* Example:
|
||||
* + pages: uid: 10, pid: 5, sys_language_uid: 0, l10n_parent: 0 -> returns 10
|
||||
* + pages: uid: 11, pid: 5, sys_language_uid: 1, l10n_parent: 10 -> returns 10
|
||||
* + pages in version, return online page ID
|
||||
* + other: uid: 12, pid: 10 -> returns 10
|
||||
*/
|
||||
public function resolveNodeAggregateIdentifier(): string
|
||||
{
|
||||
if ($this->subject->isNode()
|
||||
&& $this->context->getLanguageId() > 0
|
||||
&& $this->languageLink !== null
|
||||
) {
|
||||
return $this->languageLink->getHead()->getSubject()->getIdentifier();
|
||||
}
|
||||
if ($this->subject->isNode() && $this->versionLink) {
|
||||
return $this->versionLink->getHead()->getSubject()->getIdentifier();
|
||||
}
|
||||
if ($this->subject->isNode()) {
|
||||
return $this->subject->getIdentifier();
|
||||
}
|
||||
return $this->node->getIdentifier();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
namespace TYPO3\CMS\Core\DataHandling\Model;
|
||||
|
||||
use TYPO3\CMS\Core\Schema\Capability\TcaSchemaCapability;
|
||||
use TYPO3\CMS\Core\Schema\TcaSchemaFactory;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* Factory class that creates a record state
|
||||
*/
|
||||
class RecordStateFactory
|
||||
{
|
||||
protected string $name;
|
||||
|
||||
public static function forName(string $name): self
|
||||
{
|
||||
return GeneralUtility::makeInstance(static::class, $name);
|
||||
}
|
||||
|
||||
public function __construct(string $name)
|
||||
{
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int|string|null $pageId
|
||||
* @param int|string|null $recordId
|
||||
*/
|
||||
public function fromArray(array $data, $pageId = null, $recordId = null): RecordState
|
||||
{
|
||||
$pageId = $pageId ?? $data['pid'] ?? null;
|
||||
$recordId = $recordId ?? $data['uid'] ?? null;
|
||||
|
||||
$aspectFieldValues = $this->resolveAspectFieldValues($data);
|
||||
|
||||
$context = GeneralUtility::makeInstance(EntityContext::class)
|
||||
->withWorkspaceId($aspectFieldValues['workspace'])
|
||||
->withLanguageId($aspectFieldValues['language']);
|
||||
$node = $this->createEntityPointer($pageId, 'pages');
|
||||
$subject = $this->createEntityPointer($recordId);
|
||||
|
||||
$target = GeneralUtility::makeInstance(
|
||||
RecordState::class,
|
||||
$context,
|
||||
$node,
|
||||
$subject
|
||||
);
|
||||
return $target
|
||||
->withLanguageLink($this->resolveLanguageLink($aspectFieldValues))
|
||||
->withVersionLink($this->resolveVersionLink($aspectFieldValues));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string|null>
|
||||
*/
|
||||
protected function resolveAspectFieldNames(): array
|
||||
{
|
||||
$schema = GeneralUtility::makeInstance(TcaSchemaFactory::class)->get($this->name);
|
||||
$languageCapability = null;
|
||||
if ($schema->isLanguageAware()) {
|
||||
$languageCapability = $schema->getCapability(TcaSchemaCapability::Language);
|
||||
}
|
||||
return [
|
||||
'workspace' => 't3ver_wsid',
|
||||
'versionParent' => 't3ver_oid',
|
||||
'language' => $languageCapability?->getLanguageField()->getName(),
|
||||
'languageParent' => $languageCapability?->getTranslationOriginPointerField()->getName(),
|
||||
'languageSource' => $languageCapability?->getTranslationSourceField()?->getName(),
|
||||
];
|
||||
}
|
||||
|
||||
protected function resolveAspectFieldValues(array $data): array
|
||||
{
|
||||
return array_map(
|
||||
static function (?string $aspectFieldName) use ($data): int {
|
||||
return (int)($data[$aspectFieldName ?? ''] ?? 0);
|
||||
},
|
||||
$this->resolveAspectFieldNames()
|
||||
);
|
||||
}
|
||||
|
||||
protected function resolveLanguageLink(array $aspectFieldNames): ?EntityPointerLink
|
||||
{
|
||||
$languageSourceLink = null;
|
||||
$languageParentLink = null;
|
||||
if (!empty($aspectFieldNames['languageSource'])) {
|
||||
$languageSourceLink = GeneralUtility::makeInstance(
|
||||
EntityPointerLink::class,
|
||||
$this->createEntityPointer($aspectFieldNames['languageSource'])
|
||||
);
|
||||
}
|
||||
|
||||
if (!empty($aspectFieldNames['languageParent'])) {
|
||||
$languageParentLink = GeneralUtility::makeInstance(
|
||||
EntityPointerLink::class,
|
||||
$this->createEntityPointer($aspectFieldNames['languageParent'])
|
||||
);
|
||||
}
|
||||
|
||||
if (empty($languageSourceLink) || empty($languageParentLink)
|
||||
|| $languageSourceLink->getSubject()->isEqualTo(
|
||||
$languageParentLink->getSubject()
|
||||
)
|
||||
) {
|
||||
return $languageSourceLink ?? $languageParentLink ?? null;
|
||||
}
|
||||
return $languageSourceLink->withAncestor($languageParentLink);
|
||||
}
|
||||
|
||||
protected function resolveVersionLink(array $aspectFieldNames): ?EntityPointerLink
|
||||
{
|
||||
if (!empty($aspectFieldNames['versionParent'])) {
|
||||
return GeneralUtility::makeInstance(
|
||||
EntityPointerLink::class,
|
||||
$this->createEntityPointer($aspectFieldNames['versionParent'])
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|int|null $identifier
|
||||
* @param string|null $name
|
||||
* @throws \LogicException
|
||||
*/
|
||||
protected function createEntityPointer($identifier, ?string $name = null): EntityPointer
|
||||
{
|
||||
if ($identifier === null) {
|
||||
throw new \LogicException(
|
||||
'Cannot create null pointer',
|
||||
1536407967
|
||||
);
|
||||
}
|
||||
|
||||
$identifier = (string)$identifier;
|
||||
|
||||
return GeneralUtility::makeInstance(
|
||||
EntityUidPointer::class,
|
||||
$name ?? $this->name,
|
||||
$identifier
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user