public function updateFieldDefinition($identifier, FieldDefinitionUpdateStruct $fieldDefinitionUpdateStruct) { $contentTypeDraft = $this->contentTypeService->createContentTypeDraft($this->currentContentType); $this->contentTypeService->updateFieldDefinition($contentTypeDraft, $this->currentContentType->getFieldDefinition($identifier), $fieldDefinitionUpdateStruct); $this->contentTypeService->publishContentTypeDraft($contentTypeDraft); $this->currentContentType = $this->contentTypeService->loadContentTypeByIdentifier($this->currentContentType->identifier); }
/** * Persists relation data for a content version. * * This method creates new relations and deletes removed relations. * * @param array $inputRelations * @param mixed $sourceContentId * @param mixed $sourceContentVersionNo * @param \eZ\Publish\API\Repository\Values\ContentType\ContentType $contentType * @param \eZ\Publish\API\Repository\Values\Content\Relation[] $existingRelations An array of existing relations for Content version (empty when creating new content) * * @return void */ public function processFieldRelations(array $inputRelations, $sourceContentId, $sourceContentVersionNo, ContentType $contentType, array $existingRelations = array()) { // Map existing relations for easier handling $mappedRelations = array(); foreach ($existingRelations as $relation) { if ($relation->type === Relation::FIELD) { $fieldDefinitionId = $contentType->getFieldDefinition($relation->sourceFieldDefinitionIdentifier)->id; $mappedRelations[$relation->type][$fieldDefinitionId][$relation->destinationContentInfo->id] = $relation; } // Using bitwise AND as Legacy Stack stores COMMON, LINK and EMBED relation types // in the same entry using bitmask if ($relation->type & Relation::LINK) { $mappedRelations[Relation::LINK][$relation->destinationContentInfo->id] = $relation; } if ($relation->type & Relation::EMBED) { $mappedRelations[Relation::EMBED][$relation->destinationContentInfo->id] = $relation; } } // Add new relations foreach ($inputRelations as $relationType => $relationData) { if ($relationType === Relation::FIELD) { foreach ($relationData as $fieldDefinitionId => $contentIds) { foreach (array_keys($contentIds) as $destinationContentId) { if (isset($mappedRelations[$relationType][$fieldDefinitionId][$destinationContentId])) { unset($mappedRelations[$relationType][$fieldDefinitionId][$destinationContentId]); } else { $this->persistenceHandler->contentHandler()->addRelation(new SPIRelationCreateStruct(array("sourceContentId" => $sourceContentId, "sourceContentVersionNo" => $sourceContentVersionNo, "sourceFieldDefinitionId" => $fieldDefinitionId, "destinationContentId" => $destinationContentId, "type" => $relationType))); } } } } else { if ($relationType === Relation::LINK || $relationType === Relation::EMBED) { foreach (array_keys($relationData) as $destinationContentId) { if (isset($mappedRelations[$relationType][$destinationContentId])) { unset($mappedRelations[$relationType][$destinationContentId]); } else { $this->persistenceHandler->contentHandler()->addRelation(new SPIRelationCreateStruct(array("sourceContentId" => $sourceContentId, "sourceContentVersionNo" => $sourceContentVersionNo, "sourceFieldDefinitionId" => null, "destinationContentId" => $destinationContentId, "type" => $relationType))); } } } } } // Remove relations not present in input set foreach ($mappedRelations as $relationType => $relationData) { foreach ($relationData as $relationEntry) { switch ($relationType) { case Relation::FIELD: foreach ($relationEntry as $relation) { $this->persistenceHandler->contentHandler()->removeRelation($relation->id, $relationType); } break; case Relation::LINK: case Relation::EMBED: $this->persistenceHandler->contentHandler()->removeRelation($relationEntry->id, $relationType); } } } }
/** * This method returns the field definition for the given identifier * * @param string $fieldDefinitionIdentifier * * @return \eZ\Publish\API\Repository\Values\ContentType\FieldDefinition */ public function getFieldDefinition($fieldDefinitionIdentifier) { return $this->innerContentType->getFieldDefinition($fieldDefinitionIdentifier); }
/** * Returns an array of fields like $fields[$field->fieldDefIdentifier][$field->languageCode]. * * @throws \eZ\Publish\API\Repository\Exceptions\ContentValidationException If field definition does not exist in the ContentType * or value is set for non-translatable field in language * other than main * * @param \eZ\Publish\API\Repository\Values\Content\ContentUpdateStruct $contentUpdateStruct * @param \eZ\Publish\API\Repository\Values\ContentType\ContentType $contentType * @param string $mainLanguageCode * * @return array */ protected function mapFieldsForUpdate(APIContentUpdateStruct $contentUpdateStruct, ContentType $contentType, $mainLanguageCode) { $fields = array(); foreach ($contentUpdateStruct->fields as $field) { $fieldDefinition = $contentType->getFieldDefinition($field->fieldDefIdentifier); if ($fieldDefinition === null) { throw new ContentValidationException("Field definition '%identifier%' does not exist in given ContentType", ['%identifier%' => $field->fieldDefIdentifier]); } if ($field->languageCode === null) { if ($fieldDefinition->isTranslatable) { $languageCode = $contentUpdateStruct->initialLanguageCode; } else { $languageCode = $mainLanguageCode; } $field = $this->cloneField($field, array('languageCode' => $languageCode)); } if (!$fieldDefinition->isTranslatable && $field->languageCode != $mainLanguageCode) { throw new ContentValidationException("A value is set for non translatable field definition '%identifier%' with language '%languageCode%'", ['%identifier%' => $field->fieldDefIdentifier, '%languageCode%' => $field->languageCode]); } $fields[$field->fieldDefIdentifier][$field->languageCode] = $field; } return $fields; }
/** * This method returns the field definition for the given id * * @param mixed $fieldDefinitionId * * @return \eZ\Publish\API\Repository\Values\ContentType\FieldDefinition */ public function getFieldDefinitionById($fieldDefinitionId) { return $this->innerContentType->getFieldDefinition($fieldDefinitionId); }
/** * Serializes the field value of $field through $generator. * * @param \eZ\Publish\Core\REST\Common\Output\Generator $generator * @param \eZ\Publish\API\Repository\Values\ContentType\ContentType $contentType * @param \eZ\Publish\API\Repository\Values\Content\Field $field */ public function serializeFieldValue(Generator $generator, ContentType $contentType, Field $field) { $this->serializeValue('fieldValue', $generator, $this->fieldTypeService->getFieldType($contentType->getFieldDefinition($field->fieldDefIdentifier)->fieldTypeIdentifier), $field->value); }
/** * Fetches the list of available Field identifiers in the token and returns * an array of their current title value. * * @see \eZ\Publish\Core\Repository\FieldType::getName() * * @param string[] $schemaIdentifiers * @param \eZ\Publish\SPI\Persistence\Content\Type|\eZ\Publish\API\Repository\Values\ContentType\ContentType $contentType * @param array $fieldMap * @param string $languageCode * * @throws \eZ\Publish\Core\Base\Exceptions\InvalidArgumentType * * @return string[] Key is the field identifier, value is the title value */ protected function getFieldTitles(array $schemaIdentifiers, $contentType, array $fieldMap, $languageCode) { $fieldTitles = array(); foreach ($schemaIdentifiers as $fieldDefinitionIdentifier) { if (isset($fieldMap[$fieldDefinitionIdentifier][$languageCode])) { if ($contentType instanceof SPIContentType) { $fieldDefinition = null; foreach ($contentType->fieldDefinitions as $spiFieldDefinition) { if ($spiFieldDefinition->identifier === $fieldDefinitionIdentifier) { $fieldDefinition = $spiFieldDefinition; break; } } if ($fieldDefinition === null) { $fieldTitles[$fieldDefinitionIdentifier] = ''; continue; } $fieldType = $this->fieldTypeRegistry->getFieldType($fieldDefinition->fieldType); } elseif ($contentType instanceof ContentType) { $fieldDefinition = $contentType->getFieldDefinition($fieldDefinitionIdentifier); $fieldType = $this->fieldTypeRegistry->getFieldType($fieldDefinition->fieldTypeIdentifier); } else { throw new InvalidArgumentType('$contentType', 'API or SPI variant of ContentType'); } $fieldTitles[$fieldDefinitionIdentifier] = $fieldType->getName($fieldMap[$fieldDefinitionIdentifier][$languageCode]); } } return $fieldTitles; }
/** * Returns Field definition name in the appropriate language for a given content. * * By default, this method will return the field definition name in current language if translation is present. If not, main language will be used. * If $forcedLanguage is provided, will return the field definition name in this language, if translation is present. * * @param \eZ\Publish\API\Repository\Values\ContentType\ContentType $contentType * @param string $fieldDefIdentifier Field Definition identifier * @param string $property Specifies if 'name' or 'description' should be used * @param string $forcedLanguage Locale we want the field definition name translated in in (e.g. "fre-FR"). Null by default (takes current locale) * * @throws InvalidArgumentException * * @return string|null */ public function getTranslatedFieldDefinitionProperty(ContentType $contentType, $fieldDefIdentifier, $property = 'name', $forcedLanguage = null) { $fieldDefinition = $contentType->getFieldDefinition($fieldDefIdentifier); if (!$fieldDefinition instanceof FieldDefinition) { throw new InvalidArgumentException('$fieldDefIdentifier', "Field '{$fieldDefIdentifier}' not found on {$contentType->identifier}"); } $method = 'get' . $property; if (!method_exists($fieldDefinition, $method)) { throw new InvalidArgumentException('$property', "Method get'{$property}'() not found on FieldDefinition"); } // Loop over prioritized languages to get the appropriate translated field definition name // Should ideally have used array_unique, but in that case the loop should ideally never reach last item foreach ($this->getLanguages($forcedLanguage, $contentType->mainLanguageCode) as $lang) { if ($name = $fieldDefinition->{$method}($lang)) { return $name; } } }
/** * Fetches the list of available Field identifiers in the token and returns * an array of their current title value. * * @see \eZ\Publish\Core\Repository\FieldType::getName() * * @param string[] $schemaIdentifiers * @param \eZ\Publish\API\Repository\Values\ContentType\ContentType $contentType $fieldDefinitions * @param array $fieldMap * @param string $languageCode * * @return string[] Key is the field identifier, value is the title value */ protected function getFieldTitles(array $schemaIdentifiers, ContentType $contentType, array $fieldMap, $languageCode) { $fieldTitles = array(); foreach ($schemaIdentifiers as $fieldDefinitionIdentifier) { if (isset($fieldMap[$fieldDefinitionIdentifier][$languageCode])) { $fieldDefinition = $contentType->getFieldDefinition($fieldDefinitionIdentifier); $fieldType = $this->repository->getFieldTypeService()->getFieldType($fieldDefinition->fieldTypeIdentifier); $fieldTitles[$fieldDefinitionIdentifier] = $fieldType->getName($fieldMap[$fieldDefinitionIdentifier][$languageCode]); } } return $fieldTitles; }
/** * Compute Meta by reference * * @param Content $content * @param string|Field $fieldDefIdentifier * @param ContentType $contentType * @param bool $needFallback * * @return Meta[] */ protected function innerComputeMetas(Content $content, $fieldDefIdentifier, ContentType $contentType, &$needFallback = false) { if ($fieldDefIdentifier instanceof Field) { $metasFieldValue = $fieldDefIdentifier->value; $fieldDefIdentifier = $fieldDefIdentifier->fieldDefIdentifier; } else { $metasFieldValue = $content->getFieldValue($fieldDefIdentifier); } if ($metasFieldValue instanceof MetasFieldValue) { $metasConfig = $this->configResolver->getParameter('fieldtype_metas', 'novae_zseo'); // as the configuration is the last fallback we need to loop on it. foreach ($metasConfig as $metaName => $metasSettings) { if ($metasFieldValue->nameExists($metaName)) { $meta = $metasFieldValue->metas[$metaName]; } else { $meta = new Meta($metaName); $metasFieldValue->metas[$metaName] = $meta; } /** @var Meta $meta */ if ($meta->isEmpty()) { $meta->setContent($metasConfig[$meta->getName()]['default_pattern']); $fieldDefinition = $contentType->getFieldDefinition($fieldDefIdentifier); $configuration = $fieldDefinition->getFieldSettings()['configuration']; // but if we need something is the configuration we take it if ($configuration[$meta->getName()]) { $meta->setContent($configuration[$meta->getName()]); } } if (!$this->metaNameSchema->resolveMeta($meta, $content, $contentType)) { $needFallback = true; } } return $metasFieldValue->metas; } return []; }
/** * Maps Repository Field to the Site Field. * * @param \eZ\Publish\API\Repository\Values\Content\Field $field * @param \eZ\Publish\API\Repository\Values\ContentType\ContentType $contentType * * @return mixed|\Netgen\EzPlatformSiteApi\API\Values\Field */ private function mapFieldData(APIField $field, ContentType $contentType) { $fieldDefinition = $contentType->getFieldDefinition($field->fieldDefIdentifier); $fieldTypeIdentifier = $fieldDefinition->fieldTypeIdentifier; $isEmpty = $this->fieldTypeService->getFieldType($fieldTypeIdentifier)->isEmptyValue($field->value); return ['isEmpty' => $isEmpty, 'innerField' => $field]; }
/** * {@inheritdoc} */ protected function getFieldTitles(array $schemaIdentifiers, ContentType $contentType, array $fieldMap, $languageCode) { $fieldTitles = array(); foreach ($schemaIdentifiers as $fieldDefinitionIdentifier) { if (isset($fieldMap[$fieldDefinitionIdentifier][$languageCode])) { $fieldDefinition = $contentType->getFieldDefinition($fieldDefinitionIdentifier); $fieldType = $this->repository->getFieldTypeService()->getFieldType($fieldDefinition->fieldTypeIdentifier); // eZ XML Text if ($fieldMap[$fieldDefinitionIdentifier][$languageCode] instanceof XmlTextValue) { $fieldTitles[$fieldDefinitionIdentifier] = $this->handleXmlTextValue($fieldMap[$fieldDefinitionIdentifier][$languageCode]); continue; } //eZ Object Relation if ($fieldMap[$fieldDefinitionIdentifier][$languageCode] instanceof RelationValue) { $fieldTitles[$fieldDefinitionIdentifier] = $this->handleRelationValue($fieldMap[$fieldDefinitionIdentifier][$languageCode], $languageCode); continue; } // eZ Image if ($fieldMap[$fieldDefinitionIdentifier][$languageCode] instanceof ImageValue) { $fieldTitles[$fieldDefinitionIdentifier] = $this->handleImageValue($fieldMap[$fieldDefinitionIdentifier][$languageCode], $fieldDefinitionIdentifier, $languageCode); continue; } $fieldTitles[$fieldDefinitionIdentifier] = $fieldType->getName($fieldMap[$fieldDefinitionIdentifier][$languageCode]); } } return $fieldTitles; }
/** * Generates the names based on the given $contentType and $fields * * @param \eZ\Publish\API\Repository\Values\ContentType\ContentType $contentType * @param \eZ\Publish\API\Repository\Values\Content\Field[] $fields * * @return string[] */ private function generateNames(ContentType $contentType, array $fields) { $languages = array_unique(array_filter(array_map(function ($field) use($contentType) { $fieldDefinition = $contentType->getFieldDefinition($field->fieldDefIdentifier); return $fieldDefinition->isTranslatable ? $field->languageCode : false; }, $fields))); $names = array(); foreach ($languages as $languageCode) { $names[$languageCode] = preg_replace_callback('(<([^>]+)>)', function ($matches) use($fields, $languageCode) { $fieldIdentifiers = explode('|', $matches[1]); foreach ($fieldIdentifiers as $fieldIdentifier) { foreach ($fields as $field) { if ($field->fieldDefIdentifier == $fieldIdentifier && $field->languageCode == $languageCode) { return $field->value; } } } }, $contentType->nameSchema); } return $names; }