/** * Detects if there is a custom controller to use to render a Location/Content. * * @param FilterControllerEvent $event * * @throws \Symfony\Component\Security\Core\Exception\AccessDeniedException */ public function getController(FilterControllerEvent $event) { $request = $event->getRequest(); // Only taking content related controller (i.e. ez_content:viewLocation or ez_content:viewContent) if (strpos($request->attributes->get('_controller'), 'ez_content:') === false) { return; } try { if ($request->attributes->has('locationId')) { $valueObject = $this->repository->getLocationService()->loadLocation($request->attributes->get('locationId')); } elseif ($request->attributes->get('location') instanceof Location) { $valueObject = $request->attributes->get('location'); $request->attributes->set('locationId', $valueObject->id); } elseif ($request->attributes->has('contentId')) { $valueObject = $this->repository->sudo(function (Repository $repository) use($request) { return $repository->getContentService()->loadContentInfo($request->attributes->get('contentId')); }); } elseif ($request->attributes->get('contentInfo') instanceof ContentInfo) { $valueObject = $request->attributes->get('contentInfo'); $request->attributes->set('contentId', $valueObject->id); } } catch (UnauthorizedException $e) { throw new AccessDeniedException(); } if (!isset($valueObject)) { $this->logger->error('Could not resolver a view controller, invalid value object to match.'); return; } $controllerReference = $this->controllerManager->getControllerReference($valueObject, $request->attributes->get('viewType')); if (!$controllerReference instanceof ControllerReference) { return; } $request->attributes->set('_controller', $controllerReference->controller); $event->setController($this->controllerResolver->getController($request)); }
protected function sudo(Closure $callback) { $resolver = new OptionsResolver(); $this->configureOptions($resolver); $this->params = $resolver->resolve($this->params); return $this->repository->sudo($callback); }
/** * @inheritdoc */ public function load($data) { $this->doProgress('Creating database schema...'); $this->databaseSchemaCreator->createSchema(); $this->doProgress('Loading fixtures...'); // Always use repositoty sudo to get access for content creation $this->repository->sudo(function () use($data) { $this->loader->load($data); }); }
/** * Saves content draft corresponding to $data. * Depending on the nature of $data (create or update data), the draft will either be created or simply updated. * * @param ContentStruct|\EzSystems\RepositoryForms\Data\User\UserCreateData $data * @param $languageCode * * @return \eZ\Publish\API\Repository\Values\Content\Content */ private function saveDraft(UserCreateData $data, $languageCode) { foreach ($data->fieldsData as $fieldDefIdentifier => $fieldData) { if ($fieldData->getFieldTypeIdentifier() !== 'ezuser') { $data->setField($fieldDefIdentifier, $fieldData->value, $languageCode); } } return $this->repository->sudo(function () use($data) { return $this->userService->createUser($data, $data->getParentGroups()); }); }
/** * @param $login * @param $email * @param $firstName * @param $lastName * @return User */ public function createNewUser($login, $email, $firstName, $lastName) { $userService = $this->repository->getUserService(); $userCreateStruct = $userService->newUserCreateStruct($login, $email, md5($email . $login . time() . rand(1, 10000)), 'eng-GB', $this->repository->getContentTypeService()->loadContentTypeByIdentifier('user')); $userCreateStruct->setField('first_name', $firstName); $userCreateStruct->setField('last_name', $lastName); $user = $this->repository->sudo(function () use($userService, $userCreateStruct) { $userGroup = $userService->loadUserGroup('11'); // guest accounts return $userService->createUser($userCreateStruct, array($userGroup)); }); return $user; }
public function loadLocation(ContentInfo $contentInfo) { if (is_null($contentInfo->mainLocationId)) { throw new NotFoundException('main location of content', $contentInfo->id); } try { return $this->repository->sudo(function (Repository $repository) use($contentInfo) { return $repository->getLocationService()->loadLocation($contentInfo->mainLocationId); }); } catch (Exception $e) { throw new NotFoundException('main location of content', $contentInfo->id); } }
public function userIsSubscriber(User $user) { $roleService = $this->repository->getRoleService(); return $this->repository->sudo(function (Repository $repository) use($user, $roleService) { foreach ($repository->getUserService()->loadUserGroupsOfUser($user) as $group) { foreach ($roleService->getRoleAssignmentsForUserGroup($group) as $role) { if ($this->isSubscriberRole($role->role)) { return true; } } } return false; }); }
/** * Process embed tags for a single tag type (embed or embed-inline) * @param \DOMDocument $xmlDoc * @param $tagName string name of the tag to extract */ protected function processTag(DOMDocument $xmlDoc, $tagName) { /** @var $embed \DOMElement */ foreach ($xmlDoc->getElementsByTagName($tagName) as $embed) { if (!($view = $embed->getAttribute("view"))) { $view = $tagName; } $embedContent = null; $parameters = array("noLayout" => true, "objectParameters" => array()); foreach ($embed->attributes as $attribute) { // We only consider tags in the custom namespace, and skip disallowed names if (!isset($this->excludedAttributes[$attribute->localName])) { $parameters["objectParameters"][$attribute->localName] = $attribute->nodeValue; } } if ($contentId = $embed->getAttribute("object_id")) { /** @var \eZ\Publish\API\Repository\Values\Content\Content $content */ $content = $this->repository->sudo(function (Repository $repository) use($contentId) { return $repository->getContentService()->loadContent($contentId); }); if (!$this->repository->canUser('content', 'read', $content) && !$this->repository->canUser('content', 'view_embed', $content)) { throw new UnauthorizedException('content', 'read'); } // Check published status of the Content if ($content->getVersionInfo()->status !== APIVersionInfo::STATUS_PUBLISHED && !$this->repository->canUser('content', 'versionread', $content)) { throw new UnauthorizedException('content', 'versionread'); } $embedContent = $this->viewManager->renderContent($content, $view, $parameters); } else { if ($locationId = $embed->getAttribute("node_id")) { /** @var \eZ\Publish\API\Repository\Values\Content\Location $location */ $location = $this->repository->sudo(function (Repository $repository) use($locationId) { return $repository->getLocationService()->loadLocation($locationId); }); if (!$this->repository->canUser('content', 'read', $location->getContentInfo(), $location) && !$this->repository->canUser('content', 'view_embed', $location->getContentInfo(), $location)) { throw new UnauthorizedException('content', 'read'); } $embedContent = $this->viewManager->renderLocation($location, $view, $parameters); } } if ($embedContent !== null) { $embed->appendChild($xmlDoc->createCDATASection($embedContent)); } } }
/** * Loads a visible Location. * @todo Do we need to handle permissions here ? * * @param $locationId * * @return \eZ\Publish\API\Repository\Values\Content\Location */ private function loadLocation($locationId) { $location = $this->repository->sudo(function (Repository $repository) use($locationId) { return $repository->getLocationService()->loadLocation($locationId); }); if ($location->invisible) { throw new NotFoundHttpException('Location cannot be displayed as it is flagged as invisible.'); } return $location; }
/** * Process embed tags for a single tag type (embed or embed-inline) * @param \DOMDocument $xmlDoc * @param $tagName string name of the tag to extract */ protected function processTag(DOMDocument $xmlDoc, $tagName) { /** @var $embed \DOMElement */ foreach ($xmlDoc->getElementsByTagName($tagName) as $embed) { if (!($view = $embed->getAttribute("view"))) { $view = $tagName; } $embedContent = null; $parameters = $this->getParameters($embed); if ($contentId = $embed->getAttribute("object_id")) { try { /** @var \eZ\Publish\API\Repository\Values\Content\Content $content */ $content = $this->repository->sudo(function (Repository $repository) use($contentId) { return $repository->getContentService()->loadContent($contentId); }); if (!$this->repository->canUser('content', 'read', $content) && !$this->repository->canUser('content', 'view_embed', $content)) { throw new UnauthorizedException('content', 'read', array('contentId' => $contentId)); } // Check published status of the Content if ($content->getVersionInfo()->status !== APIVersionInfo::STATUS_PUBLISHED && !$this->repository->canUser('content', 'versionread', $content)) { throw new UnauthorizedException('content', 'versionread', array('contentId' => $contentId)); } $embedContent = $this->fragmentHandler->render(new ControllerReference('ez_content:embedContent', array('contentId' => $contentId, 'viewType' => $view, 'layout' => false, 'params' => $parameters))); } catch (APINotFoundException $e) { if ($this->logger) { $this->logger->error("While generating embed for xmltext, could not locate " . "Content object with ID " . $contentId); } } } else { if ($locationId = $embed->getAttribute("node_id")) { try { /** @var \eZ\Publish\API\Repository\Values\Content\Location $location */ $location = $this->repository->sudo(function (Repository $repository) use($locationId) { return $repository->getLocationService()->loadLocation($locationId); }); if (!$this->repository->canUser('content', 'read', $location->getContentInfo(), $location) && !$this->repository->canUser('content', 'view_embed', $location->getContentInfo(), $location)) { throw new UnauthorizedException('content', 'read', array('locationId' => $location->id)); } $embedContent = $this->fragmentHandler->render(new ControllerReference('ez_content:embedLocation', array('locationId' => $locationId, 'viewType' => $view, 'layout' => false, 'params' => $parameters))); } catch (APINotFoundException $e) { if ($this->logger) { $this->logger->error("While generating embed for xmltext, could not locate " . "Location with ID " . $locationId); } } } } if ($embedContent === null) { // Remove empty embed $embed->parentNode->removeChild($embed); } else { $embed->appendChild($xmlDoc->createCDATASection($embedContent)); } } }
/** * Uses a content type identifier + a hash of fields values * to create and publish a draft below the root location. * * @param string $contentTypeIdentifier * @param array $fields Hash of field def identifier => field value * * @return Content the created draft. */ public function createDraft($contentTypeIdentifier, array $fields) { $contentService = $this->repository->getContentService(); $createStruct = $contentService->newContentCreateStruct($this->repository->getContentTypeService()->loadContentTypeByIdentifier($contentTypeIdentifier), 'eng-GB'); foreach ($fields as $fieldDefIdentifier => $fieldValue) { $createStruct->setField($fieldDefIdentifier, $fieldValue); } $locationCreateStruct = $this->repository->getLocationService()->newLocationCreateStruct(2); $this->currentDraft = $this->repository->sudo(function () use($createStruct, $locationCreateStruct) { return $this->repository->getContentService()->createContent($createStruct, [$locationCreateStruct]); }); return $this->currentDraft; }
/** * Loads a user for the given ID. * * @param $userId * * @return \eZ\Publish\Core\REST\Server\Values\RestUser */ public function loadUser($userId) { $user = $this->userService->loadUser($userId); $userContentInfo = $user->getVersionInfo()->getContentInfo(); $contentType = $this->contentTypeService->loadContentType($userContentInfo->contentTypeId); try { $userMainLocation = $this->locationService->loadLocation($userContentInfo->mainLocationId); $relations = $this->contentService->loadRelations($user->getVersionInfo()); } catch (UnauthorizedException $e) { // TODO: Hack for special case to allow current logged in user to load him/here self (but not relations) if ($user->id == $this->repository->getCurrentUser()->id) { $userMainLocation = $this->repository->sudo(function () use($userContentInfo) { return $this->locationService->loadLocation($userContentInfo->mainLocationId); }); // user may not have permissions to read related content, for security reasons do not use sudo(). $relations = array(); } else { throw $e; } } return new Values\CachedValue(new Values\RestUser($user, $contentType, $userContentInfo, $userMainLocation, $relations), array('locationId' => $userContentInfo->mainLocationId)); }
/** * Allows API execution to be performed with full access sand-boxed * * The closure sandbox will do a catch all on exceptions and rethrow after * re-setting the sudo flag. * * Example use: * $location = $repository->sudo( * function ( $repo ) use ( $locationId ) * { * return $repo->getLocationService()->loadLocation( $locationId ) * } * ); * * @access private This function is not official API atm, and can change anytime. * * @param \Closure $callback * * @throws \RuntimeException Thrown on recursive sudo() use. * @throws \Exception Re throws exceptions thrown inside $callback * @return mixed */ public function sudo(\Closure $callback) { return $this->repository->sudo($callback); }
/** * Process embed tags for a single tag type (embed or embed-inline) * @param \DOMDocument $xmlDoc * @param $tagName string name of the tag to extract */ protected function processTag(DOMDocument $xmlDoc, $tagName) { /** @var $embed \DOMElement */ foreach ($xmlDoc->getElementsByTagName($tagName) as $embed) { if (!($view = $embed->getAttribute("view"))) { $view = $tagName; } $embedContent = null; $parameters = array("noLayout" => true, "objectParameters" => array()); foreach ($embed->attributes as $attribute) { // We only consider tags in the custom namespace, and skip disallowed names if (!isset($this->excludedAttributes[$attribute->localName])) { $parameters["objectParameters"][$attribute->localName] = $attribute->nodeValue; } } if ($contentId = $embed->getAttribute("object_id")) { try { /** @var \eZ\Publish\API\Repository\Values\Content\Content $content */ $content = $this->repository->sudo(function (Repository $repository) use($contentId) { return $repository->getContentService()->loadContent($contentId); }); if (!$this->repository->canUser('content', 'read', $content) && !$this->repository->canUser('content', 'view_embed', $content)) { throw new UnauthorizedException('content', 'read', array('contentId' => $contentId)); } // Check published status of the Content if ($content->getVersionInfo()->status !== APIVersionInfo::STATUS_PUBLISHED && !$this->repository->canUser('content', 'versionread', $content)) { throw new UnauthorizedException('content', 'versionread', array('contentId' => $contentId)); } $embedContent = $this->fragmentHandler->render(new ControllerReference('ez_content:embedContent', array('contentId' => $contentId, 'viewType' => $view, 'layout' => false, 'params' => $parameters))); } catch (APINotFoundException $e) { if ($this->logger) { $this->logger->error("While generating embed for xmltext, could not locate " . "Content object with ID " . $contentId); } } } else { if ($locationId = $embed->getAttribute("node_id")) { try { /** @var \eZ\Publish\API\Repository\Values\Content\Location $location */ $location = $this->repository->sudo(function (Repository $repository) use($locationId) { return $repository->getLocationService()->loadLocation($locationId); }); if (!$this->repository->canUser('content', 'read', $location->getContentInfo(), $location) && !$this->repository->canUser('content', 'view_embed', $location->getContentInfo(), $location)) { throw new UnauthorizedException('content', 'read', array('locationId' => $location->id)); } $embedContent = $this->fragmentHandler->render(new ControllerReference('ez_content:embedLocation', array('locationId' => $locationId, 'viewType' => $view, 'layout' => false, 'params' => $parameters))); } catch (APINotFoundException $e) { if ($this->logger) { $this->logger->error("While generating embed for xmltext, could not locate " . "Location with ID " . $locationId); } } } } if ($embedContent === null) { // Remove tmp paragraph if ($embed->parentNode->lookupNamespaceUri('tmp') !== null) { $embed->parentNode->parentNode->removeChild($embed->parentNode); } else { if ($embed->parentNode->localName === "link" && $embed->parentNode->childNodes->length === 1) { // Remove paragraph with empty link if ($embed->parentNode->parentNode->localName === "paragraph" && $embed->parentNode->parentNode->childNodes->length === 1) { $embed->parentNode->parentNode->parentNode->removeChild($embed->parentNode->parentNode); } else { $embed->parentNode->parentNode->removeChild($embed->parentNode); } } else { $embed->parentNode->removeChild($embed); } } } else { $embed->appendChild($xmlDoc->createCDATASection($embedContent)); } } }