Skip to content

Commit

Permalink
WIP !!! FEATURE: Integrate new workspace ui
Browse files Browse the repository at this point in the history
  • Loading branch information
Sebobo committed Oct 31, 2023
1 parent 93a5776 commit 90bdab1
Show file tree
Hide file tree
Showing 13 changed files with 1,226 additions and 490 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,35 @@ public function findOneByName(WorkspaceName $name): ?Workspace
return $workspace;
}


public function findOneByTitle(WorkspaceTitle $title): ?Workspace
{
# TODO: Compare lowercase to prevent two workspaces "Anke" and "anke" to be created
$workspace = $this->workspaceRuntimeCache->getWorkspaceByTitle($title);
if ($workspace !== null) {
return $workspace;
}

$connection = $this->client->getConnection();
$workspaceRow = $connection->executeQuery(
'
SELECT * FROM ' . $this->tableName . '
WHERE workspaceTitle = :workspaceTitle
',
[
'workspaceTitle' => $title->value,
]
)->fetchAssociative();

if ($workspaceRow === false) {
return null;
}

$workspace = $this->createWorkspaceFromDatabaseRow($workspaceRow);
$this->workspaceRuntimeCache->setWorkspace($workspace);
return $workspace;
}

public function findOneByCurrentContentStreamId(
ContentStreamId $contentStreamId
): ?Workspace {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

use Neos\ContentRepository\Core\SharedModel\Workspace\ContentStreamId;
use Neos\ContentRepository\Core\SharedModel\Workspace\WorkspaceName;
use Neos\ContentRepository\Core\SharedModel\Workspace\WorkspaceTitle;

/**
* Workspace Runtime Cache
Expand All @@ -31,6 +32,11 @@ final class WorkspaceRuntimeCache
*/
private array $cachedWorkspacesByName = [];

/**
* @var array<string,Workspace>
*/
private array $cachedWorkspacesByTitle = [];

/**
* @var array<string,Workspace>
*/
Expand All @@ -43,6 +49,7 @@ public function disableCache(): void
{
$this->cacheEnabled = false;
$this->cachedWorkspacesByName = [];
$this->cachedWorkspacesByTitle = [];
$this->cachedWorkspacesByContentStreamId = [];
}

Expand All @@ -54,6 +61,14 @@ public function getWorkspaceByName(WorkspaceName $name): ?Workspace
return null;
}

public function getWorkspaceByTitle(WorkspaceTitle $title): ?Workspace
{
if ($this->cacheEnabled === true && isset($this->cachedWorkspacesByTitle[$title->value])) {
return $this->cachedWorkspacesByTitle[$title->value];
}
return null;
}

