/** * Test eZ\Publish\Core\Repository\NameSchemaService method * @covers \eZ\Publish\Core\Repository\NameSchemaService::resolve * @dataProvider providerForTestResolve */ public function testResolve($nameSchema, $expectedName) { /** @var $service \eZ\Publish\Core\Repository\NameSchemaService */ $service = new NameSchemaService($this->repository); list($content, $contentType) = $this->buildTestObjects(); $name = $service->resolve($nameSchema, $contentType, $content->fields, $content->versionInfo->languageCodes); self::assertEquals($expectedName, $name); }
/** * Recovers the $trashedLocation at its original place if possible. * * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the user is not allowed to recover the trash item at the parent location location * * If $newParentLocation is provided, $trashedLocation will be restored under it. * * @param \eZ\Publish\API\Repository\Values\Content\TrashItem $trashItem * @param \eZ\Publish\API\Repository\Values\Content\Location $newParentLocation * * @return \eZ\Publish\API\Repository\Values\Content\Location the newly created or recovered location */ public function recover(APITrashItem $trashItem, Location $newParentLocation = null) { if (!is_numeric($trashItem->id)) { throw new InvalidArgumentValue("id", $trashItem->id, "TrashItem"); } if ($newParentLocation === null && !is_numeric($trashItem->parentLocationId)) { throw new InvalidArgumentValue("parentLocationId", $trashItem->parentLocationId, "TrashItem"); } if ($newParentLocation !== null && !is_numeric($newParentLocation->id)) { throw new InvalidArgumentValue("parentLocationId", $newParentLocation->id, "Location"); } if ($this->repository->hasAccess('content', 'restore') !== true) { throw new UnauthorizedException('content', 'restore'); } $this->repository->beginTransaction(); try { $newParentLocationId = $newParentLocation ? $newParentLocation->id : $trashItem->parentLocationId; $newLocationId = $this->persistenceHandler->trashHandler()->recover($trashItem->id, $newParentLocationId); $content = $this->repository->getContentService()->loadContent($trashItem->contentId); $urlAliasNames = $this->nameSchemaService->resolveUrlAliasSchema($content); // Publish URL aliases for recovered location foreach ($urlAliasNames as $languageCode => $name) { $this->persistenceHandler->urlAliasHandler()->publishUrlAliasForLocation($newLocationId, $newParentLocationId, $name, $languageCode, $content->contentInfo->alwaysAvailable); } $this->repository->commit(); } catch (Exception $e) { $this->repository->rollback(); throw $e; } return $this->repository->getLocationService()->loadLocation($newLocationId); }
/** * Moves the subtree to $newParentLocation * * If a user has the permission to move the location to a target location * he can do it regardless of an existing descendant on which the user has no permission. * * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException If the current user user is not allowed to move this location to the target * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException If the current user user does not have read access to the whole source subtree * @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException If the new parent is in a subtree of the location * * @param \eZ\Publish\API\Repository\Values\Content\Location $location * @param \eZ\Publish\API\Repository\Values\Content\Location $newParentLocation */ public function moveSubtree(APILocation $location, APILocation $newParentLocation) { $location = $this->loadLocation($location->id); $newParentLocation = $this->loadLocation($newParentLocation->id); // check create permission on target location if (!$this->repository->canUser('content', 'create', $location->getContentInfo(), $newParentLocation)) { throw new UnauthorizedException('content', 'create'); } /** Check read access to whole source subtree * @var boolean|\eZ\Publish\API\Repository\Values\Content\Query\Criterion $contentReadCriterion */ $contentReadCriterion = $this->permissionsCriterionHandler->getPermissionsCriterion(); if ($contentReadCriterion === false) { throw new UnauthorizedException('content', 'read'); } else { if ($contentReadCriterion !== true) { // Query if there are any content in subtree current user don't have access to $query = new Query(array('limit' => 0, 'filter' => new CriterionLogicalAnd(new CriterionSubtree($location->pathString), new CriterionLogicalNot($contentReadCriterion)))); $result = $this->repository->getSearchService()->findContent($query, array(), false); if ($result->totalCount > 0) { throw new UnauthorizedException('content', 'read'); } } } if (strpos($newParentLocation->pathString, $location->pathString) === 0) { throw new InvalidArgumentException("\$newParentLocation", "new parent location is in a subtree of the given \$location"); } $this->repository->beginTransaction(); try { $this->persistenceHandler->locationHandler()->move($location->id, $newParentLocation->id); $content = $this->repository->getContentService()->loadContent($location->contentId); $urlAliasNames = $this->nameSchemaService->resolveUrlAliasSchema($content); foreach ($urlAliasNames as $languageCode => $name) { $this->persistenceHandler->urlAliasHandler()->publishUrlAliasForLocation($location->id, $newParentLocation->id, $name, $languageCode, $content->contentInfo->alwaysAvailable); } $this->persistenceHandler->urlAliasHandler()->locationMoved($location->id, $location->parentLocationId, $newParentLocation->id); $this->repository->commit(); } catch (Exception $e) { $this->repository->rollback(); throw $e; } }
/** * 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->repository->getFieldTypeService()->buildFieldType($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; } else { if (!$isFieldUpdated && $isLanguageNew && !$fieldDefinition->isTranslatable) { $isCopied = true; $fieldValue = $content->getField($fieldDefinition->identifier, $valueLanguageCode)->value; } else { if ($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 '{$fieldDefinition->identifier}' with language '{$languageCode}' is empty"); } } 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->getCurrentUser()->id, "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); }