Last active
August 29, 2015 14:03
-
-
Save wizhippo/823d8b5b8455b26ad310 to your computer and use it in GitHub Desktop.
Example menu based on subtree
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Example\Bundle\ExampleBundle\Controller; | |
use eZ\Bundle\EzPublishCoreBundle\Controller; | |
use eZ\Publish\API\Repository\Values\Content\Location; | |
use eZ\Publish\Core\Pagination\Pagerfanta\ContentSearchAdapter; | |
use Pagerfanta\Pagerfanta; | |
use Symfony\Component\HttpFoundation\Response; | |
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; | |
use eZ\Publish\API\Repository\Values\Content\Query; | |
use eZ\Publish\API\Repository\Values\Content\Query\SortClause; | |
class ConsumerSiteController extends Controller | |
{ | |
/** | |
* Renders the top menu, with cache control | |
* | |
* @return \Symfony\Component\HttpFoundation\Response | |
*/ | |
public function topMenuAction() | |
{ | |
$location = $this->getRootLocation(); | |
// Setting HTTP cache for the response to be public and with a TTL of 1 day. | |
$response = new Response; | |
$response->setPublic(); | |
$response->setSharedMaxAge( 86400 ); | |
// Menu will expire when top location cache expires. | |
$response->headers->set( 'X-Location-Id', $location->id ); | |
// Menu might vary depending on user permissions, so make the cache vary on the user hash. | |
$response->setVary( 'X-User-Hash' ); | |
// Generate criterion from $excludeContentTypes and pass it to the menu helper. | |
$excludeCriterion = $this->get( 'ezdemo.criteria_helper' ) | |
->generateContentTypeExcludeCriterion( | |
// Get contentType identifiers we want to exclude from configuration (see default_settings.yml). | |
$this->container->getParameter( 'ezdemo.top_menu.content_types_exclude' ) | |
); | |
$locationTree = $this->get( 'example.menu_helper' )->getTopMenuContent( $location->pathString, $excludeCriterion ); | |
return $this->render( | |
'ExampleExampleBundle::page_topmenu.html.twig', | |
array( | |
'locationTree' => $locationTree, | |
'collapseTopLevel' => true, | |
), | |
$response | |
); | |
} | |
/** | |
* Renders page header links with cache control | |
* | |
* @return \Symfony\Component\HttpFoundation\Response | |
*/ | |
public function userLinksAction() | |
{ | |
$response = new Response(); | |
$response->setSharedMaxAge( 3600 ); | |
$response->setVary( 'Cookie' ); | |
return $this->render( | |
"eZDemoBundle::page_header_links.html.twig", | |
array(), | |
$response | |
); | |
} | |
/** | |
* Renders article with extra parameters that controls page elements visibility such as image and summary | |
* | |
* @param $locationId | |
* @param $viewType | |
* @param bool $layout | |
* @param array $params | |
* @return \Symfony\Component\HttpFoundation\Response | |
*/ | |
public function showArticleAction( $locationId, $viewType, $layout = false, array $params = array() ) | |
{ | |
return $this->get( 'ez_content' )->viewLocation( | |
$locationId, | |
$viewType, | |
$layout, | |
array( | |
'showSummary' => $this->container->getParameter( 'ezdemo.article.full_view.show_summary' ), | |
'showImage' => $this->container->getParameter( 'ezdemo.article.full_view.show_image' ) | |
) + $params | |
); | |
} | |
/** | |
* Displays the list of blog_post | |
* Note: This is a fully customized controller action, it will generate the response and call | |
* the view. Since it is not calling the ViewControler we don't need to match a specific | |
* method signature. | |
* | |
* @param int $locationId of a blog | |
* @return \Symfony\Component\HttpFoundation\Response | |
*/ | |
public function listBlogPostsAction( $locationId ) | |
{ | |
$response = new Response(); | |
// Setting default cache configuration (you can override it in you siteaccess config) | |
$response->setSharedMaxAge( $this->getConfigResolver()->getParameter( 'content.default_ttl' ) ); | |
// Make the response location cache aware for the reverse proxy | |
$response->headers->set( 'X-Location-Id', $locationId ); | |
$response->setVary( 'X-User-Hash' ); | |
$viewParameters = $this->getRequest()->attributes->get( 'viewParameters' ); | |
// TODO keyword search is not implemented in the public API yet, so we forward to a legacy view | |
if ( !empty( $viewParameters['tag'] ) ) | |
{ | |
$tag = $viewParameters['tag']; | |
return $this->redirect( | |
$this->generateUrl( | |
'ez_legacy', | |
array( 'module_uri' => '/content/keyword/' . $tag ) | |
) | |
); | |
} | |
// Getting location and content from ezpublish dedicated services | |
$repository = $this->getRepository(); | |
$location = $repository->getLocationService()->loadLocation( $locationId ); | |
if ( $location->invisible ) | |
{ | |
throw new NotFoundHttpException( "Location #$locationId cannot be displayed as it is flagged as invisible." ); | |
} | |
$content = $repository | |
->getContentService() | |
->loadContentByContentInfo( $location->getContentInfo() ); | |
// Getting language for the current siteaccess | |
$languages = $this->getConfigResolver()->getParameter( 'languages' ); | |
// Using the criteria helper (a demobundle custom service) to generate our query's criteria. | |
// This is a good practice in order to have less code in your controller. | |
$criteria = $this->get( 'ezdemo.criteria_helper' )->generateListBlogPostCriterion( | |
$location, $viewParameters, $languages | |
); | |
// Generating query | |
$query = new Query(); | |
$query->criterion = $criteria; | |
$query->sortClauses = array( | |
new SortClause\Field( 'blog_post', 'publication_date', Query::SORT_DESC, $languages[0] ) | |
); | |
// Initialize pagination. | |
$pager = new Pagerfanta( | |
new ContentSearchAdapter( $query, $this->getRepository()->getSearchService() ) | |
); | |
$pager->setMaxPerPage( $this->container->getParameter( 'ezdemo.blog.blog_post_list.limit' ) ); | |
$pager->setCurrentPage( $this->getRequest()->get( 'page', 1 ) ); | |
return $this->render( | |
'eZDemoBundle:full:blog.html.twig', | |
array( | |
'location' => $location, | |
'content' => $content, | |
'pagerBlog' => $pager | |
), | |
$response | |
); | |
} | |
/** | |
* Action used to display a blog_post | |
* - Adds the content's author to the response. | |
* Note: This is a partly customized controller action. It is executed just before the original | |
* Viewcontroller's viewLocation method. To be able to do that, we need to implement it's | |
* full signature. | |
* | |
* @param $locationId | |
* @param $viewType | |
* @param bool $layout | |
* @param array $params | |
* @return \Symfony\Component\HttpFoundation\Response | |
*/ | |
public function showBlogPostAction( $locationId, $viewType, $layout = false, array $params = array() ) | |
{ | |
// We need the author, whatever the view type is. | |
$repository = $this->getRepository(); | |
$location = $repository->getLocationService()->loadLocation( $locationId ); | |
$author = $repository->getUserService()->loadUser( $location->getContentInfo()->ownerId ); | |
// TODO once the keyword service is available, load the number of keyword for each keyword | |
// Delegate view rendering to the original ViewController | |
// (makes it possible to continue using defined template rules) | |
// We just add "author" to the list of variables exposed to the final template | |
return $this->get( 'ez_content' )->viewLocation( | |
$locationId, | |
$viewType, | |
$layout, | |
array( 'author' => $author ) | |
); | |
} | |
/** | |
* Displays content having similar tags as the given location | |
* | |
* @param \eZ\Publish\API\Repository\Values\Content\Location $location | |
* @return \Symfony\Component\HttpFoundation\Response | |
*/ | |
public function viewTagRelatedContentAction( Location $location ) | |
{ | |
// TODO once the keyword service is available replace this subrequest by a full symfony one | |
return $this->render( | |
'eZDemoBundle:parts:related_content.html.twig', | |
array( 'location' => $location ) | |
); | |
} | |
/** | |
* Displays description, tagcloud, tags, ezarchive and calendar | |
* of the parent's of a given location | |
* | |
* @param \eZ\Publish\API\Repository\Values\Content\Location $location | |
* @return \Symfony\Component\HttpFoundation\Response | |
*/ | |
public function viewParentExtraInfoAction( Location $location ) | |
{ | |
$repository = $this->getRepository(); | |
$parentLocation = $repository->getLocationService()->loadLocation( $location->parentLocationId ); | |
// TODO once the keyword service is available replace part this subrequest by a full symfony one | |
return $this->render( | |
'eZDemoBundle:parts/blog:extra_info.html.twig', | |
array( 'location' => $parentLocation ) | |
); | |
} | |
/** | |
* Displays description, tagcloud, tags, ezarchive and calendar for a given location | |
* | |
* @param \eZ\Publish\API\Repository\Values\Content\Location $location | |
* @return \Symfony\Component\HttpFoundation\Response | |
*/ | |
public function viewExtraInfoAction( Location $location ) | |
{ | |
// TODO once the keyword service is available replace part this subrequest by a full symfony one | |
return $this->render( | |
'eZDemoBundle:parts/blog:extra_info.html.twig', | |
array( 'location' => $location ) | |
); | |
} | |
/** | |
* Displays "tip a friend" link for a given location | |
* | |
* @param \eZ\Publish\API\Repository\Values\Content\Location $location | |
* @return \Symfony\Component\HttpFoundation\Response | |
*/ | |
public function viewTipAFriendAction( Location $location ) | |
{ | |
return $this->render( | |
'eZDemoBundle:parts/article:tip_a_friend.html.twig', | |
array( 'location' => $location ) | |
); | |
} | |
/** | |
* Displays star rating attribute for a given location | |
* | |
* @param \eZ\Publish\API\Repository\Values\Content\Location $location | |
* @return \Symfony\Component\HttpFoundation\Response | |
*/ | |
public function viewStarRatingAction( Location $location ) | |
{ | |
return $this->render( | |
'eZDemoBundle:parts/article:star_rating.html.twig', | |
array( 'location' => $location ) | |
); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Example\Bundle\ExampleBundle\Helper; | |
use eZ\Publish\API\Repository\Values\Content\Search\SearchResult; | |
/** | |
* Helper for searches | |
*/ | |
class SearchHelper | |
{ | |
/** | |
* Builds a Content list from $searchResult. | |
* Returned array consists of a hash of Content objects, indexed by their ID. | |
* | |
* @param \eZ\Publish\API\Repository\Values\Content\Search\SearchResult $searchResult | |
* | |
* @return array | |
*/ | |
public function buildListFromSearchResult( SearchResult $searchResult ) | |
{ | |
$list = array(); | |
foreach ( $searchResult->searchHits as $searchHit ) | |
{ | |
$list[$searchHit->valueObject->contentInfo->id] = $searchHit->valueObject; | |
} | |
return $list; | |
} | |
/** | |
* Builds a tree from $searchResult. | |
* | |
* @param $subtree to start from | |
* @param \eZ\Publish\API\Repository\Values\Content\Search\SearchResult $searchResult | |
* | |
* @return array of tree array("location" => location , "children" => array( | |
* array("location" => location , "children" => ...), | |
* array("location" => location , "children" => ...), | |
* ) | |
*/ | |
public function buildLocationTreeFromSearchResult( $subtree, SearchResult $searchResult ) | |
{ | |
$baseCount = strlen($subtree) - strlen(str_replace(str_split("/"), '', $subtree)) - 1; | |
$tree = array('location' => null, 'children' => null); | |
foreach ( $searchResult->searchHits as $searchHit ) | |
{ | |
$path = array_slice($searchHit->valueObject->path, $baseCount); | |
$leaf = &$tree; | |
while ($pathElement = array_shift($path)) { | |
if (!isset($leaf['children'][$pathElement])) { | |
$leaf['children'][$pathElement] = array('location' => null, 'children' => null); | |
} | |
$leaf = &$leaf['children'][$pathElement]; | |
} | |
$leaf['location'] = $searchHit->valueObject; | |
} | |
return $tree; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
parameters: | |
example.menu_helper.class: Example\Bundle\ExampleBundle\Helper\MenuHelper | |
example.search_helper.class: Example\Bundle\ExampleBundle\Helper\SearchHelper | |
example.menu_helper.default_limit: 10 | |
example.menu_helper.default_depth: 3 | |
services: | |
example.menu_helper: | |
class: %example.menu_helper.class% | |
arguments: [@ezpublish.api.repository, %example.menu_helper.default_limit%, %example.menu_helper.default_depth%, @example.search_helper] | |
example.search_helper: | |
class: %example.search_helper.class% |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment