public function onContentCacheClear(ContentCacheClearEvent $event) { $contentInfo = $event->getContentInfo(); foreach ($this->locationService->loadLocations($contentInfo) as $location) { $event->addLocationToClear($location); } }
/** * Parse input structure * * @param array $data * @param \eZ\Publish\Core\REST\Common\Input\ParsingDispatcher $parsingDispatcher * * @return \eZ\Publish\API\Repository\Values\Content\LocationCreateStruct */ public function parse(array $data, ParsingDispatcher $parsingDispatcher) { if (!array_key_exists('ParentLocation', $data) || !is_array($data['ParentLocation'])) { throw new Exceptions\Parser("Missing or invalid 'ParentLocation' element for LocationCreate."); } if (!array_key_exists('_href', $data['ParentLocation'])) { throw new Exceptions\Parser("Missing '_href' attribute for ParentLocation element in LocationCreate."); } $locationHrefParts = explode('/', $this->requestParser->parseHref($data['ParentLocation']['_href'], 'locationPath')); $locationCreateStruct = $this->locationService->newLocationCreateStruct(array_pop($locationHrefParts)); if (array_key_exists('priority', $data)) { $locationCreateStruct->priority = (int) $data['priority']; } if (array_key_exists('hidden', $data)) { $locationCreateStruct->hidden = $this->parserTools->parseBooleanValue($data['hidden']); } if (array_key_exists('remoteId', $data)) { $locationCreateStruct->remoteId = $data['remoteId']; } if (!array_key_exists('sortField', $data)) { throw new Exceptions\Parser("Missing 'sortField' element for LocationCreate."); } $locationCreateStruct->sortField = $this->parserTools->parseDefaultSortField($data['sortField']); if (!array_key_exists('sortOrder', $data)) { throw new Exceptions\Parser("Missing 'sortOrder' element for LocationCreate."); } $locationCreateStruct->sortOrder = $this->parserTools->parseDefaultSortOrder($data['sortOrder']); return $locationCreateStruct; }
/** * Converts internal links (ezcontent:// and ezlocation://) to URLs. * * @param \DOMDocument $document * * @return \DOMDocument */ public function convert(DOMDocument $document) { $document = clone $document; $xpath = new DOMXPath($document); $xpath->registerNamespace("docbook", "http://docbook.org/ns/docbook"); $linkAttributeExpression = "starts-with( @xlink:href, 'ezlocation://' ) or starts-with( @xlink:href, 'ezcontent://' )"; $xpathExpression = "//docbook:link[{$linkAttributeExpression}]|//docbook:ezlink"; /** @var \DOMElement $link */ foreach ($xpath->query($xpathExpression) as $link) { // Set resolved href to number character as a default if it can't be resolved $hrefResolved = "#"; $href = $link->getAttribute("xlink:href"); $location = null; preg_match("~^(.+://)?([^#]*)?(#.*|\\s*)?\$~", $href, $matches); list(, $scheme, $id, $fragment) = $matches; if ($scheme === "ezcontent://") { try { $contentInfo = $this->contentService->loadContentInfo($id); $location = $this->locationService->loadLocation($contentInfo->mainLocationId); $hrefResolved = $this->urlAliasRouter->generate($location) . $fragment; } catch (APINotFoundException $e) { if ($this->logger) { $this->logger->warning("While generating links for richtext, could not locate " . "Content object with ID " . $id); } } catch (APIUnauthorizedException $e) { if ($this->logger) { $this->logger->notice("While generating links for richtext, unauthorized to load " . "Content object with ID " . $id); } } } else { if ($scheme === "ezlocation://") { try { $location = $this->locationService->loadLocation($id); $hrefResolved = $this->urlAliasRouter->generate($location) . $fragment; } catch (APINotFoundException $e) { if ($this->logger) { $this->logger->warning("While generating links for richtext, could not locate " . "Location with ID " . $id); } } catch (APIUnauthorizedException $e) { if ($this->logger) { $this->logger->notice("While generating links for richtext, unauthorized to load " . "Location with ID " . $id); } } } else { $hrefResolved = $href; } } $hrefAttributeName = "xlink:href"; // For embeds set the resolved href to the separate attribute // Original href needs to be preserved in order to generate link parameters // This will need to change with introduction of UrlService and removal of URL link // resolving in external storage if ($link->localName === "ezlink") { $hrefAttributeName = "href_resolved"; } $link->setAttribute($hrefAttributeName, $hrefResolved); } return $document; }
public function testGetPreviewLocationNoLocation() { $contentId = 123; $contentInfo = $this->getMockBuilder('eZ\\Publish\\API\\Repository\\Values\\Content\\ContentInfo')->setConstructorArgs(array(array('id' => $contentId)))->getMockForAbstractClass(); $this->contentService->expects($this->once())->method('loadContentInfo')->with($contentId)->will($this->returnValue($contentInfo)); $this->locationHandler->expects($this->once())->method('loadParentLocationsForDraftContent')->with($contentId)->will($this->returnValue(array())); $this->locationHandler->expects($this->never())->method('loadLocation'); $this->assertNull($this->provider->loadMainLocation($contentId)); }
public function setPostCategories($postId, Request $request) { $this->login($request->request->get('username'), $request->request->get('password')); // @todo Replace categories instead of adding $contentInfo = $this->contentService->loadContentInfo($postId); foreach ($request->request->get('categories') as $category) { $this->locationService->createLocation($contentInfo, $this->locationService->newLocationCreateStruct($category['categoryId'])); } return new Response(true); }
public function filterLimitationValues(Limitation $limitation) { if (!is_array($limitation->limitationValues)) { return; } // UDW returns an array of location IDs. If we haven't used UDW, the value is as stored: an array of path strings. foreach ($limitation->limitationValues as $key => $limitationValue) { if (preg_match('/\\A\\d+\\z/', $limitationValue) === 1) { $limitation->limitationValues[$key] = $this->locationService->loadLocation($limitationValue)->pathString; } } }
/** * Parses input structure to a Criterion object. * * @param array $data * @param \eZ\Publish\Core\REST\Common\Input\ParsingDispatcher $parsingDispatcher * * @throws \eZ\Publish\Core\REST\Common\Exceptions\Parser * * @return \eZ\Publish\API\Repository\Values\Content\Query\Criterion\ParentLocationId */ public function parse(array $data, ParsingDispatcher $parsingDispatcher) { if (!array_key_exists('ParentLocationRemoteIdCriterion', $data)) { throw new Exceptions\Parser('Invalid <ParentLocationRemoteIdCriterion> format'); } $contentIdArray = array(); foreach (explode(',', $data['ParentLocationRemoteIdCriterion']) as $parentRemoteId) { $location = $this->locationService->loadLocationByRemoteId($parentRemoteId); $contentIdArray[] = $location->id; } return new ParentLocationIdCriterion($contentIdArray); }
/** * Returns all places contained in a place_list that are located between the range defined in * the default configuration. A sort clause array can be provided in order to sort the results. * * @param int|string $locationId * @param float $latitude * @param float $longitude * @param string|string[] $contentTypes to be retrieved * @param int $maxDist Maximum distance for the search in km * @param array $sortClauses * @param string|string[] $languages to be retrieved * * @return \eZ\Publish\API\Repository\Values\Content\Content[] */ public function getPlaceListSorted($locationId, $latitude, $longitude, $contentTypes, $maxDist = null, $sortClauses = array(), $languages = array()) { $location = $this->locationService->loadLocation($locationId); if ($maxDist === null) { $maxDist = $this->placeListMaxDist; } $query = new Query(); $query->filter = new Criterion\LogicalAnd(array(new Criterion\ContentTypeIdentifier($contentTypes), new Criterion\Subtree($location->pathString), new Criterion\LanguageCode($languages), new Criterion\MapLocationDistance("location", Criterion\Operator::BETWEEN, array($this->placeListMinDist, $maxDist), $latitude, $longitude))); $query->sortClauses = $sortClauses; $searchResults = $this->searchService->findContent($query); return $this->searchHelper->buildListFromSearchResult($searchResults); }
/** * Visit struct returned by controllers. * * @param \eZ\Publish\Core\REST\Common\Output\Visitor $visitor * @param \eZ\Publish\Core\REST\Common\Output\Generator $generator * @param \eZ\Publish\API\Repository\Values\Content\Location $location */ public function visit(Visitor $visitor, Generator $generator, $location) { $generator->startObjectElement('Location'); $visitor->setHeader('Content-Type', $generator->getMediaType('Location')); $visitor->setHeader('Accept-Patch', $generator->getMediaType('LocationUpdate')); $generator->startAttribute('href', $this->router->generate('ezpublish_rest_loadLocation', array('locationPath' => trim($location->pathString, '/')))); $generator->endAttribute('href'); $generator->startValueElement('id', $location->id); $generator->endValueElement('id'); $generator->startValueElement('priority', $location->priority); $generator->endValueElement('priority'); $generator->startValueElement('hidden', $this->serializeBool($generator, $location->hidden)); $generator->endValueElement('hidden'); $generator->startValueElement('invisible', $this->serializeBool($generator, $location->invisible)); $generator->endValueElement('invisible'); $generator->startObjectElement('ParentLocation', 'Location'); if (trim($location->pathString, '/') !== '1') { $generator->startAttribute('href', $this->router->generate('ezpublish_rest_loadLocation', array('locationPath' => implode('/', array_slice($location->path, 0, count($location->path) - 1))))); $generator->endAttribute('href'); } $generator->endObjectElement('ParentLocation'); $generator->startValueElement('pathString', $location->pathString); $generator->endValueElement('pathString'); $generator->startValueElement('depth', $location->depth); $generator->endValueElement('depth'); $generator->startValueElement('childCount', $this->locationService->getLocationChildCount($location)); $generator->endValueElement('childCount'); $generator->startValueElement('remoteId', $location->remoteId); $generator->endValueElement('remoteId'); $generator->startObjectElement('Children', 'LocationList'); $generator->startAttribute('href', $this->router->generate('ezpublish_rest_loadLocationChildren', array('locationPath' => trim($location->pathString, '/')))); $generator->endAttribute('href'); $generator->endObjectElement('Children'); $generator->startObjectElement('Content'); $generator->startAttribute('href', $this->router->generate('ezpublish_rest_loadContent', array('contentId' => $location->contentId))); $generator->endAttribute('href'); $generator->endObjectElement('Content'); $generator->startValueElement('sortField', $this->serializeSortField($location->sortField)); $generator->endValueElement('sortField'); $generator->startValueElement('sortOrder', $this->serializeSortOrder($location->sortOrder)); $generator->endValueElement('sortOrder'); $generator->startObjectElement('UrlAliases', 'UrlAliasRefList'); $generator->startAttribute('href', $this->router->generate('ezpublish_rest_listLocationURLAliases', array('locationPath' => trim($location->pathString, '/')))); $generator->endAttribute('href'); $generator->endObjectElement('UrlAliases'); $generator->startObjectElement('ContentInfo', 'ContentInfo'); $generator->startAttribute('href', $this->router->generate('ezpublish_rest_loadContent', array('contentId' => $location->contentId))); $generator->endAttribute('href'); $visitor->visitValueObject(new RestContentValue($location->contentInfo)); $generator->endObjectElement('ContentInfo'); $generator->endObjectElement('Location'); }
/** * Renders top menu with child items. * * @param string $template * * @return \Symfony\Component\HttpFoundation\Response */ public function getChildNodesAction($template) { $query = new LocationQuery(); $query->query = $this->menuCriteria->generateChildCriterion($this->locationService->loadLocation($this->topMenuLocationId), $this->configResolver->getParameter('languages')); $query->sortClauses = [new SortClause\Location\Priority(LocationQuery::SORT_ASC)]; $query->performCount = false; $content = $this->searchService->findLocations($query); $menuItems = []; foreach ($content->searchHits as $hit) { $menuItems[] = $hit->valueObject; } return $this->templating->renderResponse($template, ['menuItems' => $menuItems], new Response()); }
/** * Displays and processes a content creation form. Showing the form does not create a draft in the repository. * * @param int $contentTypeIdentifier ContentType id to create * @param string $language Language code to create the content in (eng-GB, ger-DE, ...)) * @param int $parentLocationId Location the content should be a child of * @param \Symfony\Component\HttpFoundation\Request $request * * @return \Symfony\Component\HttpFoundation\Response */ public function createWithoutDraftAction($contentTypeIdentifier, $language, $parentLocationId, Request $request) { $contentType = $this->contentTypeService->loadContentTypeByIdentifier($contentTypeIdentifier); $data = (new ContentCreateMapper())->mapToFormData($contentType, ['mainLanguageCode' => $language, 'parentLocation' => $this->locationService->newLocationCreateStruct($parentLocationId)]); $form = $this->createForm(ContentEditType::class, $data, ['languageCode' => $language]); $form->handleRequest($request); if ($form->isValid()) { $this->contentActionDispatcher->dispatchFormAction($form, $data, $form->getClickedButton()->getName()); if ($response = $this->contentActionDispatcher->getResponse()) { return $response; } } return $this->render('EzSystemsRepositoryFormsBundle:Content:content_edit.html.twig', ['form' => $form->createView(), 'languageCode' => $language, 'pagelayout' => $this->pagelayout]); }
/** * Returns a valid Location object for $contentId. * Will either load mainLocationId (if available) or build a virtual Location object. * * @param mixed $contentId * * @return \eZ\Publish\API\Repository\Values\Content\Location|null Null when content does not have location */ public function getPreviewLocation($contentId) { // contentInfo must be reloaded as content is not published yet (e.g. no mainLocationId) $contentInfo = $this->contentService->loadContentInfo($contentId); // mainLocationId already exists, content has been published at least once. if ($contentInfo->mainLocationId) { $location = $this->locationService->loadLocation($contentInfo->mainLocationId); } else { // @todo In future releases this will be a full draft location when this feature // is implemented. Or it might return null when content does not have location, // but for now we can't detect that so we return a virtual draft location $location = new Location(array('contentInfo' => $contentInfo, 'status' => Location::STATUS_DRAFT)); } return $location; }
/** * Restores a trashItem. * * @param $trashItemId * * @throws \eZ\Publish\Core\REST\Server\Exceptions\ForbiddenException * * @return \eZ\Publish\Core\REST\Server\Values\ResourceCreated */ public function restoreTrashItem($trashItemId, Request $request) { $requestDestination = null; try { $requestDestination = $request->headers->get('Destination'); } catch (InvalidArgumentException $e) { // No Destination header } $parentLocation = null; if ($request->headers->has('Destination')) { $locationPathParts = explode('/', $this->requestParser->parseHref($request->headers->get('Destination'), 'locationPath')); try { $parentLocation = $this->locationService->loadLocation(array_pop($locationPathParts)); } catch (NotFoundException $e) { throw new ForbiddenException($e->getMessage()); } } $trashItem = $this->trashService->loadTrashItem($trashItemId); if ($requestDestination === null) { // If we're recovering under the original location // check if it exists, to return "403 Forbidden" in case it does not try { $this->locationService->loadLocation($trashItem->parentLocationId); } catch (NotFoundException $e) { throw new ForbiddenException($e->getMessage()); } } $location = $this->trashService->recover($trashItem, $parentLocation); return new Values\ResourceCreated($this->router->generate('ezpublish_rest_loadLocation', array('locationPath' => trim($location->pathString, '/')))); }
/** * Creates and prepares location create structure. * * @param array $data * @param int $defaultLocationId * @return \eZ\Publish\API\Repository\Values\Content\LocationCreateStruct */ private function getLocationCreateStruct($data, $defaultLocationId) { $parentLocationId = $this->getContentDataParentLocationId($data, $defaultLocationId); $locationStruct = $this->locationService->newLocationCreateStruct($parentLocationId); $locationStruct->priority = isset($data['priority']) ? $data['priority'] : 0; return $locationStruct; }
/** * Assigns the user to a user group * * @param $userId * * @throws \eZ\Publish\Core\REST\Server\Exceptions\ForbiddenException * @return \eZ\Publish\Core\REST\Server\Values\UserGroupRefList */ public function assignUserToUserGroup($userId) { $user = $this->userService->loadUser($userId); try { $userGroupLocation = $this->locationService->loadLocation($this->extractLocationIdFromPath($this->request->query->get('group'))); } catch (APINotFoundException $e) { throw new Exceptions\ForbiddenException($e->getMessage()); } try { $userGroup = $this->userService->loadUserGroup($userGroupLocation->contentId); } catch (APINotFoundException $e) { throw new Exceptions\ForbiddenException($e->getMessage()); } try { $this->userService->assignUserToUserGroup($user, $userGroup); } catch (InvalidArgumentException $e) { throw new Exceptions\ForbiddenException($e->getMessage()); } $userGroups = $this->userService->loadUserGroupsOfUser($user); $restUserGroups = array(); foreach ($userGroups as $userGroup) { $userGroupContentInfo = $userGroup->getVersionInfo()->getContentInfo(); $userGroupLocation = $this->locationService->loadLocation($userGroupContentInfo->mainLocationId); $contentType = $this->contentTypeService->loadContentType($userGroupContentInfo->contentTypeId); $restUserGroups[] = new Values\RestUserGroup($userGroup, $contentType, $userGroupContentInfo, $userGroupLocation, $this->contentService->loadRelations($userGroup->getVersionInfo())); } return new Values\UserGroupRefList($restUserGroups, $this->router->generate('ezpublish_rest_loadUserGroupsOfUser', array('userId' => $userId)), $userId); }
/** * Returns a valid Location object for $contentId. * Will either load mainLocationId (if available) or build a virtual Location object. * * @param mixed $contentId * * @return \eZ\Publish\API\Repository\Values\Content\Location|null Null when content does not have location */ public function getPreviewLocation( $contentId ) { // contentInfo must be reloaded as content is not published yet (e.g. no mainLocationId) $contentInfo = $this->contentService->loadContentInfo( $contentId ); // mainLocationId already exists, content has been published at least once. if ( $contentInfo->mainLocationId ) { $location = $this->locationService->loadLocation( $contentInfo->mainLocationId ); } // New Content, never published, create a virtual location object. else { // @todo In future releases this will be a full draft location when this feature // is implemented. Or it might return null when content does not have location, // but for now we can't detect that so we return a virtual draft location $location = new Location( array( // Faking using root locationId 'id' => $this->configResolver->getParameter( 'content.tree_root.location_id' ), 'contentInfo' => $contentInfo, 'status' => Location::STATUS_DRAFT ) ); } return $location; }
/** * Returns array of child content objects from given $locationId. * * @param int $locationId * @param int $limit * * @return array */ private function fetchItems($locationId, $limit) { $languages = $this->configResolver->getParameter('languages'); $query = new Query(); $location = $this->locationService->loadLocation($locationId); $query->query = $this->childrenCriteria->generateChildCriterion($location, $languages); $query->performCount = false; $query->limit = $limit; $query->sortClauses = [new SortClause\DatePublished(Query::SORT_DESC)]; $results = $this->searchService->findContent($query); $items = []; foreach ($results->searchHits as $item) { $items[] = $item->valueObject; } return $items; }
/** * Generates a URL for a location, from the given parameters. * * It is possible to directly pass a Location object as the route name, as the ChainRouter allows it through ChainedRouterInterface. * * If $name is a route name, the "location" key in $parameters must be set to a valid eZ\Publish\API\Repository\Values\Content\Location object. * "locationId" can also be provided. * * If the generator is not able to generate the url, it must throw the RouteNotFoundException * as documented below. * * @see UrlAliasRouter::supports() * * @param string|\eZ\Publish\API\Repository\Values\Content\Location $name The name of the route or a Location instance * @param mixed $parameters An array of parameters * @param int $referenceType The type of reference to be generated (one of the constants) * * @throws \LogicException * @throws \Symfony\Component\Routing\Exception\RouteNotFoundException * @throws \InvalidArgumentException * * @return string The generated URL * * @api */ public function generate($name, $parameters = array(), $referenceType = UrlGeneratorInterface::ABSOLUTE_PATH) { // Direct access to Location if ($name instanceof Location) { return $this->generator->generate($name, $parameters, $referenceType); } // Normal route name if ($name === self::URL_ALIAS_ROUTE_NAME) { if (isset($parameters['location']) || isset($parameters['locationId'])) { // Check if location is a valid Location object if (isset($parameters['location']) && !$parameters['location'] instanceof Location) { throw new LogicException("When generating an UrlAlias route, 'location' parameter must be a valid eZ\\Publish\\API\\Repository\\Values\\Content\\Location."); } $location = isset($parameters['location']) ? $parameters['location'] : $this->locationService->loadLocation($parameters['locationId']); unset($parameters['location'], $parameters['locationId'], $parameters['viewType'], $parameters['layout']); return $this->generator->generate($location, $parameters, $referenceType); } if (isset($parameters['contentId'])) { $contentInfo = $this->contentService->loadContentInfo($parameters['contentId']); unset($parameters['contentId'], $parameters['viewType'], $parameters['layout']); if (empty($contentInfo->mainLocationId)) { throw new LogicException('Cannot generate an UrlAlias route for content without main location.'); } return $this->generator->generate($this->locationService->loadLocation($contentInfo->mainLocationId), $parameters, $referenceType); } throw new InvalidArgumentException("When generating an UrlAlias route, either 'location', 'locationId' or 'contentId' must be provided."); } throw new RouteNotFoundException('Could not match route'); }
/** * Visit struct returned by controllers. * * @param \eZ\Publish\Core\REST\Common\Output\Visitor $visitor * @param \eZ\Publish\Core\REST\Common\Output\Generator $generator * @param \eZ\Publish\Core\REST\Server\Values\RestExecutedView $data */ public function visit(Visitor $visitor, Generator $generator, $data) { $generator->startObjectElement('View'); $visitor->setHeader('Content-Type', $generator->getMediaType('View')); $generator->startAttribute('href', $this->router->generate('ezpublish_rest_views_load', array('viewId' => $data->identifier))); $generator->endAttribute('href'); $generator->startValueElement('identifier', $data->identifier); $generator->endValueElement('identifier'); // BEGIN Query $generator->startObjectElement('Query'); $generator->endObjectElement('Query'); // END Query // BEGIN Result $generator->startObjectElement('Result', 'ViewResult'); $generator->startAttribute('href', $this->router->generate('ezpublish_rest_views_load_results', array('viewId' => $data->identifier))); $generator->endAttribute('href'); // BEGIN Result metadata $generator->startValueElement('count', $data->searchResults->totalCount); $generator->endValueElement('count'); $generator->startValueElement('time', $data->searchResults->time); $generator->endValueElement('time'); $generator->startValueElement('timedOut', $generator->serializeBool($data->searchResults->timedOut)); $generator->endValueElement('timedOut'); $generator->startValueElement('maxScore', $data->searchResults->maxScore); $generator->endValueElement('maxScore'); // END Result metadata // BEGIN searchHits $generator->startHashElement('searchHits'); $generator->startList('searchHit'); foreach ($data->searchResults->searchHits as $searchHit) { $generator->startObjectElement('searchHit'); $generator->startAttribute('score', 0); $generator->endAttribute('score'); $generator->startAttribute('index', 0); $generator->endAttribute('index'); $generator->startObjectElement('value'); // @todo Refactor if ($searchHit->valueObject instanceof ApiValues\Content) { /** @var \eZ\Publish\API\Repository\Values\Content\ContentInfo $contentInfo */ $contentInfo = $searchHit->valueObject->contentInfo; $valueObject = new RestContentValue($contentInfo, $this->locationService->loadLocation($contentInfo->mainLocationId), $searchHit->valueObject, $this->contentTypeService->loadContentType($contentInfo->contentTypeId), $this->contentService->loadRelations($searchHit->valueObject->getVersionInfo())); } elseif ($searchHit->valueObject instanceof ApiValues\Location) { $valueObject = $searchHit->valueObject; } elseif ($searchHit->valueObject instanceof ApiValues\ContentInfo) { $valueObject = new RestContentValue($searchHit->valueObject); } else { throw new Exceptions\InvalidArgumentException('Unhandled object type'); } $visitor->visitValueObject($valueObject); $generator->endObjectElement('value'); $generator->endObjectElement('searchHit'); } $generator->endList('searchHit'); $generator->endHashElement('searchHits'); // END searchHits $generator->endObjectElement('Result'); // END Result $generator->endObjectElement('View'); }
/** * Displays blog post content with random selected blog posts. * * @param \eZ\Publish\Core\MVC\Symfony\View\ContentView $view * * @return \eZ\Publish\Core\MVC\Symfony\View\ContentView */ public function showBlogPostAction(ContentView $view) { $languages = $this->configResolver->getParameter('languages'); $location = $this->locationService->loadLocation($view->getLocation()->parentLocationId); $query = new Query(); $query->query = $this->childrenCriteria->generateChildCriterion($location, $languages); $query->performCount = false; $query->sortClauses = [new SortClause\DatePublished(Query::SORT_DESC)]; $results = $this->searchService->findContent($query); $randomPosts = []; foreach ($results->searchHits as $item) { $randomPosts[] = $item->valueObject; } shuffle($randomPosts); $view->addParameters(['location' => $location, 'content' => $this->contentService->loadContentByContentInfo($view->getLocation()->getContentInfo()), 'randomPosts' => array_slice($randomPosts, 0, $this->randomPostsLimit, true)]); return $view; }
/** * Queries the repository for menu items, as locations filtered on the list in TopIdentifierList in menu.ini * @param int|string $rootLocationId Root location for menu items. Only two levels below this one are searched * @return SearchHit[] */ private function getMenuItems($rootLocationId) { $rootLocation = $this->locationService->loadLocation($rootLocationId); $query = new LocationQuery(); $query->query = new Criterion\LogicalAnd(array(new Criterion\ContentTypeIdentifier($this->getTopMenuContentTypeIdentifierList()), new Criterion\Visibility(Criterion\Visibility::VISIBLE), new Criterion\Location\Depth(Criterion\Operator::BETWEEN, array($rootLocation->depth + 1, $rootLocation->depth + 2)), new Criterion\Subtree($rootLocation->pathString), new Criterion\LanguageCode($this->configResolver->getParameter('languages')))); $query->sortClauses = array(new Query\SortClause\Location\Path()); return $this->searchService->findLocations($query)->searchHits; }
/** * Converts internal links (eznode:// and ezobject://) to URLs. * * @param \DOMDocument $xmlDoc * * @return string|null */ public function convert(DOMDocument $xmlDoc) { $xpath = new DOMXPath($xmlDoc); $elements = $xpath->query('//link|//embed|//embed-inline'); /** @var \DOMElement $element */ foreach ($elements as $element) { $location = null; if ($this->elementHasAttribute($element, 'object_id')) { try { $contentInfo = $this->contentService->loadContentInfo($this->getElementAttribute($element, 'object_id')); $location = $this->locationService->loadLocation($contentInfo->mainLocationId); } catch (APINotFoundException $e) { if ($this->logger) { $this->logger->warning('While generating links for xmltext, could not locate ' . 'Content object with ID ' . $this->getElementAttribute($element, 'object_id')); } } catch (APIUnauthorizedException $e) { if ($this->logger) { $this->logger->notice('While generating links for xmltext, unauthorized to load ' . 'Content object with ID ' . $this->getElementAttribute($element, 'object_id')); } } } if ($this->elementHasAttribute($element, 'node_id')) { try { $location = $this->locationService->loadLocation($this->getElementAttribute($element, 'node_id')); } catch (APINotFoundException $e) { if ($this->logger) { $this->logger->warning('While generating links for xmltext, could not locate ' . 'Location with ID ' . $this->getElementAttribute($element, 'node_id')); } } catch (APIUnauthorizedException $e) { if ($this->logger) { $this->logger->notice('While generating links for xmltext, unauthorized to load ' . 'Location with ID ' . $this->getElementAttribute($element, 'node_id')); } } } if ($location !== null) { $element->setAttribute('url', $this->urlAliasRouter->generate($location)); } // Copy temporary URL if it exists and is not set at this point if (!$element->hasAttribute('url') && $element->hasAttribute(EmbedLinking::TEMP_PREFIX . 'url')) { $element->setAttribute('url', $element->getAttribute(EmbedLinking::TEMP_PREFIX . 'url')); } if ($this->elementHasAttribute($element, 'anchor_name')) { $element->setAttribute('url', $element->getAttribute('url') . '#' . $this->getElementAttribute($element, 'anchor_name')); } } }
/** * Parse input structure. * * @param array $data * @param \eZ\Publish\Core\REST\Common\Input\ParsingDispatcher $parsingDispatcher * * @return \eZ\Publish\Core\REST\Server\Values\RestUserGroupUpdateStruct */ public function parse(array $data, ParsingDispatcher $parsingDispatcher) { $parsedData = array(); if (array_key_exists('mainLanguageCode', $data)) { $parsedData['mainLanguageCode'] = $data['mainLanguageCode']; } if (array_key_exists('Section', $data) && is_array($data['Section'])) { if (!array_key_exists('_href', $data['Section'])) { throw new Exceptions\Parser("Missing '_href' attribute for Section element in UserGroupUpdate."); } $parsedData['sectionId'] = $this->requestParser->parseHref($data['Section']['_href'], 'sectionId'); } if (array_key_exists('remoteId', $data)) { $parsedData['remoteId'] = $data['remoteId']; } if (array_key_exists('fields', $data)) { $groupLocationParts = explode('/', $this->requestParser->parseHref($data['__url'], 'groupPath')); $groupLocation = $this->locationService->loadLocation(array_pop($groupLocationParts)); if (!is_array($data['fields']) || !array_key_exists('field', $data['fields']) || !is_array($data['fields']['field'])) { throw new Exceptions\Parser("Invalid 'fields' element for UserGroupUpdate."); } $parsedData['fields'] = array(); foreach ($data['fields']['field'] as $fieldData) { if (!array_key_exists('fieldDefinitionIdentifier', $fieldData)) { throw new Exceptions\Parser("Missing 'fieldDefinitionIdentifier' element in field data for UserGroupUpdate."); } if (!array_key_exists('fieldValue', $fieldData)) { throw new Exceptions\Parser("Missing 'fieldValue' element for '{$fieldData['fieldDefinitionIdentifier']}' identifier in UserGroupUpdate."); } $fieldValue = $this->fieldTypeParser->parseFieldValue($groupLocation->contentId, $fieldData['fieldDefinitionIdentifier'], $fieldData['fieldValue']); $languageCode = null; if (array_key_exists('languageCode', $fieldData)) { $languageCode = $fieldData['languageCode']; } $parsedData['fields'][$fieldData['fieldDefinitionIdentifier']] = array('fieldValue' => $fieldValue, 'languageCode' => $languageCode); } } $userGroupUpdateStruct = $this->userService->newUserGroupUpdateStruct(); if (!empty($parsedData)) { if (array_key_exists('mainLanguageCode', $parsedData) || array_key_exists('remoteId', $parsedData)) { $userGroupUpdateStruct->contentMetadataUpdateStruct = $this->contentService->newContentMetadataUpdateStruct(); if (array_key_exists('mainLanguageCode', $parsedData)) { $userGroupUpdateStruct->contentMetadataUpdateStruct->mainLanguageCode = $parsedData['mainLanguageCode']; } if (array_key_exists('remoteId', $parsedData)) { $userGroupUpdateStruct->contentMetadataUpdateStruct->remoteId = $parsedData['remoteId']; } } if (array_key_exists('fields', $parsedData)) { $userGroupUpdateStruct->contentUpdateStruct = $this->contentService->newContentUpdateStruct(); foreach ($parsedData['fields'] as $fieldDefinitionIdentifier => $fieldValue) { $userGroupUpdateStruct->contentUpdateStruct->setField($fieldDefinitionIdentifier, $fieldValue['fieldValue'], $fieldValue['languageCode']); } } } return new RestUserGroupUpdateStruct($userGroupUpdateStruct, array_key_exists('sectionId', $parsedData) ? $parsedData['sectionId'] : null); }
protected function execute(InputInterface $input, OutputInterface $output) { /** @var $repository \eZ\Publish\API\Repository\Repository */ $repository = $this->getContainer()->get('ezpublish.api.repository'); $this->contentService = $repository->getContentService(); $this->locationService = $repository->getLocationService(); // fetch the input argument $locationId = $input->getArgument('locationId'); try { // load the starting location and browse $location = $this->locationService->loadLocation($locationId); $this->browseLocation($location, $output); } catch (\eZ\Publish\API\Repository\Exceptions\NotFoundException $e) { $output->writeln("<error>No location found with id {$locationId}</error>"); } catch (\eZ\Publish\API\Repository\Exceptions\UnauthorizedException $e) { $output->writeln("<error>Anonymous users are not allowed to read location with id {$locationId}</error>"); } }
/** * Loads the main location for $contentId. * * If the content does not have a location (yet), but has a Location draft, it is returned instead. * Location drafts do not have an id (it is set to null), and can be tested using the isDraft() method. * * If the content doesn't have a location nor a location draft, null is returned. * * @param mixed $contentId * * @return \eZ\Publish\API\Repository\Values\Content\Location|null */ public function loadMainLocation($contentId) { $location = null; $contentInfo = $this->contentService->loadContentInfo($contentId); // mainLocationId already exists, content has been published at least once. if ($contentInfo->mainLocationId) { $location = $this->locationService->loadLocation($contentInfo->mainLocationId); } elseif (!$contentInfo->published) { // New Content, never published, create a virtual location object. // In cases content is missing locations this will return empty array $parentLocations = $this->locationHandler->loadParentLocationsForDraftContent($contentInfo->id); if (empty($parentLocations)) { return null; } $location = new Location(array('contentInfo' => $contentInfo, 'status' => Location::STATUS_DRAFT, 'parentLocationId' => $parentLocations[0]->id, 'depth' => $parentLocations[0]->depth + 1, 'pathString' => $parentLocations[0]->pathString . '/x')); } return $location; }
/** * Loads the main location for $contentId * * If the content does not have a location (yet), but has a Location draft, it is returned instead. * Location drafts do not have an id (it is set to null), and can be tested using the isDraft() method. * * If the content doesn't have a location nor a location draft, null is returned. * * @param mixed $contentInfo * * @return \eZ\Publish\API\Repository\Values\Content\Location|null */ public function loadMainLocation($contentId) { $contentInfo = $this->contentService->loadContentInfo($contentId); // mainLocationId already exists, content has been published at least once. if ($contentInfo->mainLocationId) { $location = $this->locationService->loadLocation($contentInfo->mainLocationId); } else { // @todo In future releases this will be a full draft location when this feature // is implemented. Or it might return null when content does not have location, // but for now we can't detect that so we return a virtual draft location $parentLocations = $this->locationHandler->loadParentLocationsForDraftContent($contentInfo->id); if (count($parentLocations) === 0) { return null; } $location = new Location(array('contentInfo' => $contentInfo, 'status' => Location::STATUS_DRAFT, 'parentLocationId' => $parentLocations[0]->id, 'depth' => $parentLocations[0]->depth + 1)); } return $location; }
/** * Converts internal links (ezcontent:// and ezlocation://) to URLs. * * @param \DOMDocument $document * * @return \DOMDocument */ public function convert(DOMDocument $document) { $document = clone $document; $xpath = new DOMXPath($document); $xpath->registerNamespace("docbook", "http://docbook.org/ns/docbook"); $xpathExpression = "//docbook:link[starts-with( @xlink:href, 'ezlocation://' ) or starts-with( @xlink:href, 'ezcontent://' )]"; /** @var \DOMElement $link */ foreach ($xpath->query($xpathExpression) as $link) { $location = null; preg_match("~^(.+)://([^#]*)?(#.*|\\s*)?\$~", $link->getAttribute("xlink:href"), $matches); list(, $scheme, $id, $fragment) = $matches; if ($scheme === "ezcontent") { try { $contentInfo = $this->contentService->loadContentInfo($id); $location = $this->locationService->loadLocation($contentInfo->mainLocationId); } catch (APINotFoundException $e) { if ($this->logger) { $this->logger->warning("While generating links for richtext, could not locate " . "Content object with ID " . $id); } } catch (APIUnauthorizedException $e) { if ($this->logger) { $this->logger->notice("While generating links for richtext, unauthorized to load " . "Content object with ID " . $id); } } } if ($scheme === "ezlocation") { try { $location = $this->locationService->loadLocation($id); } catch (APINotFoundException $e) { if ($this->logger) { $this->logger->warning("While generating links for richtext, could not locate " . "Location with ID " . $id); } } catch (APIUnauthorizedException $e) { if ($this->logger) { $this->logger->notice("While generating links for richtext, unauthorized to load " . "Location with ID " . $id); } } } if ($location !== null) { $link->setAttribute('xlink:href', $this->urlAliasRouter->generate($location) . $fragment); } } return $document; }
/** * Tests the LocationCreateStruct visitor. * * @return string */ public function testVisit() { $visitor = $this->getVisitor(); $generator = $this->getGenerator(); $generator->startDocument(null); $locationCreateStruct = new LocationCreateStruct(); $locationCreateStruct->hidden = false; $locationCreateStruct->parentLocationId = 42; $locationCreateStruct->priority = 0; $locationCreateStruct->remoteId = 'remote-id'; $locationCreateStruct->sortField = Location::SORT_FIELD_PATH; $locationCreateStruct->sortOrder = Location::SORT_ORDER_ASC; $this->locationServiceMock->expects($this->once())->method('loadLocation')->with(42)->will($this->returnValue(new Location(['pathString' => '/1/2/42']))); $this->getRouterMock()->expects($this->once())->method('generate')->with('ezpublish_rest_loadLocation', ['locationPath' => '1/2/42'])->will($this->returnValue('/content/locations/1/2/42')); $visitor->visit($this->getVisitorMock(), $generator, $locationCreateStruct); $result = $generator->endDocument(null); $this->assertNotNull($result); return $result; }
public function onContentCacheClear(ContentCacheClearEvent $event) { $contentInfo = $event->getContentInfo(); $versionInfo = $this->contentService->loadVersionInfo($contentInfo); foreach ($this->contentService->loadRelations($versionInfo) as $relation) { foreach ($this->locationService->loadLocations($relation->getDestinationContentInfo()) as $relatedLocation) { $event->addLocationToClear($relatedLocation); } } // Using sudo since loading reverse relations is conditioned to content/reverserelatedlist permission and we don't need this check here. /** @var \eZ\Publish\API\Repository\Values\Content\Relation[] $reverseRelations */ $reverseRelations = $this->repository->sudo(function () use($contentInfo) { return $this->contentService->loadReverseRelations($contentInfo); }); foreach ($reverseRelations as $reverseRelation) { foreach ($this->locationService->loadLocations($reverseRelation->getSourceContentInfo()) as $relatedLocation) { $event->addLocationToClear($relatedLocation); } } }
/** * Returns a role assignment to the given user group * * @param $groupPath * @param $roleId * * @throws \eZ\Publish\Core\REST\Common\Exceptions\NotFoundException * @return \eZ\Publish\Core\REST\Server\Values\RestUserGroupRoleAssignment */ public function loadRoleAssignmentForUserGroup($groupPath, $roleId) { $groupLocationParts = explode('/', $groupPath); $groupLocation = $this->locationService->loadLocation(array_pop($groupLocationParts)); $userGroup = $this->userService->loadUserGroup($groupLocation->contentId); $roleAssignments = $this->roleService->getRoleAssignmentsForUserGroup($userGroup); foreach ($roleAssignments as $roleAssignment) { if ($roleAssignment->getRole()->id == $roleId) { return new Values\RestUserGroupRoleAssignment($roleAssignment, $groupPath); } } throw new Exceptions\NotFoundException("Role assignment not found: '{$this->request->getPathInfo()}'."); }