public function setWorkspace(Workspace $workspace): void
{
if ($this->cacheEnabled === true) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
<?php

declare(strict_types=1);

/**
* This file is part of the Shel.Neos.WorkspaceModule package.
*
* (c) 2022 Sebastian Helzle
*
* This package is Open Source Software. For the full copyright and license
* information, please view the LICENSE file which was distributed with this
* source code.
*/

namespace Shel\Neos\WorkspaceModule\Aspect;

use Neos\ContentRepository\Core\Projection\Workspace\Workspace;
use Neos\Flow\Annotations as Flow;
use Neos\Flow\Aop\JoinPointInterface;
use Neos\Flow\Persistence\PersistenceManagerInterface;
use Neos\Neos\Domain\Model\User;
use Neos\Neos\Domain\Service\UserService;
use Neos\Neos\Ui\ContentRepository\Service\WorkspaceService;
use Neos\Utility\Exception\PropertyNotAccessibleException;
use Neos\Utility\ObjectAccess;
//use Shel\Neos\WorkspaceModule\Domain\Repository\WorkspaceDetailsRepository;

/**
* @Flow\Aspect
*/
class SharedWorkspaceAccessAspect
{
// #[Flow\Inject]
// protected WorkspaceDetailsRepository $workspaceDetailsRepository;

#[Flow\Inject]
protected PersistenceManagerInterface $persistenceManager;

/**
* Adjust workspace permission check for shared workspaces
*
* @Flow\Around("method(Neos\Neos\Domain\Service\UserService->currentUserCanReadWorkspace())")
* @Flow\Around("method(Neos\Neos\Domain\Service\UserService->currentUserCanPublishToWorkspace())")
*/
public function currentUserCanManageSharedWorkspace(JoinPointInterface $joinPoint): bool
{
$result = $joinPoint->getAdviceChain()->proceed($joinPoint);

if ($result) {
return true;
}

/** @var UserService $userService */
$userService = $joinPoint->getProxy();
$currentUser = $userService->getCurrentUser();
$workspace = $joinPoint->getMethodArgument('workspace');

return $currentUser
&& $workspace->isPrivateWorkspace()
&& $workspace->workspaceOwner !== $this->persistenceManager->getIdentifierByObject($currentUser)
&& $this->isWorkspaceSharedWithUser($workspace, $currentUser);
}

/**
* Adjust workspace permission check for shared workspaces in the Neos UI
*
* @Flow\Around("method(Neos\Neos\Ui\ContentRepository\Service\WorkspaceService->getAllowedTargetWorkspaces())")
* @return Workspace[]
* @throws PropertyNotAccessibleException
*/
public function getAllowedTargetWorkspacesIncludingSharedOnes(JoinPointInterface $joinPoint): array
{
/** @var WorkspaceService $workspaceService */
$workspaceService = $joinPoint->getProxy();
/** @var UserService $userService */
$userService = ObjectAccess::getProperty($workspaceService, 'domainUserService', true);
$contentRepository = $joinPoint->getMethodArgument('contentRepository');
$user = $userService->getCurrentUser();
// $sharedWorkspaceNames = $user ? $this->workspaceDetailsRepository->findAllowedWorkspaceNamesForUser($user) : [];
$sharedWorkspaceNames = [];

$workspacesArray = [];
/** @var Workspace $workspace */
foreach ($contentRepository->getWorkspaceFinder()->findAll() as $workspace) {
// Skip personal workspaces and private workspace not shared with the current user
if (!in_array($workspace->workspaceName->value, $sharedWorkspaceNames)
&& (
($workspace->workspaceOwner !== null && $workspace->workspaceOwner !== $user)
|| $workspace->isPersonalWorkspace()
)
) {
continue;
}

$workspaceArray = [
'name' => $workspace->workspaceName->value,
'title' => $workspace->workspaceTitle?->value,
'description' => $workspace->workspaceDescription->value,
'readonly' => !$userService->currentUserCanPublishToWorkspace($workspace)
];
$workspacesArray[$workspace->workspaceName->value] = $workspaceArray;
}

return $workspacesArray;
}

/**
* Checks whether the given workspace is shared with the given user.
*/
protected function isWorkspaceSharedWithUser(Workspace $workspace, User $user): bool
{
// TODO: Reimplement
return false;

// $workspaceDetails = $this->workspaceDetailsRepository->findOneByWorkspace($workspace);
// if (!$workspaceDetails) {
// return false;
// }
// $allowedUsers = array_map(fn($user) => $this->persistenceManager->getIdentifierByObject($user),
// $workspaceDetails->getAcl());
// return in_array($this->persistenceManager->getIdentifierByObject($user), $allowedUsers, true);
}
}
123 changes: 123 additions & 0 deletions Neos.Workspace.Ui/Classes/Controller/Domain/Model/WorkspaceDetails.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
<?php

declare(strict_types=1);

namespace Shel\Neos\WorkspaceModule\Domain\Model;

/**
* This file is part of the Shel.Neos.WorkspaceModule package.
*
* (c) 2022 Sebastian Helzle
*
* This package is Open Source Software. For the full copyright and license
* information, please view the LICENSE file which was distributed with this
* source code.
*/

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Neos\ContentRepository\Core\Projection\Workspace\Workspace;
use Neos\Flow\Annotations as Flow;
use Neos\Neos\Domain\Model\User;

//#[Flow\Entity]
class WorkspaceDetails
{
// /**
// * @ORM\Column(nullable=true)
// * @var \DateTime | null
// */
// protected $lastChangedDate;
//
// /**
// * @ORM\Column(nullable=true)
// * @var string | null
// */
// protected $lastChangedBy;
//
// /**
// * @ORM\OneToOne
// * @Flow\Identity
// * @var Workspace
// */
// protected $workspace;
//
// /**
// * @ORM\Column(nullable=true)
// * @var string | null
// */
// protected $creator;
//
// /**
// * @ORM\ManyToMany
// * @var ArrayCollection<User>
// */
// protected $acl = [];
//
// public function __construct(
// Workspace $workspace,
// string $creator = null,
// \DateTime $lastChangedDate = null,
// string $lastChangedBy = null,
// ArrayCollection $acl = null
// ) {
// $this->workspace = $workspace;
// $this->creator = $creator;
// $this->lastChangedDate = $lastChangedDate ?? new \DateTime();
// $this->lastChangedBy = $lastChangedBy ?? $creator;
// $this->acl = $acl ?? new ArrayCollection();
// }
//
// public function getLastChangedDate(): ?\DateTime
// {
// return $this->lastChangedDate;
// }
//
// public function setLastChangedDate(?\DateTime $lastChangedDate): void
// {
// $this->lastChangedDate = $lastChangedDate;
// }
//
// public function getLastChangedBy(): ?string
// {
// return $this->lastChangedBy;
// }
//
// public function setLastChangedBy(?string $lastChangedBy): void
// {
// $this->lastChangedBy = $lastChangedBy;
// }
//
// public function getWorkspace(): Workspace
// {
// return $this->workspace;
// }
//
// public function getCreator(): ?string
// {
// return $this->creator;
// }
//
// public function setCreator(?string $creator): void
// {
// $this->creator = $creator;
// }
//
// /**
// * @param User[] $acl
// */
// public function setAcl(array $acl): void
// {
// $this->acl = $acl;
// }
//
// /**
// * @return User[]
// */
// public function getAcl(): array
// {
// return $this->acl instanceof Collection ? $this->acl->toArray() : $this->acl;
// }
//
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php

declare(strict_types=1);

namespace Shel\Neos\WorkspaceModule\Domain\Repository;

/**
* This file is part of the Shel.Neos.WorkspaceModule package.
*
* (c) 2022 Sebastian Helzle
*
* This package is Open Source Software. For the full copyright and license
* information, please view the LICENSE file which was distributed with this
* source code.
*/

use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Query\ResultSetMapping;
use Neos\ContentRepository\Core\Projection\Workspace\Workspace;
use Neos\Flow\Annotations as Flow;
use Neos\Flow\Persistence\QueryResultInterface;
use Neos\Flow\Persistence\Repository;
use Neos\Neos\Domain\Model\User;
//use Shel\Neos\WorkspaceModule\Domain\Model\WorkspaceDetails;

///**
// * @method WorkspaceDetails findOneByWorkspace(Workspace $workspace)
// * @method QueryResultInterface<WorkspaceDetails> findAll()
// */
#[Flow\Scope('singleton')]
class WorkspaceDetailsRepository extends Repository
{
// #[Flow\Inject]
// protected EntityManagerInterface $entityManager;
//
// /**
// * @return string[] The names of all workspaces shared with the given user
// */
// public function findAllowedWorkspaceNamesForUser(User $user): array
// {
// // Prepare raw query
// $rsm = new ResultSetMapping();
// $rsm->addScalarResult('workspace', 'workspace');
//
// // Find all workspaces shared with the given user with one query
// $queryString = '
// SELECT d.workspace FROM shel_neos_workspacemodule_domain_model_workspacedetails d
// JOIN shel_neos_workspacemodule_domain_model_workspace_1536f_acl_join a
// ON d.persistence_object_identifier = a.workspacemodule_workspacedetails
// WHERE a.neos_user = ?
// ';
// $query = $this->entityManager->createNativeQuery($queryString, $rsm);
// $query->setParameter(1, $user);
// return $query->getSingleColumnResult();
// }
}
Loading

0 comments on commit 90bdab1

Please sign in to comment.