コード例 #1
0
 public function testGetFieldTypes()
 {
     $fieldTypes = array('one' => $this->getFieldTypeMock(), 'two' => $this->getClosure($this->getFieldTypeMock()));
     $registry = new FieldTypeRegistry($fieldTypes);
     $fieldTypes = $registry->getFieldTypes();
     $this->assertInternalType('array', $fieldTypes);
     $this->assertCount(2, $fieldTypes);
     $this->assertArrayHasKey('one', $fieldTypes);
     $this->assertInstanceOf('eZ\\Publish\\SPI\\FieldType\\FieldType', $fieldTypes['one']);
     $this->assertArrayHasKey('two', $fieldTypes);
     $this->assertInstanceOf('eZ\\Publish\\SPI\\FieldType\\FieldType', $fieldTypes['two']);
 }
コード例 #2
0
 /**
  * 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;
 }
コード例 #3
0
 /**
  * Returns an array of domain fields created from given array of SPI fields.
  *
  * @param \eZ\Publish\SPI\Persistence\Content\Field[] $spiFields
  * @param ContentType|SPIType $contentType
  *
  * @return array
  */
 public function buildDomainFields(array $spiFields, $contentType)
 {
     $fieldIdentifierMap = array();
     if (!$contentType instanceof SPIType && !$contentType instanceof ContentType) {
         throw new InvalidArgumentType('$contentType', 'SPI ContentType | API ContentType');
     }
     foreach ($contentType->fieldDefinitions as $fieldDefinitions) {
         $fieldIdentifierMap[$fieldDefinitions->id] = $fieldDefinitions->identifier;
     }
     $fields = array();
     foreach ($spiFields as $spiField) {
         $fields[] = new Field(array('id' => $spiField->id, 'value' => $this->fieldTypeRegistry->getFieldType($spiField->type)->fromPersistenceValue($spiField->value), 'languageCode' => $spiField->languageCode, 'fieldDefIdentifier' => $fieldIdentifierMap[$spiField->fieldDefinitionId]));
     }
     return $fields;
 }
