public function testGetSlice() { $offset = 20; $limit = 10; $nbResults = 123; $query = new Query(); $query->criterion = $this->getMock('eZ\\Publish\\API\\Repository\\Values\\Content\\Query\\CriterionInterface'); $query->sortClauses = $this->getMockBuilder('eZ\\Publish\\API\\Repository\\Values\\Content\\Query\\SortClause')->disableOriginalConstructor()->getMockForAbstractClass(); // Injected query is being cloned to modify offset/limit, // so we need to do the same here for our assertions. $searchQuery = clone $query; $searchQuery->offset = $offset; $searchQuery->limit = $limit; $hits = array(); for ($i = 0; $i < $limit; ++$i) { $content = $this->getMockForAbstractClass('eZ\\Publish\\API\\Repository\\Values\\Content\\Content'); $hits[] = new SearchHit(array('valueObject' => $content)); } $finalResult = $this->getExpectedFinalResultFromHits($hits); $searchResult = new SearchResult(array('searchHits' => $hits, 'totalCount' => $nbResults)); $this->searchService->expects($this->once())->method('findContent')->with($this->equalTo($searchQuery))->will($this->returnValue($searchResult)); $adapter = $this->getAdapter($query, $this->searchService); $this->assertSame($finalResult, $adapter->getSlice($offset, $limit)); $this->assertSame($nbResults, $adapter->getNbResults()); }
/** * Returns an slice of the results. * * @param integer $offset The offset. * @param integer $length The length. * * @return array|\Iterator|\IteratorAggregate The slice. */ function getSlice( $offset, $length ) { $query = clone $this->query; $query->limit = $length; $query->offset = $offset; $searchResult = $this->searchService->findLocations( $query ); return $this->extractObjectsFromSearchResult( $searchResult ); }
/** * Returns image items for a gallery, as Content objects. * * @param mixed $galleryLocationId * * @return \eZ\Publish\API\Repository\Values\Content\Content[] */ public function getGalleryItems($galleryLocationId) { $result = $this->searchService->findContent($this->generateGalleryItemsQuery($galleryLocationId)); $contentObjects = []; foreach ($result->searchHits as $hit) { $contentObjects[] = $hit->valueObject; } return $contentObjects; }
/** * Renders top menu with child items. * * @param string $template * * @return \Symfony\Component\HttpFoundation\Response */ public function getChildNodesAction($template) { $locationSearchResults = $this->searchService->findLocations($this->menuQueryType->getQuery()); $menuItems = []; foreach ($locationSearchResults->searchHits as $hit) { $menuItems[] = $hit->valueObject; } return $this->templating->renderResponse($template, ['menuItems' => $menuItems], new Response()); }
public function findNodes(LocationQuery $query) { $searchResult = $this->searchService->findLocations($query, ['languages' => $this->prioritizedLanguages, 'useAlwaysAvailable' => $this->useAlwaysAvailable]); foreach ($searchResult->searchHits as $searchHit) { /** @var \eZ\Publish\API\Repository\Values\Content\Location $location */ $location = $searchHit->valueObject; $searchHit->valueObject = $this->domainObjectMapper->mapNode($location, $this->contentService->loadContent($location->contentInfo->id, [$searchHit->matchedTranslation], $location->contentInfo->currentVersionNo), $searchHit->matchedTranslation); } return $searchResult; }
/** * Returns a slice of the results, as SearchHit objects. * * @param integer $offset The offset. * @param integer $length The length. * * @return \eZ\Publish\API\Repository\Values\Content\Search\SearchHit[] */ public function getSlice($offset, $length) { $query = clone $this->query; $query->offset = $offset; $query->limit = $length; $searchResult = $this->searchService->findLocations($query); if (!isset($this->nbResults)) { $this->nbResults = $searchResult->totalCount; } return $searchResult->searchHits; }
/** * 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()); }
/** * Returns a slice of the results, as SearchHit objects. * * @param int $offset The offset. * @param int $length The length. * * @return \eZ\Publish\API\Repository\Values\Content\Search\SearchHit[] */ public function getSlice($offset, $length) { $query = clone $this->query; $query->offset = $offset; $query->limit = $length; $query->performCount = false; $searchResult = $this->searchService->findContent($query); // Set count for further use if returned by search engine despite !performCount (Solr, ES) if (!isset($this->nbResults) && isset($searchResult->totalCount)) { $this->nbResults = $searchResult->totalCount; } return $searchResult->searchHits; }
/** * 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 ); }
/** * 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; }
public function viewContentTypeAction($contentTypeId, $languageCode = null) { $languageCode = $languageCode ?: $this->prioritizedLanguages[0]; $contentType = $this->contentTypeService->loadContentType($contentTypeId); $countQuery = new Query(['filter' => new Query\Criterion\ContentTypeId($contentTypeId), 'limit' => 0]); $contentCount = $this->searchService->findContent($countQuery, [], false)->totalCount; $deleteForm = $this->createForm(new ContentTypeDeleteType(), ['contentTypeId' => $contentTypeId]); return $this->render('eZPlatformUIBundle:ContentType:view_content_type.html.twig', ['language_code' => $languageCode, 'content_type' => $contentType, 'content_count' => $contentCount, 'modifier' => $this->userService->loadUser($contentType->modifierId), 'delete_form' => $deleteForm->createView(), 'can_edit' => $this->isGranted(new Attribute('class', 'update')), 'can_delete' => $this->isGranted(new Attribute('class', 'delete')) && !$this->contentTypeService->isContentTypeUsed($contentType)]); }
/** * Search User Groups with given name. * * @param string $name name of User Group to search for * @param string $parentLocationId (optional) parent location id to search in * * @return search results */ public function searchUserGroups($name, $parentLocationId = null) { $criterionArray = array(new Criterion\Subtree(self::USERGROUP_ROOT_SUBTREE), new Criterion\ContentTypeIdentifier(self::USERGROUP_CONTENT_IDENTIFIER), new Criterion\Field('name', Criterion\Operator::EQ, $name)); if ($parentLocationId) { $criterionArray[] = new Criterion\ParentLocationId($parentLocationId); } $query = new Query(); $query->filter = new Criterion\LogicalAnd($criterionArray); $result = $this->searchService->findContent($query, array(), false); return $result->searchHits; }
/** * 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; }
/** * 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; }
/** * Finds Locations for the given query. * * @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException if query is not valid * * @param \eZ\Publish\API\Repository\Values\Content\LocationQuery $query * @param array $fieldFilters - a map of filters for the returned fields. * Currently supports: <code>array("languages" => array(<language1>,..), "useAlwaysAvailable" => bool)</code> * useAlwaysAvailable defaults to true to avoid exceptions on missing translations * @param bool $filterOnUserPermissions if true only the objects which is the user allowed to read are returned. * * @return \eZ\Publish\API\Repository\Values\Content\Search\SearchResult */ public function findLocations(LocationQuery $query, array $fieldFilters = array(), $filterOnUserPermissions = true) { return $this->service->findLocations($query, $fieldFilters, $filterOnUserPermissions); }
/** * Fetches a subtree for a given location object. * * @param mixed $locationObj * @param array $params * * @return array */ private function fetchSubtree($locationObj, array $params = array()) { $criterion = array(); // ToDo: ignore visibility $criterion[] = new Criterion\Visibility(Criterion\Visibility::VISIBLE); $locationList = array(); // List fetch direct children $paramDepth = 1; if (isset($params['depth'])) { $paramDepth = (int) $params['depth']; } // list fetch use parentNodeId for faster fetch if ($paramDepth <= 1) { $depth = $locationObj->depth + $paramDepth; // http://share.ez.no/blogs/thiago-campos-viana/ez-publish-5-tip-search-cheat-sheet $criterion[] = new Criterion\ParentLocationId($locationObj->id); } else { $depth = $locationObj->depth + $paramDepth; // http://share.ez.no/blogs/thiago-campos-viana/ez-publish-5-tip-search-cheat-sheet $criterion[] = new Criterion\Subtree($locationObj->pathString); $criterion[] = new Criterion\Location\Depth(Criterion\Operator::GT, $locationObj->depth); $criterion[] = new Criterion\Location\Depth(Criterion\Operator::LTE, $depth); } // main_node_only => true => only include mainlocatione if (isset($params['main_location_only'])) { // true, 1, '1' if ((int) $params['main_location_only'] === 1) { // only include mainLocations $criterion[] = new Criterion\Location\IsMainLocation(Criterion\Location\IsMainLocation::MAIN); } } if (isset($params['include']) && is_array($params['include']) && count($params['include']) > 0) { $criterion[] = new Criterion\ContentTypeIdentifier($params['include']); // TODO get ID for Identifier and use this for search so we save a subrequest and its lots faster // if ( in_array( 'article', $params['include'] ) ) // { // $criterion[] = new Criterion\ContentTypeId( array( 16 ) ); // } // else // { // $criterion[] = new Criterion\ContentTypeIdentifier( $params['include'] ); // } } // ToDo: role and rights, visibility, date, object states criterion $offset = 0; if (isset($params['offset']) && $params['offset'] > 0) { $offset = $params['offset']; } $limit = null; if (isset($params['limit']) && $params['limit'] > 0) { $limit = $params['limit']; } $sortClauses = array(); if (isset($params['sortby']) && is_array($params['sortby']) && count($params['sortby']) > 0) { foreach ($params['sortby'] as $sortKey => $sortArray) { // deprecated, for backwards compability (sort by content meta / attribute) if (is_array($sortArray) === false) { $newSortClause = $this->generateSortClauseFromString($sortKey, $sortArray); if ($newSortClause !== false) { $sortClauses[] = $newSortClause; } } // 2 array items means sorts by content meta / attribute if (is_array($sortArray) && count($sortArray) == 2) { $newSortClause = $this->generateSortClauseFromString($sortArray['0'], $sortArray['1']); if ($newSortClause !== false) { $sortClauses[] = $newSortClause; } } // 4 array items means sorts by content field if (is_array($sortArray) && count($sortArray) == 4) { $sortOrder = 'ascending'; if ($sortArray['2'] == 'DESC' || $sortArray['2'] == 'descending') { $sortOrder = 'descending'; } // $lang = $this->getPrioritizedLanguages(); $sortClauses[] = new SortClause\Field($sortArray['0'], $sortArray['1'], $sortOrder, $sortArray['3']); } } } else { // default sort by parent object sort clause $sortClauses[] = $this->generateSortClauseFromId($locationObj->sortField, $locationObj->sortOrder); } /* vendor/ezsystems/ezpublish-kernel/eZ/Publish/API/Repository/Values/Content/Query/Criterion/Operator.php abstract class Operator { const EQ = "="; const GT = ">"; const GTE = ">="; const LT = "<"; const LTE = "<="; const IN = "in"; const BETWEEN = "between"; const LIKE = "like"; const CONTAINS = "contains"; } */ if (isset($params['filter_relations']) && is_array($params['filter_relations']) && count($params['filter_relations']) > 0) { foreach ($params['filter_relations'] as $fieldCriterion) { // todo check valid syntax if (is_array($fieldCriterion) && count($fieldCriterion == 3)) { $criterion[] = new Criterion\FieldRelation($fieldCriterion['0'], $fieldCriterion['1'], $fieldCriterion['2']); } } } if (isset($params['filter_fields']) && is_array($params['filter_fields']) && count($params['filter_fields']) > 0) { foreach ($params['filter_fields'] as $fieldCriterion) { // todo check valid syntax if (is_array($fieldCriterion) && count($fieldCriterion == 3)) { // Attention! criterion field must set to be searchable $criterion[] = new Criterion\Field($fieldCriterion['0'], $fieldCriterion['1'], $fieldCriterion['2']); } } } if (isset($params['language']) && is_array($params['language']) && count($params['language']) > 0) { // ToDo: combine with and, always available? $criterion[] = new Criterion\LanguageCode($params['language']); } else { // only include languages which are defined in siteaccess config system default|siteaccess languages // if more than on a correct bitmask is build to include all object where one of the language is set $criterion[] = new Criterion\LanguageCode($this->getPrioritizedLanguages()); } $querySearch = new LocationQuery(array('offset' => $offset, 'limit' => $limit)); $querySearch->criterion = new Criterion\LogicalAnd($criterion); $querySearch->sortClauses = $sortClauses; $searchResult = $this->searchService->findLocations($querySearch); $searchCount = false; // only if count parameter is set return count // in newer ez version > 5.4 and in 5.3.5 the count is optional so you can // save 1 sql query if (isset($params['count']) && $params['count'] === true) { // use count from searchResult => the fastest way :-) $searchCount = $searchResult->totalCount; } foreach ($searchResult->searchHits as $searchItem) { $childLocationId = $searchItem->valueObject->id; if (isset($params['datamap']) && $params['datamap'] === true) { $childContentId = $searchItem->valueObject->contentInfo->id; $locationList[] = $this->contentService->loadContent($childContentId); } else { $locationList[] = $searchItem->valueObject; } } return array('searchResult' => $locationList, 'searchCount' => $searchCount); }
/** * Check if children locations are/are not ivisible. * * @param \eZ\Publish\API\Repository\SearchService $searchService * @param int $parentLocationId parent location Id * @param bool $expected expected value of {invisible} property in subtree */ private function assertSubtreeInvisibleProperty(SearchService $searchService, $parentLocationId, $expected) { $criterion = new Criterion\ParentLocationId($parentLocationId); $query = new LocationQuery(array('filter' => $criterion)); $result = $searchService->findLocations($query); foreach ($result->searchHits as $searchHit) { $this->assertEquals($expected, $searchHit->valueObject->invisible, sprintf('Location %s is not hidden', $searchHit->valueObject->id)); // Perform recursive check for children locations $this->assertSubtreeInvisibleProperty($searchService, $searchHit->valueObject->id, $expected); } }