/** * @param \eZ\Publish\API\Repository\Repository $repository * @param ConfigResolverInterface|\Psr\Log\LoggerInterface $resolver */ public function __construct(Repository $repository, ConfigResolverInterface $resolver) { $this->repository = $repository; $this->searchService = $this->repository->getSearchService(); $this->locationService = $this->repository->getLocationService(); $this->contentService = $this->repository->getContentService(); $this->languageService = $this->repository->getContentLanguageService(); $this->userService = $this->repository->getUserService(); $this->contentTypeService = $this->repository->getContentTypeService(); $this->configResolver = $resolver; }
/** * Get Content Language Service * * Get service object to perform operations on Content language objects * * @return \eZ\Publish\API\Repository\LanguageService */ public function getContentLanguageService() { if ($this->languageService !== null) { return $this->languageService; } $this->languageService = new LanguageService($this->repository->getContentLanguageService(), $this->signalDispatcher); return $this->languageService; }
/** * Setups service with reference to repository object that created it & corresponding handler. * * @param \eZ\Publish\API\Repository\Repository $repository * @param \eZ\Publish\SPI\Persistence\Content\UrlAlias\Handler $urlAliasHandler * @param array $settings */ public function __construct(RepositoryInterface $repository, Handler $urlAliasHandler, array $settings = array()) { $this->repository = $repository; $this->urlAliasHandler = $urlAliasHandler; // Union makes sure default settings are ignored if provided in argument $this->settings = $settings + array('showAllTranslations' => false); // Get prioritized languages from language service to not have to call it several times $this->settings['prioritizedLanguageList'] = $repository->getContentLanguageService()->getPrioritizedLanguageCodeList(); }
/** * Builds ContentType update struct for storage layer * * @param \eZ\Publish\API\Repository\Values\ContentType\ContentTypeDraft $contentTypeDraft * @param \eZ\Publish\API\Repository\Values\ContentType\ContentTypeUpdateStruct $contentTypeUpdateStruct * * @return \eZ\Publish\SPI\Persistence\Content\Type\UpdateStruct */ protected function buildSPIContentTypeUpdateStruct( APIContentTypeDraft $contentTypeDraft, ContentTypeUpdateStruct $contentTypeUpdateStruct ) { $updateStruct = new SPIContentTypeUpdateStruct(); $updateStruct->identifier = $contentTypeUpdateStruct->identifier !== null ? $contentTypeUpdateStruct->identifier : $contentTypeDraft->identifier; $updateStruct->remoteId = $contentTypeUpdateStruct->remoteId !== null ? $contentTypeUpdateStruct->remoteId : $contentTypeDraft->remoteId; $updateStruct->name = $contentTypeUpdateStruct->names !== null ? $contentTypeUpdateStruct->names : $contentTypeDraft->names; $updateStruct->description = $contentTypeUpdateStruct->descriptions !== null ? $contentTypeUpdateStruct->descriptions : $contentTypeDraft->descriptions; $updateStruct->modified = $contentTypeUpdateStruct->modificationDate !== null ? $contentTypeUpdateStruct->modificationDate->getTimestamp() : time(); $updateStruct->modifierId = $contentTypeUpdateStruct->modifierId !== null ? $contentTypeUpdateStruct->modifierId : $this->repository->getCurrentUser()->id; $updateStruct->urlAliasSchema = $contentTypeUpdateStruct->urlAliasSchema !== null ? $contentTypeUpdateStruct->urlAliasSchema : $contentTypeDraft->urlAliasSchema; $updateStruct->nameSchema = $contentTypeUpdateStruct->nameSchema !== null ? $contentTypeUpdateStruct->nameSchema : $contentTypeDraft->nameSchema; $updateStruct->isContainer = $contentTypeUpdateStruct->isContainer !== null ? $contentTypeUpdateStruct->isContainer : $contentTypeDraft->isContainer; $updateStruct->sortField = $contentTypeUpdateStruct->defaultSortField !== null ? $contentTypeUpdateStruct->defaultSortField : $contentTypeDraft->defaultSortField; $updateStruct->sortOrder = $contentTypeUpdateStruct->defaultSortOrder !== null ? (int)$contentTypeUpdateStruct->defaultSortOrder : $contentTypeDraft->defaultSortOrder; $updateStruct->defaultAlwaysAvailable = $contentTypeUpdateStruct->defaultAlwaysAvailable !== null ? $contentTypeUpdateStruct->defaultAlwaysAvailable : $contentTypeDraft->defaultAlwaysAvailable; $updateStruct->initialLanguageId = $this->repository->getContentLanguageService()->loadLanguage( $contentTypeUpdateStruct->mainLanguageCode !== null ? $contentTypeUpdateStruct->mainLanguageCode : $contentTypeDraft->mainLanguageCode )->id; return $updateStruct; }
/** * Validates input for updating object state groups and builds the InputStruct object. * * @param \eZ\Publish\API\Repository\Values\ObjectState\ObjectStateGroup $objectStateGroup * @param string $identifier * @param string $defaultLanguageCode * @param string[] $names * @param string[] $descriptions * * @return \eZ\Publish\SPI\Persistence\Content\ObjectState\InputStruct */ protected function buildObjectStateGroupUpdateInputStruct(APIObjectStateGroup $objectStateGroup, $identifier, $defaultLanguageCode, $names, $descriptions) { $inputStruct = new InputStruct(); if ($identifier !== null && (!is_string($identifier) || empty($identifier))) { throw new InvalidArgumentValue('identifier', $identifier); } $inputStruct->identifier = $identifier !== null ? $identifier : $objectStateGroup->identifier; if ($defaultLanguageCode !== null && (!is_string($defaultLanguageCode) || empty($defaultLanguageCode))) { throw new InvalidArgumentValue('defaultLanguageCode', $defaultLanguageCode); } $inputStruct->defaultLanguage = $defaultLanguageCode !== null ? $defaultLanguageCode : $objectStateGroup->defaultLanguageCode; if ($names !== null && (!is_array($names) || empty($names))) { throw new InvalidArgumentValue('names', $names); } $inputStruct->name = $names !== null ? $names : $objectStateGroup->getNames(); if (!isset($inputStruct->name[$inputStruct->defaultLanguage])) { throw new InvalidArgumentValue('names', $inputStruct->name); } foreach ($inputStruct->name as $languageCode => $name) { try { $this->repository->getContentLanguageService()->loadLanguage($languageCode); } catch (NotFoundException $e) { throw new InvalidArgumentValue('names', $inputStruct->name); } if (!is_string($name) || empty($name)) { throw new InvalidArgumentValue('names', $inputStruct->name); } } if ($descriptions !== null && !is_array($descriptions)) { throw new InvalidArgumentValue('descriptions', $descriptions); } $descriptions = $descriptions !== null ? $descriptions : $objectStateGroup->getDescriptions(); $descriptions = $descriptions !== null ? $descriptions : array(); $inputStruct->description = array(); foreach ($inputStruct->name as $languageCode => $name) { if (isset($descriptions[$languageCode]) && !empty($descriptions[$languageCode])) { $inputStruct->description[$languageCode] = $descriptions[$languageCode]; } else { $inputStruct->description[$languageCode] = ''; } } return $inputStruct; }
/** * Create a Content Type object. * * The content type is created in the state STATUS_DRAFT. * * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the user is not allowed to create a content type * @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException In case when * - array of content type groups does not contain at least one content type group * - identifier or remoteId in the content type create struct already exists * - there is a duplicate field identifier in the content type create struct * @throws \eZ\Publish\API\Repository\Exceptions\ContentTypeFieldDefinitionValidationException * if a field definition in the $contentTypeCreateStruct is not valid * @throws \eZ\Publish\API\Repository\Exceptions\ContentTypeValidationException * if a multiple field definitions of a same singular type are given * * @param \eZ\Publish\API\Repository\Values\ContentType\ContentTypeCreateStruct $contentTypeCreateStruct * @param \eZ\Publish\API\Repository\Values\ContentType\ContentTypeGroup[] $contentTypeGroups Required array of {@link APIContentTypeGroup} to link type with (must contain one) * * @return \eZ\Publish\API\Repository\Values\ContentType\ContentTypeDraft */ public function createContentType(APIContentTypeCreateStruct $contentTypeCreateStruct, array $contentTypeGroups) { if ($this->repository->hasAccess('class', 'create') !== true) { throw new UnauthorizedException('ContentType', 'create'); } // Prevent argument mutation $contentTypeCreateStruct = clone $contentTypeCreateStruct; $this->validateInputContentTypeCreateStruct($contentTypeCreateStruct); $this->validateInputContentTypeGroups($contentTypeGroups); $initialLanguageId = $this->repository->getContentLanguageService()->loadLanguage($contentTypeCreateStruct->mainLanguageCode)->id; try { $this->contentTypeHandler->loadByIdentifier($contentTypeCreateStruct->identifier); throw new InvalidArgumentException('$contentTypeCreateStruct', "Another ContentType with identifier '{$contentTypeCreateStruct->identifier}' exists"); } catch (APINotFoundException $e) { // Do nothing } if ($contentTypeCreateStruct->remoteId !== null) { try { $this->contentTypeHandler->loadByRemoteId($contentTypeCreateStruct->remoteId); throw new InvalidArgumentException('$contentTypeCreateStruct', "Another ContentType with remoteId '{$contentTypeCreateStruct->remoteId}' exists"); } catch (APINotFoundException $e) { // Do nothing } } $fieldDefinitionIdentifierSet = array(); $fieldDefinitionPositionSet = array(); foreach ($contentTypeCreateStruct->fieldDefinitions as $fieldDefinitionCreateStruct) { // Check for duplicate identifiers if (!isset($fieldDefinitionIdentifierSet[$fieldDefinitionCreateStruct->identifier])) { $fieldDefinitionIdentifierSet[$fieldDefinitionCreateStruct->identifier] = true; } else { throw new InvalidArgumentException('$contentTypeCreateStruct', "Argument contains duplicate field definition identifier '{$fieldDefinitionCreateStruct->identifier}'"); } // Check for duplicate positions if (!isset($fieldDefinitionPositionSet[$fieldDefinitionCreateStruct->position])) { $fieldDefinitionPositionSet[$fieldDefinitionCreateStruct->position] = true; } else { throw new InvalidArgumentException('$contentTypeCreateStruct', "Argument contains duplicate field definition position '{$fieldDefinitionCreateStruct->position}'"); } } $allValidationErrors = array(); $spiFieldDefinitions = array(); $fieldTypeIdentifierSet = array(); foreach ($contentTypeCreateStruct->fieldDefinitions as $fieldDefinitionCreateStruct) { /** @var $fieldType \eZ\Publish\SPI\FieldType\FieldType */ $fieldType = $this->fieldTypeRegistry->getFieldType($fieldDefinitionCreateStruct->fieldTypeIdentifier); if ($fieldType->isSingular() && isset($fieldTypeIdentifierSet[$fieldDefinitionCreateStruct->fieldTypeIdentifier])) { throw new ContentTypeValidationException("FieldType '%identifier%' is singular and can't be repeated in a ContentType", ['%identifier%' => $fieldDefinitionCreateStruct->fieldTypeIdentifier]); } $fieldTypeIdentifierSet[$fieldDefinitionCreateStruct->fieldTypeIdentifier] = true; $fieldType->applyDefaultSettings($fieldDefinitionCreateStruct->fieldSettings); $fieldType->applyDefaultValidatorConfiguration($fieldDefinitionCreateStruct->validatorConfiguration); $validationErrors = $this->validateFieldDefinitionCreateStruct($fieldDefinitionCreateStruct, $fieldType); if (!empty($validationErrors)) { $allValidationErrors[$fieldDefinitionCreateStruct->identifier] = $validationErrors; } if (!empty($allValidationErrors)) { continue; } $spiFieldDefinitions[] = $this->contentTypeDomainMapper->buildSPIFieldDefinitionCreate($fieldDefinitionCreateStruct, $fieldType); } if (!empty($allValidationErrors)) { throw new ContentTypeFieldDefinitionValidationException($allValidationErrors); } $groupIds = array_map(function (APIContentTypeGroup $contentTypeGroup) { return $contentTypeGroup->id; }, $contentTypeGroups); if ($contentTypeCreateStruct->creatorId === null) { $contentTypeCreateStruct->creatorId = $this->repository->getCurrentUserReference()->getUserId(); } if ($contentTypeCreateStruct->creationDate === null) { $timestamp = time(); } else { $timestamp = $contentTypeCreateStruct->creationDate->getTimestamp(); } if ($contentTypeCreateStruct->remoteId === null) { $contentTypeCreateStruct->remoteId = $this->domainMapper->getUniqueHash($contentTypeCreateStruct); } $spiContentTypeCreateStruct = new SPIContentTypeCreateStruct(array('identifier' => $contentTypeCreateStruct->identifier, 'name' => $contentTypeCreateStruct->names, 'status' => APIContentType::STATUS_DRAFT, 'description' => $contentTypeCreateStruct->descriptions === null ? array() : $contentTypeCreateStruct->descriptions, 'created' => $timestamp, 'modified' => $timestamp, 'creatorId' => $contentTypeCreateStruct->creatorId, 'modifierId' => $contentTypeCreateStruct->creatorId, 'remoteId' => $contentTypeCreateStruct->remoteId, 'urlAliasSchema' => $contentTypeCreateStruct->urlAliasSchema === null ? '' : $contentTypeCreateStruct->urlAliasSchema, 'nameSchema' => $contentTypeCreateStruct->nameSchema === null ? '' : $contentTypeCreateStruct->nameSchema, 'isContainer' => $contentTypeCreateStruct->isContainer === null ? false : $contentTypeCreateStruct->isContainer, 'initialLanguageId' => $initialLanguageId, 'sortField' => $contentTypeCreateStruct->defaultSortField === null ? Location::SORT_FIELD_PUBLISHED : $contentTypeCreateStruct->defaultSortField, 'sortOrder' => $contentTypeCreateStruct->defaultSortOrder === null ? Location::SORT_ORDER_DESC : $contentTypeCreateStruct->defaultSortOrder, 'groupIds' => $groupIds, 'fieldDefinitions' => $spiFieldDefinitions, 'defaultAlwaysAvailable' => $contentTypeCreateStruct->defaultAlwaysAvailable)); $this->repository->beginTransaction(); try { $spiContentType = $this->contentTypeHandler->create($spiContentTypeCreateStruct); $this->repository->commit(); } catch (Exception $e) { $this->repository->rollback(); throw $e; } return $this->contentTypeDomainMapper->buildContentTypeDraftDomainObject($spiContentType, array_map(function ($id) { return $this->contentTypeHandler->loadGroup($id); }, $spiContentType->groupIds)); }