/** * Render user initials or an abbreviated name for a given username. If the account was deleted, use the username as fallback. * * @param string $format Supported are "fullFirstName" and "initials" * @return string */ public function render($format = 'initials') { if (!in_array($format, array('fullFirstName', 'initials', 'fullName'))) { throw new \InvalidArgumentException(sprintf('Format "%s" given to history:userInitials(), only supporting "fullFirstName", "initials" and "fullName".', $format), 1415705861); } $username = $this->renderChildren(); /* @var $requestedUser Person */ $requestedUser = $this->domainUserService->getUser($username); if ($requestedUser === null || $requestedUser->getName() === null) { return $username; } $currentUser = $this->userService->getBackendUser(); if ($currentUser) { if ($currentUser === $requestedUser) { $translationHelper = new TranslationHelper(); $you = $translationHelper->translate('you', null, [], 'Main', 'TYPO3.Neos'); } } switch ($format) { case 'initials': return mb_substr($requestedUser->getName()->getFirstName(), 0, 1) . mb_substr($requestedUser->getName()->getLastName(), 0, 1); case 'fullFirstName': return isset($you) ? $you : $requestedUser->getName()->getFirstName() . ' ' . mb_substr($requestedUser->getName()->getLastName(), 0, 1) . '.'; case 'fullName': return isset($you) ? $you : $requestedUser->getName()->getFullName(); } }
public function initializeWorkspacesByName() { $workspaces = []; $personalWorkspace = $this->userService->getPersonalWorkspace(); $workspaces[$personalWorkspace->getName()] = ['name' => $personalWorkspace->getName(), 'publishableNodes' => $this->getPublishableNodeInfo($personalWorkspace)]; return $workspaces; }
/** * Returns an array of usage reference objects. * * @param AssetInterface $asset * @return array<\TYPO3\Neos\Domain\Model\Dto\AssetUsageInNodeProperties> * @throws \TYPO3\TYPO3CR\Exception\NodeConfigurationException */ public function getUsageReferences(AssetInterface $asset) { $assetIdentifier = $this->persistenceManager->getIdentifierByObject($asset); if (isset($this->firstlevelCache[$assetIdentifier])) { return $this->firstlevelCache[$assetIdentifier]; } $userWorkspace = $this->userService->getPersonalWorkspace(); $relatedNodes = []; foreach ($this->getRelatedNodes($asset) as $relatedNodeData) { $accessible = $this->domainUserService->currentUserCanReadWorkspace($relatedNodeData->getWorkspace()); if ($accessible) { $context = $this->createContextMatchingNodeData($relatedNodeData); } else { $context = $this->createContentContext($userWorkspace->getName()); } $site = $context->getCurrentSite(); $node = $this->nodeFactory->createFromNodeData($relatedNodeData, $context); $flowQuery = new FlowQuery([$node]); /** @var \TYPO3\TYPO3CR\Domain\Model\NodeInterface $documentNode */ $documentNode = $flowQuery->closest('[instanceof TYPO3.Neos:Document]')->get(0); $relatedNodes[] = new AssetUsageInNodeProperties($asset, $site, $documentNode, $node, $accessible); } $this->firstlevelCache[$assetIdentifier] = $relatedNodes; return $this->firstlevelCache[$assetIdentifier]; }
/** * Render user initials or an abbreviated name for a given username. If the account was deleted, use the username as fallback. * * @param string $format Supported are "fullFirstName" and "initials" * @return string */ public function render($format = 'initials') { if (!in_array($format, array('fullFirstName', 'initials', 'fullName'))) { throw new \InvalidArgumentException(sprintf('Format "%s" given to history:userInitials(), only supporting "fullFirstName", "initials" and "fullName".', $format), 1415705861); } $accountIdentifier = $this->renderChildren(); // TODO: search by credential source is still needed /* @var $account \TYPO3\Flow\Security\Account */ $account = $this->accountRepository->findOneByAccountIdentifier($accountIdentifier); if ($account === null) { return $accountIdentifier; } /* @var $requestedUser Person */ $requestedUser = $account->getParty(); if ($requestedUser === null || $requestedUser->getName() === null) { return $accountIdentifier; } $currentUser = $this->userService->getBackendUser(); if ($currentUser) { if ($currentUser === $requestedUser) { $translationHelper = new TranslationHelper(); $you = $translationHelper->translateById('you', 'TYPO3.Neos'); } } switch ($format) { case 'initials': return mb_substr($requestedUser->getName()->getFirstName(), 0, 1) . mb_substr($requestedUser->getName()->getLastName(), 0, 1); case 'fullFirstName': return isset($you) ? $you : $requestedUser->getName()->getFirstName() . ' ' . mb_substr($requestedUser->getName()->getLastName(), 0, 1) . '.'; case 'fullName': return isset($you) ? $you : $requestedUser->getName()->getFullName(); } }
/** * Get the current rendering mode (editPreviewMode). * Will return a live mode when not in backend. * * @return UserInterfaceMode */ public function findModeByCurrentUser() { if ($this->userService->getBackendUser() === NULL || !$this->privilegeManager->isPrivilegeTargetGranted('TYPO3.Neos:Backend.GeneralAccess')) { return $this->findModeByName('live'); } /** @var \TYPO3\Neos\Domain\Model\User $user */ $editPreviewMode = $this->userService->getUserPreference('contentEditing.editPreviewMode'); if ($editPreviewMode === NULL) { $editPreviewMode = $this->defaultEditPreviewMode; } $mode = $this->findModeByName($editPreviewMode); return $mode; }
/** * @test */ public function getUserWorkspaceNameReturnsTheUsersWorkspaceNameIfAUserIsLoggedIn() { $mockAccount = $this->getMockBuilder('TYPO3\\Flow\\Security\\Account')->disableOriginalConstructor()->getMock(); $mockAccount->expects($this->atLeastOnce())->method('getAccountIdentifier')->will($this->returnValue('The UserName')); $this->mockSecurityContext->expects($this->atLeastOnce())->method('getAccount')->will($this->returnValue($mockAccount)); $this->assertSame('user-TheUserName', $this->userService->getUserWorkspaceName()); }
/** * @test */ public function getPersonalWorkspaceNameReturnsTheUsersWorkspaceNameIfAUserIsLoggedIn() { $mockUser = $this->getMockBuilder('TYPO3\\Neos\\Domain\\Model\\User')->disableOriginalConstructor()->getMock(); $this->mockUserDomainService->expects($this->atLeastOnce())->method('getCurrentUser')->will($this->returnValue($mockUser)); $this->mockUserDomainService->expects($this->atLeastOnce())->method('getUserName')->with($mockUser)->will($this->returnValue('TheUserName')); $this->assertSame('user-TheUserName', $this->userService->getPersonalWorkspaceName()); }
/** * Returns the node this even refers to, if it can be resolved. * * It might happen that, if this event refers to a node contained in a site which is not available anymore, * Doctrine's proxy class of the Site domain model will fail with an EntityNotFoundException. We catch this * case and return NULL. * * @return NodeInterface */ public function getNode() { try { $context = $this->contextFactory->create(array('workspaceName' => $this->userService->getUserWorkspace()->getName(), 'dimensions' => $this->dimension, 'currentSite' => $this->getCurrentSite(), 'invisibleContentShown' => true)); return $context->getNodeByIdentifier($this->nodeIdentifier); } catch (EntityNotFoundException $e) { return null; } }
/** * If the specified workspace or its root node does not exist yet, the workspace and root node will be created. * * This method is basically a safeguard for legacy and potentially broken websites where users might not have * their own workspace yet. In a normal setup, the Domain User Service is responsible for creating and deleting * user workspaces. * * @param string $workspaceName Name of the workspace * @return void */ protected function createWorkspaceAndRootNodeIfNecessary($workspaceName) { $workspace = $this->workspaceRepository->findOneByName($workspaceName); if ($workspace === null) { $liveWorkspace = $this->workspaceRepository->findOneByName('live'); $owner = $this->userService->getBackendUser(); $workspace = new Workspace($workspaceName, $liveWorkspace, $owner); $this->workspaceRepository->add($workspace); $this->persistenceManager->whitelistObject($workspace); } $contentContext = $this->createContext($workspaceName); $rootNode = $contentContext->getRootNode(); $this->persistenceManager->whitelistObject($rootNode); $this->persistenceManager->whitelistObject($rootNode->getNodeData()); $this->persistenceManager->persistAll(true); }
/** * Display a list of unpublished content * * @param Workspace $workspace * @return void * @todo Pagination * @todo Tree filtering + level limit * @todo Search field * @todo Difference mechanism */ public function indexAction(Workspace $workspace = NULL) { if ($workspace === NULL) { $workspace = $this->userService->getUserWorkspace(); } $sites = array(); foreach ($this->publishingService->getUnpublishedNodes($workspace) as $node) { $pathParts = explode('/', $node->getPath()); if (count($pathParts) > 2) { $siteNodeName = $pathParts[2]; $q = new FlowQuery(array($node)); $document = $q->closest('[instanceof TYPO3.Neos:Document]')->get(0); // FIXME: $document will be NULL if we have a broken rootline for this node. This actually should never happen, but currently can in some scenarios. if ($document !== NULL) { $documentPath = implode('/', array_slice(explode('/', $document->getPath()), 3)); $relativePath = str_replace(sprintf('/sites/%s/%s', $siteNodeName, $documentPath), '', $node->getPath()); if (!isset($sites[$siteNodeName]['siteNode'])) { $sites[$siteNodeName]['siteNode'] = $this->siteRepository->findOneByNodeName($siteNodeName); } $sites[$siteNodeName]['documents'][$documentPath]['documentNode'] = $document; $change = array('node' => $node); if ($node->getNodeType()->isOfType('TYPO3.Neos:Node')) { $change['configuration'] = $node->getNodeType()->getFullConfiguration(); } $sites[$siteNodeName]['documents'][$documentPath]['changes'][$relativePath] = $change; } } } $liveContext = $this->contextFactory->create(array('workspaceName' => 'live')); ksort($sites); foreach ($sites as $siteKey => $site) { foreach ($site['documents'] as $documentKey => $document) { foreach ($document['changes'] as $changeKey => $change) { $liveNode = $liveContext->getNodeByIdentifier($change['node']->getIdentifier()); $sites[$siteKey]['documents'][$documentKey]['changes'][$changeKey]['isNew'] = is_null($liveNode); $sites[$siteKey]['documents'][$documentKey]['changes'][$changeKey]['isMoved'] = $liveNode && $change['node']->getPath() !== $liveNode->getPath(); } } ksort($sites[$siteKey]['documents']); } $workspaces = array(); foreach ($this->workspaceRepository->findAll() as $workspaceInstance) { array_push($workspaces, array('workspaceNode' => $workspaceInstance, 'unpublishedNodesCount' => $this->publishingService->getUnpublishedNodesCount($workspaceInstance))); } $this->view->assignMultiple(array('workspace' => $workspace, 'workspaces' => $workspaces, 'sites' => $sites)); }
/** * Returns a specific URI string to redirect to after the login; or NULL if there is none. * * @param ActionRequest $actionRequest * @return string */ public function getAfterLoginRedirectionUri(ActionRequest $actionRequest) { $user = $this->userService->getBackendUser(); if ($user === NULL) { return NULL; } $workspaceName = $this->userService->getUserWorkspaceName(); $this->createWorkspaceAndRootNodeIfNecessary($workspaceName); $uriBuilder = new UriBuilder(); $uriBuilder->setRequest($actionRequest); $uriBuilder->setFormat('html'); $uriBuilder->setCreateAbsoluteUri(TRUE); $contentContext = $this->createContext($workspaceName); $lastVisitedNode = $this->getLastVisitedNode($workspaceName); if ($lastVisitedNode !== NULL) { return $uriBuilder->uriFor('show', array('node' => $lastVisitedNode), 'Frontend\\Node', 'TYPO3.Neos'); } return $uriBuilder->uriFor('show', array('node' => $contentContext->getCurrentSiteNode()), 'Frontend\\Node', 'TYPO3.Neos'); }
/** * Renders the translated label. * * Replaces all placeholders with corresponding values if they exist in the * translated label. * * @param string $id Id to use for finding translation (trans-unit id in XLIFF) * @param string $value If $key is not specified or could not be resolved, this value is used. If this argument is not set, child nodes will be used to render the default * @param array $arguments Numerically indexed array of values to be inserted into placeholders * @param string $source Name of file with translations * @param string $package Target package key. If not set, the current package key will be used * @param mixed $quantity A number to find plural form for (float or int), NULL to not use plural forms * @param string $languageIdentifier An identifier of a language to use (NULL for using the default language) * @return string Translated label or source label / ID key * @throws ViewHelper\Exception */ public function render($id = null, $value = null, array $arguments = array(), $source = 'Main', $package = null, $quantity = null, $languageIdentifier = null) { if (preg_match(TranslationHelper::I18N_LABEL_ID_PATTERN, $id) === 1) { // In the longer run, this "extended ID" format should directly be resolved in the localization service list($package, $source, $id) = explode(':', $id, 3); $source = str_replace('.', '/', $source); } if ($languageIdentifier === null) { $languageIdentifier = $this->userService->getInterfaceLanguage(); } // Catch exception in case the translation file doesn't exist, should be fixed in Flow 3.1 try { $translation = parent::render($id, $value, $arguments, $source, $package, $quantity, $languageIdentifier); // Fallback to english label if label was not available in specific language if ($translation === $id && $languageIdentifier !== 'en') { $translation = parent::render($id, $value, $arguments, $source, $package, $quantity, 'en'); } return $translation; } catch (Exception $exception) { return $value ?: $id; } }
/** * Displays the backend interface * * @param NodeInterface $node The node that will be displayed on the first tab * @return void */ public function indexAction(NodeInterface $node = null) { $this->contentCache->flush(); $this->session->start(); $this->session->putData('__cheEnabled__', true); if ($user = $this->userService->getBackendUser()) { $workspaceName = $this->userService->getPersonalWorkspaceName(); $contentContext = $this->createContext($workspaceName); $contentContext->getWorkspace(); $this->persistenceManager->persistAll(); $siteNode = $contentContext->getCurrentSiteNode(); if ($node === null) { $node = $siteNode; } $this->view->assign('user', $user); $this->view->assign('documentNode', $node); $this->view->assign('site', $node); $this->view->assign('translations', $this->xliffService->getCachedJson(new Locale($this->userService->getInterfaceLanguage()))); return; } $this->redirectToUri($this->uriBuilder->uriFor('index', array(), 'Login', 'TYPO3.Neos')); }
/** * Get Related Nodes for an asset * * @param Asset $asset * @return void */ public function relatedNodesAction(Asset $asset) { $userWorkspace = $this->userService->getPersonalWorkspace(); $relatedNodes = []; foreach ($this->getRelatedNodes($asset) as $relatedNodeData) { $accessible = $this->domainUserService->currentUserCanReadWorkspace($relatedNodeData->getWorkspace()); if ($accessible) { $context = $this->createContextMatchingNodeData($relatedNodeData); } else { $context = $this->createContentContext($userWorkspace->getName()); } $site = $context->getCurrentSite(); $node = $this->nodeFactory->createFromNodeData($relatedNodeData, $context); $flowQuery = new FlowQuery([$node]); /** @var Node $documentNode */ $documentNode = $flowQuery->closest('[instanceof TYPO3.Neos:Document]')->get(0); $documentNodeIdentifier = $documentNode instanceof NodeInterface ? $documentNode->getIdentifier() : null; $relatedNodes[$site->getNodeName()]['site'] = $site; $relatedNodes[$site->getNodeName()]['documentNodes'][$documentNodeIdentifier]['node'] = $documentNode; $relatedNodes[$site->getNodeName()]['documentNodes'][$documentNodeIdentifier]['nodes'][] = ['node' => $node, 'nodeData' => $relatedNodeData, 'contextDocumentNode' => $documentNode, 'accessible' => $accessible]; } $this->view->assignMultiple(['asset' => $asset, 'relatedNodes' => $relatedNodes, 'contentDimensions' => $this->contentDimensionPresetSource->getAllPresets(), 'userWorkspace' => $userWorkspace]); }
/** * Get data * * @param NodeInterface $node The node that is currently edited (optional) * @param array $arguments Additional arguments (key / value) * @return mixed JSON serializable data * @api */ public function getData(NodeInterface $node = NULL, array $arguments) { return array('name' => $this->userService->getBackendUser()->getName()->getFullName()); }
/** * Returns the cached json array with the xliff labels * * @return string */ public function getXliffAsJsonAction() { $this->response->setHeader('Content-Type', 'application/json'); $locale = new Locale($this->userService->getInterfaceLanguage()); return $this->xliffService->getCachedJson($locale); }
/** * @return string The current backend users interface language */ public function render() { return $this->userService->getInterfaceLanguage(); }
/** * Get Related Nodes for an asset * * @param AssetInterface $asset * @return void */ public function relatedNodesAction(AssetInterface $asset) { $userWorkspace = $this->userService->getPersonalWorkspace(); $usageReferences = $this->assetService->getUsageReferences($asset); $relatedNodes = []; /** @var AssetUsageInNodeProperties $usage */ foreach ($usageReferences as $usage) { $documentNodeIdentifier = $usage->getDocumentNode() instanceof NodeInterface ? $usage->getDocumentNode()->getIdentifier() : null; $relatedNodes[$usage->getSite()->getNodeName()]['site'] = $usage->getSite(); $relatedNodes[$usage->getSite()->getNodeName()]['documentNodes'][$documentNodeIdentifier]['node'] = $usage->getDocumentNode(); $relatedNodes[$usage->getSite()->getNodeName()]['documentNodes'][$documentNodeIdentifier]['nodes'][] = ['node' => $usage->getNode(), 'nodeData' => $usage->getNode()->getNodeData(), 'contextDocumentNode' => $usage->getDocumentNode(), 'accessible' => $usage->isAccessible()]; } $this->view->assignMultiple(['asset' => $asset, 'relatedNodes' => $relatedNodes, 'contentDimensions' => $this->contentDimensionPresetSource->getAllPresets(), 'userWorkspace' => $userWorkspace]); }
/** * Set the locale according to the user settings * * @return void */ protected function initializeObject() { $this->_localizationService->getConfiguration()->setCurrentLocale(new \TYPO3\Flow\I18n\Locale($this->_userService->getInterfaceLanguage())); }