コード例 #4
0
 /**
  * Builds SPIFieldDefinition object using API FieldDefinitionUpdateStruct
  * and API FieldDefinition.
  *
  * @throws \eZ\Publish\API\Repository\Exceptions\ContentTypeFieldDefinitionValidationException if validator configuration or
  *         field setting do not validate
  *
  * @param \eZ\Publish\API\Repository\Values\ContentType\FieldDefinitionUpdateStruct $fieldDefinitionUpdateStruct
  * @param \eZ\Publish\API\Repository\Values\ContentType\FieldDefinition $fieldDefinition
  *
  * @return \eZ\Publish\SPI\Persistence\Content\Type\FieldDefinition
  */
 public function buildSPIFieldDefinitionUpdate(APIFieldDefinitionUpdateStruct $fieldDefinitionUpdateStruct, APIFieldDefinition $fieldDefinition)
 {
     /** @var $fieldType \eZ\Publish\SPI\FieldType\FieldType */
     $fieldType = $this->fieldTypeRegistry->getFieldType($fieldDefinition->fieldTypeIdentifier);
     $validatorConfiguration = $fieldDefinitionUpdateStruct->validatorConfiguration === null ? $fieldDefinition->validatorConfiguration : $fieldDefinitionUpdateStruct->validatorConfiguration;
     $fieldSettings = $fieldDefinitionUpdateStruct->fieldSettings === null ? $fieldDefinition->fieldSettings : $fieldDefinitionUpdateStruct->fieldSettings;
     $validationErrors = array();
     if ($fieldDefinitionUpdateStruct->isSearchable && !$fieldType->isSearchable()) {
         $validationErrors[] = new ValidationError("FieldType '{$fieldDefinition->fieldTypeIdentifier}' is not searchable");
     }
     $validationErrors = array_merge($validationErrors, $fieldType->validateValidatorConfiguration($validatorConfiguration), $fieldType->validateFieldSettings($fieldSettings));
     if (!empty($validationErrors)) {
         throw new ContentTypeFieldDefinitionValidationException($validationErrors);
     }
     $spiFieldDefinition = new SPIFieldDefinition(array('id' => $fieldDefinition->id, 'fieldType' => $fieldDefinition->fieldTypeIdentifier, 'name' => $fieldDefinitionUpdateStruct->names === null ? $fieldDefinition->getNames() : $fieldDefinitionUpdateStruct->names, 'description' => $fieldDefinitionUpdateStruct->descriptions === null ? $fieldDefinition->getDescriptions() : $fieldDefinitionUpdateStruct->descriptions, 'identifier' => $fieldDefinitionUpdateStruct->identifier === null ? $fieldDefinition->identifier : $fieldDefinitionUpdateStruct->identifier, 'fieldGroup' => $fieldDefinitionUpdateStruct->fieldGroup === null ? $fieldDefinition->fieldGroup : $fieldDefinitionUpdateStruct->fieldGroup, 'position' => $fieldDefinitionUpdateStruct->position === null ? $fieldDefinition->position : $fieldDefinitionUpdateStruct->position, 'isTranslatable' => $fieldDefinitionUpdateStruct->isTranslatable === null ? $fieldDefinition->isTranslatable : $fieldDefinitionUpdateStruct->isTranslatable, 'isRequired' => $fieldDefinitionUpdateStruct->isRequired === null ? $fieldDefinition->isRequired : $fieldDefinitionUpdateStruct->isRequired, 'isInfoCollector' => $fieldDefinitionUpdateStruct->isInfoCollector === null ? $fieldDefinition->isInfoCollector : $fieldDefinitionUpdateStruct->isInfoCollector, 'isSearchable' => $fieldDefinitionUpdateStruct->isSearchable === null ? $fieldDefinition->isSearchable : $fieldDefinitionUpdateStruct->isSearchable));
     $spiFieldDefinition->fieldTypeConstraints->validators = $validatorConfiguration;
     $spiFieldDefinition->fieldTypeConstraints->fieldSettings = $fieldSettings;
     $spiFieldDefinition->defaultValue = $fieldType->toPersistenceValue($fieldType->acceptValue($fieldDefinitionUpdateStruct->defaultValue));
     return $spiFieldDefinition;
 }
コード例 #5
0
 /**
  * Returns an array of domain fields created from given array of SPI fields.
  *
  * @throws InvalidArgumentType On invalid $contentType
  *
  * @param \eZ\Publish\SPI\Persistence\Content\Field[] $spiFields
  * @param ContentType|SPIType $contentType
  * @param array|null $languages Language codes to filter fields on
  * @param string|null $alwaysAvailableLanguage Language code fallback if a given field is not found in $languages
  *
  * @return array
  */
 public function buildDomainFields(array $spiFields, $contentType, array $languages = null, $alwaysAvailableLanguage = null)
 {
     if (!$contentType instanceof SPIType && !$contentType instanceof ContentType) {
         throw new InvalidArgumentType('$contentType', 'SPI ContentType | API ContentType');
     }
     $fieldIdentifierMap = array();
     foreach ($contentType->fieldDefinitions as $fieldDefinitions) {
         $fieldIdentifierMap[$fieldDefinitions->id] = $fieldDefinitions->identifier;
     }
     $fieldInFilterLanguagesMap = array();
     if ($languages !== null && $alwaysAvailableLanguage !== null) {
         foreach ($spiFields as $spiField) {
             if (in_array($spiField->languageCode, $languages)) {
                 $fieldInFilterLanguagesMap[$spiField->fieldDefinitionId] = true;
             }
         }
     }
     $fields = array();
     foreach ($spiFields as $spiField) {
         // We ignore fields in content not part of the content type
         if (!isset($fieldIdentifierMap[$spiField->fieldDefinitionId])) {
             continue;
         }
         if ($languages !== null && !in_array($spiField->languageCode, $languages)) {
             // If filtering is enabled we ignore fields in other languages then $fieldLanguages, if:
             if ($alwaysAvailableLanguage === null) {
                 // Ignore field if we don't have $alwaysAvailableLanguageCode fallback
                 continue;
             } elseif (!empty($fieldInFilterLanguagesMap[$spiField->fieldDefinitionId])) {
                 // Ignore field if it exists in one of the filtered languages
                 continue;
             } elseif ($spiField->languageCode !== $alwaysAvailableLanguage) {
                 // Also ignore if field is not in $alwaysAvailableLanguageCode
                 continue;
             }
         }
         $fields[] = new Field(array('id' => $spiField->id, 'value' => $this->fieldTypeRegistry->getFieldType($spiField->type)->fromPersistenceValue($spiField->value), 'languageCode' => $spiField->languageCode, 'fieldDefIdentifier' => $fieldIdentifierMap[$spiField->fieldDefinitionId]));
     }
     return $fields;
 }
