language = (int)($suggestedValues[$item->getLanguageFieldName()] ?? $persistedValues[$item->getLanguageFieldName()] ?? 0); $item->setParent($suggestedValues[$item->getParentFieldName()] ?? $persistedValues[$item->getParentFieldName()] ?? ''); if ($item->getSourceFieldName() !== null) { $item->setSource($suggestedValues[$item->getSourceFieldName()] ?? $persistedValues[$item->getSourceFieldName()] ?? ''); } // assign live-id of item if available $versionSourceFieldName = $item->getVersionSourceFieldName(); if ($versionSourceFieldName !== null && !empty($persistedValues[$versionSourceFieldName])) { $item->liveId = $persistedValues[$versionSourceFieldName]; } return $item; } public function __construct( string $tableName, string|int $id, array $suggestedValues, array $persistedValues, array $configurationFieldNames ) { $this->tableName = $tableName; $this->id = $id; $this->suggestedValues = $suggestedValues; $this->persistedValues = $persistedValues; $this->configurationFieldNames = $configurationFieldNames; $this->new = !MathUtility::canBeInterpretedAsInteger($id); } /** * Gets the current table name of this data-map item. */ public function getTableName(): string { return $this->tableName; } /** * Gets the id of this data-map item. */ public function getId(): string|int { return $this->id; } public function getLiveId(): int|string { return $this->liveId ?? $this->id; } /** * Gets the suggested values that were initially * submitted as the whole data-map to the DataHandler. */ public function getSuggestedValues(): array { return $this->suggestedValues; } /** * Gets the persisted values that represent the persisted state * of the record this data-map item is a surrogate for - does only * contain relevant field values. */ public function getPersistedValues(): array { return $this->persistedValues; } public function getConfigurationFieldNames(): array { return $this->configurationFieldNames; } public function getLanguageFieldName(): string { return $this->configurationFieldNames['language']; } public function getParentFieldName(): string { return $this->configurationFieldNames['parent']; } public function getSourceFieldName(): ?string { return $this->configurationFieldNames['source'] ?? null; } protected function getVersionSourceFieldName(): ?string { return $this->configurationFieldNames['versionSource'] ?? null; } public function isNew(): bool { return $this->new; } public function getType(): string { if ($this->type === null) { // implicit: default language, it's a parent if ($this->language === 0) { $this->type = static::TYPE_PARENT; } elseif ( // implicit: having source value different to parent value, it's a 2nd or higher level translation $this->source !== 0 && $this->source !== null && $this->source !== $this->parent ) { $this->type = static::TYPE_GRAND_CHILD; } else { // implicit: otherwise, it's a 1st level translation $this->type = static::TYPE_DIRECT_CHILD; } } return $this->type; } public function isParentType(): bool { return $this->getType() === static::TYPE_PARENT; } public function isDirectChildType(): bool { return $this->getType() === static::TYPE_DIRECT_CHILD; } public function isGrandChildType(): bool { return $this->getType() === static::TYPE_GRAND_CHILD; } public function getState(): ?State { if ($this->state === null && !$this->isParentType()) { $this->state = $this->buildState(); } return $this->state; } public function getLanguage(): string|int { return $this->language; } public function setLanguage(string|int $language): void { $this->language = $language; } public function getParent(): string|int { return $this->parent; } public function setParent(string|int $parent): void { $this->parent = $this->extractId($parent); } public function getSource(): string|int|null { return $this->source; } public function setSource(string|int $source): void { $this->source = $this->extractId($source); } public function getIdForScope(string $scope): string|int { if ( $scope === static::SCOPE_PARENT || $scope === static::SCOPE_EXCLUDE ) { return $this->getParent(); } if ($scope === static::SCOPE_SOURCE) { // $source is guaranteed to be non-null when SCOPE_SOURCE is applicable: // getApplicableScopes() only includes it when getSourceFieldName() !== null, // which means setSource() was called during build(). return $this->source; } throw new \RuntimeException('Invalid scope', 1486325248); } /** * @return DataMapItem[][] */ public function getDependencies(): array { return $this->dependencies; } /** * @param DataMapItem[][] $dependencies */ public function setDependencies(array $dependencies): void { $this->dependencies = $dependencies; } /** * @return DataMapItem[] */ public function findDependencies(string $scope): array { return $this->dependencies[$scope] ?? []; } /** * @return string[] */ public function getApplicableScopes(): array { $scopes = []; if (!empty($this->getSourceFieldName())) { $scopes[] = static::SCOPE_SOURCE; } $scopes[] = static::SCOPE_PARENT; $scopes[] = static::SCOPE_EXCLUDE; return $scopes; } /** * Extracts real id from provided id-value, which can either be a real * integer value, a 'NEW...' id, or a combined identifier 'tt_content_13'. */ protected function extractId(int|string $idValue): int|string { if (MathUtility::canBeInterpretedAsInteger($idValue)) { return $idValue; } $idValue = (string)$idValue; if (str_starts_with($idValue, 'NEW')) { return $idValue; } // @todo Handle if $tableName does not match $this->tableName $id = BackendUtility::splitTable_Uid($idValue)[1]; return $id; } protected function buildState(): ?State { // build from persisted states if (!$this->isNew()) { $state = State::fromJSON( $this->tableName, $this->persistedValues['l10n_state'] ?? null ); } elseif (is_string($this->suggestedValues['l10n_state'] ?? null)) { // use provided states for a new and copied element $state = State::fromJSON( $this->tableName, $this->suggestedValues['l10n_state'] ); } else { // provide the default states $state = State::create($this->tableName); } // switch "custom" to "source" state for 2nd level translations if ($this->isNew() && $this->isGrandChildType()) { $state->updateStates(State::STATE_CUSTOM, State::STATE_SOURCE); } // apply any provided updates to the states if (is_array($this->suggestedValues['l10n_state'] ?? null)) { $state->update($this->suggestedValues['l10n_state']); } return $state; } }