/** * Adds a new field definition to an existing content type. * * The content type must be in state DRAFT. * * @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException if the identifier in already exists in the content type * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the user is not allowed to edit a content type * @throws \eZ\Publish\API\Repository\Exceptions\ContentTypeFieldDefinitionValidationException * if a field definition in the $contentTypeCreateStruct is not valid * @throws \eZ\Publish\API\Repository\Exceptions\BadStateException If field definition of the same non-repeatable type is being * added to the ContentType that already contains one * or field definition that can't be added to a ContentType that * has Content instances is being added to such ContentType * * @param \eZ\Publish\API\Repository\Values\ContentType\ContentTypeDraft $contentTypeDraft * @param \eZ\Publish\API\Repository\Values\ContentType\FieldDefinitionCreateStruct $fieldDefinitionCreateStruct */ public function addFieldDefinition(APIContentTypeDraft $contentTypeDraft, FieldDefinitionCreateStruct $fieldDefinitionCreateStruct) { if ($this->repository->hasAccess('class', 'update') !== true) { throw new UnauthorizedException('ContentType', 'update'); } $this->validateInputFieldDefinitionCreateStruct($fieldDefinitionCreateStruct); $loadedContentTypeDraft = $this->loadContentTypeDraft($contentTypeDraft->id); if ($loadedContentTypeDraft->getFieldDefinition($fieldDefinitionCreateStruct->identifier) !== null) { throw new InvalidArgumentException("\$fieldDefinitionCreateStruct", "Another FieldDefinition with identifier '{$fieldDefinitionCreateStruct->identifier}' exists in the ContentType"); } /** @var $fieldType \eZ\Publish\SPI\FieldType\FieldType */ $fieldType = $this->repository->getFieldTypeService()->buildFieldType($fieldDefinitionCreateStruct->fieldTypeIdentifier); $fieldType->applyDefaultSettings($fieldDefinitionCreateStruct->fieldSettings); $fieldType->applyDefaultValidatorConfiguration($fieldDefinitionCreateStruct->validatorConfiguration); $validationErrors = $this->validateFieldDefinitionCreateStruct($fieldDefinitionCreateStruct, $fieldType); if (!empty($validationErrors)) { $validationErrors = array($fieldDefinitionCreateStruct->identifier => $validationErrors); throw new ContentTypeFieldDefinitionValidationException($validationErrors); } if ($fieldType->isSingular()) { foreach ($loadedContentTypeDraft->getFieldDefinitions() as $fieldDefinition) { if ($fieldDefinition->fieldTypeIdentifier === $fieldDefinitionCreateStruct->fieldTypeIdentifier) { throw new BadStateException("\$contentTypeDraft", "ContentType already contains field definition of non-repeatable field type '{$fieldDefinition->fieldTypeIdentifier}'"); } } } if ($fieldType->onlyEmptyInstance() && $this->contentTypeHandler->getContentCount($loadedContentTypeDraft->id)) { throw new BadStateException("\$contentTypeDraft", "Field definition of '{$fieldDefinitionCreateStruct->fieldTypeIdentifier}' field type cannot be added because ContentType has Content instances"); } $spiFieldDefinitionCreateStruct = $this->buildSPIFieldDefinitionCreate($fieldDefinitionCreateStruct, $fieldType); $this->repository->beginTransaction(); try { $this->contentTypeHandler->addFieldDefinition($contentTypeDraft->id, $contentTypeDraft->status, $spiFieldDefinitionCreateStruct); $this->repository->commit(); } catch (Exception $e) { $this->repository->rollback(); throw $e; } }
/** * Adds a new field definition to an existing Type. * * This method creates a new status of the Type with the $fieldDefinition * added. It does not update existing content objects depending on the * field (default) values. * * @param mixed $contentTypeId * @param int $status One of Type::STATUS_DEFINED|Type::STATUS_DRAFT|Type::STATUS_MODIFIED * @param \eZ\Publish\SPI\Persistence\Content\Type\FieldDefinition $fieldDefinition * @return void */ public function addFieldDefinition($contentTypeId, $status, FieldDefinition $fieldDefinition) { $this->clearCache(); return $this->innerHandler->addFieldDefinition($contentTypeId, $status, $fieldDefinition); }