コード例 #6
0
 /**
  * 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->fieldTypeRegistry->getFieldType($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;
     }
 }
コード例 #7
0
 /**
  * Updates the fields of a draft.
  *
  * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the user is not allowed to update this version
  * @throws \eZ\Publish\API\Repository\Exceptions\BadStateException if the version is not a draft
  * @throws \eZ\Publish\API\Repository\Exceptions\ContentFieldValidationException if a field in the $contentUpdateStruct is not valid
  * @throws \eZ\Publish\API\Repository\Exceptions\ContentValidationException if a required field is set to an empty value
  *
  * @param \eZ\Publish\API\Repository\Values\Content\VersionInfo $versionInfo
  * @param \eZ\Publish\API\Repository\Values\Content\ContentUpdateStruct $contentUpdateStruct
  *
  * @return \eZ\Publish\API\Repository\Values\Content\Content the content draft with the updated fields
  */
 public function updateContent(APIVersionInfo $versionInfo, APIContentUpdateStruct $contentUpdateStruct)
 {
     $contentUpdateStruct = clone $contentUpdateStruct;
     /** @var $content \eZ\Publish\Core\Repository\Values\Content\Content */
     $content = $this->loadContent($versionInfo->getContentInfo()->id, null, $versionInfo->versionNo);
     if ($content->versionInfo->status !== APIVersionInfo::STATUS_DRAFT) {
         throw new BadStateException('$versionInfo', 'Version is not a draft and can not be updated');
     }
     if (!$this->repository->canUser('content', 'edit', $content)) {
         throw new UnauthorizedException('content', 'edit', array('contentId' => $content->id));
     }
     $mainLanguageCode = $content->contentInfo->mainLanguageCode;
     $languageCodes = $this->getLanguageCodesForUpdate($contentUpdateStruct, $content);
     $contentType = $this->repository->getContentTypeService()->loadContentType($content->contentInfo->contentTypeId);
     $fields = $this->mapFieldsForUpdate($contentUpdateStruct, $contentType, $mainLanguageCode);
     $fieldValues = array();
     $spiFields = array();
     $allFieldErrors = array();
     $inputRelations = array();
     $locationIdToContentIdMapping = array();
     foreach ($contentType->getFieldDefinitions() as $fieldDefinition) {
         /** @var $fieldType \eZ\Publish\SPI\FieldType\FieldType */
         $fieldType = $this->fieldTypeRegistry->getFieldType($fieldDefinition->fieldTypeIdentifier);
         foreach ($languageCodes as $languageCode) {
             $isCopied = $isEmpty = $isRetained = false;
             $isLanguageNew = !in_array($languageCode, $content->versionInfo->languageCodes);
             $valueLanguageCode = $fieldDefinition->isTranslatable ? $languageCode : $mainLanguageCode;
             $isFieldUpdated = isset($fields[$fieldDefinition->identifier][$valueLanguageCode]);
             $isProcessed = isset($fieldValues[$fieldDefinition->identifier][$valueLanguageCode]);
             if (!$isFieldUpdated && !$isLanguageNew) {
                 $isRetained = true;
                 $fieldValue = $content->getField($fieldDefinition->identifier, $valueLanguageCode)->value;
             } elseif (!$isFieldUpdated && $isLanguageNew && !$fieldDefinition->isTranslatable) {
                 $isCopied = true;
                 $fieldValue = $content->getField($fieldDefinition->identifier, $valueLanguageCode)->value;
             } elseif ($isFieldUpdated) {
                 $fieldValue = $fields[$fieldDefinition->identifier][$valueLanguageCode]->value;
             } else {
                 $fieldValue = $fieldDefinition->defaultValue;
             }
             $fieldValue = $fieldType->acceptValue($fieldValue);
             if ($fieldType->isEmptyValue($fieldValue)) {
                 $isEmpty = true;
                 if ($fieldDefinition->isRequired) {
                     throw new ContentValidationException("Value for required field definition '%identifier%' with language '%languageCode%' is empty", ['%identifier%' => $fieldDefinition->identifier, '%languageCode%' => $languageCode]);
                 }
             } else {
                 $fieldErrors = $fieldType->validate($fieldDefinition, $fieldValue);
                 if (!empty($fieldErrors)) {
                     $allFieldErrors[$fieldDefinition->id][$languageCode] = $fieldErrors;
                 }
             }
             if (!empty($allFieldErrors)) {
                 continue;
             }
             $this->relationProcessor->appendFieldRelations($inputRelations, $locationIdToContentIdMapping, $fieldType, $fieldValue, $fieldDefinition->id);
             $fieldValues[$fieldDefinition->identifier][$languageCode] = $fieldValue;
             if ($isRetained || $isCopied || $isLanguageNew && $isEmpty || $isProcessed) {
                 continue;
             }
             $spiFields[] = new SPIField(array('id' => $isLanguageNew ? null : $content->getField($fieldDefinition->identifier, $languageCode)->id, 'fieldDefinitionId' => $fieldDefinition->id, 'type' => $fieldDefinition->fieldTypeIdentifier, 'value' => $fieldType->toPersistenceValue($fieldValue), 'languageCode' => $languageCode, 'versionNo' => $versionInfo->versionNo));
         }
     }
     if (!empty($allFieldErrors)) {
         throw new ContentFieldValidationException($allFieldErrors);
     }
     $spiContentUpdateStruct = new SPIContentUpdateStruct(array('name' => $this->nameSchemaService->resolveNameSchema($content, $fieldValues, $languageCodes, $contentType), 'creatorId' => $contentUpdateStruct->creatorId ?: $this->repository->getCurrentUserReference()->getUserId(), 'fields' => $spiFields, 'modificationDate' => time(), 'initialLanguageId' => $this->persistenceHandler->contentLanguageHandler()->loadByLanguageCode($contentUpdateStruct->initialLanguageCode)->id));
     $existingRelations = $this->loadRelations($versionInfo);
     $this->repository->beginTransaction();
     try {
         $spiContent = $this->persistenceHandler->contentHandler()->updateContent($versionInfo->getContentInfo()->id, $versionInfo->versionNo, $spiContentUpdateStruct);
         $this->relationProcessor->processFieldRelations($inputRelations, $spiContent->versionInfo->contentInfo->id, $spiContent->versionInfo->versionNo, $contentType, $existingRelations);
         $this->repository->commit();
     } catch (Exception $e) {
         $this->repository->rollback();
         throw $e;
     }
     return $this->domainMapper->buildContentDomainObject($spiContent, $contentType);
 }
コード例 #8
0
 /**
  * Returns if there is a FieldType registered under $identifier
  *
  * @param string $identifier
  *
  * @return boolean
  */
 public function hasFieldType($identifier)
 {
     return $this->fieldTypeRegistry->hasFieldType($identifier);
 }