@@ -101,16 +100,6 @@ WorkspaceProgression.propTypes = {
)
}
-const WorkspaceShortcuts = props =>
-
-
const WorkspaceMenu = (props) => {
let workspaceActions
if (!isEmpty(props.workspace)) {
@@ -125,7 +114,8 @@ const WorkspaceMenu = (props) => {
}
return (
- {
tools={props.tools
// hide tools that can not be configured in models for now
.filter(tool => !get(props.workspace, 'meta.model', false) || -1 !== constants.WORKSPACE_MODEL_TOOLS.indexOf(tool.name))
- .filter(tool => hasPermission('open', tool))
- .map(tool => ({
- name: tool.name,
- icon: tool.icon,
- path: workspaceRoute(props.workspace, tool.name),
- order: get(tool, 'display.order'),
- displayed: !get(tool, 'restrictions.hidden', false)
- }))
}
actions={workspaceActions}
+ shortcuts={props.shortcuts}
>
{!props.impersonated && get(props.workspace, 'display.showProgression') &&
{
workspace={props.workspace}
/>
}
-
- {!isEmpty(props.shortcuts) &&
- {
- return props.shortcuts
- .map(shortcut => {
- if ('tool' === shortcut.type) {
- const tool = props.tools.find(tool => tool.name === shortcut.name)
- if (tool) {
- return {
- name: tool.name,
- type: LINK_BUTTON,
- icon: `fa fa-fw fa-${tool.icon}`,
- label: trans('open-tool', {tool: trans(tool.name, {}, 'tools')}, 'actions'),
- target: workspaceRoute(props.workspace, tool.name)
- }
- }
-
- } else {
- return actions.find(action => action.name === shortcut.name)
- }
- })
- .filter(link => !!link)
- })}
- />
- }
-
- props.changeSection('tool')}
- />
-
+
)
}
@@ -225,7 +177,6 @@ WorkspaceMenu.propTypes = {
name: T.string.isRequired,
permissions: T.object
})),
- changeSection: T.func.isRequired,
update: T.func.isRequired
}
diff --git a/src/main/app/Resources/modules/contexts/workspace/containers/menu.jsx b/src/main/app/Resources/modules/contexts/workspace/containers/menu.jsx
index bd76a6ed6e3..a74d5a72dc0 100644
--- a/src/main/app/Resources/modules/contexts/workspace/containers/menu.jsx
+++ b/src/main/app/Resources/modules/contexts/workspace/containers/menu.jsx
@@ -3,7 +3,6 @@ import {connect} from 'react-redux'
import {withRouter} from '#/main/app/router'
import {selectors as securitySelectors} from '#/main/app/security/store'
-import {actions as menuActions, selectors as menuSelectors} from '#/main/app/layout/menu/store'
import {selectors as contextSelectors} from '#/main/app/context/store'
import {WorkspaceMenu as WorkspaceMenuComponent} from '#/main/app/contexts/workspace/components/menu'
@@ -16,7 +15,8 @@ const WorkspaceMenu = withRouter(
impersonated: contextSelectors.impersonated(state),
roles: contextSelectors.roles(state),
workspace: contextSelectors.data(state),
- section: menuSelectors.openedSection(state),
+
+ basePath: contextSelectors.path(state),
tools: contextSelectors.tools(state),
shortcuts: contextSelectors.shortcuts(state),
userEvaluation: selectors.userEvaluation(state)
@@ -24,9 +24,6 @@ const WorkspaceMenu = withRouter(
(dispatch) => ({
update(workspace) {
dispatch(actions.reload(workspace))
- },
- changeSection(section) {
- dispatch(menuActions.changeSection(section))
}
})
)(WorkspaceMenuComponent)
diff --git a/src/main/app/Security/Voter/AbstractVoter.php b/src/main/app/Security/Voter/AbstractVoter.php
index ec558c5cfc1..c414e1fd30b 100644
--- a/src/main/app/Security/Voter/AbstractVoter.php
+++ b/src/main/app/Security/Voter/AbstractVoter.php
@@ -14,7 +14,6 @@
use Claroline\AppBundle\Persistence\ObjectManager;
use Claroline\AppBundle\Security\ObjectCollection;
use Claroline\AppBundle\Security\Voter\VoterInterface as ClarolineVoterInterface;
-use Claroline\CoreBundle\Entity\Tool\AdminTool;
use Claroline\CoreBundle\Entity\Tool\OrderedTool;
use Claroline\CoreBundle\Entity\User;
use Claroline\CoreBundle\Entity\Workspace\Workspace;
@@ -59,7 +58,7 @@ public function vote(TokenInterface $token, $subject, array $attributes): int
}
}
- //maybe abstain sometimes
+ // maybe abstain sometimes
return VoterInterface::ACCESS_GRANTED;
}
@@ -76,9 +75,6 @@ protected function getObjectManager()
/**
* /!\ Try not to go infinite looping with this. Careful.
*
- * @param mixed $attributes
- * @param mixed $object
- *
* @deprecated do it yourself !
*/
protected function isGranted($attributes, $object = null): bool
@@ -86,9 +82,6 @@ protected function isGranted($attributes, $object = null): bool
return $this->security->isGranted($attributes, $object);
}
- /**
- * @param mixed $object
- */
private function supports($object): bool
{
return is_a($object, $this->getClass(), true)
@@ -113,27 +106,26 @@ public function supportsAttribute(string $attribute): bool
return in_array($attribute, $this->getSupportedActions());
}
+ /**
+ * @deprecated
+ */
protected function isToolGranted($permission, string $toolName, Workspace $workspace = null): bool
{
$orderedToolRepo = $this->getObjectManager()->getRepository(OrderedTool::class);
-
- if ($workspace) {
- $orderedTool = $orderedToolRepo->findOneByNameAndWorkspace($toolName, $workspace);
- } else {
- $orderedTool = $orderedToolRepo->findOneByNameAndDesktop($toolName);
- }
+ $orderedTool = $orderedToolRepo->findOneByNameAndContext($toolName, !empty($workspace) ? 'workspace' : 'desktop', $workspace);
return $this->isGranted($permission, $orderedTool);
}
+ /**
+ * @deprecated
+ */
protected function hasAdminToolAccess(TokenInterface $token, string $name): bool
{
- /** @var AdminTool $tool */
- $tool = $this->getObjectManager()
- ->getRepository(AdminTool::class)
- ->findOneBy(['name' => $name]);
+ $orderedToolRepo = $this->getObjectManager()->getRepository(OrderedTool::class);
+ $orderedTool = $orderedToolRepo->findOneByNameAndContext($name, 'administration');
- return $this->isGranted('OPEN', $tool);
+ return $this->isGranted('OPEN', $orderedTool);
}
/**
@@ -161,7 +153,7 @@ public function checkPermission(TokenInterface $token, $object, array $attribute
{
$collection = isset($options['collection']) ? $options['collection'] : null;
- //crud actions
+ // crud actions
switch ($attributes[0]) {
case self::VIEW: return $this->checkView($token, $object);
case self::CREATE: return $this->checkCreation($token, $object);
diff --git a/src/main/authentication/Component/Tool/AuthenticationTool.php b/src/main/authentication/Component/Tool/AuthenticationTool.php
new file mode 100644
index 00000000000..e231bb2de26
--- /dev/null
+++ b/src/main/authentication/Component/Tool/AuthenticationTool.php
@@ -0,0 +1,55 @@
+ $this->serializer->serialize(
+ $this->authenticationManager->getParameters()
+ ),
+ ];
+ }
+
+ return [];
+ }
+
+ public function configure(string $context, ContextSubjectInterface $contextSubject = null, array $configData = []): ?array
+ {
+ return [];
+ }
+}
diff --git a/src/main/authentication/DependencyInjection/ClarolineAuthenticationExtension.php b/src/main/authentication/DependencyInjection/ClarolineAuthenticationExtension.php
index 5481445ce47..f0c171d02b9 100644
--- a/src/main/authentication/DependencyInjection/ClarolineAuthenticationExtension.php
+++ b/src/main/authentication/DependencyInjection/ClarolineAuthenticationExtension.php
@@ -16,19 +16,14 @@
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
-/**
- * Loads the authentication services configuration files.
- */
class ClarolineAuthenticationExtension extends Extension
{
- /**
- * {@inheritdoc}
- */
- public function load(array $configs, ContainerBuilder $container)
+ public function load(array $configs, ContainerBuilder $container): void
{
$locator = new FileLocator(__DIR__.'/../Resources/config');
$loader = new YamlFileLoader($container, $locator);
$loader->load('services.yml');
+ $loader->load('components.yml');
}
}
diff --git a/src/main/authentication/Installation/ClarolineAuthenticationInstaller.php b/src/main/authentication/Installation/ClarolineAuthenticationInstaller.php
index 0616764c03f..a35da049fd1 100644
--- a/src/main/authentication/Installation/ClarolineAuthenticationInstaller.php
+++ b/src/main/authentication/Installation/ClarolineAuthenticationInstaller.php
@@ -13,4 +13,9 @@ public static function getUpdaters(): array
'14.0.0' => Updater140000::class,
];
}
+
+ public function hasMigrations(): bool
+ {
+ return true;
+ }
}
diff --git a/src/main/authentication/Installation/Updater/Updater140000.php b/src/main/authentication/Installation/Updater/Updater140000.php
index 930728b8b54..f361e6c4b07 100644
--- a/src/main/authentication/Installation/Updater/Updater140000.php
+++ b/src/main/authentication/Installation/Updater/Updater140000.php
@@ -22,7 +22,7 @@ public function __construct(
public function postUpdate(): void
{
- $this->log('Update AuthenticationParameters ...');
+ $this->logger->info('Update AuthenticationParameters ...');
$authenticationParameters = $this->authenticationManager->getParameters();
diff --git a/src/main/authentication/Resources/config/components.yml b/src/main/authentication/Resources/config/components.yml
new file mode 100644
index 00000000000..cc128a70a3d
--- /dev/null
+++ b/src/main/authentication/Resources/config/components.yml
@@ -0,0 +1,2 @@
+imports:
+ - { resource: components/tool.yml }
diff --git a/src/main/authentication/Resources/config/components/tool.yml b/src/main/authentication/Resources/config/components/tool.yml
new file mode 100644
index 00000000000..438ebe39f31
--- /dev/null
+++ b/src/main/authentication/Resources/config/components/tool.yml
@@ -0,0 +1,7 @@
+services:
+ Claroline\AuthenticationBundle\Component\Tool\AuthenticationTool:
+ parent: Claroline\AppBundle\Component\Tool\AbstractTool
+ tags: [ 'claroline.component.tool' ]
+ arguments:
+ - '@Claroline\AppBundle\API\SerializerProvider'
+ - '@Claroline\AuthenticationBundle\Manager\AuthenticationManager'
diff --git a/src/main/authentication/Resources/config/services/subscriber.yml b/src/main/authentication/Resources/config/services/subscriber.yml
index c6e27b75d58..c5616714fb1 100644
--- a/src/main/authentication/Resources/config/services/subscriber.yml
+++ b/src/main/authentication/Resources/config/services/subscriber.yml
@@ -10,10 +10,3 @@ services:
- '@Claroline\CoreBundle\Library\Configuration\PlatformConfigurationHandler'
- '@Claroline\AppBundle\API\SerializerProvider'
- '@Claroline\AuthenticationBundle\Manager\AuthenticationManager'
-
- # Administration
- Claroline\AuthenticationBundle\Subscriber\Administration\ParametersSubscriber:
- tags: [ kernel.event_subscriber ]
- arguments:
- - '@Claroline\AppBundle\API\SerializerProvider'
- - '@Claroline\AuthenticationBundle\Manager\AuthenticationManager'
diff --git a/src/main/authentication/Resources/modules/account/tokens/components/main.jsx b/src/main/authentication/Resources/modules/account/authentication/components/tool.jsx
similarity index 92%
rename from src/main/authentication/Resources/modules/account/tokens/components/main.jsx
rename to src/main/authentication/Resources/modules/account/authentication/components/tool.jsx
index 77dc9c3b308..ea3372cbe35 100644
--- a/src/main/authentication/Resources/modules/account/tokens/components/main.jsx
+++ b/src/main/authentication/Resources/modules/account/authentication/components/tool.jsx
@@ -12,9 +12,9 @@ import {route} from '#/main/app/account/routing'
import {MODAL_TOKEN_PARAMETERS} from '#/main/authentication/token/modals/parameters'
import {TokenList} from '#/main/authentication/token/components/list'
-import {selectors} from '#/main/authentication/account/tokens/store'
+import {selectors} from '#/main/authentication/account/authentication/store'
-const TokensMain = props =>
+const AuthenticationTool = props =>
-TokensMain.propTypes = {
+AuthenticationTool.propTypes = {
currentUser: T.shape(
UserTypes.propTypes
).isRequired,
@@ -75,5 +75,5 @@ TokensMain.propTypes = {
}
export {
- TokensMain
+ AuthenticationTool
}
diff --git a/src/main/authentication/Resources/modules/account/tokens/containers/main.jsx b/src/main/authentication/Resources/modules/account/authentication/containers/tool.jsx
similarity index 66%
rename from src/main/authentication/Resources/modules/account/tokens/containers/main.jsx
rename to src/main/authentication/Resources/modules/account/authentication/containers/tool.jsx
index 09c91f9f194..283547292b7 100644
--- a/src/main/authentication/Resources/modules/account/tokens/containers/main.jsx
+++ b/src/main/authentication/Resources/modules/account/authentication/containers/tool.jsx
@@ -4,10 +4,10 @@ import {withReducer} from '#/main/app/store/components/withReducer'
import {selectors as securitySelectors} from '#/main/app/security/store'
import {actions as listActions} from '#/main/app/content/list/store'
-import {reducer, selectors} from '#/main/authentication/account/tokens/store'
-import {TokensMain as TokensMainComponent} from '#/main/authentication/account/tokens/components/main'
+import {reducer, selectors} from '#/main/authentication/account/authentication/store'
+import {AuthenticationTool as AuthenticationToolComponent} from '#/main/authentication/account/authentication/components/tool'
-const TokensMain = withReducer(selectors.STORE_NAME, reducer)(
+const AuthenticationTool = withReducer(selectors.STORE_NAME, reducer)(
connect(
(state) => ({
currentUser: securitySelectors.currentUser(state)
@@ -17,9 +17,9 @@ const TokensMain = withReducer(selectors.STORE_NAME, reducer)(
dispatch(listActions.invalidateData(selectors.STORE_NAME))
}
})
- )(TokensMainComponent)
+ )(AuthenticationToolComponent)
)
export {
- TokensMain
+ AuthenticationTool
}
diff --git a/src/main/authentication/Resources/modules/account/authentication/index.js b/src/main/authentication/Resources/modules/account/authentication/index.js
new file mode 100644
index 00000000000..0f9caf598e1
--- /dev/null
+++ b/src/main/authentication/Resources/modules/account/authentication/index.js
@@ -0,0 +1,8 @@
+import {AuthenticationTool} from '#/main/authentication/account/authentication/containers/tool'
+
+export default {
+ component: AuthenticationTool/*,
+ name: 'tokens',
+ icon: 'fa fa-fw fa-coins',
+ label: trans('tokens', {}, 'security')*/
+}
diff --git a/src/main/authentication/Resources/modules/account/authentication/store/index.js b/src/main/authentication/Resources/modules/account/authentication/store/index.js
new file mode 100644
index 00000000000..a69327fb471
--- /dev/null
+++ b/src/main/authentication/Resources/modules/account/authentication/store/index.js
@@ -0,0 +1,7 @@
+import {reducer} from '#/main/authentication/account/authentication/store/reducer'
+import {selectors} from '#/main/authentication/account/authentication/store/selectors'
+
+export {
+ reducer,
+ selectors
+}
diff --git a/src/main/authentication/Resources/modules/account/tokens/store/reducer.js b/src/main/authentication/Resources/modules/account/authentication/store/reducer.js
similarity index 50%
rename from src/main/authentication/Resources/modules/account/tokens/store/reducer.js
rename to src/main/authentication/Resources/modules/account/authentication/store/reducer.js
index d36a5ac6133..ffe384681aa 100644
--- a/src/main/authentication/Resources/modules/account/tokens/store/reducer.js
+++ b/src/main/authentication/Resources/modules/account/authentication/store/reducer.js
@@ -1,7 +1,6 @@
-import {combineReducers} from '#/main/app/store/reducer'
import {makeListReducer} from '#/main/app/content/list/store'
-import {selectors} from '#/main/authentication/account/tokens/store/selectors'
+import {selectors} from '#/main/authentication/account/authentication/store/selectors'
const reducer = makeListReducer(selectors.STORE_NAME)
diff --git a/src/main/authentication/Resources/modules/account/tokens/store/selectors.js b/src/main/authentication/Resources/modules/account/authentication/store/selectors.js
similarity index 55%
rename from src/main/authentication/Resources/modules/account/tokens/store/selectors.js
rename to src/main/authentication/Resources/modules/account/authentication/store/selectors.js
index dbe275e1af7..d8bd3f3cc69 100644
--- a/src/main/authentication/Resources/modules/account/tokens/store/selectors.js
+++ b/src/main/authentication/Resources/modules/account/authentication/store/selectors.js
@@ -1,5 +1,5 @@
-const STORE_NAME = 'accountTokens'
+const STORE_NAME = 'authentication'
export const selectors = {
STORE_NAME
diff --git a/src/main/authentication/Resources/modules/account/tokens/index.js b/src/main/authentication/Resources/modules/account/tokens/index.js
deleted file mode 100644
index c1f5494dd53..00000000000
--- a/src/main/authentication/Resources/modules/account/tokens/index.js
+++ /dev/null
@@ -1,10 +0,0 @@
-import {trans} from '#/main/app/intl/translation'
-
-import {TokensMain} from '#/main/authentication/account/tokens/containers/main'
-
-export default {
- name: 'tokens',
- icon: 'fa fa-fw fa-coins',
- label: trans('tokens', {}, 'security'),
- component: TokensMain
-}
diff --git a/src/main/authentication/Resources/modules/account/tokens/store/index.js b/src/main/authentication/Resources/modules/account/tokens/store/index.js
deleted file mode 100644
index 3319e109c41..00000000000
--- a/src/main/authentication/Resources/modules/account/tokens/store/index.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import {reducer} from '#/main/authentication/account/tokens/store/reducer'
-import {selectors} from '#/main/authentication/account/tokens/store/selectors'
-
-export {
- reducer,
- selectors
-}
diff --git a/src/main/authentication/Resources/modules/administration/authentication/components/menu.jsx b/src/main/authentication/Resources/modules/administration/authentication/components/menu.jsx
new file mode 100644
index 00000000000..070daaef8ca
--- /dev/null
+++ b/src/main/authentication/Resources/modules/administration/authentication/components/menu.jsx
@@ -0,0 +1,25 @@
+import React from 'react'
+import {PropTypes as T} from 'prop-types'
+import omit from 'lodash/omit'
+
+import {trans} from '#/main/app/intl/translation'
+import {MenuSection} from '#/main/app/layout/menu/components/section'
+
+const AuthenticationMenu = (props) =>
+
+
+AuthenticationMenu.propTypes = {
+ path: T.string,
+
+ // from menu
+ opened: T.bool.isRequired,
+ toggle: T.func.isRequired,
+ autoClose: T.func.isRequired
+}
+
+export {
+ AuthenticationMenu
+}
diff --git a/src/main/authentication/Resources/modules/administration/authentication/components/tool.jsx b/src/main/authentication/Resources/modules/administration/authentication/components/tool.jsx
index 1ed57d637c3..702e4341e05 100644
--- a/src/main/authentication/Resources/modules/administration/authentication/components/tool.jsx
+++ b/src/main/authentication/Resources/modules/administration/authentication/components/tool.jsx
@@ -5,6 +5,7 @@ import get from 'lodash/get'
import {trans} from '#/main/app/intl/translation'
import {LINK_BUTTON} from '#/main/app/buttons'
import {FormData} from '#/main/app/content/form/containers/data'
+import {ToolPage} from '#/main/core/tool/containers/page'
import {selectors} from '#/main/authentication/administration/authentication/store/selectors'
@@ -15,8 +16,8 @@ const displayPasswordValidation = (data) => get(data, 'password._forceComplexity
|| get(data, 'password.requireNumber')
|| get(data, 'password.requireSpecialChar')
-const AuthenticationTool = (props) => {
- return (
+const AuthenticationTool = (props) =>
+
{
}
]}
/>
- )
-}
+
AuthenticationTool.propTypes = {
path: T.string.isRequired,
diff --git a/src/main/authentication/Resources/modules/administration/authentication/index.js b/src/main/authentication/Resources/modules/administration/authentication/index.js
new file mode 100644
index 00000000000..8ff1fd16607
--- /dev/null
+++ b/src/main/authentication/Resources/modules/administration/authentication/index.js
@@ -0,0 +1,9 @@
+import {reducer} from '#/main/authentication/administration/authentication/store'
+import {AuthenticationTool} from '#/main/authentication/administration/authentication/containers/tool'
+import {AuthenticationMenu} from '#/main/authentication/administration/authentication/components/menu'
+
+export default {
+ component: AuthenticationTool,
+ menu: AuthenticationMenu,
+ store: reducer
+}
diff --git a/src/main/authentication/Resources/modules/administration/authentication/store/selectors.js b/src/main/authentication/Resources/modules/administration/authentication/store/selectors.js
index 045f40b4b0d..b0ca2e7f842 100644
--- a/src/main/authentication/Resources/modules/administration/authentication/store/selectors.js
+++ b/src/main/authentication/Resources/modules/administration/authentication/store/selectors.js
@@ -2,7 +2,7 @@ import {createSelector} from 'reselect'
import {selectors as paramSelectors} from '#/main/core/administration/parameters/store/selectors'
-const STORE_NAME = 'authenticationParameters'
+const STORE_NAME = 'authentication'
const FORM_NAME = paramSelectors.STORE_NAME+'.'+STORE_NAME
const store = createSelector(
diff --git a/src/main/authentication/Resources/modules/plugin.js b/src/main/authentication/Resources/modules/plugin.js
index bd7efc95cdc..ca6041c3211 100644
--- a/src/main/authentication/Resources/modules/plugin.js
+++ b/src/main/authentication/Resources/modules/plugin.js
@@ -17,7 +17,11 @@ registry.add('ClarolineAuthenticationBundle', {
* Provides current user Account sections.
*/
account: {
- 'tokens': () => { return import(/* webpackChunkName: "authentication-account-tokens" */ '#/main/authentication/account/tokens') }
+ 'authentication': () => { return import(/* webpackChunkName: "authentication-account-authentication" */ '#/main/authentication/account/authentication') }
+ },
+
+ administration: {
+ 'authentication': () => { return import(/* webpackChunkName: "authentication-administration-authentication" */ '#/main/authentication/administration/authentication') }
},
integration: {
diff --git a/src/main/authentication/Subscriber/Administration/ParametersSubscriber.php b/src/main/authentication/Subscriber/Administration/ParametersSubscriber.php
deleted file mode 100644
index e674c98a9b6..00000000000
--- a/src/main/authentication/Subscriber/Administration/ParametersSubscriber.php
+++ /dev/null
@@ -1,41 +0,0 @@
-serializer = $serializer;
- $this->authenticationManager = $authenticationManager;
- }
-
- public static function getSubscribedEvents(): array
- {
- return [
- ToolEvents::getEventName(ToolEvents::OPEN, Tool::ADMINISTRATION, static::NAME) => 'onOpen',
- ];
- }
-
- public function onOpen(OpenToolEvent $event): void
- {
- $event->setData([
- 'authentication' => $this->serializer->serialize(
- $this->authenticationManager->getParameters()
- ),
- ]);
- }
-}
diff --git a/src/main/community/Component/Tool/CommunityTool.php b/src/main/community/Component/Tool/CommunityTool.php
new file mode 100644
index 00000000000..e8ee8c1862f
--- /dev/null
+++ b/src/main/community/Component/Tool/CommunityTool.php
@@ -0,0 +1,248 @@
+tokenStorage->getToken()->getUser() instanceof User && $context === WorkspaceContext::getName()) {
+ $userTeams = $this->teamManager->getTeamsByUserAndWorkspace($this->tokenStorage->getToken()->getUser(), $contextSubject);
+ }
+
+ return [
+ 'userTeams' => array_map(function (Team $team) {
+ return $this->serializer->serialize($team, [SerializerInterface::SERIALIZE_MINIMAL]);
+ }, $userTeams),
+ 'profile' => $this->profileSerializer->serialize(),
+ 'usersLimitReached' => $this->userManager->hasReachedLimit(),
+ // for retro compatibility :
+ // - in workspace tool, configuration is stored in the workspace entity
+ // - in desktop tool, configuration is stored in the platform options
+ // to remove when the community options get their own entity
+ 'parameters' => $contextSubject ? $this->getWorkspaceParameters($contextSubject) : $this->getDesktopParameters(),
+ ];
+ }
+
+ public function configure(string $context, ContextSubjectInterface $contextSubject = null, array $configData = []): ?array
+ {
+ if (isset($configData['parameters'])) {
+ if (!empty($contextSubject)) {
+ // configure workspace tool
+ $updatedParameters = $this->updateWorkspaceParameters($configData['parameters'], $contextSubject);
+ } else {
+ // configure desktop tool
+ $updatedParameters = $this->updateDesktopParameters($configData['parameters']);
+ }
+
+ // send updated data to the caller
+ return [
+ 'parameters' => $updatedParameters,
+ ];
+ }
+
+ return [];
+ }
+
+ public function export(string $context, ContextSubjectInterface $contextSubject = null, FileBag $fileBag = null): ?array
+ {
+ if (WorkspaceContext::getName() !== $context) {
+ return [];
+ }
+
+ $teams = $this->om->getRepository(Team::class)->findBy(['workspace' => $contextSubject]);
+
+ return [
+ 'teams' => array_map(function (Team $team) {
+ return $this->serializer->serialize($team);
+ }, $teams),
+ ];
+ }
+
+ public function import(string $context, ContextSubjectInterface $contextSubject = null, FileBag $fileBag = null, array $data = [], array $entities = []): ?array
+ {
+ if (WorkspaceContext::getName() !== $context) {
+ return [];
+ }
+
+ if (empty($data['teams'])) {
+ return [];
+ }
+
+ $this->om->startFlushSuite();
+
+ // import teams
+ foreach ($data['teams'] as $teamData) {
+ // correct relation to external entities
+ if (isset($teamData['workspace'])) {
+ unset($teamData['workspace']);
+ }
+
+ if (!empty($teamData['directory']) && $entities[$teamData['directory']['id']]) {
+ $teamData['directory'] = [
+ 'id' => $entities[$teamData['directory']['id']]->getUuid(),
+ ];
+ }
+
+ if (!empty($teamData['role']) && $entities[$teamData['role']['id']]) {
+ $teamData['role'] = [
+ 'id' => $entities[$teamData['role']['id']]->getUuid(),
+ ];
+ }
+
+ if (!empty($teamData['managerRole']) && $entities[$teamData['managerRole']['id']]) {
+ $teamData['managerRole'] = [
+ 'id' => $entities[$teamData['managerRole']['id']]->getUuid(),
+ ];
+ }
+
+ $team = new Team();
+ $team->setWorkspace($contextSubject);
+
+ $this->crud->create($team, $teamData, [Crud::NO_PERMISSIONS, Crud::NO_VALIDATION, Options::REFRESH_UUID]);
+
+ $entities[$teamData['id']] = $team;
+ }
+
+ $this->om->endFlushSuite();
+
+ return [];
+ }
+
+ private function getWorkspaceParameters(Workspace $workspace): array
+ {
+ $parameters = $this->serializer->serialize($workspace);
+
+ // only grab workspace props we want
+ return [
+ 'registration' => $parameters['registration'],
+ ];
+ }
+
+ private function getDesktopParameters(): array
+ {
+ $parameters = $this->parametersSerializer->serialize();
+
+ // load default role entity for UI rendering
+ $defaultRoleName = ArrayUtils::get($parameters, 'registration.default_role') ?? PlatformRoles::USER;
+ $roleUser = $this->roleManager->getRoleByName($defaultRoleName);
+ if (empty($parameters['registration'])) {
+ $parameters['registration'] = [];
+ }
+ $parameters['registration']['default_role'] = $this->serializer->serialize($roleUser, [SerializerInterface::SERIALIZE_MINIMAL]);
+
+ // only grab platform options we want
+ return [
+ 'registration' => $parameters['registration'] ?? [],
+ 'authentication' => $parameters['authentication'] ?? [],
+ 'profile' => $parameters['profile'] ?? [],
+ 'community' => $parameters['community'] ?? [],
+ ];
+ }
+
+ private function updateDesktopParameters(array $parametersData): array
+ {
+ // only keep parameters linked to community to avoid exposing all the platform parameters here
+ $communityParameters = [];
+ if (isset($parametersData['registration'])) {
+ $communityParameters['registration'] = $parametersData['registration'];
+
+ // only store default role name in platform options
+ if (!empty($parametersData['registration']['default_role'])) {
+ $communityParameters['registration']['default_role'] = $parametersData['registration']['default_role']['name'];
+ }
+ }
+ if (isset($parametersData['authentication'])) {
+ $communityParameters['authentication'] = $parametersData['authentication'];
+ }
+ if (isset($parametersData['profile'])) {
+ $communityParameters['profile'] = $parametersData['profile'];
+ }
+ if (isset($parametersData['community'])) {
+ $communityParameters['community'] = $parametersData['community'];
+ }
+
+ // removes locked parameters values if any
+ $locked = $this->config->getParameter('lockedParameters') ?? [];
+ foreach ($locked as $lockedParam) {
+ ArrayUtils::remove($communityParameters, $lockedParam);
+ }
+
+ // save updated parameters
+ $this->parametersSerializer->deserialize($communityParameters);
+
+ return $this->parametersSerializer->serialize();
+ }
+
+ private function updateWorkspaceParameters(array $parametersData, Workspace $workspace): array
+ {
+ // only keep parameters linked to community to avoid exposing all the workspace parameters here
+ $communityParameters = [];
+ if (isset($parametersData['registration'])) {
+ $communityParameters['registration'] = $parametersData['registration'];
+ }
+
+ $this->crud->update($workspace, $communityParameters, [Crud::THROW_EXCEPTION]);
+
+ return $this->serializer->serialize($workspace);
+ }
+}
diff --git a/src/main/community/Component/Tool/ProfileTool.php b/src/main/community/Component/Tool/ProfileTool.php
new file mode 100644
index 00000000000..4df8aae2dff
--- /dev/null
+++ b/src/main/community/Component/Tool/ProfileTool.php
@@ -0,0 +1,35 @@
+checkToolAccess('SHOW_ACTIVITY', $contextId)) {
throw new AccessDeniedException();
@@ -132,7 +130,7 @@ public function openAction(?string $contextId = null): JsonResponse
/**
* @Route("/global/{contextId}", name="apiv2_community_activity_global")
*/
- public function globalAction(Request $request, ?string $contextId = null): JsonResponse
+ public function globalAction(Request $request, string $contextId = null): JsonResponse
{
if (!$this->checkToolAccess('SHOW_ACTIVITY', $contextId)) {
throw new AccessDeniedException();
@@ -154,7 +152,7 @@ public function globalAction(Request $request, ?string $contextId = null): JsonR
/**
* @Route("/logs/{contextId}", name="apiv2_community_activity_logs", methods={"GET"})
*/
- public function listLogsAction(Request $request, ?string $contextId = null): JsonResponse
+ public function listLogsAction(Request $request, string $contextId = null): JsonResponse
{
if (!$this->checkToolAccess('SHOW_ACTIVITY', $contextId)) {
throw new AccessDeniedException();
@@ -165,7 +163,7 @@ public function listLogsAction(Request $request, ?string $contextId = null): Jso
);
}
- private function checkToolAccess(string $rights = 'OPEN', ?string $contextId = null): bool
+ private function checkToolAccess(string $rights = 'OPEN', string $contextId = null): bool
{
if ($contextId) {
$communityTool = $this->toolManager->getOrderedTool('community', Tool::WORKSPACE, $contextId);
@@ -180,7 +178,7 @@ private function checkToolAccess(string $rights = 'OPEN', ?string $contextId = n
return true;
}
- private function filterQuery(array $query, ?string $contextId = null): array
+ private function filterQuery(array $query, string $contextId = null): array
{
if ($contextId) {
$workspace = $this->om->getRepository(Workspace::class)->findOneBy(['uuid' => $contextId]);
diff --git a/src/main/community/Controller/RoleController.php b/src/main/community/Controller/RoleController.php
index fe2290c86f5..24acd97c8aa 100644
--- a/src/main/community/Controller/RoleController.php
+++ b/src/main/community/Controller/RoleController.php
@@ -16,12 +16,6 @@
use Claroline\CoreBundle\Controller\APINew\Model\HasGroupsTrait;
use Claroline\CoreBundle\Controller\APINew\Model\HasUsersTrait;
use Claroline\CoreBundle\Entity\Role;
-use Claroline\CoreBundle\Entity\Tool\AdminTool;
-use Claroline\CoreBundle\Entity\Tool\OrderedTool;
-use Claroline\CoreBundle\Entity\Tool\Tool;
-use Claroline\CoreBundle\Entity\User;
-use Claroline\CoreBundle\Entity\Workspace\Workspace;
-use Claroline\CoreBundle\Manager\LogManager;
use Claroline\CoreBundle\Manager\Tool\ToolManager;
use Claroline\CoreBundle\Security\PermissionCheckerTrait;
use Sensio\Bundle\FrameworkExtraBundle\Configuration as EXT;
@@ -39,21 +33,11 @@ class RoleController extends AbstractCrudController
use HasGroupsTrait;
use PermissionCheckerTrait;
- /** @var AuthorizationCheckerInterface */
- private $authorization;
- /** @var ToolManager */
- private $toolManager;
- /** @var LogManager */
- private $logManager;
-
public function __construct(
AuthorizationCheckerInterface $authorization,
- ToolManager $toolManager,
- LogManager $logManager
+ private readonly ToolManager $toolManager
) {
$this->authorization = $authorization;
- $this->toolManager = $toolManager;
- $this->logManager = $logManager;
}
public function getName(): string
@@ -91,41 +75,18 @@ public function listAction(Request $request, $class): JsonResponse
* Get a role rights for the given context.
*
* @Route("/{id}/rights/{contextType}/{contextId}", name="apiv2_role_rights_list", defaults={"contextId"=null}, methods={"GET"})
+ *
* @EXT\ParamConverter("role", options={"mapping": {"id": "uuid"}})
*/
- public function listRightsAction(Role $role, string $contextType, ?string $contextId = null): JsonResponse
+ public function listRightsAction(Role $role, string $contextType, string $contextId = null): JsonResponse
{
$this->checkPermission('OPEN', $role, [], true);
$rights = [];
- switch ($contextType) {
- case Tool::DESKTOP:
- // get desktop tools
- $orderedTools = $this->om->getRepository(OrderedTool::class)->findByDesktop();
- foreach ($orderedTools as $orderedTool) {
- $rights[$orderedTool->getTool()->getName()] = $this->toolManager->getPermissions($orderedTool, $role);
- }
-
- break;
- case Tool::WORKSPACE:
- // get workspace tools
- $workspace = $this->om->getRepository(Workspace::class)->findOneBy(['uuid' => $contextId]);
- $orderedTools = $this->om->getRepository(OrderedTool::class)->findByWorkspace($workspace);
- foreach ($orderedTools as $orderedTool) {
- $rights[$orderedTool->getTool()->getName()] = $this->toolManager->getPermissions($orderedTool, $role);
- }
-
- break;
- case Tool::ADMINISTRATION:
- $adminTools = $this->om->getRepository(AdminTool::class)->findAll();
- foreach ($adminTools as $adminTool) {
- $rights[$adminTool->getName()] = [
- 'open' => $role->getAdminTools()->contains($adminTool),
- ];
- }
-
- break;
+ $orderedTools = $this->toolManager->getOrderedTools($contextType, $contextId);
+ foreach ($orderedTools as $orderedTool) {
+ $rights[$orderedTool->getName()] = $this->toolManager->getPermissions($orderedTool, $role);
}
return new JsonResponse($rights);
@@ -135,9 +96,10 @@ public function listRightsAction(Role $role, string $contextType, ?string $conte
* Manages workspace tools accesses for a Role.
*
* @Route("/{id}/rights/{contextType}/{contextId}", name="apiv2_role_rights_update", defaults={"contextId"=null}, methods={"PUT"})
+ *
* @EXT\ParamConverter("role", options={"mapping": {"id": "uuid"}})
*/
- public function updateRightsAction(Request $request, Role $role, string $contextType, ?string $contextId = null): JsonResponse
+ public function updateRightsAction(Request $request, Role $role, string $contextType, string $contextId = null): JsonResponse
{
$this->checkPermission('ADMINISTRATE', $role, [], true);
@@ -146,32 +108,11 @@ public function updateRightsAction(Request $request, Role $role, string $context
if ($rightsData) {
$this->om->startFlushSuite();
- switch ($contextType) {
- case Tool::DESKTOP:
- case Tool::WORKSPACE:
- foreach ($rightsData as $toolName => $toolRights) {
- $orderedTool = $this->toolManager->getOrderedTool($toolName, $contextType, $contextId);
- if ($orderedTool) {
- $this->toolManager->setPermissions($toolRights, $orderedTool, $role);
- }
- }
-
- break;
- case Tool::ADMINISTRATION:
- foreach ($rightsData as $toolName => $toolRights) {
- $adminTool = $this->toolManager->getAdminToolByName($toolName);
- if ($adminTool) {
- if ($toolRights['open']) {
- $adminTool->addRole($role);
- } else {
- $adminTool->removeRole($role);
- }
-
- $this->om->persist($adminTool);
- }
- }
-
- break;
+ foreach ($rightsData as $toolName => $toolRights) {
+ $orderedTool = $this->toolManager->getOrderedTool($toolName, $contextType, $contextId);
+ if ($orderedTool) {
+ $this->toolManager->setPermissions($toolRights, $orderedTool, $role);
+ }
}
$this->om->endFlushSuite();
@@ -180,62 +121,6 @@ public function updateRightsAction(Request $request, Role $role, string $context
return new JsonResponse();
}
- /**
- * @Route("/{id}/analytics/{year}", name="apiv2_role_analytics")
- * @EXT\ParamConverter("role", options={"mapping": {"id": "uuid"}})
- * @EXT\ParamConverter("currentUser", converter="current_user", options={"allowAnonymous"=false})
- */
- public function analyticsAction(User $currentUser, Role $role, string $year): JsonResponse
- {
- $this->checkPermission('OPEN', $role, [], true);
-
- // get values for user administrated organizations
- $organizations = null;
- $defaultFilters = [];
- if (!$currentUser->hasRole('ROLE_ADMIN')) {
- $organizations = $currentUser->getOrganizations();
- $defaultFilters = [
- 'organization' => $organizations,
- ];
- }
-
- $connections = $this->logManager->getData([
- 'hiddenFilters' => array_merge($defaultFilters, [
- 'doerActive' => true,
- 'doerCreated' => $year.'-12-31',
- 'doerRoles' => [$role->getId()],
- 'action' => 'user-login',
- 'unique' => true,
-
- // filter for current year
- 'dateLog' => $year.'-01-01',
- 'dateTo' => $year.'-12-31',
- ]),
- ]);
-
- $actions = $this->logManager->getData([
- 'hiddenFilters' => array_merge($defaultFilters, [
- 'doerActive' => true,
- 'doerCreated' => $year.'-12-31',
- 'doerRoles' => [$role->getId()],
-
- // filter for current year
- 'dateLog' => $year.'-01-01',
- 'dateTo' => $year.'-12-31',
- ]),
- ]);
-
- return new JsonResponse([
- 'users' => $this->om->getRepository(User::class)->countUsersByRole($role, $organizations, $year.'-12-31'),
- 'connections' => array_reduce($connections, function (int $total, array $connection) {
- return $total + ($connection['total'] ?? 0);
- }, 0),
- 'actions' => array_reduce($actions, function (int $total, array $action) {
- return $total + ($action['total'] ?? 0);
- }, 0),
- ]);
- }
-
protected function getDefaultHiddenFilters(): array
{
return [
diff --git a/src/main/community/Controller/UserController.php b/src/main/community/Controller/UserController.php
index 1969a71bfff..2d278bd0b38 100644
--- a/src/main/community/Controller/UserController.php
+++ b/src/main/community/Controller/UserController.php
@@ -16,6 +16,7 @@
use Claroline\AppBundle\API\Options;
use Claroline\AppBundle\Controller\AbstractCrudController;
use Claroline\AuthenticationBundle\Manager\MailManager;
+use Claroline\CoreBundle\Component\Context\DesktopContext;
use Claroline\CoreBundle\Controller\APINew\Model\HasGroupsTrait;
use Claroline\CoreBundle\Controller\APINew\Model\HasOrganizationsTrait;
use Claroline\CoreBundle\Controller\APINew\Model\HasRolesTrait;
@@ -229,7 +230,7 @@ public function disableAction(Request $request): JsonResponse
*/
public function disableInactiveAction(Request $request): JsonResponse
{
- $tool = $this->toolManager->getToolByName('community');
+ $tool = $this->toolManager->getOrderedTool('community', DesktopContext::getName());
$this->checkPermission('ADMINISTRATE', $tool, [], true);
$data = $this->decodeRequest($request);
diff --git a/src/main/community/DependencyInjection/ClarolineCommunityExtension.php b/src/main/community/DependencyInjection/ClarolineCommunityExtension.php
index a846d5c96a0..c6089275af6 100644
--- a/src/main/community/DependencyInjection/ClarolineCommunityExtension.php
+++ b/src/main/community/DependencyInjection/ClarolineCommunityExtension.php
@@ -18,13 +18,11 @@
class ClarolineCommunityExtension extends Extension
{
- /**
- * {@inheritdoc}
- */
- public function load(array $configs, ContainerBuilder $container)
+ public function load(array $configs, ContainerBuilder $container): void
{
$locator = new FileLocator(__DIR__.'/../Resources/config');
$loader = new YamlFileLoader($container, $locator);
$loader->load('services.yml');
+ $loader->load('components.yml');
}
}
diff --git a/src/main/community/Installation/ClarolineCommunityInstaller.php b/src/main/community/Installation/ClarolineCommunityInstaller.php
index 37009d278cc..32f6cc939fa 100644
--- a/src/main/community/Installation/ClarolineCommunityInstaller.php
+++ b/src/main/community/Installation/ClarolineCommunityInstaller.php
@@ -15,4 +15,8 @@
class ClarolineCommunityInstaller extends AdditionalInstaller
{
+ public function hasMigrations(): bool
+ {
+ return true;
+ }
}
diff --git a/src/main/community/Manager/TeamManager.php b/src/main/community/Manager/TeamManager.php
index 7c5fbc8b6d0..a5fbe6a4812 100644
--- a/src/main/community/Manager/TeamManager.php
+++ b/src/main/community/Manager/TeamManager.php
@@ -15,51 +15,32 @@
use Claroline\AppBundle\API\Options;
use Claroline\AppBundle\Persistence\ObjectManager;
use Claroline\CommunityBundle\Entity\Team;
+use Claroline\CommunityBundle\Repository\TeamRepository;
+use Claroline\CoreBundle\Component\Context\WorkspaceContext;
use Claroline\CoreBundle\Entity\Resource\Directory;
use Claroline\CoreBundle\Entity\Resource\ResourceNode;
use Claroline\CoreBundle\Entity\Role;
-use Claroline\CoreBundle\Entity\Tool\OrderedTool;
-use Claroline\CoreBundle\Entity\Tool\Tool;
use Claroline\CoreBundle\Entity\User;
use Claroline\CoreBundle\Entity\Workspace\Workspace;
use Claroline\CoreBundle\Manager\Resource\RightsManager;
use Claroline\CoreBundle\Manager\ResourceManager;
use Claroline\CoreBundle\Manager\RoleManager;
+use Claroline\CoreBundle\Manager\Tool\ToolManager;
use Claroline\CoreBundle\Manager\Tool\ToolRightsManager;
class TeamManager
{
- /** @var ObjectManager */
- private $om;
- /** @var Crud */
- private $crud;
- /** @var ResourceManager */
- private $resourceManager;
- /** @var RightsManager */
- private $rightsManager;
- /** @var RoleManager */
- private $roleManager;
- /** @var ToolRightsManager */
- private $toolRightsManager;
- private $resourceNodeRepo;
- private $teamRepo;
+ private TeamRepository $teamRepo;
public function __construct(
- ObjectManager $om,
- Crud $crud,
- ResourceManager $resourceManager,
- RightsManager $rightsManager,
- RoleManager $roleManager,
- ToolRightsManager $toolRightsManager
+ private readonly ObjectManager $om,
+ private readonly Crud $crud,
+ private readonly ResourceManager $resourceManager,
+ private readonly RightsManager $rightsManager,
+ private readonly RoleManager $roleManager,
+ private readonly ToolManager $toolManager,
+ private readonly ToolRightsManager $toolRightsManager
) {
- $this->om = $om;
- $this->crud = $crud;
- $this->resourceManager = $resourceManager;
- $this->rightsManager = $rightsManager;
- $this->roleManager = $roleManager;
- $this->toolRightsManager = $toolRightsManager;
-
- $this->resourceNodeRepo = $om->getRepository(ResourceNode::class);
$this->teamRepo = $om->getRepository(Team::class);
}
@@ -79,11 +60,8 @@ public function createTeamRole(Team $team, ?bool $isManager = false): Role
$root = $this->resourceManager->getWorkspaceRoot($workspace);
$this->rightsManager->update(['open' => true], $role, $root);
- $tool = $this->om->getRepository(Tool::class)->findOneBy(['name' => 'resources']);
- $orderedTool = $this->om
- ->getRepository(OrderedTool::class)
- ->findOneBy(['workspace' => $workspace, 'tool' => $tool]);
+ $orderedTool = $this->toolManager->getOrderedTool('resources', WorkspaceContext::getName(), $workspace->getUuid());
if (!empty($orderedTool)) {
$this->toolRightsManager->setToolRights($orderedTool, $role, 1);
}
diff --git a/src/main/community/Resources/config/components.yml b/src/main/community/Resources/config/components.yml
new file mode 100644
index 00000000000..cc128a70a3d
--- /dev/null
+++ b/src/main/community/Resources/config/components.yml
@@ -0,0 +1,2 @@
+imports:
+ - { resource: components/tool.yml }
diff --git a/src/main/community/Resources/config/components/tool.yml b/src/main/community/Resources/config/components/tool.yml
new file mode 100644
index 00000000000..c6dd3a46dec
--- /dev/null
+++ b/src/main/community/Resources/config/components/tool.yml
@@ -0,0 +1,19 @@
+services:
+ Claroline\CommunityBundle\Component\Tool\CommunityTool:
+ parent: Claroline\AppBundle\Component\Tool\AbstractTool
+ tags: [ 'claroline.component.tool' ]
+ arguments:
+ - '@security.token_storage'
+ - '@Claroline\AppBundle\Persistence\ObjectManager'
+ - '@Claroline\AppBundle\API\SerializerProvider'
+ - '@Claroline\AppBundle\API\Crud'
+ - '@Claroline\CoreBundle\Library\Configuration\PlatformConfigurationHandler'
+ - '@Claroline\CoreBundle\API\Serializer\ParametersSerializer'
+ - '@Claroline\CommunityBundle\Serializer\ProfileSerializer'
+ - '@Claroline\CoreBundle\Manager\UserManager'
+ - '@Claroline\CoreBundle\Manager\RoleManager'
+ - '@Claroline\CommunityBundle\Manager\TeamManager'
+
+ Claroline\CommunityBundle\Component\Tool\ProfileTool:
+ parent: Claroline\AppBundle\Component\Tool\AbstractTool
+ tags: [ 'claroline.component.tool' ]
diff --git a/src/main/community/Resources/config/services/controller.yml b/src/main/community/Resources/config/services/controller.yml
index de1a988f500..d3289d5915c 100644
--- a/src/main/community/Resources/config/services/controller.yml
+++ b/src/main/community/Resources/config/services/controller.yml
@@ -54,7 +54,6 @@ services:
arguments:
- '@security.authorization_checker'
- '@Claroline\CoreBundle\Manager\Tool\ToolManager'
- - '@Claroline\CoreBundle\Manager\LogManager'
Claroline\CommunityBundle\Controller\TeamController:
parent: Claroline\AppBundle\Controller\AbstractCrudController
diff --git a/src/main/community/Resources/config/services/manager.yml b/src/main/community/Resources/config/services/manager.yml
index 6755b87241b..2d50e717381 100644
--- a/src/main/community/Resources/config/services/manager.yml
+++ b/src/main/community/Resources/config/services/manager.yml
@@ -13,4 +13,5 @@ services:
- '@Claroline\CoreBundle\Manager\ResourceManager'
- '@Claroline\CoreBundle\Manager\Resource\RightsManager'
- '@Claroline\CoreBundle\Manager\RoleManager'
+ - '@Claroline\CoreBundle\Manager\Tool\ToolManager'
- '@Claroline\CoreBundle\Manager\Tool\ToolRightsManager'
diff --git a/src/main/community/Resources/modules/account/profile/index.js b/src/main/community/Resources/modules/account/profile/index.js
index ac5f23c7fb7..0c101270ab1 100644
--- a/src/main/community/Resources/modules/account/profile/index.js
+++ b/src/main/community/Resources/modules/account/profile/index.js
@@ -1,11 +1,10 @@
-import {trans} from '#/main/app/intl/translation'
-
import {ProfileMain} from '#/main/community/account/profile/containers/main'
export default {
+ component: ProfileMain/*,
+
name: 'profile',
icon: 'fa fa-fw fa-user-circle',
label: trans('user_profile'),
- component: ProfileMain,
- order: 1
+ order: 1*/
}
diff --git a/src/main/community/Resources/modules/role/components/metrics.jsx b/src/main/community/Resources/modules/role/components/metrics.jsx
deleted file mode 100644
index 13af0437007..00000000000
--- a/src/main/community/Resources/modules/role/components/metrics.jsx
+++ /dev/null
@@ -1,115 +0,0 @@
-import React, {Component} from 'react'
-import {PropTypes as T} from 'prop-types'
-import moment from 'moment'
-import {schemeCategory20c} from '#/main/theme/color/utils'
-
-import {trans} from '#/main/app/intl/translation'
-import {Toolbar} from '#/main/app/action/components/toolbar'
-import {ContentCounter} from '#/main/app/content/components/counter'
-import {CALLBACK_BUTTON} from '#/main/app/buttons'
-
-class RoleMetrics extends Component {
- constructor(props) {
- super(props)
-
- this.state = {
- loaded: false,
- current: moment().year(),
- available: [
- moment().year(),
- moment().year() - 1,
- moment().year() - 2
- ],
- count: {
- users: 20,
- connections: 50,
- actions: 90
- }
- }
- }
-
- componentDidMount() {
- this.props.load(this.state.current).then((response) => this.setState({
- count: response,
- loaded: true
- }))
- }
-
- changeYear(year) {
- this.setState({
- loaded: false,
- current: year
- })
-
- // reload
- this.props.load(year).then((response) => this.setState({
- count: response,
- loaded: true
- }))
- }
-
- render() {
- let ellapsedDays = 365
- if (this.state.current === moment().year()) {
- // current period
- ellapsedDays = moment().diff(moment([this.state.current, '01, 01']), 'days') + 1
- }
-
- return (
-
- 'y'+year).join(' ')}
- size="sm"
- actions={this.state.available.map(year => (
- {
- primary: year === this.state.current,
- name: 'y'+year,
- type: CALLBACK_BUTTON,
- label: year,
- callback: () => this.changeYear(year)
- }
- ))}
- />
-
-
-
-
-
-
-
- )
- }
-}
-
-RoleMetrics.propTypes = {
- load: T.func.isRequired
-}
-
-export {
- RoleMetrics
-}
diff --git a/src/main/community/Resources/modules/tools/community/role/components/show.jsx b/src/main/community/Resources/modules/tools/community/role/components/show.jsx
index 618d676cf28..88a6a3dfac5 100644
--- a/src/main/community/Resources/modules/tools/community/role/components/show.jsx
+++ b/src/main/community/Resources/modules/tools/community/role/components/show.jsx
@@ -16,7 +16,6 @@ import {GroupList} from '#/main/community/group/components/list'
import {constants} from '#/main/community/constants'
import {Role as RoleTypes} from '#/main/community/role/prop-types'
import {RolePage} from '#/main/community/role/components/page'
-import {RoleMetrics} from '#/main/community/role/components/metrics'
import {selectors} from '#/main/community/tools/community/role/store/selectors'
import {RoleShortcuts} from '#/main/community/tools/community/role/containers/shortcuts'
import {RoleRights} from '#/main/community/tools/community/role/components/rights'
@@ -28,12 +27,6 @@ const RoleShow = (props) =>
reload={(role) => props.reload(role, props.contextData)}
>
- {get(props.role, 'id') &&
-
props.loadMetrics(props.role.id, year)}
- />
- }
-
(dispatch) => dispatch({
}
})
-actions.fetchMetrics = (id, year) => ({
- [API_REQUEST]: {
- url: ['apiv2_role_analytics', {id: id, year: year}],
- silent: true
- }
-})
-
actions.fetchWorkspaceRights = (id, contextId = null) => (dispatch) => dispatch({
[API_REQUEST]: {
url: ['apiv2_role_rights_list', {id: id, contextType: 'workspace', contextId: contextId}],
diff --git a/src/main/community/Security/Voter/UserVoter.php b/src/main/community/Security/Voter/UserVoter.php
index a0752c05747..b4fde620d5a 100644
--- a/src/main/community/Security/Voter/UserVoter.php
+++ b/src/main/community/Security/Voter/UserVoter.php
@@ -13,21 +13,16 @@
use Claroline\AppBundle\Security\ObjectCollection;
use Claroline\CoreBundle\Entity\Role;
-use Claroline\CoreBundle\Entity\Tool\OrderedTool;
use Claroline\CoreBundle\Entity\User;
use Claroline\CoreBundle\Library\Configuration\PlatformConfigurationHandler;
-use Claroline\CoreBundle\Repository\Tool\OrderedToolRepository;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
class UserVoter extends AbstractRoleSubjectVoter
{
- /** @var PlatformConfigurationHandler */
- private $config;
-
- public function __construct(PlatformConfigurationHandler $config)
- {
- $this->config = $config;
+ public function __construct(
+ private readonly PlatformConfigurationHandler $config
+ ) {
}
/**
@@ -68,17 +63,7 @@ private function checkOpen(TokenInterface $token, User $user): int
return VoterInterface::ACCESS_GRANTED;
}
- if ($this->isToolGranted('EDIT', 'community')) {
- return VoterInterface::ACCESS_GRANTED;
- }
-
- // allow open for all of those who have the open right on community tool
- // TODO : this should also check user is in the same organization
- /** @var OrderedToolRepository $orderedToolRepo */
- $orderedToolRepo = $this->getObjectManager()->getRepository(OrderedTool::class);
- /** @var OrderedTool $communityTools */
- $communityTool = $orderedToolRepo->findOneByNameAndDesktop('community');
- if ($communityTool && $this->isGranted('OPEN', $communityTool)) {
+ if ($this->isToolGranted('OPEN', 'community')) {
return VoterInterface::ACCESS_GRANTED;
}
@@ -159,19 +144,6 @@ private function checkCreate(TokenInterface $token, User $user)
return VoterInterface::ACCESS_GRANTED;
}
- // allow creation for all of those who have the create right on a community tool
- /** @var OrderedToolRepository $orderedToolRepo */
- $orderedToolRepo = $this->getObjectManager()->getRepository(OrderedTool::class);
- /** @var OrderedTool[] $communityTools */
- $communityTools = $orderedToolRepo->findByName('community');
- foreach ($communityTools as $communityTool) {
- // we do not take into account tool in personal ws, otherwise anyone will be granted
- // (users are managers of their personal ws)
- if ((empty($communityTool->getWorkspace()) || !$communityTool->getWorkspace()->isPersonal()) && $this->isGranted('CREATE_USER', $communityTool)) {
- return VoterInterface::ACCESS_GRANTED;
- }
- }
-
// allow creation for self registration
if ($this->config->getParameter('registration.self')) {
$defaultRole = $this->config->getParameter('registration.default_role');
diff --git a/src/main/community/Tests/Repository/RoleRepositoryTest.php b/src/main/community/Tests/Repository/RoleRepositoryTest.php
index 914fe7016ce..9b567fa918c 100644
--- a/src/main/community/Tests/Repository/RoleRepositoryTest.php
+++ b/src/main/community/Tests/Repository/RoleRepositoryTest.php
@@ -25,14 +25,13 @@ public static function setUpBeforeClass(): void
self::createWorkspace('ws_1');
self::createWorkspace('ws_2');
- self::createTool('tool_1');
self::createRole('ROLE_WS_VISITOR_'.self::get('ws_1')->getUuid(), self::get('ws_1'));
self::createRole('ROLE_WS_COLLABORATOR_'.self::get('ws_1')->getUuid(), self::get('ws_1'));
self::createRole('ROLE_WS_MANAGER_'.self::get('ws_1')->getUuid(), self::get('ws_1'));
self::createRole('ROLE_WS_CUSTOM_1', self::get('ws_1'));
self::createRole('ROLE_WS_CUSTOM_2', self::get('ws_1'));
self::createRole('ROLE_PLATFORM_CUSTOM');
- self::createWorkspaceTool(self::get('tool_1'), self::get('ws_1'), [self::get('ROLE_WS_CUSTOM_1')], 1);
+ self::createWorkspaceTool('tool_1', self::get('ws_1'), [self::get('ROLE_WS_CUSTOM_1')], 1);
self::createUser('john', [self::get('ROLE_WS_CUSTOM_1'), self::get('ROLE_PLATFORM_CUSTOM')]);
self::createGroup('group_1', [], [self::get('ROLE_WS_CUSTOM_2')]);
}
diff --git a/src/main/core/API/Finder/Tool/AdminToolFinder.php b/src/main/core/API/Finder/Tool/AdminToolFinder.php
deleted file mode 100644
index a0b47ad8f65..00000000000
--- a/src/main/core/API/Finder/Tool/AdminToolFinder.php
+++ /dev/null
@@ -1,63 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Claroline\CoreBundle\API\Finder\Tool;
-
-use Claroline\AppBundle\API\Finder\AbstractFinder;
-use Claroline\CoreBundle\Entity\Tool\AdminTool;
-use Claroline\CoreBundle\Manager\PluginManager;
-use Doctrine\ORM\QueryBuilder;
-
-class AdminToolFinder extends AbstractFinder
-{
- /** @var PluginManager */
- private $pluginManager;
-
- /**
- * AdminToolFinder constructor.
- */
- public function __construct(PluginManager $pluginManager)
- {
- $this->pluginManager = $pluginManager;
- }
-
- public static function getClass(): string
- {
- return AdminTool::class;
- }
-
- public function configureQueryBuilder(QueryBuilder $qb, array $searches = [], array $sortBy = null): QueryBuilder
- {
- $bundles = $this->pluginManager->getEnabled();
-
- // only grab tools from enabled plugins
- $qb->leftJoin('obj.plugin', 'p');
- $qb->andWhere($qb->expr()->orX(
- $qb->expr()->in('CONCAT(p.vendorName, p.bundleName)', ':bundles'),
- $qb->expr()->isNull('p')
- ));
- $qb->setParameter('bundles', $bundles);
-
- foreach ($searches as $filterName => $filterValue) {
- switch ($filterName) {
- case 'roles':
- $qb->join('obj.roles', 'r');
- $qb->andWhere("r.name IN (:{$filterName})");
- $qb->setParameter($filterName, is_array($filterValue) ? $filterValue : [$filterValue]);
- break;
- default:
- $this->setDefaults($qb, $filterName, $filterValue);
- }
- }
-
- return $qb;
- }
-}
diff --git a/src/main/core/API/Finder/Tool/OrderedToolFinder.php b/src/main/core/API/Finder/Tool/OrderedToolFinder.php
index ad85e4c94f4..bf47f11387d 100644
--- a/src/main/core/API/Finder/Tool/OrderedToolFinder.php
+++ b/src/main/core/API/Finder/Tool/OrderedToolFinder.php
@@ -26,17 +26,20 @@ public function configureQueryBuilder(QueryBuilder $qb, array $searches = [], ar
{
foreach ($searches as $filterName => $filterValue) {
switch ($filterName) {
+ case 'context':
+ $qb->andWhere('obj.contextName = :contextName');
+ $qb->setParameter('contextName', $filterValue);
+ break;
+ case 'contextId':
case 'workspace':
- $qb->leftJoin('obj.workspace', 'ws');
- $qb->andWhere($qb->expr()->orX(
- $qb->expr()->eq('ws.uuid', ':workspace')
- ));
- $qb->setParameter('workspace', $filterValue);
+ $qb->andWhere('obj.contextId = :contextId');
+ $qb->setParameter('contextId', $filterValue);
break;
case 'tool':
$qb->leftJoin('obj.tool', 'tool');
$qb->andWhere('tool.name = :tool');
$qb->setParameter('tool', $filterValue);
+ break;
}
}
diff --git a/src/main/core/API/Finder/Tool/ToolFinder.php b/src/main/core/API/Finder/Tool/ToolFinder.php
deleted file mode 100644
index 65ce4e432c8..00000000000
--- a/src/main/core/API/Finder/Tool/ToolFinder.php
+++ /dev/null
@@ -1,88 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Claroline\CoreBundle\API\Finder\Tool;
-
-use Claroline\AppBundle\API\Finder\AbstractFinder;
-use Claroline\CoreBundle\Entity\Tool\Tool;
-use Claroline\CoreBundle\Manager\PluginManager;
-use Claroline\CoreBundle\Manager\Tool\ToolManager;
-use Doctrine\ORM\Query\Expr\Join;
-use Doctrine\ORM\QueryBuilder;
-
-class ToolFinder extends AbstractFinder
-{
- /** @var PluginManager */
- private $pluginManager;
-
- public function __construct(PluginManager $pluginManager)
- {
- $this->pluginManager = $pluginManager;
- }
-
- public static function getClass(): string
- {
- return Tool::class;
- }
-
- public function configureQueryBuilder(QueryBuilder $qb, array $searches = [], array $sortBy = null): QueryBuilder
- {
- $bundles = $this->pluginManager->getEnabled();
-
- $qb->leftJoin('obj.plugin', 'p');
- $qb->andWhere($qb->expr()->orX(
- $qb->expr()->in('CONCAT(p.vendorName, p.bundleName)', ':bundles'),
- $qb->expr()->isNull('p')
- ));
- $qb->setParameter('bundles', $bundles);
-
- $otJoin = false;
-
- foreach ($searches as $filterName => $filterValue) {
- switch ($filterName) {
- case 'user':
- if (!$otJoin) {
- $qb->join('Claroline\\CoreBundle\\Entity\\Tool\\OrderedTool', 'ot', Join::WITH, 'ot.tool = obj');
- $otJoin = true;
- }
-
- $qb->andWhere('ot.user IS NULL AND ot.workspace IS NULL');
- break;
- case 'workspace':
- if (!$otJoin) {
- $qb->join('Claroline\\CoreBundle\\Entity\\Tool\\OrderedTool', 'ot', Join::WITH, 'ot.tool = obj');
- $otJoin = true;
- }
- $qb->join('ot.workspace', 'w');
- $qb->andWhere("w.uuid = :{$filterName}");
- $qb->andWhere('(w.model = false OR obj.name IN (:availableTools))');
- $qb->setParameter($filterName, $filterValue);
- $qb->setParameter('availableTools', ToolManager::WORKSPACE_MODEL_TOOLS);
- break;
- case 'roles':
- if (!$otJoin) {
- $qb->join('Claroline\\CoreBundle\\Entity\\Tool\\OrderedTool', 'ot', Join::WITH, 'ot.tool = obj');
- $otJoin = true;
- }
- $qb->join('ot.rights', 'r');
- $qb->join('r.role', 'rr');
- $qb->andWhere('BIT_AND(r.mask, 1) = 1');
- $qb->andWhere("rr.name IN (:{$filterName})");
- $qb->setParameter($filterName, is_array($filterValue) ? $filterValue : [$filterValue]);
- break;
- default:
- $this->setDefaults($qb, $filterName, $filterValue);
- }
- }
-
- return $qb;
- }
-}
diff --git a/src/main/core/API/Serializer/Log/Connection/LogConnectAdminToolSerializer.php b/src/main/core/API/Serializer/Log/Connection/LogConnectAdminToolSerializer.php
deleted file mode 100644
index 22d0ca9fedb..00000000000
--- a/src/main/core/API/Serializer/Log/Connection/LogConnectAdminToolSerializer.php
+++ /dev/null
@@ -1,48 +0,0 @@
-serializer = $serializer; // bad
- }
-
- public function getClass()
- {
- return LogConnectAdminTool::class;
- }
-
- public function getName()
- {
- return 'log_connect_admin_tool';
- }
-
- /**
- * @return array
- */
- public function serialize(LogConnectAdminTool $log, array $options = [])
- {
- $serialized = [
- 'id' => $log->getUuid(),
- 'date' => $log->getConnectionDate()->format('Y-m-d\TH:i:s'),
- 'duration' => $log->getDuration(),
- 'user' => $this->serializer->serialize($log->getUser(), [Options::SERIALIZE_MINIMAL]),
- 'tool' => $this->serializer->serialize($log->getTool(), [Options::SERIALIZE_MINIMAL]),
- 'toolName' => $log->getToolName(),
- ];
-
- return $serialized;
- }
-}
diff --git a/src/main/core/API/Serializer/Log/Connection/LogConnectPlatformSerializer.php b/src/main/core/API/Serializer/Log/Connection/LogConnectPlatformSerializer.php
deleted file mode 100644
index 63b7ef661f6..00000000000
--- a/src/main/core/API/Serializer/Log/Connection/LogConnectPlatformSerializer.php
+++ /dev/null
@@ -1,46 +0,0 @@
-serializer = $serializer; // bad
- }
-
- public function getClass()
- {
- return LogConnectPlatform::class;
- }
-
- public function getName()
- {
- return 'log_connect_platform';
- }
-
- /**
- * @return array
- */
- public function serialize(LogConnectPlatform $log, array $options = [])
- {
- $serialized = [
- 'id' => $log->getUuid(),
- 'date' => $log->getConnectionDate()->format('Y-m-d\TH:i:s'),
- 'duration' => $log->getDuration(),
- 'user' => $this->serializer->serialize($log->getUser(), [Options::SERIALIZE_MINIMAL]),
- ];
-
- return $serialized;
- }
-}
diff --git a/src/main/core/API/Serializer/Log/Connection/LogConnectResourceSerializer.php b/src/main/core/API/Serializer/Log/Connection/LogConnectResourceSerializer.php
deleted file mode 100644
index d0a88853e00..00000000000
--- a/src/main/core/API/Serializer/Log/Connection/LogConnectResourceSerializer.php
+++ /dev/null
@@ -1,49 +0,0 @@
-serializer = $serializer; // bad
- }
-
- public function getClass()
- {
- return LogConnectResource::class;
- }
-
- public function getName()
- {
- return 'log_connect_resource';
- }
-
- /**
- * @return array
- */
- public function serialize(LogConnectResource $log, array $options = [])
- {
- $serialized = [
- 'id' => $log->getUuid(),
- 'date' => $log->getConnectionDate()->format('Y-m-d\TH:i:s'),
- 'duration' => $log->getDuration(),
- 'user' => $this->serializer->serialize($log->getUser(), [Options::SERIALIZE_MINIMAL]),
- 'resource' => $this->serializer->serialize($log->getResource(), [Options::SERIALIZE_MINIMAL]),
- 'resourceName' => $log->getResourceName(),
- 'resourceType' => $log->getResourceType(),
- ];
-
- return $serialized;
- }
-}
diff --git a/src/main/core/API/Serializer/Log/Connection/LogConnectToolSerializer.php b/src/main/core/API/Serializer/Log/Connection/LogConnectToolSerializer.php
deleted file mode 100644
index 30e1bdeb5b3..00000000000
--- a/src/main/core/API/Serializer/Log/Connection/LogConnectToolSerializer.php
+++ /dev/null
@@ -1,53 +0,0 @@
-serializer = $serializer;
- }
-
- public function getClass()
- {
- return LogConnectTool::class;
- }
-
- public function getName()
- {
- return 'log_connect_tool';
- }
-
- /**
- * @return array
- */
- public function serialize(LogConnectTool $log, array $options = [])
- {
- $serialized = [
- 'id' => $log->getUuid(),
- 'date' => $log->getConnectionDate()->format('Y-m-d\TH:i:s'),
- 'duration' => $log->getDuration(),
- 'user' => $this->serializer->serialize($log->getUser(), [Options::SERIALIZE_MINIMAL]),
- 'tool' => $this->serializer->serialize($log->getTool(), [Options::SERIALIZE_MINIMAL]),
- 'toolName' => $log->getToolName(),
- 'originalToolName' => $log->getOrignalToolName(),
- 'workspace' => $log->getWorkspace() ?
- $this->serializer->serialize($log->getWorkspace(), [Options::SERIALIZE_MINIMAL]) :
- null,
- 'workspaceName' => $log->getWorkspaceName(),
- ];
-
- return $serialized;
- }
-}
diff --git a/src/main/core/API/Serializer/Log/Connection/LogConnectWorkspaceSerializer.php b/src/main/core/API/Serializer/Log/Connection/LogConnectWorkspaceSerializer.php
deleted file mode 100644
index 4b8c9307ded..00000000000
--- a/src/main/core/API/Serializer/Log/Connection/LogConnectWorkspaceSerializer.php
+++ /dev/null
@@ -1,48 +0,0 @@
-serializer = $serializer;
- }
-
- public function getClass()
- {
- return LogConnectWorkspace::class;
- }
-
- public function getName()
- {
- return 'log_connect_workspace';
- }
-
- /**
- * @return array
- */
- public function serialize(LogConnectWorkspace $log, array $options = [])
- {
- $serialized = [
- 'id' => $log->getUuid(),
- 'date' => $log->getConnectionDate()->format('Y-m-d\TH:i:s'),
- 'duration' => $log->getDuration(),
- 'user' => $this->serializer->serialize($log->getUser(), [Options::SERIALIZE_MINIMAL]),
- 'workspace' => $this->serializer->serialize($log->getWorkspace(), [Options::SERIALIZE_MINIMAL]),
- 'workspaceName' => $log->getWorkspaceName(),
- ];
-
- return $serialized;
- }
-}
diff --git a/src/main/core/API/Serializer/Tool/AdminToolSerializer.php b/src/main/core/API/Serializer/Tool/AdminToolSerializer.php
deleted file mode 100644
index 645a4503c63..00000000000
--- a/src/main/core/API/Serializer/Tool/AdminToolSerializer.php
+++ /dev/null
@@ -1,27 +0,0 @@
- $tool->getUuid(),
- 'icon' => $tool->getClass(),
- 'name' => $tool->getName(),
- ];
-
- return $serialized;
- }
-}
diff --git a/src/main/core/API/Serializer/Tool/OrderedToolSerializer.php b/src/main/core/API/Serializer/Tool/OrderedToolSerializer.php
index a251d81c1be..3a6f1e038bc 100644
--- a/src/main/core/API/Serializer/Tool/OrderedToolSerializer.php
+++ b/src/main/core/API/Serializer/Tool/OrderedToolSerializer.php
@@ -32,8 +32,8 @@ public function serialize(OrderedTool $orderedTool, ?array $options = []): array
{
$serialized = [
'id' => $orderedTool->getUuid(),
- 'name' => $orderedTool->getTool()->getName(),
- 'icon' => $orderedTool->getTool()->getClass(),
+ 'name' => $orderedTool->getName(),
+ // 'icon' => $orderedTool->getTool()->getClass(),
'poster' => $orderedTool->getPoster(),
'thumbnail' => $orderedTool->getThumbnail(),
'display' => [
@@ -61,12 +61,13 @@ public function deserialize(array $data, OrderedTool $orderedTool, ?array $optio
$orderedTool->refreshUuid();
}
+ $this->sipe('name', 'setName', $data, $orderedTool);
+ $this->sipe('poster', 'setPoster', $data, $orderedTool);
+ $this->sipe('thumbnail', 'setThumbnail', $data, $orderedTool);
$this->sipe('display.order', 'setOrder', $data, $orderedTool);
$this->sipe('display.showIcon', 'setShowIcon', $data, $orderedTool);
$this->sipe('display.fullscreen', 'setFullscreen', $data, $orderedTool);
$this->sipe('restrictions.hidden', 'setHidden', $data, $orderedTool);
- $this->sipe('poster', 'setPoster', $data, $orderedTool);
- $this->sipe('thumbnail', 'setThumbnail', $data, $orderedTool);
return $orderedTool;
}
diff --git a/src/main/core/API/Serializer/Tool/ToolRightsSerializer.php b/src/main/core/API/Serializer/Tool/ToolRightsSerializer.php
index 227347a7a57..d923deb5f73 100644
--- a/src/main/core/API/Serializer/Tool/ToolRightsSerializer.php
+++ b/src/main/core/API/Serializer/Tool/ToolRightsSerializer.php
@@ -12,29 +12,19 @@
class ToolRightsSerializer
{
- /** @var ObjectManager */
- private $om;
- /** @var RoleSerializer */
- private $roleSerializer;
- /** @var ToolMaskDecoderManager */
- private $maskManager;
-
public function __construct(
- ObjectManager $om,
- RoleSerializer $roleSerializer,
- ToolMaskDecoderManager $maskManager
+ private readonly ObjectManager $om,
+ private readonly RoleSerializer $roleSerializer,
+ private readonly ToolMaskDecoderManager $maskManager
) {
- $this->om = $om;
- $this->roleSerializer = $roleSerializer;
- $this->maskManager = $maskManager;
}
- public function getClass()
+ public function getClass(): string
{
return ToolRights::class;
}
- public function getName()
+ public function getName(): string
{
return 'tool_rights';
}
@@ -46,9 +36,9 @@ public function serialize(ToolRights $toolRights): array
$serialized = [
'id' => $toolRights->getId(),
- 'orderedToolId' => $orderedTool->getUuid(),
+ 'orderedToolId' => $orderedTool->getUuid(), // TODO : to remove
'role' => $this->roleSerializer->serialize($role, [SerializerInterface::SERIALIZE_MINIMAL]),
- 'permissions' => $this->maskManager->decodeMask($toolRights->getMask(), $orderedTool->getTool()),
+ 'permissions' => $this->maskManager->decodeMask($toolRights->getMask(), $orderedTool->getName()),
// TODO : do not flatten role data (UI expects this structure).
'translationKey' => $role->getTranslationKey(),
@@ -80,16 +70,16 @@ public function deserialize(array $data, ToolRights $toolRights): ToolRights
$toolRights->setRole($role);
}
- if (!empty($data['orderedToolId'])) {
+ if (!empty($data['orderedTool'])) {
/** @var OrderedTool $orderedTool */
- $orderedTool = $this->om->getRepository(OrderedTool::class)->findOneBy(['uuid' => $data['orderedToolId']]);
+ $orderedTool = $this->om->getObject($data['orderedTool'], OrderedTool::class);
if ($orderedTool) {
$toolRights->setOrderedTool($orderedTool);
}
}
if ($toolRights->getOrderedTool()) {
- $toolRights->setMask($this->maskManager->encodeMask($data['permissions'], $toolRights->getOrderedTool()->getTool()));
+ $toolRights->setMask($this->maskManager->encodeMask($data['permissions'], $toolRights->getOrderedTool()->getName()));
}
return $toolRights;
diff --git a/src/main/core/API/Serializer/Tool/ToolSerializer.php b/src/main/core/API/Serializer/Tool/ToolSerializer.php
deleted file mode 100644
index 0997a9feb7e..00000000000
--- a/src/main/core/API/Serializer/Tool/ToolSerializer.php
+++ /dev/null
@@ -1,27 +0,0 @@
- $tool->getUuid(),
- 'name' => $tool->getName(),
- 'icon' => $tool->getClass(),
- ];
- }
-
- public function getName()
- {
- return 'tool';
- }
-}
diff --git a/src/main/core/Component/Context/AccountContext.php b/src/main/core/Component/Context/AccountContext.php
index 4626814ea1f..e3bd326a8f4 100644
--- a/src/main/core/Component/Context/AccountContext.php
+++ b/src/main/core/Component/Context/AccountContext.php
@@ -3,6 +3,7 @@
namespace Claroline\CoreBundle\Component\Context;
use Claroline\AppBundle\Component\Context\AbstractContext;
+use Claroline\AppBundle\Component\Context\ContextSubjectInterface;
use Claroline\AppBundle\Manager\SecurityManager;
use Claroline\CoreBundle\Entity\Role;
use Claroline\CoreBundle\Entity\User;
@@ -15,7 +16,7 @@ public function __construct(
) {
}
- public static function getShortName(): string
+ public static function getName(): string
{
return 'account';
}
@@ -25,32 +26,27 @@ public function getObject(?string $contextId): ?User
return $this->securityManager->getCurrentUser();
}
- public function isAvailable(?string $contextId, TokenInterface $token): bool
+ public function isAvailable(?string $contextId): bool
{
return !empty($this->securityManager->getCurrentUser());
}
- public function getAccessErrors(?string $contextId, TokenInterface $token): array
+ public function getAccessErrors(TokenInterface $token, ?ContextSubjectInterface $contextSubject): array
{
return [];
}
- public function isManager(?string $contextId, TokenInterface $token): bool
+ public function isManager(TokenInterface $token, ?ContextSubjectInterface $contextSubject): bool
{
return $this->securityManager->isAdmin();
}
- public function isImpersonated(?string $contextId, TokenInterface $token): bool
+ public function isImpersonated(TokenInterface $token, ?ContextSubjectInterface $contextSubject): bool
{
return $this->securityManager->isImpersonated();
}
- public function getAdditionalData(?string $contextId): array
- {
- return [];
- }
-
- public function getRoles(?string $contextId, TokenInterface $token): array
+ public function getRoles(TokenInterface $token, ?ContextSubjectInterface $contextSubject): array
{
$currentUser = $this->securityManager->getCurrentUser();
if (empty($currentUser)) {
@@ -61,10 +57,4 @@ public function getRoles(?string $contextId, TokenInterface $token): array
return Role::PLATFORM_ROLE === $role->getType();
});
}
-
- public function getShortcuts(?string $contextId): array
- {
- // only supported by Workspace context atm
- return [];
- }
}
diff --git a/src/main/core/Component/Context/AdministrationContext.php b/src/main/core/Component/Context/AdministrationContext.php
index cdd54c0c9c1..c1b6ccea35c 100644
--- a/src/main/core/Component/Context/AdministrationContext.php
+++ b/src/main/core/Component/Context/AdministrationContext.php
@@ -3,6 +3,7 @@
namespace Claroline\CoreBundle\Component\Context;
use Claroline\AppBundle\Component\Context\AbstractContext;
+use Claroline\AppBundle\Component\Context\ContextSubjectInterface;
use Claroline\AppBundle\Manager\SecurityManager;
use Claroline\CoreBundle\Entity\Role;
use Claroline\CoreBundle\Library\Configuration\PlatformConfigurationHandler;
@@ -21,38 +22,38 @@ public function __construct(
) {
}
- public static function getShortName(): string
+ public static function getName(): string
{
return 'administration';
}
- public function getObject(?string $contextId): mixed
+ public function getObject(?string $contextId): ?ContextSubjectInterface
{
return null;
}
- public function isAvailable(?string $contextId, TokenInterface $token): bool
+ public function isAvailable(?string $contextId): bool
{
- return !empty($this->securityManager->getCurrentUser())
- && !empty($this->toolManager->getAdminToolsByRoles($token->getRoleNames()));
+ return !empty($this->securityManager->getCurrentUser());
+ // && !empty($this->toolManager->getAdminToolsByRoles($token->getRoleNames()));
}
- public function getAccessErrors(?string $contextId, TokenInterface $token): array
+ public function getAccessErrors(TokenInterface $token, ?ContextSubjectInterface $contextSubject): array
{
return [];
}
- public function isImpersonated(?string $contextId, TokenInterface $token): bool
+ public function isImpersonated(TokenInterface $token, ?ContextSubjectInterface $contextSubject): bool
{
return $this->securityManager->isImpersonated();
}
- public function isManager(?string $contextId, TokenInterface $token): bool
+ public function isManager(TokenInterface $token, ?ContextSubjectInterface $contextSubject): bool
{
return $this->securityManager->isAdmin();
}
- public function getAdditionalData(?string $contextId): array
+ public function getAdditionalData(?ContextSubjectInterface $contextSubject): array
{
// for retro-compatibility, should not be exposed here
$defaultTool = $this->config->getParameter('admin.default_tool');
@@ -68,7 +69,7 @@ public function getAdditionalData(?string $contextId): array
];
}
- public function getRoles(?string $contextId, TokenInterface $token): array
+ public function getRoles(TokenInterface $token, ?ContextSubjectInterface $contextSubject): array
{
$currentUser = $this->securityManager->getCurrentUser();
if (empty($currentUser)) {
@@ -79,10 +80,4 @@ public function getRoles(?string $contextId, TokenInterface $token): array
return Role::PLATFORM_ROLE === $role->getType();
});
}
-
- public function getShortcuts(?string $contextId): array
- {
- // only supported by Workspace context atm
- return [];
- }
}
diff --git a/src/main/core/Component/Context/DesktopContext.php b/src/main/core/Component/Context/DesktopContext.php
index 707086e6642..9dd988a81dd 100644
--- a/src/main/core/Component/Context/DesktopContext.php
+++ b/src/main/core/Component/Context/DesktopContext.php
@@ -3,6 +3,7 @@
namespace Claroline\CoreBundle\Component\Context;
use Claroline\AppBundle\Component\Context\AbstractContext;
+use Claroline\AppBundle\Component\Context\ContextSubjectInterface;
use Claroline\AppBundle\Manager\SecurityManager;
use Claroline\CoreBundle\Entity\Role;
use Claroline\CoreBundle\Library\Configuration\PlatformConfigurationHandler;
@@ -16,39 +17,51 @@ public function __construct(
) {
}
- public static function getShortName(): string
+ public static function getName(): string
{
return 'desktop';
}
- public function getObject(?string $contextId): mixed
+ public function getObject(?string $contextId): ?ContextSubjectInterface
{
return null;
}
- public function isAvailable(?string $contextId, TokenInterface $token): bool
+ public function isAvailable(?string $contextId): bool
{
+ return !empty($this->securityManager->getCurrentUser());
// do user have access to at least one tool ?
- return !empty($this->toolManager->getOrderedToolsByDesktop($token->getRoleNames()));
+ // return !empty($this->toolManager->getOrderedToolsByDesktop($token->getRoleNames()));
}
- public function getAccessErrors(?string $contextId, TokenInterface $token): array
+ public function getAccessErrors(TokenInterface $token, ?ContextSubjectInterface $contextSubject): array
{
- return [
- ];
+ return [];
}
- public function isImpersonated(?string $contextId, TokenInterface $token): bool
+ public function isImpersonated(TokenInterface $token, ?ContextSubjectInterface $contextSubject): bool
{
return $this->securityManager->isImpersonated();
}
- public function isManager(?string $contextId, TokenInterface $token): bool
+ public function isManager(TokenInterface $token, ?ContextSubjectInterface $contextSubject): bool
{
return $this->securityManager->isAdmin();
}
- public function getAdditionalData(?string $contextId): array
+ public function getRoles(TokenInterface $token, ?ContextSubjectInterface $contextSubject): array
+ {
+ $currentUser = $this->securityManager->getCurrentUser();
+ if (empty($currentUser)) {
+ return [];
+ }
+
+ return array_filter($currentUser->getEntityRoles(), function (Role $role) {
+ return Role::PLATFORM_ROLE === $role->getType();
+ });
+ }
+
+ public function getAdditionalData(?ContextSubjectInterface $contextSubject): array
{
// for retro-compatibility, should not be exposed here
$defaultTool = $this->config->getParameter('desktop.default_tool');
@@ -63,23 +76,4 @@ public function getAdditionalData(?string $contextId): array
],
];
}
-
- public function getRoles(?string $contextId, TokenInterface $token): array
- {
- $currentUser = $this->securityManager->getCurrentUser();
- if (empty($currentUser)) {
- return [];
- }
-
- return array_filter($currentUser->getEntityRoles(), function (Role $role) {
- return Role::PLATFORM_ROLE === $role->getType();
- });
- }
-
- public function getShortcuts(?string $contextId): array
- {
- // only supported by Workspace context atm
- // return $this->config->getParameter('desktop.shortcuts') ?? [];
- return [];
- }
}
diff --git a/src/main/core/Component/Context/PublicContext.php b/src/main/core/Component/Context/PublicContext.php
index 172428f9a35..30997981a28 100644
--- a/src/main/core/Component/Context/PublicContext.php
+++ b/src/main/core/Component/Context/PublicContext.php
@@ -3,6 +3,7 @@
namespace Claroline\CoreBundle\Component\Context;
use Claroline\AppBundle\Component\Context\AbstractContext;
+use Claroline\AppBundle\Component\Context\ContextSubjectInterface;
use Claroline\AppBundle\Manager\SecurityManager;
use Claroline\CoreBundle\Entity\Role;
use Claroline\CoreBundle\Library\Configuration\PlatformConfigurationHandler;
@@ -16,37 +17,49 @@ public function __construct(
) {
}
- public static function getShortName(): string
+ public static function getName(): string
{
return 'public';
}
- public function getObject(?string $contextId): mixed
+ public function getObject(?string $contextId): ?ContextSubjectInterface
{
return null;
}
- public function isAvailable(?string $contextId, TokenInterface $token): bool
+ public function isAvailable(?string $contextId): bool
{
return 'tool' === $this->config->getParameter('home.type');
}
- public function getAccessErrors(?string $contextId, TokenInterface $token): array
+ public function getAccessErrors(TokenInterface $token, ?ContextSubjectInterface $contextSubject): array
{
return [];
}
- public function isImpersonated(?string $contextId, TokenInterface $token): bool
+ public function isImpersonated(TokenInterface $token, ?ContextSubjectInterface $contextSubject): bool
{
return $this->securityManager->isImpersonated();
}
- public function isManager(?string $contextId, TokenInterface $token): bool
+ public function isManager(TokenInterface $token, ?ContextSubjectInterface $contextSubject): bool
{
return $this->securityManager->isAdmin();
}
- public function getAdditionalData(?string $contextId): array
+ public function getRoles(TokenInterface $token, ?ContextSubjectInterface $contextSubject): array
+ {
+ $currentUser = $this->securityManager->getCurrentUser();
+ if (empty($currentUser)) {
+ return [];
+ }
+
+ return array_filter($currentUser->getEntityRoles(), function (Role $role) {
+ return Role::PLATFORM_ROLE === $role->getType();
+ });
+ }
+
+ public function getAdditionalData(?ContextSubjectInterface $contextSubject): array
{
// for retro-compatibility, should not be exposed here
$type = $this->config->getParameter('home.type');
@@ -61,22 +74,4 @@ public function getAdditionalData(?string $contextId): array
],
];
}
-
- public function getRoles(?string $contextId, TokenInterface $token): array
- {
- $currentUser = $this->securityManager->getCurrentUser();
- if (empty($currentUser)) {
- return [];
- }
-
- return array_filter($currentUser->getEntityRoles(), function (Role $role) {
- return Role::PLATFORM_ROLE === $role->getType();
- });
- }
-
- public function getShortcuts(?string $contextId): array
- {
- // only supported by Workspace context atm
- return [];
- }
}
diff --git a/src/main/core/Component/Context/WorkspaceContext.php b/src/main/core/Component/Context/WorkspaceContext.php
index f0aa25f8c53..2790a1ca50c 100644
--- a/src/main/core/Component/Context/WorkspaceContext.php
+++ b/src/main/core/Component/Context/WorkspaceContext.php
@@ -5,6 +5,7 @@
use Claroline\AppBundle\API\Serializer\SerializerInterface;
use Claroline\AppBundle\API\SerializerProvider;
use Claroline\AppBundle\Component\Context\AbstractContext;
+use Claroline\AppBundle\Component\Context\ContextSubjectInterface;
use Claroline\AppBundle\Persistence\ObjectManager;
use Claroline\CoreBundle\Entity\Resource\ResourceNode;
use Claroline\CoreBundle\Entity\User;
@@ -27,88 +28,83 @@ public function __construct(
) {
}
- public static function getShortName(): string
+ public static function getName(): string
{
return 'workspace';
}
- public function getObject(?string $contextId): ?Workspace
+ public function getObject(?string $contextId): Workspace
{
+ if (empty($contextId)) {
+ throw new \RuntimeException('WorkspaceContext can not be opened without an ID.');
+ }
+
// we receive the slug on context open,
// and we receive the uuid when tools are opened
return $this->om->getObject(['id' => $contextId, 'slug' => $contextId], Workspace::class, ['slug']);
}
- public function getAdditionalData(?string $contextId): array
- {
- $workspace = $this->getObject($contextId);
- $user = $this->tokenStorage->getToken()->getUser();
-
- $userEvaluation = null;
- if ($user instanceof User) {
- $userEvaluation = $this->serializer->serialize(
- $this->evaluationManager->getUserEvaluation($workspace, $user),
- [SerializerInterface::SERIALIZE_MINIMAL]
- );
- }
-
- $rootNode = $this->om->getRepository(ResourceNode::class)->findOneBy(['workspace' => $workspace, 'parent' => null]);
-
- return [
- 'userEvaluation' => $userEvaluation,
- // do not expose root resource here (used in the WS to configure opening target)
- 'root' => $this->serializer->serialize($rootNode, [SerializerInterface::SERIALIZE_MINIMAL]),
- ];
- }
-
- public function isAvailable(?string $contextId, TokenInterface $token): bool
+ public function isAvailable(?string $contextId): bool
{
- return true;
+ return !empty($contextId);
}
- public function isManager(?string $contextId, TokenInterface $token): bool
+ public function isManager(TokenInterface $token, ?ContextSubjectInterface $contextSubject): bool
{
- $workspace = $this->getObject($contextId);
+ /** @var Workspace $workspace */
+ $workspace = $contextSubject;
return $this->manager->isManager($workspace, $token);
}
- public function getAccessErrors(?string $contextId, TokenInterface $token): array
+ public function getAccessErrors(TokenInterface $token, ?ContextSubjectInterface $contextSubject): array
{
- $workspace = $this->getObject($contextId);
+ /** @var Workspace $workspace */
+ $workspace = $contextSubject;
return $this->restrictionsManager->getErrors($workspace, $token->getUser() instanceof User ? $token->getUser() : null);
}
- public function isImpersonated(?string $contextId, TokenInterface $token): bool
+ public function isImpersonated(TokenInterface $token, ?ContextSubjectInterface $contextSubject): bool
{
return $this->manager->isImpersonated($token);
}
- public function getRoles(?string $contextId, TokenInterface $token): array
+ public function getRoles(TokenInterface $token, ?ContextSubjectInterface $contextSubject): array
{
- if (empty($contextId)) {
- return [];
- }
-
- $workspace = $this->getObject($contextId);
+ /** @var Workspace $workspace */
+ $workspace = $contextSubject;
return $this->manager->getTokenRoles($token, $workspace);
}
- public function getTools(?string $contextId): array
+ public function getAdditionalData(?ContextSubjectInterface $contextSubject): array
{
- // TODO : filter based on workspace model flag.
- return parent::getTools($contextId);
- }
+ /** @var Workspace $workspace */
+ $workspace = $contextSubject;
+ $user = $this->tokenStorage->getToken()->getUser();
- public function getShortcuts(?string $contextId): array
- {
- if (empty($contextId)) {
- return [];
+ $userEvaluation = null;
+ if ($user instanceof User) {
+ $userEvaluation = $this->serializer->serialize(
+ $this->evaluationManager->getUserEvaluation($workspace, $user),
+ [SerializerInterface::SERIALIZE_MINIMAL]
+ );
}
- $workspace = $this->getObject($contextId);
+ $rootNode = $this->om->getRepository(ResourceNode::class)->findOneBy(['workspace' => $workspace, 'parent' => null]);
+
+ return [
+ 'userEvaluation' => $userEvaluation,
+ // do not expose root resource here (used in the WS to configure opening target)
+ 'root' => $this->serializer->serialize($rootNode, [SerializerInterface::SERIALIZE_MINIMAL]),
+ ];
+ }
+
+ public function getShortcuts(?ContextSubjectInterface $contextSubject): array
+ {
+ /** @var Workspace $workspace */
+ $workspace = $contextSubject;
// TODO : only export current user shortcuts (we get all roles for the configuration in community/editor)
// $this->manager->getShortcuts($workspace, $this->tokenStorage->getToken()->getRoleNames()),
diff --git a/src/main/core/Component/Tool/ConnectionMessagesTool.php b/src/main/core/Component/Tool/ConnectionMessagesTool.php
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/src/main/core/Component/Tool/IntegrationTool.php b/src/main/core/Component/Tool/IntegrationTool.php
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/src/main/core/Component/Tool/LocationsTool.php b/src/main/core/Component/Tool/LocationsTool.php
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/src/main/core/Component/Tool/ParametersTool.php b/src/main/core/Component/Tool/ParametersTool.php
index 1ceed87aa4a..1a296fc1868 100644
--- a/src/main/core/Component/Tool/ParametersTool.php
+++ b/src/main/core/Component/Tool/ParametersTool.php
@@ -2,18 +2,56 @@
namespace Claroline\CoreBundle\Component\Tool;
+use Claroline\AppBundle\Component\Context\ContextSubjectInterface;
use Claroline\AppBundle\Component\Tool\AbstractTool;
+use Claroline\CoreBundle\API\Serializer\ParametersSerializer;
+use Claroline\CoreBundle\Component\Context\AccountContext;
use Claroline\CoreBundle\Component\Context\AdministrationContext;
+use Claroline\CoreBundle\Manager\LocaleManager;
class ParametersTool extends AbstractTool
{
- public static function getShortName(): string
+ public function __construct(
+ private readonly ParametersSerializer $serializer,
+ private readonly LocaleManager $localeManager
+ ) {
+ }
+
+ public static function getName(): string
{
return 'parameters';
}
+ public function isRequired(string $context, ?string $contextId): bool
+ {
+ return true;
+ }
+
public function supportsContext(string $context): bool
{
- return AdministrationContext::class === $context;
+ return in_array($context, [
+ AccountContext::getName(),
+ AdministrationContext::getName(),
+ ]);
+ }
+
+ public function open(string $context, ContextSubjectInterface $contextSubject = null): ?array
+ {
+ if (AdministrationContext::getName() === $context) {
+ $parameters = $this->serializer->serialize();
+
+ return [
+ 'lockedParameters' => $parameters['lockedParameters'] ?? [],
+ 'parameters' => $parameters,
+ 'availableLocales' => $this->localeManager->getAvailableLocales(),
+ ];
+ }
+
+ return [];
+ }
+
+ public function configure(string $context, ContextSubjectInterface $contextSubject = null, array $configData = []): ?array
+ {
+ return [];
}
}
diff --git a/src/main/core/Component/Tool/ResourcesTool.php b/src/main/core/Component/Tool/ResourcesTool.php
index bc8d15a5730..ae747a300ae 100644
--- a/src/main/core/Component/Tool/ResourcesTool.php
+++ b/src/main/core/Component/Tool/ResourcesTool.php
@@ -2,13 +2,39 @@
namespace Claroline\CoreBundle\Component\Tool;
+use Claroline\AppBundle\API\Crud;
+use Claroline\AppBundle\API\Options;
+use Claroline\AppBundle\API\Serializer\SerializerInterface;
+use Claroline\AppBundle\API\SerializerProvider;
+use Claroline\AppBundle\API\Utils\FileBag;
+use Claroline\AppBundle\Component\Context\ContextSubjectInterface;
use Claroline\AppBundle\Component\Tool\AbstractTool;
+use Claroline\AppBundle\Persistence\ObjectManager;
use Claroline\CoreBundle\Component\Context\DesktopContext;
use Claroline\CoreBundle\Component\Context\WorkspaceContext;
+use Claroline\CoreBundle\Entity\Resource\AbstractResource;
+use Claroline\CoreBundle\Entity\Resource\ResourceNode;
+use Claroline\CoreBundle\Entity\Resource\ResourceRights;
+use Claroline\CoreBundle\Entity\Workspace\Workspace;
+use Claroline\CoreBundle\Event\Resource\ExportResourceEvent;
+use Claroline\CoreBundle\Event\Resource\ImportResourceEvent;
+use Claroline\CoreBundle\Repository\Resource\ResourceNodeRepository;
+use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
class ResourcesTool extends AbstractTool
{
- public static function getShortName(): string
+ private ResourceNodeRepository $resourceRepository;
+
+ public function __construct(
+ private readonly ObjectManager $om,
+ private readonly EventDispatcherInterface $dispatcher,
+ private readonly SerializerProvider $serializer,
+ private readonly Crud $crud
+ ) {
+ $this->resourceRepository = $om->getRepository(ResourceNode::class);
+ }
+
+ public static function getName(): string
{
return 'resources';
}
@@ -16,8 +42,191 @@ public static function getShortName(): string
public function supportsContext(string $context): bool
{
return in_array($context, [
- DesktopContext::class,
- WorkspaceContext::class,
+ DesktopContext::getName(),
+ WorkspaceContext::getName(),
]);
}
+
+ public function open(string $context, ContextSubjectInterface $contextSubject = null): ?array
+ {
+ $root = null;
+ if (WorkspaceContext::getName() === $context) {
+ // filters resources for the current workspace
+ $root = $this->serializer->serialize(
+ $this->resourceRepository->findWorkspaceRoot($contextSubject)
+ );
+ }
+
+ return [
+ 'root' => $root,
+ ];
+ }
+
+ public function configure(string $context, ContextSubjectInterface $contextSubject = null, array $configData = []): ?array
+ {
+ return [];
+ }
+
+ public function export(string $context, ContextSubjectInterface $contextSubject = null, FileBag $fileBag = null): ?array
+ {
+ if (WorkspaceContext::getName() !== $context) {
+ return [];
+ }
+
+ $root = $this->resourceRepository->findWorkspaceRoot($contextSubject);
+ if (empty($root)) {
+ return [];
+ }
+
+ return [
+ 'resources' => $this->recursiveExport($root, $fileBag),
+ ];
+ }
+
+ public function import(string $context, ContextSubjectInterface $contextSubject = null, FileBag $fileBag = null, array $data = [], array $entities = []): ?array
+ {
+ if (WorkspaceContext::getName() !== $context) {
+ return [];
+ }
+
+ if (empty($data['resources'])) {
+ return [];
+ }
+
+ $resources = $data['resources'];
+
+ // we need to push the resource types with linked resources last, because we need all resources to be created
+ // to link them to the new resources.
+ // this should not be done here and as is it doesn't work in all cases (e.g. if we link paths to others paths).
+ $typesWithResourceLinks = ['innova_path', 'shortcut'];
+ uksort($resources, function (int $a, int $b) use ($resources, $typesWithResourceLinks) {
+ if (in_array($resources[$a]['resourceNode']['meta']['type'], $typesWithResourceLinks)) {
+ return 1;
+ } elseif (in_array($resources[$b]['resourceNode']['meta']['type'], $typesWithResourceLinks)) {
+ return -1;
+ }
+
+ // we want to keep the original order (required for the parent directories to be created first)
+ // that's why we use uksort and not usort (from the usort doc : If two members compare as equal, they retain their original order. Prior to PHP 8.0.0, their relative order in the sorted array was undefined.)
+ return $a - $b;
+ });
+
+ /** @var Workspace $workspace */
+ $workspace = $contextSubject;
+
+ // manage workspace opening
+ // this is for retro-compatibility, we have stored the autoincrement id of the resource in the workspace options
+ // when using the UUID, replacement is automatically done in the serialized data
+ $workspaceOptions = $workspace->getOptions()->getDetails();
+ $openingResourceId = null;
+ if ($workspaceOptions && 'resource' === $workspaceOptions['opening_target'] && !empty($workspaceOptions['workspace_opening_resource'])) {
+ // this only works because the WorkspaceSerializer::deserialize does not check if the resource exists
+ $openingResourceId = $workspaceOptions['workspace_opening_resource'];
+ }
+
+ foreach ($resources as $resourceData) {
+ // create resource node
+ $nodeData = $resourceData['resourceNode'];
+ unset($nodeData['workspace']);
+ unset($nodeData['slug']);
+
+ $resourceNode = new ResourceNode();
+ $resourceNode->setWorkspace($workspace);
+
+ // workspace name root directory based on the new workspace name
+ if (empty($nodeData['parent'])) {
+ $nodeData['name'] = $workspace->getName();
+ $nodeData['code'] = $workspace->getCode();
+ }
+
+ if (!empty($nodeData['parent']) && $entities[$nodeData['parent']['id']]) {
+ $resourceNode->setParent($entities[$nodeData['parent']['id']]);
+ unset($nodeData['parent']);
+ }
+
+ $this->crud->create($resourceNode, $nodeData, [Crud::NO_PERMISSIONS, Crud::NO_VALIDATION, Options::NO_RIGHTS/* , Options::REFRESH_UUID */]);
+
+ $entities[$nodeData['id']] = $resourceNode;
+ // $event->addCreatedEntity($nodeData['id'], $resourceNode);
+
+ // create rights
+ if (!empty($resourceData['rights'])) {
+ foreach ($resourceData['rights'] as $rightsData) {
+ $role = $entities[$rightsData['role']['id']];
+ if (empty($role)) {
+ continue;
+ }
+
+ $rights = new ResourceRights();
+ $rights->setResourceNode($resourceNode);
+ $this->serializer->deserialize(array_merge($rightsData, [
+ 'role' => [
+ 'id' => $role->getUuid(),
+ ],
+ ]), $rights);
+
+ $this->om->persist($rights);
+ }
+ }
+
+ // create custom resource Entity
+ $resourceClass = $resourceNode->getResourceType()->getClass();
+
+ // should be removed. It's only used by quizzes
+ $resSerializer = $this->serializer->get($resourceClass);
+ $resSerializeOptions = method_exists($resSerializer, 'getCopyOptions') ? $resSerializer->getCopyOptions() : [];
+
+ /** @var AbstractResource $resource */
+ $resource = $this->crud->create($resourceClass, $resourceData['resource'], array_merge([Crud::NO_PERMISSIONS, Crud::NO_VALIDATION, Options::REFRESH_UUID], $resSerializeOptions));
+ $resource->setResourceNode($resourceNode);
+
+ $importEvent = new ImportResourceEvent($resource, $fileBag, $resourceData);
+ $this->dispatcher->dispatch($importEvent, 'resource.'.$resourceNode->getType().'.import');
+
+ // replace workspace opening resource id by the new one
+ // this is for retro-compatibility, when we have stored the autoincrement id of the resource in the workspace options
+ // when using the UUID, replacement is automatically done in the serialized data
+ if (!empty($openingResourceId) && $resourceData['autoId'] === $openingResourceId) {
+ $workspace->getOptions()->setDetails(array_merge($workspaceOptions, [
+ 'workspace_opening_resource' => $resourceNode->getUuid(),
+ ]));
+ }
+
+ // we need the resources to be persisted in DB to be exploitable in listeners (e.g. path do a DB call to retrieve linked resources)
+ $this->om->forceFlush();
+ }
+
+ return [];
+ }
+
+ private function recursiveExport(ResourceNode $resourceNode, FileBag $fileBag): array
+ {
+ $exported = [];
+
+ $resource = $this->om->getRepository($resourceNode->getClass())->findOneBy(['resourceNode' => $resourceNode]);
+ if ($resource) {
+ // should be removed. It's only used by quizzes
+ $resSerializer = $this->serializer->get($resourceNode->getClass());
+ $resSerializeOptions = method_exists($resSerializer, 'getCopyOptions') ? $resSerializer->getCopyOptions() : [];
+
+ $exportEvent = new ExportResourceEvent($resource, $fileBag);
+ $this->dispatcher->dispatch($exportEvent, 'resource.'.$resourceNode->getType().'.export');
+
+ $exported[] = array_merge([
+ 'resourceNode' => $this->serializer->serialize($resourceNode, [SerializerInterface::SERIALIZE_TRANSFER, Options::NO_RIGHTS]),
+ 'resource' => $this->serializer->serialize($resource, array_merge([SerializerInterface::SERIALIZE_TRANSFER], $resSerializeOptions)),
+ 'rights' => array_map(function (ResourceRights $rights) {
+ return $this->serializer->serialize($rights, [SerializerInterface::SERIALIZE_TRANSFER]);
+ }, $resourceNode->getRights()->toArray()),
+ ], $exportEvent->getData());
+
+ foreach ($resourceNode->getChildren() as $child) {
+ if ($child->isActive()) {
+ $exported = array_merge($exported, $this->recursiveExport($child, $fileBag));
+ }
+ }
+ }
+
+ return $exported;
+ }
}
diff --git a/src/main/core/Component/Tool/ResourcesTrashTool.php b/src/main/core/Component/Tool/ResourcesTrashTool.php
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/src/main/core/Component/Tool/TemplateTool.php b/src/main/core/Component/Tool/TemplateTool.php
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/src/main/core/Component/Tool/WorkspacesTool.php b/src/main/core/Component/Tool/WorkspacesTool.php
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/src/main/core/Controller/APINew/Location/MaterialController.php b/src/main/core/Controller/APINew/Location/MaterialController.php
index 6b196acbdbc..d37f9cd6be4 100644
--- a/src/main/core/Controller/APINew/Location/MaterialController.php
+++ b/src/main/core/Controller/APINew/Location/MaterialController.php
@@ -13,10 +13,10 @@
use Claroline\AppBundle\API\Crud;
use Claroline\AppBundle\Controller\AbstractCrudController;
+use Claroline\CoreBundle\Component\Context\DesktopContext;
use Claroline\CoreBundle\Entity\Location\Material;
use Claroline\CoreBundle\Entity\Location\MaterialBooking;
-use Claroline\CoreBundle\Entity\Tool\OrderedTool;
-use Claroline\CoreBundle\Repository\Tool\OrderedToolRepository;
+use Claroline\CoreBundle\Manager\Tool\ToolManager;
use Claroline\CoreBundle\Security\PermissionCheckerTrait;
use Sensio\Bundle\FrameworkExtraBundle\Configuration as EXT;
use Symfony\Component\HttpFoundation\JsonResponse;
@@ -31,11 +31,10 @@ class MaterialController extends AbstractCrudController
{
use PermissionCheckerTrait;
- /** @var AuthorizationCheckerInterface */
- private $authorization;
-
- public function __construct(AuthorizationCheckerInterface $authorization)
- {
+ public function __construct(
+ AuthorizationCheckerInterface $authorization,
+ private readonly ToolManager $toolManager
+ ) {
$this->authorization = $authorization;
}
@@ -51,6 +50,7 @@ public function getClass(): string
/**
* @Route("/{material}/booking", name="apiv2_booking_material_book", methods={"POST"})
+ *
* @EXT\ParamConverter("material", class="Claroline\CoreBundle\Entity\Location\Material", options={"mapping": {"material": "uuid"}})
*/
public function bookAction(Material $material, Request $request): JsonResponse
@@ -72,6 +72,7 @@ public function bookAction(Material $material, Request $request): JsonResponse
/**
* @Route("/{material}/booking", name="apiv2_booking_material_list_booking", methods={"GET"})
+ *
* @EXT\ParamConverter("material", class="Claroline\CoreBundle\Entity\Location\Material", options={"mapping": {"material": "uuid"}})
*/
public function listBookingAction(Material $material, Request $request): JsonResponse
@@ -90,6 +91,7 @@ public function listBookingAction(Material $material, Request $request): JsonRes
/**
* @Route("/{$material}/booking", name="apiv2_booking_material_remove_booking", methods={"DELETE"})
+ *
* @EXT\ParamConverter("$material", class="Claroline\CoreBundle\Entity\Location\Material", options={"mapping": {"$material": "uuid"}})
*/
public function deleteBookingAction(Material $material, Request $request): JsonResponse
@@ -103,12 +105,9 @@ public function deleteBookingAction(Material $material, Request $request): JsonR
return new JsonResponse(null, 204);
}
- private function canBook()
+ private function canBook(): void
{
- /** @var OrderedToolRepository $orderedToolRepo */
- $orderedToolRepo = $this->om->getRepository(OrderedTool::class);
-
- $bookingTool = $orderedToolRepo->findOneByNameAndDesktop('locations');
+ $bookingTool = $this->toolManager->getOrderedTool('locations', DesktopContext::getName());
$this->checkPermission('BOOK', $bookingTool, [], true);
}
diff --git a/src/main/core/Controller/APINew/Log/LogConnectController.php b/src/main/core/Controller/APINew/Log/LogConnectController.php
deleted file mode 100644
index 9a9f854b0cf..00000000000
--- a/src/main/core/Controller/APINew/Log/LogConnectController.php
+++ /dev/null
@@ -1,176 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Claroline\CoreBundle\Controller\APINew\Log;
-
-use Claroline\AppBundle\API\FinderProvider;
-use Claroline\CoreBundle\Entity\Log\Connection\LogConnectPlatform;
-use Claroline\CoreBundle\Entity\Log\Connection\LogConnectResource;
-use Claroline\CoreBundle\Entity\Log\Connection\LogConnectWorkspace;
-use Claroline\CoreBundle\Entity\Organization\Organization;
-use Claroline\CoreBundle\Entity\Resource\ResourceNode;
-use Claroline\CoreBundle\Entity\User;
-use Claroline\CoreBundle\Entity\Workspace\Workspace;
-use Claroline\CoreBundle\Manager\LogConnectManager;
-use Claroline\CoreBundle\Manager\Tool\ToolManager;
-use Claroline\CoreBundle\Security\ToolPermissions;
-use Sensio\Bundle\FrameworkExtraBundle\Configuration as EXT;
-use Symfony\Component\HttpFoundation\JsonResponse;
-use Symfony\Component\HttpFoundation\Request;
-use Symfony\Component\Routing\Annotation\Route;
-use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
-use Symfony\Component\Security\Core\Exception\AccessDeniedException;
-
-/**
- * @Route("/log_connect")
- */
-class LogConnectController
-{
- /** @var AuthorizationCheckerInterface */
- private $authorization;
-
- /** @var FinderProvider */
- private $finder;
-
- /** @var LogConnectManager */
- private $logConnectManager;
-
- /** @var ToolManager */
- private $toolManager;
-
- /**
- * CourseController constructor.
- */
- public function __construct(
- AuthorizationCheckerInterface $authorization,
- FinderProvider $finder,
- LogConnectManager $logConnectManager,
- ToolManager $toolManager
- ) {
- $this->authorization = $authorization;
- $this->finder = $finder;
- $this->logConnectManager = $logConnectManager;
- $this->toolManager = $toolManager;
- }
-
- public function getName()
- {
- return 'log_connect_platform';
- }
-
- /**
- * @Route(
- * "/platform/list",
- * name="apiv2_log_connect_platform_list"
- * )
- *
- * @EXT\ParamConverter("user", converter="current_user", options={"allowAnonymous"=false})
- */
- public function logConnectPlatformListAction(User $user, Request $request): JsonResponse
- {
- $this->checkAdminToolAccess();
- $isAdmin = $this->authorization->isGranted('ROLE_ADMIN');
- $hiddenFilters = $isAdmin ?
- [] :
- ['hiddenFilters' => [
- 'organizations' => array_map(function (Organization $organization) {
- return $organization->getUuid();
- }, $user->getAdministratedOrganizations()->toArray()),
- ]];
-
- return new JsonResponse(
- $this->finder->search(LogConnectPlatform::class, array_merge(
- $request->query->all(),
- $hiddenFilters
- ))
- );
- }
-
- /**
- * @Route(
- * "/workspace/{workspace}/list",
- * name="apiv2_log_connect_workspace_list"
- * )
- *
- * @EXT\ParamConverter(
- * "workspace",
- * class="Claroline\CoreBundle\Entity\Workspace\Workspace",
- * options={"mapping": {"workspace": "uuid"}}
- * )
- *
- * @return JsonResponse
- */
- public function logConnectWorkspaceListAction(Workspace $workspace, Request $request)
- {
- $this->checkWorkspaceToolAccess($workspace);
-
- return new JsonResponse(
- $this->finder->search(LogConnectWorkspace::class, array_merge(
- $request->query->all(),
- [
- 'hiddenFilters' => [
- 'workspace' => $workspace->getUuid(),
- ],
- ]
- ))
- );
- }
-
- /**
- * @Route(
- * "/resource/{resource}/list",
- * name="apiv2_log_connect_resource_list"
- * )
- *
- * @EXT\ParamConverter(
- * "resource",
- * class="Claroline\CoreBundle\Entity\Resource\ResourceNode",
- * options={"mapping": {"resource": "uuid"}}
- * )
- * @EXT\ParamConverter("user", converter="current_user", options={"allowAnonymous"=false})
- *
- * @return JsonResponse
- */
- public function logConnectResourceListAction(ResourceNode $resource, User $user, Request $request)
- {
- $hiddenFilters = ['resource' => $resource->getUuid()];
-
- if (!$this->authorization->isGranted('ADMINISTRATE', $resource->getWorkspace())) {
- $hiddenFilters['user'] = $user->getUuid();
- }
-
- return new JsonResponse(
- $this->finder->search(LogConnectResource::class, array_merge(
- $request->query->all(),
- ['hiddenFilters' => $hiddenFilters]
- ))
- );
- }
-
- /**
- * @param string $rights
- */
- private function checkAdminToolAccess($rights = 'OPEN')
- {
- $logsTool = $this->toolManager->getAdminToolByName('dashboard');
-
- if (is_null($logsTool) || !$this->authorization->isGranted($rights, $logsTool)) {
- throw new AccessDeniedException();
- }
- }
-
- private function checkWorkspaceToolAccess(Workspace $workspace, ?string $permission = 'OPEN'): void
- {
- if (!$this->authorization->isGranted(ToolPermissions::getPermission('dashboard', $permission), $workspace)) {
- throw new AccessDeniedException();
- }
- }
-}
diff --git a/src/main/core/Controller/APINew/Workspace/WorkspaceController.php b/src/main/core/Controller/APINew/Workspace/WorkspaceController.php
index 2d823b03e43..cfabdd469c9 100644
--- a/src/main/core/Controller/APINew/Workspace/WorkspaceController.php
+++ b/src/main/core/Controller/APINew/Workspace/WorkspaceController.php
@@ -14,7 +14,6 @@
use Claroline\AppBundle\Annotations\ApiDoc;
use Claroline\AppBundle\API\Options;
use Claroline\AppBundle\Controller\AbstractCrudController;
-use Claroline\AppBundle\Event\StrictDispatcher;
use Claroline\AppBundle\Manager\File\TempFileManager;
use Claroline\AuthenticationBundle\Messenger\Stamp\AuthenticationStamp;
use Claroline\CoreBundle\Controller\APINew\Model\HasGroupsTrait;
@@ -24,9 +23,9 @@
use Claroline\CoreBundle\Entity\User;
use Claroline\CoreBundle\Entity\Workspace\Workspace;
use Claroline\CoreBundle\Library\Normalizer\TextNormalizer;
-use Claroline\CoreBundle\Manager\LogConnectManager;
use Claroline\CoreBundle\Manager\RoleManager;
use Claroline\CoreBundle\Manager\Workspace\WorkspaceManager;
+use Claroline\CoreBundle\Manager\Workspace\WorkspaceRestrictionsManager;
use Claroline\CoreBundle\Messenger\Message\CopyWorkspace;
use Claroline\CoreBundle\Messenger\Message\ImportWorkspace;
use Claroline\CoreBundle\Security\PermissionCheckerTrait;
@@ -49,32 +48,16 @@ class WorkspaceController extends AbstractCrudController
use HasRolesTrait;
use PermissionCheckerTrait;
- private TokenStorageInterface $tokenStorage;
- private StrictDispatcher $dispatcher;
- private MessageBusInterface $messageBus;
- private RoleManager $roleManager;
- private WorkspaceManager $workspaceManager;
- private LogConnectManager $logConnectManager;
- private TempFileManager $tempManager;
-
public function __construct(
- TokenStorageInterface $tokenStorage,
+ private readonly TokenStorageInterface $tokenStorage,
AuthorizationCheckerInterface $authorization,
- StrictDispatcher $dispatcher,
- MessageBusInterface $messageBus,
- RoleManager $roleManager,
- WorkspaceManager $workspaceManager,
- LogConnectManager $logConnectManager,
- TempFileManager $tempManager
+ private readonly MessageBusInterface $messageBus,
+ private readonly TempFileManager $tempManager,
+ private readonly RoleManager $roleManager,
+ private readonly WorkspaceManager $workspaceManager,
+ private readonly WorkspaceRestrictionsManager $restrictionsManager
) {
- $this->tokenStorage = $tokenStorage;
$this->authorization = $authorization;
- $this->dispatcher = $dispatcher;
- $this->messageBus = $messageBus;
- $this->roleManager = $roleManager;
- $this->workspaceManager = $workspaceManager;
- $this->logConnectManager = $logConnectManager;
- $this->tempManager = $tempManager;
}
public function getName(): string
@@ -365,6 +348,20 @@ public function unarchiveBulkAction(Request $request): JsonResponse
}, $processed));
}
+ /**
+ * Submit access code.
+ *
+ * @Route("/unlock/{id}", name="claro_workspace_unlock", methods={"POST"})
+ *
+ * @EXT\ParamConverter("workspace", options={"mapping": {"id": "uuid"}})
+ */
+ public function unlockAction(Workspace $workspace, Request $request): JsonResponse
+ {
+ $this->restrictionsManager->unlock($workspace, json_decode($request->getContent(), true)['code']);
+
+ return new JsonResponse(null, 204);
+ }
+
/**
* @Route("/{id}/users", name="apiv2_workspace_list_users", methods={"GET"})
*
diff --git a/src/main/core/Controller/AdministrationController.php b/src/main/core/Controller/AdministrationController.php
deleted file mode 100644
index 3eac9a01fad..00000000000
--- a/src/main/core/Controller/AdministrationController.php
+++ /dev/null
@@ -1,155 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Claroline\CoreBundle\Controller;
-
-use Claroline\AppBundle\Event\StrictDispatcher;
-use Claroline\CoreBundle\Entity\Tool\AbstractTool;
-use Claroline\CoreBundle\Entity\Tool\AdminTool;
-use Claroline\CoreBundle\Entity\User;
-use Claroline\CoreBundle\Event\CatalogEvents\ToolEvents;
-use Claroline\CoreBundle\Event\Tool\OpenToolEvent;
-use Claroline\CoreBundle\Manager\Tool\ToolManager;
-use Symfony\Component\HttpFoundation\JsonResponse;
-use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
-use Symfony\Component\Routing\Annotation\Route;
-use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
-use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
-use Symfony\Component\Security\Core\Exception\AccessDeniedException;
-
-/**
- * @Route("/admin", options={"expose"=true})
- */
-class AdministrationController
-{
- /** @var AuthorizationCheckerInterface */
- private $authorization;
-
- /** @var TokenStorageInterface */
- private $tokenStorage;
-
- /** @var ToolManager */
- private $toolManager;
-
- /** @var StrictDispatcher */
- private $strictDispatcher;
-
- public function __construct(
- AuthorizationCheckerInterface $authorization,
- TokenStorageInterface $tokenStorage,
- ToolManager $toolManager,
- StrictDispatcher $strictDispatcher
- ) {
- $this->authorization = $authorization;
- $this->toolManager = $toolManager;
- $this->tokenStorage = $tokenStorage;
- $this->strictDispatcher = $strictDispatcher;
- }
-
- /**
- * Opens the administration index.
- *
- * @Route("/", name="claro_admin_index")
- * @Route("/", name="claro_admin_open")
- *
- * @return JsonResponse
- *
- * @throws AccessDeniedException
- */
- public function openAction()
- {
- $tools = $this->toolManager->getAdminToolsByRoles($this->tokenStorage->getToken()->getRoleNames());
- if (0 === count($tools)) {
- throw new AccessDeniedException();
- }
-
- return new JsonResponse([
- 'tools' => array_values(array_map(function (AdminTool $tool) {
- return [
- 'icon' => $tool->getClass(),
- 'name' => $tool->getName(),
- ];
- }, $tools)),
- ]);
- }
-
- /**
- * Opens an administration tool.
- *
- * @Route("/open/{toolName}", name="claro_admin_open_tool")
- *
- * @return JsonResponse
- *
- * @throws AccessDeniedException
- */
- public function openToolAction($toolName)
- {
- $tool = $this->toolManager->getAdminToolByName($toolName);
- if (!$tool) {
- throw new NotFoundHttpException('Tool not found');
- }
-
- if (!$this->authorization->isGranted('OPEN', $tool)) {
- throw new AccessDeniedException();
- }
-
- $currentUser = $this->tokenStorage->getToken()->getUser();
- $eventParams = [
- $toolName,
- AbstractTool::ADMINISTRATION,
- null,
- $currentUser instanceof User ? $currentUser : null,
- ];
-
- $this->strictDispatcher->dispatch(
- ToolEvents::OPEN,
- OpenToolEvent::class,
- $eventParams
- );
-
- /** @var OpenToolEvent $event */
- $event = $this->strictDispatcher->dispatch(
- ToolEvents::getEventName(ToolEvents::OPEN, AbstractTool::ADMINISTRATION, $toolName),
- OpenToolEvent::class,
- $eventParams
- );
-
- return new JsonResponse(array_merge($event->getData(), [
- 'data' => [
- 'permissions' => [
- 'open' => $this->authorization->isGranted('OPEN', $tool),
- 'edit' => $this->authorization->isGranted('EDIT', $tool),
- ],
- ],
- ]));
- }
-
- /**
- * Lists admin tools accessible by the current user.
- *
- * @Route("/tools", name="claro_admin_tools")
- *
- * @return JsonResponse
- */
- public function listToolsAction()
- {
- $tools = $this->toolManager->getAdminToolsByRoles($this->tokenStorage->getToken()->getRoleNames());
-
- return new JsonResponse([
- 'tools' => array_values(array_map(function (AdminTool $tool) {
- return [
- 'icon' => $tool->getClass(),
- 'name' => $tool->getName(),
- ];
- }, $tools)),
- ]);
- }
-}
diff --git a/src/main/core/Controller/WorkspaceController.php b/src/main/core/Controller/WorkspaceController.php
deleted file mode 100644
index ce69fe31dba..00000000000
--- a/src/main/core/Controller/WorkspaceController.php
+++ /dev/null
@@ -1,182 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Claroline\CoreBundle\Controller;
-
-use Claroline\AppBundle\API\Serializer\SerializerInterface;
-use Claroline\AppBundle\API\SerializerProvider;
-use Claroline\AppBundle\Event\StrictDispatcher;
-use Claroline\AppBundle\Persistence\ObjectManager;
-use Claroline\CoreBundle\Entity\Resource\ResourceNode;
-use Claroline\CoreBundle\Entity\Role;
-use Claroline\CoreBundle\Entity\Tool\OrderedTool;
-use Claroline\CoreBundle\Entity\User;
-use Claroline\CoreBundle\Entity\Workspace\Shortcuts;
-use Claroline\CoreBundle\Entity\Workspace\Workspace;
-use Claroline\CoreBundle\Event\CatalogEvents\WorkspaceEvents;
-use Claroline\CoreBundle\Event\Log\LogWorkspaceEnterEvent;
-use Claroline\CoreBundle\Event\Workspace\OpenWorkspaceEvent;
-use Claroline\CoreBundle\Manager\Tool\ToolManager;
-use Claroline\CoreBundle\Manager\Workspace\WorkspaceManager;
-use Claroline\CoreBundle\Manager\Workspace\WorkspaceRestrictionsManager;
-use Claroline\EvaluationBundle\Manager\WorkspaceEvaluationManager;
-use Sensio\Bundle\FrameworkExtraBundle\Configuration as EXT;
-use Symfony\Component\HttpFoundation\JsonResponse;
-use Symfony\Component\HttpFoundation\Request;
-use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
-use Symfony\Component\Routing\Annotation\Route;
-use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
-use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
-
-/**
- * @Route("/workspaces", options={"expose" = true})
- */
-class WorkspaceController
-{
- /** @var AuthorizationCheckerInterface */
- private $authorization;
- /** @var ObjectManager */
- private $om;
- /** @var TokenStorageInterface */
- private $tokenStorage;
- /** @var SerializerProvider */
- private $serializer;
- /** @var ToolManager */
- private $toolManager;
- /** @var WorkspaceManager */
- private $manager;
- /** @var WorkspaceRestrictionsManager */
- private $restrictionsManager;
- /** @var WorkspaceEvaluationManager */
- private $evaluationManager;
- /** @var StrictDispatcher */
- private $strictDispatcher;
-
- public function __construct(
- AuthorizationCheckerInterface $authorization,
- ObjectManager $om,
- TokenStorageInterface $tokenStorage,
- SerializerProvider $serializer,
- ToolManager $toolManager,
- WorkspaceManager $manager,
- WorkspaceRestrictionsManager $restrictionsManager,
- WorkspaceEvaluationManager $evaluationManager,
- StrictDispatcher $strictDispatcher
- ) {
- $this->authorization = $authorization;
- $this->om = $om;
- $this->tokenStorage = $tokenStorage;
- $this->serializer = $serializer;
- $this->toolManager = $toolManager;
- $this->manager = $manager;
- $this->restrictionsManager = $restrictionsManager;
- $this->evaluationManager = $evaluationManager;
- $this->strictDispatcher = $strictDispatcher;
- }
-
- /**
- * @Route("/{slug}", name="claro_workspace_open")
- *
- * @EXT\ParamConverter("user", converter="current_user", options={"allowAnonymous"=true})
- */
- public function openAction(string $slug, User $user = null): JsonResponse
- {
- /** @var Workspace $workspace */
- $workspace = $this->om->getRepository(Workspace::class)->findOneBy(['slug' => $slug]);
-
- if (!$workspace) {
- throw new NotFoundHttpException('Workspace not found');
- }
-
- // this should not be done here
- $this->toolManager->addMissingWorkspaceTools($workspace);
-
- $isManager = $this->manager->isManager($workspace, $this->tokenStorage->getToken());
- $accessErrors = $this->restrictionsManager->getErrors($workspace, $user);
- if (empty($accessErrors) || $isManager) {
- $this->strictDispatcher->dispatch(
- WorkspaceEvents::OPEN,
- OpenWorkspaceEvent::class,
- [$workspace]
- );
-
- // Log workspace opening
- $this->strictDispatcher->dispatch(
- 'log',
- LogWorkspaceEnterEvent::class,
- [$workspace]
- );
-
- $userEvaluation = null;
- if ($user) {
- $userEvaluation = $this->serializer->serialize(
- $this->evaluationManager->getUserEvaluation($workspace, $user),
- [SerializerInterface::SERIALIZE_MINIMAL]
- );
- }
-
- return new JsonResponse([
- 'workspace' => $this->serializer->serialize($workspace),
- 'managed' => $isManager,
- 'impersonated' => $this->manager->isImpersonated($this->tokenStorage->getToken()),
- // the list of current workspace roles the user owns
- 'roles' => array_map(function (Role $role) {
- return $this->serializer->serialize($role, [SerializerInterface::SERIALIZE_MINIMAL]);
- }, $this->manager->getTokenRoles($this->tokenStorage->getToken(), $workspace)),
- // append access restrictions to the loaded data if any
- // to let the manager knows that other users can not enter the workspace
- 'accessErrors' => $accessErrors,
- 'userEvaluation' => $userEvaluation,
- // get the list of enabled workspace tool
- 'tools' => array_values(array_map(function (OrderedTool $orderedTool) {
- return $this->serializer->serialize($orderedTool, [SerializerInterface::SERIALIZE_MINIMAL]);
- }, $this->toolManager->getOrderedToolsByWorkspace($workspace))),
- // do not expose root resource here (used in the WS to configure opening target)
- 'root' => $this->serializer->serialize($this->om->getRepository(ResourceNode::class)->findOneBy(['workspace' => $workspace, 'parent' => null]), [SerializerInterface::SERIALIZE_MINIMAL]),
- // TODO : only export current user shortcuts (we get all roles for the configuration in community/editor)
- // 'shortcuts' => $this->manager->getShortcuts($workspace, $this->tokenStorage->getToken()->getRoleNames()),
- 'shortcuts' => array_values(array_map(function (Shortcuts $shortcuts) {
- return $this->serializer->serialize($shortcuts);
- }, $workspace->getShortcuts()->toArray())),
- ]);
- }
-
- $statusCode = 403;
- if (!$workspace->getSelfRegistration() && !$this->authorization->isGranted('IS_AUTHENTICATED_FULLY') && !$this->restrictionsManager->hasRights($workspace)) {
- // let the API handles the access error
- $statusCode = 401;
- }
-
- // return the details of access errors to display it to users
- return new JsonResponse([
- 'impersonated' => $this->manager->isImpersonated($this->tokenStorage->getToken()),
- 'roles' => array_map(function (Role $role) {
- return $this->serializer->serialize($role, [SerializerInterface::SERIALIZE_MINIMAL]);
- }, $this->manager->getTokenRoles($this->tokenStorage->getToken(), $workspace)),
- 'workspace' => $this->serializer->serialize($workspace),
- 'accessErrors' => $accessErrors,
- ], $statusCode);
- }
-
- /**
- * Submit access code.
- *
- * @Route("/unlock/{id}", name="claro_workspace_unlock", methods={"POST"})
- *
- * @EXT\ParamConverter("workspace", class="Claroline\CoreBundle\Entity\Workspace\Workspace", options={"mapping": {"id": "uuid"}})
- */
- public function unlockAction(Workspace $workspace, Request $request): JsonResponse
- {
- $this->restrictionsManager->unlock($workspace, json_decode($request->getContent(), true)['code']);
-
- return new JsonResponse(null, 204);
- }
-}
diff --git a/src/main/core/DependencyInjection/ClarolineCoreExtension.php b/src/main/core/DependencyInjection/ClarolineCoreExtension.php
index d089f19bc48..e20b9e711ff 100644
--- a/src/main/core/DependencyInjection/ClarolineCoreExtension.php
+++ b/src/main/core/DependencyInjection/ClarolineCoreExtension.php
@@ -21,7 +21,7 @@
*/
class ClarolineCoreExtension extends Extension
{
- public function load(array $configs, ContainerBuilder $container)
+ public function load(array $configs, ContainerBuilder $container): void
{
$locator = new FileLocator(__DIR__.'/../Resources/config');
$loader = new YamlFileLoader($container, $locator);
diff --git a/src/main/core/Entity/Log/Connection/AbstractLogConnect.php b/src/main/core/Entity/Log/Connection/AbstractLogConnect.php
deleted file mode 100644
index 3e99c8bc84c..00000000000
--- a/src/main/core/Entity/Log/Connection/AbstractLogConnect.php
+++ /dev/null
@@ -1,94 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Claroline\CoreBundle\Entity\Log\Connection;
-
-use Claroline\AppBundle\Entity\Identifier\Id;
-use Claroline\AppBundle\Entity\Identifier\Uuid;
-use Claroline\CoreBundle\Entity\User;
-use Doctrine\ORM\Mapping as ORM;
-
-/**
- * @ORM\MappedSuperclass
- */
-abstract class AbstractLogConnect
-{
- use Id;
- use Uuid;
-
- /**
- * @ORM\ManyToOne(targetEntity="Claroline\CoreBundle\Entity\User")
- * @ORM\JoinColumn(name="user_id", onDelete="CASCADE")
- */
- protected $user;
-
- /**
- * @ORM\Column(name="connection_date", type="datetime")
- */
- protected $connectionDate;
-
- /**
- * @ORM\Column(name="total_duration", type="integer", nullable=true)
- */
- protected $duration;
-
- /**
- * AbstractLogConnect constructor.
- */
- public function __construct()
- {
- $this->refreshUuid();
-
- $this->connectionDate = new \DateTime();
- }
-
- /**
- * @return User
- */
- public function getUser()
- {
- return $this->user;
- }
-
- public function setUser(User $user)
- {
- $this->user = $user;
- }
-
- /**
- * @return \DateTime
- */
- public function getConnectionDate()
- {
- return $this->connectionDate;
- }
-
- public function setConnectionDate(\DateTime $connectionDate)
- {
- $this->connectionDate = $connectionDate;
- }
-
- /**
- * @return int
- */
- public function getDuration()
- {
- return $this->duration;
- }
-
- /**
- * @param int $duration
- */
- public function setDuration($duration)
- {
- $this->duration = $duration;
- }
-}
diff --git a/src/main/core/Entity/Log/Connection/LogConnectAdminTool.php b/src/main/core/Entity/Log/Connection/LogConnectAdminTool.php
deleted file mode 100644
index 79ea675fa57..00000000000
--- a/src/main/core/Entity/Log/Connection/LogConnectAdminTool.php
+++ /dev/null
@@ -1,69 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Claroline\CoreBundle\Entity\Log\Connection;
-
-use Claroline\CoreBundle\Entity\Tool\AdminTool;
-use Doctrine\ORM\Mapping as ORM;
-
-/**
- * @ORM\Entity
- * @ORM\Table(name="claro_log_connect_admin_tool")
- */
-class LogConnectAdminTool extends AbstractLogConnect
-{
- /**
- * @ORM\ManyToOne(targetEntity="Claroline\CoreBundle\Entity\Tool\AdminTool")
- * @ORM\JoinColumn(name="tool_id", onDelete="SET NULL", nullable=true)
- */
- protected $tool;
-
- /**
- * @ORM\Column(name="tool_name")
- */
- protected $toolName;
-
- /**
- * @return AdminTool
- */
- public function getTool()
- {
- return $this->tool;
- }
-
- /**
- * @param AdminTool $tool
- */
- public function setTool(AdminTool $tool = null)
- {
- $this->tool = $tool;
-
- if ($tool) {
- $this->setToolName($tool->getName());
- }
- }
-
- /**
- * @return string
- */
- public function getToolName()
- {
- return $this->toolName;
- }
-
- /**
- * @param string $toolName
- */
- public function setToolName($toolName)
- {
- $this->toolName = $toolName;
- }
-}
diff --git a/src/main/core/Entity/Log/Connection/LogConnectPlatform.php b/src/main/core/Entity/Log/Connection/LogConnectPlatform.php
deleted file mode 100644
index 03fd808d3f2..00000000000
--- a/src/main/core/Entity/Log/Connection/LogConnectPlatform.php
+++ /dev/null
@@ -1,22 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Claroline\CoreBundle\Entity\Log\Connection;
-
-use Doctrine\ORM\Mapping as ORM;
-
-/**
- * @ORM\Entity(repositoryClass="Claroline\CoreBundle\Repository\Log\Connection\LogConnectPlatformRepository")
- * @ORM\Table(name="claro_log_connect_platform")
- */
-class LogConnectPlatform extends AbstractLogConnect
-{
-}
diff --git a/src/main/core/Entity/Log/Connection/LogConnectResource.php b/src/main/core/Entity/Log/Connection/LogConnectResource.php
deleted file mode 100644
index 158cb109381..00000000000
--- a/src/main/core/Entity/Log/Connection/LogConnectResource.php
+++ /dev/null
@@ -1,112 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Claroline\CoreBundle\Entity\Log\Connection;
-
-use Claroline\CoreBundle\Entity\Resource\ResourceNode;
-use Doctrine\ORM\Mapping as ORM;
-
-/**
- * @ORM\Entity(repositoryClass="Claroline\CoreBundle\Repository\Log\Connection\LogConnectResourceRepository")
- * @ORM\Table(name="claro_log_connect_resource")
- */
-class LogConnectResource extends AbstractLogConnect
-{
- /**
- * @ORM\ManyToOne(targetEntity="Claroline\CoreBundle\Entity\Resource\ResourceNode")
- * @ORM\JoinColumn(name="resource_id", onDelete="SET NULL", nullable=true)
- */
- protected $resource;
-
- /**
- * @ORM\Column(name="resource_name")
- */
- protected $resourceName;
-
- /**
- * @ORM\Column(name="resource_type")
- */
- protected $resourceType;
-
- /**
- * @ORM\Column(name="embedded", type="boolean")
- */
- protected $embedded = false;
-
- /**
- * @return ResourceNode
- */
- public function getResource()
- {
- return $this->resource;
- }
-
- /**
- * @param ResourceNode $resource
- */
- public function setResource(ResourceNode $resource = null)
- {
- $this->resource = $resource;
-
- if ($resource) {
- $this->setResourceName($resource->getName());
- $this->setResourceType($resource->getResourceType()->getName());
- }
- }
-
- /**
- * @return string
- */
- public function getResourceName()
- {
- return $this->resourceName;
- }
-
- /**
- * @param string $resourceName
- */
- public function setResourceName($resourceName)
- {
- $this->resourceName = $resourceName;
- }
-
- /**
- * @return string
- */
- public function getResourceType()
- {
- return $this->resourceType;
- }
-
- /**
- * @param string $resourceType
- */
- public function setResourceType($resourceType)
- {
- $this->resourceType = $resourceType;
- }
-
- /**
- * @return bool
- */
- public function isEmbedded()
- {
- return $this->embedded;
- }
-
- /**
- * @param bool $embedded
- */
- public function setEmbedded($embedded)
- {
- $this->embedded = $embedded;
- }
-}
diff --git a/src/main/core/Entity/Log/Connection/LogConnectTool.php b/src/main/core/Entity/Log/Connection/LogConnectTool.php
deleted file mode 100644
index 8cb4cf52f13..00000000000
--- a/src/main/core/Entity/Log/Connection/LogConnectTool.php
+++ /dev/null
@@ -1,146 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Claroline\CoreBundle\Entity\Log\Connection;
-
-use Claroline\CoreBundle\Entity\Tool\OrderedTool;
-use Claroline\CoreBundle\Entity\Workspace\Workspace;
-use Doctrine\ORM\Mapping as ORM;
-
-/**
- * @ORM\Entity
- * @ORM\Table(name="claro_log_connect_tool")
- */
-class LogConnectTool extends AbstractLogConnect
-{
- /**
- * @ORM\ManyToOne(targetEntity="Claroline\CoreBundle\Entity\Tool\OrderedTool")
- * @ORM\JoinColumn(name="tool_id", onDelete="SET NULL", nullable=true)
- */
- protected $tool;
-
- /**
- * @ORM\Column(name="tool_name")
- */
- protected $toolName;
-
- /**
- * @ORM\Column(name="original_tool_name")
- */
- protected $originalToolName;
-
- /**
- * @ORM\ManyToOne(targetEntity="Claroline\CoreBundle\Entity\Workspace\Workspace")
- * @ORM\JoinColumn(name="workspace_id", onDelete="SET NULL", nullable=true)
- */
- protected $workspace;
-
- /**
- * @ORM\Column(name="workspace_name", nullable=true)
- */
- protected $workspaceName;
-
- /**
- * @return OrderedTool
- */
- public function getTool()
- {
- return $this->tool;
- }
-
- /**
- * @param OrderedTool $tool
- */
- public function setTool(OrderedTool $tool = null)
- {
- $this->tool = $tool;
-
- if ($tool) {
- $this->setToolName($tool->getTool()->getName());
- $this->setOrignalToolName($tool->getTool()->getName());
-
- $workspace = $tool->getWorkspace();
-
- if ($workspace) {
- $this->setWorkspace($workspace);
- $this->setWorkspaceName($tool->getWorkspace()->getName());
- }
- }
- }
-
- /**
- * @return string
- */
- public function getToolName()
- {
- return $this->toolName;
- }
-
- /**
- * @param string $toolName
- */
- public function setToolName($toolName)
- {
- $this->toolName = $toolName;
- }
-
- /**
- * @return string
- */
- public function getOrignalToolName()
- {
- return $this->originalToolName;
- }
-
- /**
- * @param string $originalToolName
- */
- public function setOrignalToolName($originalToolName)
- {
- $this->originalToolName = $originalToolName;
- }
-
- /**
- * @return Workspace
- */
- public function getWorkspace()
- {
- return $this->workspace;
- }
-
- /**
- * @param Workspace $workspace
- */
- public function setWorkspace(Workspace $workspace = null)
- {
- $this->workspace = $workspace;
-
- if ($workspace) {
- $this->setWorkspaceName($workspace->getName());
- }
- }
-
- /**
- * @return string
- */
- public function getWorkspaceName()
- {
- return $this->workspaceName;
- }
-
- /**
- * @param string $workspaceName
- */
- public function setWorkspaceName($workspaceName)
- {
- $this->workspaceName = $workspaceName;
- }
-}
diff --git a/src/main/core/Entity/Log/Connection/LogConnectWorkspace.php b/src/main/core/Entity/Log/Connection/LogConnectWorkspace.php
deleted file mode 100644
index 0ebf60d0a60..00000000000
--- a/src/main/core/Entity/Log/Connection/LogConnectWorkspace.php
+++ /dev/null
@@ -1,69 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Claroline\CoreBundle\Entity\Log\Connection;
-
-use Claroline\CoreBundle\Entity\Workspace\Workspace;
-use Doctrine\ORM\Mapping as ORM;
-
-/**
- * @ORM\Entity(repositoryClass="Claroline\CoreBundle\Repository\Log\Connection\LogConnectWorkspaceRepository")
- * @ORM\Table(name="claro_log_connect_workspace")
- */
-class LogConnectWorkspace extends AbstractLogConnect
-{
- /**
- * @ORM\ManyToOne(targetEntity="Claroline\CoreBundle\Entity\Workspace\Workspace")
- * @ORM\JoinColumn(name="workspace_id", onDelete="SET NULL", nullable=true)
- */
- protected $workspace;
-
- /**
- * @ORM\Column(name="workspace_name")
- */
- protected $workspaceName;
-
- /**
- * @return Workspace
- */
- public function getWorkspace()
- {
- return $this->workspace;
- }
-
- /**
- * @param Workspace $workspace
- */
- public function setWorkspace(Workspace $workspace = null)
- {
- $this->workspace = $workspace;
-
- if ($workspace) {
- $this->setWorkspaceName($workspace->getName());
- }
- }
-
- /**
- * @return string
- */
- public function getWorkspaceName()
- {
- return $this->workspaceName;
- }
-
- /**
- * @param string $workspaceName
- */
- public function setWorkspaceName($workspaceName)
- {
- $this->workspaceName = $workspaceName;
- }
-}
diff --git a/src/main/core/Entity/Tool/OrderedTool.php b/src/main/core/Entity/Tool/OrderedTool.php
index 1552e634fd9..40eb432f875 100644
--- a/src/main/core/Entity/Tool/OrderedTool.php
+++ b/src/main/core/Entity/Tool/OrderedTool.php
@@ -11,14 +11,13 @@
namespace Claroline\CoreBundle\Entity\Tool;
+use Claroline\AppBundle\Entity\Display\Hidden;
+use Claroline\AppBundle\Entity\Display\Order;
+use Claroline\AppBundle\Entity\Display\Poster;
+use Claroline\AppBundle\Entity\Display\Thumbnail;
+use Claroline\AppBundle\Entity\HasContext;
use Claroline\AppBundle\Entity\Identifier\Id;
use Claroline\AppBundle\Entity\Identifier\Uuid;
-use Claroline\AppBundle\Entity\Meta\Order;
-use Claroline\AppBundle\Entity\Meta\Poster;
-use Claroline\AppBundle\Entity\Meta\Thumbnail;
-use Claroline\AppBundle\Entity\Restriction\Hidden;
-use Claroline\CoreBundle\Entity\User;
-use Claroline\CoreBundle\Entity\Workspace\Workspace;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints as DoctrineAssert;
@@ -26,34 +25,26 @@
/**
* @ORM\Entity(repositoryClass="Claroline\CoreBundle\Repository\Tool\OrderedToolRepository")
*
- * @ORM\Table(
- * name="claro_ordered_tool",
- * uniqueConstraints={
+ * @ORM\Table(name="claro_ordered_tool")
*
- * @ORM\UniqueConstraint(
- * name="ordered_tool_unique_tool_user_type",
- * columns={"tool_id", "user_id"}
- * ),
- * @ORM\UniqueConstraint(
- * name="ordered_tool_unique_tool_ws_type",
- * columns={"tool_id", "workspace_id"}
- * )
- * }
- * )
- *
- * @DoctrineAssert\UniqueEntity({"tool", "workspace"})
- * @DoctrineAssert\UniqueEntity({"tool", "user"})
+ * @DoctrineAssert\UniqueEntity({"tool", "contextName", "contextId"})
*/
class OrderedTool
{
use Id;
use Uuid;
+ use HasContext;
// meta
use Thumbnail;
use Poster;
use Order;
use Hidden;
+ /**
+ * @ORM\Column(name="tool_name", type="string", nullable=false)
+ */
+ private ?string $name;
+
/**
* Display tool icon when the tool is rendered.
*
@@ -68,42 +59,6 @@ class OrderedTool
*/
private bool $fullscreen = false;
- /**
- * @ORM\ManyToOne(
- * targetEntity="Claroline\CoreBundle\Entity\Workspace\Workspace",
- * cascade={"persist", "merge"},
- * inversedBy="orderedTools"
- * )
- *
- * @ORM\JoinColumn(onDelete="CASCADE")
- *
- * @var Workspace
- */
- private $workspace;
-
- /**
- * @ORM\ManyToOne(
- * targetEntity="Claroline\CoreBundle\Entity\Tool\Tool"
- * )
- *
- * @ORM\JoinColumn(nullable=false, onDelete="CASCADE")
- *
- * @var Tool
- */
- private $tool;
-
- /**
- * @ORM\ManyToOne(
- * targetEntity="Claroline\CoreBundle\Entity\User",
- * cascade={"persist"}
- * )
- *
- * @ORM\JoinColumn(onDelete="CASCADE")
- *
- * @var User
- */
- private $user;
-
/**
* @ORM\OneToMany(
* targetEntity="Claroline\CoreBundle\Entity\Tool\ToolRights",
@@ -121,28 +76,24 @@ public function __construct()
$this->rights = new ArrayCollection();
}
- public function __toString()
+ public function getName(): string
{
- if (!empty($this->workspace)) {
- return '['.$this->workspace->getName().'] '.$this->tool->getName();
- }
-
- return $this->tool->getName();
+ return $this->name;
}
- public function getShowIcon()
+ public function setName(string $name): void
{
- return $this->showIcon;
+ $this->name = $name;
}
- public function setShowIcon($showIcon)
+ public function getShowIcon(): bool
{
- $this->showIcon = $showIcon;
+ return $this->showIcon;
}
- public function setFullscreen(bool $fullscreen)
+ public function setShowIcon(bool $showIcon): void
{
- $this->fullscreen = $fullscreen;
+ $this->showIcon = $showIcon;
}
public function getFullscreen(): bool
@@ -150,43 +101,9 @@ public function getFullscreen(): bool
return $this->fullscreen;
}
- public function setWorkspace(Workspace $ws = null)
+ public function setFullscreen(bool $fullscreen): void
{
- $this->workspace = $ws;
- }
-
- /**
- * @return Workspace
- */
- public function getWorkspace()
- {
- return $this->workspace;
- }
-
- public function setTool(Tool $tool)
- {
- $this->tool = $tool;
- }
-
- /**
- * @return Tool
- */
- public function getTool()
- {
- return $this->tool;
- }
-
- public function setUser(User $user = null)
- {
- $this->user = $user;
- }
-
- /**
- * @return User
- */
- public function getUser()
- {
- return $this->user;
+ $this->fullscreen = $fullscreen;
}
/**
@@ -197,14 +114,15 @@ public function getRights()
return $this->rights;
}
- public function addRight(ToolRights $right)
+ public function addRight(ToolRights $right): void
{
if (!$this->rights->contains($right)) {
$this->rights->add($right);
+ $right->setOrderedTool($this);
}
}
- public function removeRight(ToolRights $right)
+ public function removeRight(ToolRights $right): void
{
if ($this->rights->contains($right)) {
$this->rights->removeElement($right);
diff --git a/src/main/core/Entity/Tool/ToolMaskDecoder.php b/src/main/core/Entity/Tool/ToolMaskDecoder.php
index 7060aa57a32..5243075350b 100644
--- a/src/main/core/Entity/Tool/ToolMaskDecoder.php
+++ b/src/main/core/Entity/Tool/ToolMaskDecoder.php
@@ -23,7 +23,7 @@
*
* @ORM\UniqueConstraint(
* name="tool_mask_decoder_unique_tool_and_name",
- * columns={"tool_id", "name"}
+ * columns={"tool_name", "name"}
* )
* })
*/
@@ -41,53 +41,44 @@ class ToolMaskDecoder
/**
* @ORM\Column(type="integer")
*/
- protected $value;
+ private int $value;
/**
* @ORM\Column()
*/
- protected $name;
+ protected string $name;
/**
- * @ORM\ManyToOne(
- * targetEntity="Claroline\CoreBundle\Entity\Tool\Tool",
- * inversedBy="maskDecoders",
- * cascade={"persist"}
- * )
- *
- * @ORM\JoinColumn(name="tool_id", onDelete="CASCADE", nullable=false)
+ * @ORM\Column(name="tool_name", nullable=false)
*/
- protected $tool;
+ protected string $tool;
- public function getValue()
+ public function getValue(): int
{
return $this->value;
}
- public function setValue($value)
+ public function setValue($value): void
{
$this->value = $value;
}
- public function getName()
+ public function getName(): string
{
return $this->name;
}
- public function setName($name)
+ public function setName($name): void
{
$this->name = $name;
}
- /**
- * @return Tool
- */
- public function getTool()
+ public function getTool(): string
{
return $this->tool;
}
- public function setTool(Tool $tool)
+ public function setTool(string $tool): void
{
$this->tool = $tool;
}
diff --git a/src/main/core/Entity/Tool/ToolRights.php b/src/main/core/Entity/Tool/ToolRights.php
index a026ab36156..e92ca7143ea 100644
--- a/src/main/core/Entity/Tool/ToolRights.php
+++ b/src/main/core/Entity/Tool/ToolRights.php
@@ -11,14 +11,17 @@
namespace Claroline\CoreBundle\Entity\Tool;
+use Claroline\AppBundle\Entity\Identifier\Id;
use Claroline\CoreBundle\Entity\Role;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass="Claroline\CoreBundle\Repository\Tool\ToolRightsRepository")
+ *
* @ORM\Table(
* name="claro_tool_rights",
* uniqueConstraints={
+ *
* @ORM\UniqueConstraint(
* name="tool_rights_unique_ordered_tool_role",
* columns={"ordered_tool_id", "role_id"}
@@ -28,26 +31,22 @@
*/
class ToolRights
{
- /**
- * @ORM\Id
- * @ORM\Column(type="integer")
- * @ORM\GeneratedValue(strategy="AUTO")
- */
- protected $id;
+ use Id;
/**
* @ORM\Column(type="integer")
*/
- protected $mask = 0;
+ private int $mask = 0;
/**
* @ORM\ManyToOne(
* targetEntity="Claroline\CoreBundle\Entity\Role",
* inversedBy="toolRights"
* )
+ *
* @ORM\JoinColumn(name="role_id", nullable=false, onDelete="CASCADE")
*/
- protected $role;
+ private Role $role;
/**
* @ORM\ManyToOne(
@@ -55,58 +54,40 @@ class ToolRights
* inversedBy="rights",
* cascade={"persist"}
* )
+ *
* @ORM\JoinColumn(name="ordered_tool_id", nullable=false, onDelete="CASCADE")
*/
- protected $orderedTool;
+ private OrderedTool $orderedTool;
- /**
- * @return int
- */
- public function getId()
- {
- return $this->id;
- }
-
- /**
- * @return int
- */
- public function getMask()
+ public function getMask(): int
{
return $this->mask;
}
- /**
- * @return Role
- */
- public function getRole()
+ public function setMask(int $mask): void
{
- return $this->role;
- }
-
- /**
- * @return OrderedTool
- */
- public function getOrderedTool()
- {
- return $this->orderedTool;
+ $this->mask = $mask;
}
- public function setId($id)
+ public function getRole(): Role
{
- $this->id = $id;
+ return $this->role;
}
- public function setMask($mask)
+ public function setRole(Role $role): void
{
- $this->mask = $mask;
+ $this->role = $role;
}
- public function setRole(Role $role)
+ public function getOrderedTool(): OrderedTool
{
- $this->role = $role;
+ return $this->orderedTool;
}
- public function setOrderedTool(OrderedTool $orderedTool)
+ /**
+ * @internal
+ */
+ public function setOrderedTool(OrderedTool $orderedTool): void
{
$this->orderedTool = $orderedTool;
}
diff --git a/src/main/core/Entity/User.php b/src/main/core/Entity/User.php
index a0c775251ff..ca8cb9f3fc4 100644
--- a/src/main/core/Entity/User.php
+++ b/src/main/core/Entity/User.php
@@ -11,6 +11,7 @@
namespace Claroline\CoreBundle\Entity;
+use Claroline\AppBundle\Component\Context\ContextSubjectInterface;
use Claroline\AppBundle\Entity\IdentifiableInterface;
use Claroline\AppBundle\Entity\Identifier\Id;
use Claroline\AppBundle\Entity\Identifier\Uuid;
@@ -42,7 +43,7 @@
* @ORM\Index(name="is_removed", columns={"is_removed"})
* })
*/
-class User extends AbstractRoleSubject implements UserInterface, EquatableInterface, PasswordAuthenticatedUserInterface, LegacyPasswordAuthenticatedUserInterface, IdentifiableInterface
+class User extends AbstractRoleSubject implements UserInterface, EquatableInterface, PasswordAuthenticatedUserInterface, LegacyPasswordAuthenticatedUserInterface, IdentifiableInterface, ContextSubjectInterface
{
use Id;
use Uuid;
@@ -353,6 +354,11 @@ public function getUserIdentifier(): string
return $this->username;
}
+ public function getContextIdentifier(): string
+ {
+ return $this->uuid;
+ }
+
public function getFirstName(): ?string
{
return $this->firstName;
diff --git a/src/main/core/Entity/Workspace/Workspace.php b/src/main/core/Entity/Workspace/Workspace.php
index a01df19cc98..ea02bca7aae 100644
--- a/src/main/core/Entity/Workspace/Workspace.php
+++ b/src/main/core/Entity/Workspace/Workspace.php
@@ -11,6 +11,7 @@
namespace Claroline\CoreBundle\Entity\Workspace;
+use Claroline\AppBundle\Component\Context\ContextSubjectInterface;
use Claroline\AppBundle\Entity\IdentifiableInterface;
use Claroline\AppBundle\Entity\Identifier\Code;
use Claroline\AppBundle\Entity\Identifier\Id;
@@ -45,7 +46,7 @@
* @ORM\Index(name="name_idx", columns={"entity_name"})
* })
*/
-class Workspace implements IdentifiableInterface
+class Workspace implements IdentifiableInterface, ContextSubjectInterface
{
// identifiers
use Id;
@@ -261,6 +262,11 @@ public function __toString(): string
return $this->name.' ['.$this->code.']';
}
+ public function getContextIdentifier(): string
+ {
+ return $this->uuid;
+ }
+
public function getSlug(): ?string
{
return $this->slug;
diff --git a/src/main/core/Event/Tool/AbstractToolEvent.php b/src/main/core/Event/Tool/AbstractToolEvent.php
index dd6ef12a49b..9e82db4e61f 100644
--- a/src/main/core/Event/Tool/AbstractToolEvent.php
+++ b/src/main/core/Event/Tool/AbstractToolEvent.php
@@ -11,23 +11,20 @@
namespace Claroline\CoreBundle\Event\Tool;
-use Claroline\CoreBundle\Entity\Workspace\Workspace;
+use Claroline\AppBundle\Component\Context\ContextSubjectInterface;
use Symfony\Contracts\EventDispatcher\Event;
abstract class AbstractToolEvent extends Event
{
- /** @var string */
- private $toolName;
- /** @var string */
- private $context;
- /** @var Workspace */
- private $workspace;
-
- public function __construct(string $toolName, string $context, ?Workspace $workspace = null)
+ private string $toolName;
+ private string $context;
+ private ?ContextSubjectInterface $contextSubject = null;
+
+ public function __construct(string $toolName, string $context, ContextSubjectInterface $contextSubject = null)
{
$this->toolName = $toolName;
$this->context = $context;
- $this->workspace = $workspace;
+ $this->contextSubject = $contextSubject;
}
public function getToolName(): string
@@ -40,8 +37,16 @@ public function getContext(): string
return $this->context;
}
- public function getWorkspace(): ?Workspace
+ public function getContextSubject(): ?ContextSubjectInterface
+ {
+ return $this->contextSubject;
+ }
+
+ /**
+ * @deprecated use getContextSubject() instead
+ */
+ public function getWorkspace(): ?ContextSubjectInterface
{
- return $this->workspace;
+ return $this->getContextSubject();
}
}
diff --git a/src/main/core/Event/Tool/ExportToolEvent.php b/src/main/core/Event/Tool/ExportToolEvent.php
index 4caad9d410e..2960f0c2e9c 100644
--- a/src/main/core/Event/Tool/ExportToolEvent.php
+++ b/src/main/core/Event/Tool/ExportToolEvent.php
@@ -8,24 +8,22 @@
class ExportToolEvent extends AbstractToolEvent
{
- /** @var FileBag */
- private $fileBag;
+ private FileBag $fileBag;
- /** @var array */
- private $data = [];
+ private array $data = [];
public function __construct(
string $toolName,
string $context,
- ?Workspace $workspace = null,
- ?FileBag $fileBag = null
+ Workspace $workspace = null,
+ FileBag $fileBag = null
) {
parent::__construct($toolName, $context, $workspace);
$this->fileBag = $fileBag ?? new FileBag();
}
- public function setData(?array $data = [])
+ public function setData(?array $data = []): void
{
$this->data = $data;
}
@@ -35,7 +33,7 @@ public function getData(): array
return $this->data;
}
- public function addFile($path, $file)
+ public function addFile($path, $file): void
{
$this->fileBag->add($path, $file);
}
@@ -45,7 +43,7 @@ public function getFileBag(): FileBag
return $this->fileBag;
}
- public function overwrite($key, $value)
+ public function overwrite($key, $value): void
{
ArrayUtils::set($this->data, $key, $value);
}
diff --git a/src/main/core/Event/Tool/ImportToolEvent.php b/src/main/core/Event/Tool/ImportToolEvent.php
index 6e1b6309704..181cbedc3ca 100644
--- a/src/main/core/Event/Tool/ImportToolEvent.php
+++ b/src/main/core/Event/Tool/ImportToolEvent.php
@@ -7,28 +7,23 @@
class ImportToolEvent extends AbstractToolEvent
{
- /** @var FileBag */
- private $fileBag;
+ private FileBag $fileBag;
/**
* The serialized data to import.
- *
- * @var array
*/
- private $data;
+ private array $data;
/**
* The list of entities created by the import. Keys are the old UUIDs of the entities.
- *
- * @var array
*/
- private $entities;
+ private array $entities;
public function __construct(
string $toolName,
string $context,
- ?Workspace $workspace = null,
- ?FileBag $fileBag = null,
+ Workspace $workspace = null,
+ FileBag $fileBag = null,
?array $data = [],
?array $entities = []
) {
@@ -59,7 +54,7 @@ public function getCreatedEntities(): array
return $this->entities;
}
- public function getCreatedEntity(string $oldUuid)
+ public function getCreatedEntity(string $oldUuid): mixed
{
if (!empty($this->entities[$oldUuid])) {
return $this->entities[$oldUuid];
@@ -68,7 +63,7 @@ public function getCreatedEntity(string $oldUuid)
return null;
}
- public function addCreatedEntity(string $oldUuid, $entity)
+ public function addCreatedEntity(string $oldUuid, $entity): void
{
$this->entities[$oldUuid] = $entity;
}
diff --git a/src/main/core/Event/Tool/OpenToolEvent.php b/src/main/core/Event/Tool/OpenToolEvent.php
index 8e2adc0dbf3..54de45848f9 100644
--- a/src/main/core/Event/Tool/OpenToolEvent.php
+++ b/src/main/core/Event/Tool/OpenToolEvent.php
@@ -11,8 +11,8 @@
namespace Claroline\CoreBundle\Event\Tool;
+use Claroline\AppBundle\Component\Context\ContextSubjectInterface;
use Claroline\CoreBundle\Entity\User;
-use Claroline\CoreBundle\Entity\Workspace\Workspace;
use Symfony\Contracts\Translation\TranslatorInterface;
class OpenToolEvent extends AbstractToolEvent
@@ -23,10 +23,10 @@ class OpenToolEvent extends AbstractToolEvent
public function __construct(
string $toolName,
string $context,
- Workspace $workspace = null,
+ ContextSubjectInterface $contextSubject = null,
User $user = null
) {
- parent::__construct($toolName, $context, $workspace);
+ parent::__construct($toolName, $context, $contextSubject);
$this->user = $user;
}
diff --git a/src/main/core/Installation/ClarolineCoreInstaller.php b/src/main/core/Installation/ClarolineCoreInstaller.php
index 6cb202dafb3..58ab91c343c 100644
--- a/src/main/core/Installation/ClarolineCoreInstaller.php
+++ b/src/main/core/Installation/ClarolineCoreInstaller.php
@@ -13,6 +13,7 @@
use Claroline\CoreBundle\Installation\Updater\Updater140000;
use Claroline\CoreBundle\Installation\Updater\Updater140010;
+use Claroline\CoreBundle\Installation\Updater\Updater140100;
use Claroline\CoreBundle\Library\Configuration\PlatformConfigurationHandler;
use Claroline\CoreBundle\Library\Normalizer\DateNormalizer;
use Claroline\InstallationBundle\Additional\AdditionalInstaller;
@@ -24,15 +25,21 @@ public static function getUpdaters(): array
return [
'14.0.0' => Updater140000::class,
'14.0.10' => Updater140010::class,
+ '14.1.0' => Updater140100::class,
];
}
+ public function hasMigrations(): bool
+ {
+ return true;
+ }
+
public function hasFixtures(): bool
{
return true;
}
- public function postInstall()
+ public function postInstall(): void
{
parent::postInstall();
@@ -40,14 +47,14 @@ public function postInstall()
$this->setUpdateDate();
}
- public function postUpdate($currentVersion, $targetVersion)
+ public function postUpdate(string $currentVersion, string $targetVersion): void
{
parent::postUpdate($currentVersion, $targetVersion);
$this->setUpdateDate();
}
- public function end($currentVersion, $targetVersion)
+ public function end(string $currentVersion, string $targetVersion): void
{
$workspaceManager = $this->container->get('claroline.manager.workspace_manager');
@@ -56,7 +63,7 @@ public function end($currentVersion, $targetVersion)
$workspaceManager->getDefaultModel(true);
}
- private function setInstallationDate()
+ private function setInstallationDate(): void
{
/** @var PlatformConfigurationHandler $ch */
$ch = $this->container->get(PlatformConfigurationHandler::class);
@@ -64,7 +71,7 @@ private function setInstallationDate()
$ch->setParameter('meta.created', DateNormalizer::normalize(new \DateTime()));
}
- private function setUpdateDate()
+ private function setUpdateDate(): void
{
/** @var PlatformConfigurationHandler $ch */
$ch = $this->container->get(PlatformConfigurationHandler::class);
diff --git a/src/main/core/Installation/DataFixtures/PlatformRolesData.php b/src/main/core/Installation/DataFixtures/PlatformRolesData.php
index 804c70a20bd..5caed3efba8 100644
--- a/src/main/core/Installation/DataFixtures/PlatformRolesData.php
+++ b/src/main/core/Installation/DataFixtures/PlatformRolesData.php
@@ -11,7 +11,7 @@
namespace Claroline\CoreBundle\Installation\DataFixtures;
-use Claroline\CoreBundle\Entity\Tool\Tool;
+use Claroline\CoreBundle\Component\Context\DesktopContext;
use Claroline\CoreBundle\Manager\RoleManager;
use Claroline\CoreBundle\Manager\Tool\ToolManager;
use Claroline\CoreBundle\Security\PlatformRoles;
@@ -53,7 +53,7 @@ public function load(ObjectManager $manager)
$userRole = $this->roleManager->createBaseRole(PlatformRoles::USER, 'user', true, true);
// initialize some tools rights to let users open their desktop
foreach (['home', 'resources', 'workspaces'] as $tool) {
- $orderedTool = $this->toolManager->getOrderedTool($tool, Tool::DESKTOP);
+ $orderedTool = $this->toolManager->getOrderedTool($tool, DesktopContext::getName());
if ($orderedTool) {
$this->toolManager->setPermissions(['open' => true], $orderedTool, $userRole);
}
diff --git a/src/main/core/Installation/Migrations/Version20231110053448.php b/src/main/core/Installation/Migrations/Version20231110053448.php
new file mode 100644
index 00000000000..9acc70bfe26
--- /dev/null
+++ b/src/main/core/Installation/Migrations/Version20231110053448.php
@@ -0,0 +1,40 @@
+addSql('
+ ALTER TABLE claro_resource_evaluation CHANGE progression progression DOUBLE PRECISION NOT NULL
+ ');
+ $this->addSql('
+ ALTER TABLE claro_resource_user_evaluation CHANGE progression progression DOUBLE PRECISION NOT NULL
+ ');
+ $this->addSql('
+ ALTER TABLE claro_workspace_evaluation CHANGE progression progression DOUBLE PRECISION NOT NULL
+ ');
+ }
+
+ public function down(Schema $schema): void
+ {
+ $this->addSql('
+ ALTER TABLE claro_resource_evaluation CHANGE progression progression INT NOT NULL
+ ');
+ $this->addSql('
+ ALTER TABLE claro_resource_user_evaluation CHANGE progression progression INT NOT NULL
+ ');
+ $this->addSql('
+ ALTER TABLE claro_workspace_evaluation CHANGE progression progression INT NOT NULL
+ ');
+ }
+}
diff --git a/src/main/core/Installation/Migrations/Version20231110053450.php b/src/main/core/Installation/Migrations/Version20231110053450.php
new file mode 100644
index 00000000000..7ac8d5aeb75
--- /dev/null
+++ b/src/main/core/Installation/Migrations/Version20231110053450.php
@@ -0,0 +1,96 @@
+addSql('
+ ALTER TABLE claro_ordered_tool
+ ADD context_name VARCHAR(255) NOT NULL,
+ ADD context_id VARCHAR(255) DEFAULT NULL
+ ');
+
+ // migrate desktop tools
+ $this->addSql('
+ UPDATE claro_ordered_tool SET context_name = "desktop" WHERE workspace_id IS NULL
+ ');
+
+ // migrate workspace tools
+ $this->addSql('
+ UPDATE claro_ordered_tool AS t
+ LEFT JOIN claro_workspace AS w ON t.workspace_id = w.id
+ SET context_name = "workspace", context_id = w.uuid WHERE workspace_id IS NOT NULL
+ ');
+
+ $this->addSql('
+ ALTER TABLE claro_ordered_tool
+ DROP FOREIGN KEY FK_6CF1320E82D40A1F
+ ');
+ $this->addSql('
+ ALTER TABLE claro_ordered_tool
+ DROP FOREIGN KEY FK_6CF1320EA76ED395
+ ');
+ $this->addSql('
+ DROP INDEX ordered_tool_unique_tool_user_type ON claro_ordered_tool
+ ');
+ $this->addSql('
+ DROP INDEX ordered_tool_unique_tool_ws_type ON claro_ordered_tool
+ ');
+ $this->addSql('
+ DROP INDEX IDX_6CF1320E82D40A1F ON claro_ordered_tool
+ ');
+ $this->addSql('
+ DROP INDEX IDX_6CF1320EA76ED395 ON claro_ordered_tool
+ ');
+ $this->addSql('
+ ALTER TABLE claro_ordered_tool
+ DROP workspace_id,
+ DROP user_id
+ ');
+ }
+
+ public function down(Schema $schema): void
+ {
+ $this->addSql('
+ ALTER TABLE claro_ordered_tool
+ ADD workspace_id INT DEFAULT NULL,
+ ADD user_id INT DEFAULT NULL,
+ DROP context_name,
+ DROP context_id
+ ');
+ $this->addSql('
+ ALTER TABLE claro_ordered_tool
+ ADD CONSTRAINT FK_6CF1320E82D40A1F FOREIGN KEY (workspace_id)
+ REFERENCES claro_workspace (id) ON UPDATE NO ACTION
+ ON DELETE CASCADE
+ ');
+ $this->addSql('
+ ALTER TABLE claro_ordered_tool
+ ADD CONSTRAINT FK_6CF1320EA76ED395 FOREIGN KEY (user_id)
+ REFERENCES claro_user (id) ON UPDATE NO ACTION
+ ON DELETE CASCADE
+ ');
+ $this->addSql('
+ CREATE UNIQUE INDEX ordered_tool_unique_tool_user_type ON claro_ordered_tool (tool_id, user_id)
+ ');
+ $this->addSql('
+ CREATE UNIQUE INDEX ordered_tool_unique_tool_ws_type ON claro_ordered_tool (tool_id, workspace_id)
+ ');
+ $this->addSql('
+ CREATE INDEX IDX_6CF1320E82D40A1F ON claro_ordered_tool (workspace_id)
+ ');
+ $this->addSql('
+ CREATE INDEX IDX_6CF1320EA76ED395 ON claro_ordered_tool (user_id)
+ ');
+ }
+}
diff --git a/src/main/core/Installation/Migrations/Version20231116084035.php b/src/main/core/Installation/Migrations/Version20231116084035.php
new file mode 100644
index 00000000000..c8ad9cdf20c
--- /dev/null
+++ b/src/main/core/Installation/Migrations/Version20231116084035.php
@@ -0,0 +1,107 @@
+addSql('
+ ALTER TABLE claro_tool_mask_decoder
+ DROP FOREIGN KEY FK_323623448F7B22CC
+ ');
+ $this->addSql('
+ DROP INDEX IDX_323623448F7B22CC ON claro_tool_mask_decoder
+ ');
+ $this->addSql('
+ DROP INDEX tool_mask_decoder_unique_tool_and_name ON claro_tool_mask_decoder
+ ');
+ $this->addSql('
+ ALTER TABLE claro_tool_mask_decoder
+ ADD tool_name VARCHAR(255) NOT NULL
+ ');
+
+ $this->addSql('
+ UPDATE claro_tool_mask_decoder AS m
+ LEFT JOIN claro_tools AS t ON m.tool_id = t.id
+ SET m.tool_name = t.name
+ ');
+
+ /*$this->addSql('
+ ALTER TABLE claro_tool_mask_decoder
+ DROP tool_id
+ ');*/
+
+ $this->addSql('
+ CREATE UNIQUE INDEX tool_mask_decoder_unique_tool_and_name ON claro_tool_mask_decoder (tool_name, `name`)
+ ');
+ $this->addSql('
+ ALTER TABLE claro_ordered_tool
+ DROP FOREIGN KEY FK_6CF1320E8F7B22CC
+ ');
+ $this->addSql('
+ DROP INDEX IDX_6CF1320E8F7B22CC ON claro_ordered_tool
+ ');
+ $this->addSql('
+ ALTER TABLE claro_ordered_tool
+ ADD tool_name VARCHAR(255) NOT NULL
+ ');
+
+ $this->addSql('
+ UPDATE claro_ordered_tool AS ot
+ LEFT JOIN claro_tools AS t ON ot.tool_id = t.id
+ SET ot.tool_name = t.name
+ ');
+
+ /*$this->addSql('
+ ALTER TABLE claro_ordered_tool
+ DROP tool_id
+ ');*/
+ }
+
+ public function down(Schema $schema): void
+ {
+ $this->addSql('
+ ALTER TABLE claro_ordered_tool
+ ADD tool_id INT NOT NULL,
+ DROP tool_name
+ ');
+ $this->addSql('
+ ALTER TABLE claro_ordered_tool
+ ADD CONSTRAINT FK_6CF1320E8F7B22CC FOREIGN KEY (tool_id)
+ REFERENCES claro_tools (id) ON UPDATE NO ACTION
+ ON DELETE CASCADE
+ ');
+ $this->addSql('
+ CREATE INDEX IDX_6CF1320E8F7B22CC ON claro_ordered_tool (tool_id)
+ ');
+ $this->addSql('
+ DROP INDEX tool_mask_decoder_unique_tool_and_name ON claro_tool_mask_decoder
+ ');
+ $this->addSql('
+ ALTER TABLE claro_tool_mask_decoder
+ ADD tool_id INT NOT NULL,
+ DROP tool_name
+ ');
+ $this->addSql('
+ ALTER TABLE claro_tool_mask_decoder
+ ADD CONSTRAINT FK_323623448F7B22CC FOREIGN KEY (tool_id)
+ REFERENCES claro_tools (id) ON UPDATE NO ACTION
+ ON DELETE CASCADE
+ ');
+ $this->addSql('
+ CREATE INDEX IDX_323623448F7B22CC ON claro_tool_mask_decoder (tool_id)
+ ');
+ $this->addSql('
+ CREATE UNIQUE INDEX tool_mask_decoder_unique_tool_and_name ON claro_tool_mask_decoder (tool_id, name)
+ ');
+ }
+}
diff --git a/src/main/core/Installation/Updater/Updater140000.php b/src/main/core/Installation/Updater/Updater140000.php
index c32c9052b6c..f4c78057401 100644
--- a/src/main/core/Installation/Updater/Updater140000.php
+++ b/src/main/core/Installation/Updater/Updater140000.php
@@ -20,7 +20,7 @@ public function __construct(
$this->connection = $connection;
}
- public function preUpdate()
+ public function preUpdate(): void
{
// Adds migration FQCN in the versions tables (required by new doctrine migrations version)
$this->renameMigrations();
@@ -28,7 +28,7 @@ public function preUpdate()
// the namespace of the migrations has changed (eg. removed the `pdo_mysql` part)
// Doctrine will try to re-execute migrations because of the renaming
// we need to update the version classnames in the DB to avoid breaking updates
- $this->log('Updating doctrine migration versions...');
+ $this->logger->info('Updating doctrine migration versions...');
// retrieve all doctrine versions tables
$stmt = $this->connection->prepare('
SHOW TABLES LIKE "doctrine_%_versions"
@@ -38,7 +38,7 @@ public function preUpdate()
$tables = $results->fetchFirstColumn();
foreach ($tables as $table) {
- $this->log(sprintf('Updating doctrine migration versions %s...', $table));
+ $this->logger->info(sprintf('Updating doctrine migration versions %s...', $table));
// update last version execution
$versionsQuery = $this->connection->prepare("
diff --git a/src/main/core/Installation/Updater/Updater140010.php b/src/main/core/Installation/Updater/Updater140010.php
index 9e8c1c69f84..c26d9b06c48 100644
--- a/src/main/core/Installation/Updater/Updater140010.php
+++ b/src/main/core/Installation/Updater/Updater140010.php
@@ -15,7 +15,7 @@ public function __construct(
$this->connection = $connection;
}
- public function postUpdate()
+ public function postUpdate(): void
{
$updateUsers = $this->connection->prepare("
UPDATE claro_user AS u SET u.mail = CONCAT('email', CONCAT(u.id, '@deleted.com')) WHERE u.is_removed = true
diff --git a/src/main/core/Installation/Updater/Updater140100.php b/src/main/core/Installation/Updater/Updater140100.php
new file mode 100644
index 00000000000..6cd90451116
--- /dev/null
+++ b/src/main/core/Installation/Updater/Updater140100.php
@@ -0,0 +1,50 @@
+createAccountTools();
+ // create home tools
+ // migrate old home config
+ }
+
+ private function createAccountTools(): void
+ {
+ // static list to preserve original order
+ $tools = [
+ 'profile',
+ 'parameters',
+ 'privacy',
+ 'authentication',
+ 'badges',
+ 'notifications',
+ 'logs',
+ ];
+
+ foreach ($tools as $index => $tool) {
+ $orderedTool = new OrderedTool();
+ $orderedTool->setContextName(AccountContext::getName());
+ $orderedTool->setOrder($index);
+ $orderedTool->setName($tool);
+
+ $this->om->persist($orderedTool);
+ }
+
+ $this->om->flush();
+ }
+}
diff --git a/src/main/core/Library/Installation/Plugin/DatabaseWriter.php b/src/main/core/Library/Installation/Plugin/DatabaseWriter.php
index 141a65ed86a..43cbfce1c56 100644
--- a/src/main/core/Library/Installation/Plugin/DatabaseWriter.php
+++ b/src/main/core/Library/Installation/Plugin/DatabaseWriter.php
@@ -11,7 +11,6 @@
namespace Claroline\CoreBundle\Library\Installation\Plugin;
-use Claroline\AppBundle\Log\LoggableTrait;
use Claroline\AppBundle\Persistence\ObjectManager;
use Claroline\CoreBundle\Entity\DataSource;
use Claroline\CoreBundle\Entity\Plugin;
@@ -23,14 +22,13 @@
use Claroline\CoreBundle\Entity\Tool\Tool;
use Claroline\CoreBundle\Entity\Widget\Widget;
use Claroline\CoreBundle\Manager\Resource\MaskManager;
-use Claroline\CoreBundle\Manager\Tool\ToolManager;
use Claroline\CoreBundle\Manager\Tool\ToolMaskDecoderManager;
use Claroline\CoreBundle\Repository\PluginRepository;
use Claroline\KernelBundle\Bundle\PluginBundleInterface;
use Claroline\ThemeBundle\Entity\Theme;
use Claroline\ThemeBundle\Manager\IconSetBuilderManager;
use Psr\Log\LoggerAwareInterface;
-use Psr\Log\LogLevel;
+use Psr\Log\LoggerAwareTrait;
use Symfony\Component\Filesystem\Filesystem;
/**
@@ -41,39 +39,17 @@
*/
class DatabaseWriter implements LoggerAwareInterface
{
- use LoggableTrait;
-
- /** @var ObjectManager */
- private $em;
- /** @var MaskManager */
- private $mm;
- /** @var Filesystem */
- private $fileSystem;
- /** @var ToolManager */
- private $toolManager;
- /** @var ToolMaskDecoderManager */
- private $toolMaskManager;
- /** @var IconSetBuilderManager */
- private $iconSetManager;
-
- /** @var PluginRepository */
- private $pluginRepository;
+ use LoggerAwareTrait;
+
+ private PluginRepository $pluginRepository;
public function __construct(
- ObjectManager $em,
- MaskManager $mm,
- Filesystem $fileSystem,
- ToolManager $toolManager,
- ToolMaskDecoderManager $toolMaskManager,
- IconSetBuilderManager $iconSetManager
+ private readonly ObjectManager $em,
+ private readonly MaskManager $mm,
+ private readonly Filesystem $fileSystem,
+ private readonly ToolMaskDecoderManager $toolMaskManager,
+ private readonly IconSetBuilderManager $iconSetManager
) {
- $this->em = $em;
- $this->mm = $mm;
- $this->fileSystem = $fileSystem;
- $this->toolManager = $toolManager;
- $this->toolMaskManager = $toolMaskManager;
- $this->iconSetManager = $iconSetManager;
-
$this->pluginRepository = $this->em->getRepository(Plugin::class);
}
@@ -106,13 +82,13 @@ public function update(PluginBundleInterface $pluginBundle, array $pluginConfigu
]);
if (null === $plugin) {
- $this->log('Unable to retrieve plugin for updating its configuration.', LogLevel::ERROR);
+ $this->logger->error('Unable to retrieve plugin for updating its configuration.');
return null;
}
$this->em->persist($plugin);
- $this->log('Configuration was retrieved: updating...');
+ $this->logger->info('Configuration was retrieved: updating...');
$this->updateConfiguration($pluginConfiguration, $plugin, $pluginBundle);
@@ -226,7 +202,7 @@ private function updateConfiguration(array $processedConfiguration, Plugin $plug
});
foreach ($widgetsToDelete as $widget) {
- $this->log('Removing widget '.$widget->getName());
+ $this->logger->info('Removing widget '.$widget->getName());
$this->em->remove($widget);
}
@@ -242,7 +218,7 @@ private function updateConfiguration(array $processedConfiguration, Plugin $plug
});
foreach ($sourcesToDelete as $source) {
- $this->log('Removing data source '.$source->getName());
+ $this->logger->info('Removing data source '.$source->getName());
$this->em->remove($source);
}
@@ -260,7 +236,7 @@ private function updateConfiguration(array $processedConfiguration, Plugin $plug
});
foreach ($toRemove as $tool) {
- $this->log('Removing tool '.$tool->getName());
+ $this->logger->info('Removing tool '.$tool->getName());
$this->em->remove($tool);
}
@@ -281,7 +257,7 @@ private function updateConfiguration(array $processedConfiguration, Plugin $plug
private function updateResourceType(array $resourceConfiguration, Plugin $plugin, PluginBundleInterface $pluginBundle): ResourceType
{
- $this->log(sprintf('Updating the resource type : "%s".', $resourceConfiguration['name']));
+ $this->logger->info(sprintf('Updating the resource type : "%s".', $resourceConfiguration['name']));
$resourceType = $this->em->getRepository(ResourceType::class)
->findOneBy(['name' => $resourceConfiguration['name']]);
@@ -323,7 +299,7 @@ private function updateResourceType(array $resourceConfiguration, Plugin $plugin
foreach ($toRemove as $el) {
$mask = $this->em->getRepository(MaskDecoder::class)->findOneBy(['resourceType' => $resourceType, 'name' => $el]);
- $this->log('Remove mask decoder '.$el, LogLevel::ERROR);
+ $this->logger->info('Remove mask decoder '.$el);
$this->em->remove($mask);
}
@@ -371,7 +347,7 @@ public function persistResourceAction(array $action, Plugin $plugin): void
->findOneBy(['name' => $action['resource_type']]);
}
- $this->log(sprintf('Updating resource action : "%s".', $action['name']));
+ $this->logger->info(sprintf('Updating resource action : "%s".', $action['name']));
// initializes the mask decoder if needed
$this->mm->createDecoder($action['decoder'], $resourceType);
@@ -405,7 +381,7 @@ public function updateResourceAction(array $action, Plugin $plugin): void
private function persistResourceType(array $resourceConfiguration, Plugin $plugin, PluginBundleInterface $pluginBundle): ResourceType
{
- $this->log('Adding resource type '.$resourceConfiguration['name']);
+ $this->logger->info('Adding resource type '.$resourceConfiguration['name']);
$resourceType = new ResourceType();
$resourceType->setName($resourceConfiguration['name']);
$resourceType->setClass($resourceConfiguration['class']);
@@ -507,7 +483,7 @@ private function updateDataSource($sourceConfiguration, Plugin $plugin): DataSou
private function persistTool(array $toolConfiguration, Plugin $plugin, Tool $tool): void
{
- $this->log(sprintf('Updating the tool : "%s".', $toolConfiguration['name']));
+ $this->logger->info(sprintf('Updating the tool : "%s".', $toolConfiguration['name']));
$tool->setName($toolConfiguration['name']);
$tool->setPlugin($plugin);
@@ -520,8 +496,10 @@ private function persistTool(array $toolConfiguration, Plugin $plugin, Tool $too
$tool->setClass('tools');
}
- $this->toolManager->setLogger($this->logger);
- $this->toolManager->create($tool);
+ $this->em->persist($tool);
+
+ $this->toolMaskManager->createDefaultToolMaskDecoders($tool->getName());
+
$this->persistCustomToolRights($toolConfiguration['tool_rights'], $tool);
}
@@ -558,7 +536,7 @@ private function createAdminTool(array $adminToolConfiguration, Plugin $plugin):
private function persistAdminTool(array $adminToolConfiguration, Plugin $plugin, AdminTool $adminTool): void
{
- $this->log(sprintf('Update the administration tool : "%s".', $adminToolConfiguration['name']));
+ $this->logger->info(sprintf('Update the administration tool : "%s".', $adminToolConfiguration['name']));
$adminTool->setName($adminToolConfiguration['name']);
$adminTool->setClass($adminToolConfiguration['class']);
@@ -581,17 +559,17 @@ private function updateAdminTool(array $adminToolConfiguration, Plugin $plugin):
private function persistCustomToolRights(array $rights, Tool $tool): void
{
- $decoders = $this->toolMaskManager->getMaskDecodersByTool($tool);
+ $decoders = $this->toolMaskManager->getMaskDecodersByTool($tool->getName());
$nb = count($decoders);
foreach ($rights as $right) {
$maskDecoder = $this->toolMaskManager
- ->getMaskDecoderByToolAndName($tool, $right['name']);
+ ->getMaskDecoderByToolAndName($tool->getName(), $right['name']);
if (is_null($maskDecoder)) {
$value = pow(2, $nb);
$this->toolMaskManager->createToolMaskDecoder(
- $tool,
+ $tool->getName(),
$right['name'],
$value
);
diff --git a/src/main/core/Library/Installation/Plugin/Installer.php b/src/main/core/Library/Installation/Plugin/Installer.php
deleted file mode 100644
index 62ee34ab281..00000000000
--- a/src/main/core/Library/Installation/Plugin/Installer.php
+++ /dev/null
@@ -1,138 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Claroline\CoreBundle\Library\Installation\Plugin;
-
-use Claroline\AppBundle\Log\LoggableTrait;
-use Claroline\AppBundle\Persistence\ObjectManager;
-use Claroline\CoreBundle\Manager\PluginManager;
-use Claroline\CoreBundle\Manager\VersionManager;
-use Claroline\InstallationBundle\Manager\InstallationManager;
-use Claroline\KernelBundle\Bundle\PluginBundleInterface;
-use Psr\Log\LoggerAwareInterface;
-
-/**
- * This class is used to perform the (un-)installation of a plugin.
- */
-class Installer implements LoggerAwareInterface
-{
- use LoggableTrait;
-
- /** @var Validator */
- private $validator;
- /** @var Recorder */
- private $recorder;
- /** @var InstallationManager */
- private $baseInstaller;
- /** @var ObjectManager */
- private $om;
- /** @var VersionManager */
- private $versionManager;
- /** @var PluginManager */
- private $pluginManager;
-
- public function __construct(
- Validator $validator,
- Recorder $recorder,
- InstallationManager $installer,
- ObjectManager $om,
- PluginManager $pluginManager,
- VersionManager $versionManager
- ) {
- $this->validator = $validator;
- $this->recorder = $recorder;
- $this->baseInstaller = $installer;
- $this->om = $om;
- $this->pluginManager = $pluginManager;
- $this->versionManager = $versionManager;
- }
-
- /**
- * Installs a plugin.
- *
- * @throws \Exception if the plugin doesn't pass the validation
- */
- public function install(PluginBundleInterface $plugin)
- {
- $this->baseInstaller->install($plugin);
-
- $pluginEntity = $this->pluginManager->getPluginByShortName(
- $plugin->getName()
- );
-
- if (!$this->pluginManager->isReady($pluginEntity)) {
- $errors = $this->pluginManager->getMissingRequirements($pluginEntity);
-
- foreach ($errors['extensions'] as $extension) {
- $this->log(sprintf('Extension %s missing for %s !', $extension, $plugin->getName()));
- }
-
- foreach ($errors['plugins'] as $bundle) {
- $this->log(sprintf('The plugin %s is required for %s ! You must enable it first to use %s.', $bundle, $plugin->getName(), $plugin->getName()));
- }
-
- foreach ($errors['extras'] as $extra) {
- $this->log(sprintf('The plugin %s has extra requirements ! %s.', $plugin->getName(), $extra));
- }
-
- $this->log(sprintf('Disabling %s...', $plugin->getName()));
- $this->pluginManager->disable($pluginEntity);
- }
-
- $version = $this->versionManager->register($plugin);
- $this->versionManager->execute($version);
- }
-
- /**
- * Uninstalls a plugin.
- */
- public function uninstall(PluginBundleInterface $plugin)
- {
- $this->checkInstallationStatus($plugin, true);
-
- $this->log('Removing plugin configuration...');
- $this->recorder->unregister($plugin);
- $this->baseInstaller->uninstall($plugin);
- }
-
- /**
- * Upgrades/downgrades a plugin to a specific version.
- *
- * @param string $currentVersion
- * @param string $targetVersion
- */
- public function update(PluginBundleInterface $plugin, $currentVersion, $targetVersion)
- {
- $this->checkInstallationStatus($plugin, true);
-
- $this->baseInstaller->update($plugin, $currentVersion, $targetVersion);
-
- // updates plugin version
- $version = $this->versionManager->register($plugin);
- $this->versionManager->execute($version);
- }
-
- public function end(PluginBundleInterface $plugin, $currentVersion = null, $targetVersion = null)
- {
- $this->baseInstaller->end($plugin, $currentVersion, $targetVersion);
- }
-
- private function checkInstallationStatus(PluginBundleInterface $plugin, $shouldBeInstalled = true): void
- {
- $this->log(sprintf('Checking installation status for plugin %s', $plugin->getName()));
-
- if ($this->recorder->isRegistered($plugin) !== $shouldBeInstalled) {
- $stateDiscr = $shouldBeInstalled ? 'not' : 'already';
-
- throw new \LogicException("Plugin '{$plugin->getName()}' is {$stateDiscr} installed.");
- }
- }
-}
diff --git a/src/main/core/Library/Testing/RepositoryTestCase.php b/src/main/core/Library/Testing/RepositoryTestCase.php
index 5fdd4b122f4..1e6de79ff1b 100644
--- a/src/main/core/Library/Testing/RepositoryTestCase.php
+++ b/src/main/core/Library/Testing/RepositoryTestCase.php
@@ -11,7 +11,6 @@
namespace Claroline\CoreBundle\Library\Testing;
-use Claroline\CoreBundle\Entity\Log\Log;
use Claroline\CoreBundle\Entity\Plugin;
use Claroline\CoreBundle\Entity\Resource\AbstractResource;
use Claroline\CoreBundle\Entity\Resource\Directory;
@@ -19,16 +18,11 @@
use Claroline\CoreBundle\Entity\Resource\ResourceNode;
use Claroline\CoreBundle\Entity\Resource\ResourceRights;
use Claroline\CoreBundle\Entity\Resource\ResourceType;
-use Claroline\CoreBundle\Entity\Resource\Revision;
-use Claroline\CoreBundle\Entity\Resource\Text;
use Claroline\CoreBundle\Entity\Role;
use Claroline\CoreBundle\Entity\Tool\OrderedTool;
-use Claroline\CoreBundle\Entity\Tool\Tool;
use Claroline\CoreBundle\Entity\Tool\ToolRights;
use Claroline\CoreBundle\Entity\User;
use Claroline\CoreBundle\Entity\Workspace\Workspace;
-use Claroline\MessageBundle\Entity\Message;
-use Claroline\MessageBundle\Entity\UserMessage;
use Gedmo\Timestampable\TimestampableListener;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
@@ -61,8 +55,8 @@ public static function setUpBeforeClass(): void
public function tearDown(): void
{
- //we don't want to tear down between each tests because we lose the container otherwise
- //and can't shut down everything properly afterwards
+ // we don't want to tear down between each tests because we lose the container otherwise
+ // and can't shut down everything properly afterwards
}
public static function tearDownAfterClass(): void
@@ -123,12 +117,12 @@ protected static function getTime($format = 'Y-m-d H:i:s')
*
* @param int $seconds
*/
- protected static function sleep($seconds)
+ protected static function sleep($seconds): void
{
self::$time->add(new \DateInterval("PT{$seconds}S"));
}
- protected static function createUser($name, array $roles = [], Workspace $personalWorkspace = null)
+ protected static function createUser($name, array $roles = [], Workspace $personalWorkspace = null): void
{
$user = self::$persister->user($name);
@@ -143,7 +137,7 @@ protected static function createUser($name, array $roles = [], Workspace $person
self::create($name, $user);
}
- protected static function createGroup($name, array $users = [], array $roles = [])
+ protected static function createGroup($name, array $users = [], array $roles = []): void
{
$group = self::$persister->group($name);
@@ -158,7 +152,7 @@ protected static function createGroup($name, array $users = [], array $roles = [
self::create($name, $group);
}
- protected static function createRole($name, Workspace $workspace = null)
+ protected static function createRole($name, Workspace $workspace = null): void
{
$role = new Role();
$role->setName($name);
@@ -178,7 +172,7 @@ protected static function createRole($name, Workspace $workspace = null)
}
}
- protected static function createWorkspace($name)
+ protected static function createWorkspace($name): void
{
$workspace = new Workspace();
$workspace->setName($name);
@@ -188,7 +182,7 @@ protected static function createWorkspace($name)
self::create($name, $workspace);
}
- protected static function createDisplayableWorkspace($name, $selfRegistration)
+ protected static function createDisplayableWorkspace($name, $selfRegistration): void
{
$workspace = new Workspace();
$workspace->setName($name);
@@ -199,7 +193,7 @@ protected static function createDisplayableWorkspace($name, $selfRegistration)
self::create($name, $workspace);
}
- protected static function createResourceType($name, $class, $isExportable = true, Plugin $plugin = null)
+ protected static function createResourceType($name, $class, $isExportable = true, Plugin $plugin = null): void
{
$type = new ResourceType();
$type->setName($name);
@@ -219,7 +213,7 @@ protected static function createDirectory(
User $creator,
Workspace $workspace,
Directory $parent = null
- ) {
+ ): void {
if ($parent) {
$parent = $parent->getResourceNode();
}
@@ -236,7 +230,7 @@ protected static function createDirectory(
self::create($name, $directory);
}
- protected static function createFile($name, ResourceType $type, User $creator, Directory $parent)
+ protected static function createFile($name, ResourceType $type, User $creator, Directory $parent): void
{
$file = self::prepareResource(
new File(),
@@ -252,37 +246,12 @@ protected static function createFile($name, ResourceType $type, User $creator, D
self::create($name, $file);
}
- protected static function createText(
- $name,
- $revisionNumber,
- ResourceType $type,
- User $creator,
- Directory $parent
- ) {
- $text = self::prepareResource(
- new Text(),
- $type,
- $creator,
- $parent->getResourceNode()->getWorkspace(),
- $name,
- 'text/mime',
- $parent->getResourceNode()
- );
- self::create($name, $text);
-
- $revision = new Revision();
- $revision->setVersion($revisionNumber);
- $revision->setContent($name.'Content');
- $revision->setText($text);
- self::create("revision/{$text->getName()}-{$revisionNumber}", $revision);
- }
-
protected static function createResourceRights(
Role $role,
AbstractResource $resource,
$mask,
array $creatableResourceTypes = []
- ) {
+ ): void {
$rights = new ResourceRights();
$rights->setRole($role);
$rights->setResourceNode($resource->getResourceNode());
@@ -295,23 +264,16 @@ protected static function createResourceRights(
self::create("resource_right/{$role->getName()}-{$resource->getResourceNode()->getName()}", $rights);
}
- protected static function createTool($name)
- {
- $tool = new Tool();
- $tool->setName($name);
- $tool->setClass($name.'Class');
- self::create($name, $tool);
- }
-
protected static function createWorkspaceTool(
- Tool $tool,
+ string $toolName,
Workspace $workspace,
array $roles,
$position
- ) {
+ ): void {
$orderedTool = new OrderedTool();
- $orderedTool->setTool($tool);
- $orderedTool->setWorkspace($workspace);
+ $orderedTool->setName($toolName);
+ $orderedTool->setContextName('workspace');
+ $orderedTool->setContextId($workspace->getUuid());
$orderedTool->setOrder($position);
foreach ($roles as $role) {
@@ -322,23 +284,10 @@ protected static function createWorkspaceTool(
self::$om->persist($rights);
}
- self::create("orderedTool/{$workspace->getName()}-{$tool->getName()}", $orderedTool);
- }
-
- protected static function createDesktopTool(
- Tool $tool,
- User $user,
- $position
- ) {
- $orderedTool = new OrderedTool();
- $orderedTool->setTool($tool);
- $orderedTool->setUser($user);
- $orderedTool->setOrder($position);
-
- self::create("orderedTool/{$user->getUsername()}-{$tool->getName()}", $orderedTool);
+ self::create("orderedTool/{$workspace->getName()}-{$toolName}", $orderedTool);
}
- protected static function createPlugin($vendor, $bundle)
+ protected static function createPlugin($vendor, $bundle): void
{
$plugin = new Plugin();
$plugin->setVendorName($vendor);
@@ -346,63 +295,8 @@ protected static function createPlugin($vendor, $bundle)
self::create($vendor.$bundle, $plugin);
}
- protected static function createLog(User $doer, $action, Workspace $workspace = null)
- {
- $log = new Log();
- $log->setDoer($doer);
- $log->setAction($action);
- $log->setDoerType(Log::DOER_USER);
- $log->setDateLog(self::$time);
-
- if ($workspace) {
- $log->setWorkspace($workspace);
- }
-
- self::$om->persist($log);
- self::$om->flush();
- }
-
- protected static function createMessage(
- $alias,
- User $sender,
- array $receivers,
- $object,
- $content,
- Message $parent = null,
- $removed = false
- ) {
- $message = new Message();
- $message->setSender($sender);
- $message->setObject($object);
- $message->setContent($content);
- $message->setDate(self::$time);
- $message->setTo('x1;x2;x3');
- if ($parent) {
- $message->setParent($parent);
- }
- self::$om->startFlushSuite();
- self::create($alias, $message);
- $userMessage = new UserMessage();
- $userMessage->setIsSent(true);
- $userMessage->setUser($sender);
- $userMessage->setMessage($message);
- if ($removed) {
- $userMessage->setRemoved($removed);
- }
- self::create($alias.'/'.$sender->getUsername(), $userMessage);
- foreach ($receivers as $receiver) {
- $userMessage = new UserMessage();
- $userMessage->setUser($receiver);
- $userMessage->setMessage($message);
- self::create($alias.'/'.$receiver->getUsername(), $userMessage);
- }
- self::$om->endFlushSuite();
- }
-
/**
* Sets the common properties of a resource.
- *
- * @return AbstractResource
*/
private static function prepareResource(
AbstractResource $resource,
@@ -412,7 +306,7 @@ private static function prepareResource(
$name,
$mimeType,
$parent = null
- ) {
+ ): AbstractResource {
$node = new ResourceNode();
$node->setResourceType($type);
$node->setCreator($creator);
@@ -437,9 +331,9 @@ private static function prepareResource(
/**
* Disables the timestamp listener so that fixture methods are forced to set
- * dates explicitely.
+ * dates explicitly.
*/
- private static function disableTimestampableListener()
+ private static function disableTimestampableListener(): void
{
$eventManager = self::$om->getEventManager();
@@ -460,7 +354,7 @@ private static function disableTimestampableListener()
*
* @throws \InvalidArgumentException if the reference is already set
*/
- private static function set($reference, $entity)
+ private static function set($reference, $entity): void
{
if (isset(self::$references[$reference])) {
throw new \InvalidArgumentException("Fixture reference '{$reference}' is already set");
@@ -475,7 +369,7 @@ private static function set($reference, $entity)
* @param string $reference
* @param object $entity
*/
- private static function create($reference, $entity)
+ private static function create($reference, $entity): void
{
self::$om->persist($entity);
self::$om->flush();
diff --git a/src/main/core/Manager/Tool/ToolManager.php b/src/main/core/Manager/Tool/ToolManager.php
index 96ebfeef282..270d3936b45 100644
--- a/src/main/core/Manager/Tool/ToolManager.php
+++ b/src/main/core/Manager/Tool/ToolManager.php
@@ -13,8 +13,8 @@
use Claroline\AppBundle\Log\LoggableTrait;
use Claroline\AppBundle\Persistence\ObjectManager;
+use Claroline\CoreBundle\Component\Context\DesktopContext;
use Claroline\CoreBundle\Entity\Role;
-use Claroline\CoreBundle\Entity\Tool\AbstractTool;
use Claroline\CoreBundle\Entity\Tool\AdminTool;
use Claroline\CoreBundle\Entity\Tool\OrderedTool;
use Claroline\CoreBundle\Entity\Tool\Tool;
@@ -33,96 +33,36 @@ class ToolManager implements LoggerAwareInterface
// todo adds a config in tools to avoid this
public const WORKSPACE_MODEL_TOOLS = ['home', 'resources', 'community', 'badges'];
- /** @var AuthorizationCheckerInterface */
- private $authorization;
- /** @var ObjectManager */
- private $om;
- /** @var ToolMaskDecoderManager */
- private $toolMaskManager;
- /** @var ToolRightsManager */
- private $toolRightsManager;
-
- /** @var OrderedToolRepository */
- private $orderedToolRepo;
- /** @var ToolRepository */
- private $toolRepo;
- /** @var AdministrationToolRepository */
- private $adminToolRepo;
+ private OrderedToolRepository $orderedToolRepo;
+ private ToolRepository $toolRepo;
+ private AdministrationToolRepository $adminToolRepo;
public function __construct(
- AuthorizationCheckerInterface $authorization,
- ObjectManager $om,
- ToolMaskDecoderManager $toolMaskManager,
- ToolRightsManager $toolRightsManager
+ private readonly AuthorizationCheckerInterface $authorization,
+ private readonly ObjectManager $om,
+ private readonly ToolMaskDecoderManager $toolMaskManager,
+ private readonly ToolRightsManager $toolRightsManager
) {
- $this->authorization = $authorization;
- $this->om = $om;
- $this->toolMaskManager = $toolMaskManager;
- $this->toolRightsManager = $toolRightsManager;
-
$this->orderedToolRepo = $om->getRepository(OrderedTool::class);
$this->toolRepo = $om->getRepository(Tool::class);
$this->adminToolRepo = $om->getRepository(AdminTool::class);
}
- public function create(Tool $tool): void
+ /**
+ * @deprecated
+ */
+ public function create(string $toolName): void
{
- $this->om->startFlushSuite();
- $this->om->persist($tool);
- $this->om->forceFlush();
- $this->toolMaskManager->createDefaultToolMaskDecoders($tool);
- $this->om->endFlushSuite();
-
- if ($tool->isDisplayableInWorkspace()) {
- // check if there are already workspace tools, if not we add them
- $ot = $this->om->getRepository(OrderedTool::class)->findBy(['tool' => $tool], [], 1, 0);
- if (0 === count($ot)) {
- $offset = 0;
- $totalTools = $this->om->count(Tool::class);
- $total = $this->om->count(Workspace::class);
- $this->log('Adding tool '.$tool->getName().' to workspaces ('.$total.')');
-
- $this->om->startFlushSuite();
-
- while ($offset < $total) {
- /** @var Workspace $workspaces */
- $workspaces = $this->om->getRepository(Workspace::class)->findBy([], [], 500, $offset);
-
- foreach ($workspaces as $workspace) {
- $this->setWorkspaceTool($tool, $totalTools, $workspace);
- ++$offset;
- $this->log('Adding tool '.$offset.'/'.$total);
- }
-
- $this->log('Flush');
- $this->om->forceFlush();
- }
-
- $this->om->endFlushSuite();
- }
- }
-
- if ($tool->isDisplayableInDesktop()) {
- // check if there is already desktop tool, if not we add it
- $ot = $this->om->getRepository(OrderedTool::class)->findBy(['tool' => $tool, 'workspace' => null, 'user' => null], [], 1, 0);
- if (0 === count($ot)) {
- $desktopTools = $this->om->getRepository(OrderedTool::class)->findBy(['workspace' => null, 'user' => null]);
-
- $orderedTool = new OrderedTool();
- $orderedTool->setWorkspace(null);
- $orderedTool->setUser(null);
- $orderedTool->setTool($tool);
- $orderedTool->setOrder(count($desktopTools) + 1);
-
- $this->om->persist($orderedTool);
- $this->om->flush();
- }
- }
+ //$this->om->startFlushSuite();
+ //$this->om->persist($tool);
+ //$this->om->forceFlush();
+ $this->toolMaskManager->createDefaultToolMaskDecoders($toolName);
+ //$this->om->endFlushSuite();
}
public function getCurrentPermissions(OrderedTool $orderedTool): array
{
- $decoders = $this->toolMaskManager->getMaskDecodersByTool($orderedTool->getTool());
+ $decoders = $this->toolMaskManager->getMaskDecodersByTool($orderedTool->getName());
// certainly not the optimal way to generate it, but it avoids to replicate logic from OrderedToolVoter
$perms = [];
@@ -142,7 +82,7 @@ public function getPermissions(OrderedTool $orderedTool, Role $role): array
$mask = 0 < count($toolRights) ? $toolRights[0]->getMask() : 0;
- return $this->toolMaskManager->decodeMask($mask, $orderedTool->getTool());
+ return $this->toolMaskManager->decodeMask($mask, $orderedTool->getName());
}
/**
@@ -150,89 +90,21 @@ public function getPermissions(OrderedTool $orderedTool, Role $role): array
*/
public function setPermissions(array $perms, OrderedTool $orderedTool, Role $role): void
{
- $mask = $this->toolMaskManager->encodeMask($perms, $orderedTool->getTool());
+ $mask = $this->toolMaskManager->encodeMask($perms, $orderedTool->getName());
$this->toolRightsManager->setToolRights($orderedTool, $role, $mask);
}
public function getOrderedTool(string $name, string $context, string $contextId = null): ?OrderedTool
{
- /** @var OrderedTool|null $orderedTool */
- $orderedTool = null;
- switch ($context) {
- case AbstractTool::DESKTOP:
- $orderedTool = $this->orderedToolRepo->findOneByNameAndDesktop($name);
-
- break;
- case AbstractTool::WORKSPACE:
- $contextObject = $this->om->getRepository(Workspace::class)->findOneBy(['uuid' => $contextId]);
- $orderedTool = $this->orderedToolRepo->findOneByNameAndWorkspace($name, $contextObject);
-
- break;
- case AbstractTool::ADMINISTRATION:
- // implement later
- break;
- }
-
- return $orderedTool;
+ return $this->orderedToolRepo->findOneByNameAndContext($name, $context, $contextId);
}
/**
* @return OrderedTool[]
*/
- public function getOrderedTools(string $context, string $contextId = null): array
+ public function getOrderedTools(string $context, string $contextId = null, ?array $roles = []): array
{
- $tools = [];
-
- switch ($context) {
- case AbstractTool::DESKTOP:
- return $this->orderedToolRepo->findByDesktop();
-
- case AbstractTool::WORKSPACE:
- $contextObject = $this->om->getRepository(Workspace::class)->findOneBy(['slug' => $contextId]);
-
- return $this->orderedToolRepo->findByWorkspace($contextObject);
-
- case AbstractTool::ADMINISTRATION:
- // TODO : implement later
- break;
- }
-
- return $tools;
- }
-
- /**
- * @return OrderedTool[]
- *
- * @deprecated
- */
- public function getOrderedToolsByDesktop(array $roles = []): array
- {
- if (empty($roles) || in_array('ROLE_ADMIN', $roles)) {
- return $this->orderedToolRepo->findByDesktop();
- }
-
- return $this->orderedToolRepo->findByDesktopAndRoles($roles);
- }
-
- /**
- * @return OrderedTool[]
- *
- * @deprecated
- */
- public function getOrderedToolsByWorkspace(Workspace $workspace, array $roles = []): array
- {
- if (empty($roles)) {
- $tools = $this->orderedToolRepo->findByWorkspace($workspace);
- } else {
- $tools = $this->orderedToolRepo->findByWorkspaceAndRoles($workspace, $roles);
- }
-
- return $tools;
- }
-
- public function getAdminToolByName(string $name): ?AdminTool
- {
- return $this->adminToolRepo->findOneBy(['name' => $name]);
+ return $this->orderedToolRepo->findByContext($context, $contextId, $roles);
}
/**
@@ -245,52 +117,11 @@ public function getAdminToolsByRoles(array $roles)
return $this->adminToolRepo->findByRoles($roles);
}
- public function getToolByName(string $name): ?Tool
- {
- return $this->toolRepo->findOneBy(['name' => $name]);
- }
-
- /**
- * Adds the tools missing in the database for a workspace.
- */
- public function addMissingWorkspaceTools(Workspace $workspace): void
- {
- $undisplayedTools = $this->toolRepo->findUndisplayedToolsByWorkspace($workspace);
- if (0 === count($undisplayedTools)) {
- return;
- }
-
- $initPos = $this->toolRepo->countDisplayedToolsByWorkspace($workspace);
- ++$initPos;
-
- $this->om->startFlushSuite();
-
- foreach ($undisplayedTools as $undisplayedTool) {
- $wot = $this->orderedToolRepo->findOneBy([
- 'workspace' => $workspace,
- 'tool' => $undisplayedTool,
- ]);
-
- // create a WorkspaceOrderedTool for each Tool that hasn't already one
- if (null === $wot) {
- $this->setWorkspaceTool(
- $undisplayedTool,
- $initPos,
- $workspace
- );
-
- ++$initPos;
- }
- }
-
- $this->om->endFlushSuite();
- }
-
- private function setWorkspaceTool(Tool $tool, int $position, Workspace $workspace): OrderedTool
+ private function setWorkspaceTool(string $toolName, int $position, Workspace $workspace): OrderedTool
{
$orderedTool = $this->orderedToolRepo->findOneBy([
- 'workspace' => $workspace,
- 'tool' => $tool,
+ 'contextId' => $workspace->getUuid(),
+ 'tool' => $toolName,
]);
if (!$orderedTool) {
@@ -301,7 +132,7 @@ private function setWorkspaceTool(Tool $tool, int $position, Workspace $workspac
// At the workspace creation, the workspace id is still null because we only flush once at the very end.
if (null !== $workspace->getId()) {
$switchTool = $this->orderedToolRepo->findOneBy([
- 'workspace' => $workspace,
+ 'contextId' => $workspace->getUuid(),
'order' => $position,
]);
}
@@ -309,14 +140,14 @@ private function setWorkspaceTool(Tool $tool, int $position, Workspace $workspac
while (!is_null($switchTool)) {
++$position;
$switchTool = $this->orderedToolRepo->findOneBy([
- 'workspace' => $workspace,
+ 'contextId' => $workspace->getUuid(),
'order' => $position,
]);
}
$orderedTool->setWorkspace($workspace);
$orderedTool->setOrder($position);
- $orderedTool->setTool($tool);
+ $orderedTool->setName($toolName);
$this->om->persist($orderedTool);
$this->om->flush();
diff --git a/src/main/core/Manager/Tool/ToolMaskDecoderManager.php b/src/main/core/Manager/Tool/ToolMaskDecoderManager.php
index 05e758bd5ac..389d8ffd108 100644
--- a/src/main/core/Manager/Tool/ToolMaskDecoderManager.php
+++ b/src/main/core/Manager/Tool/ToolMaskDecoderManager.php
@@ -30,15 +30,15 @@ public function __construct(ObjectManager $om)
/**
* Create a mask decoder with default actions for a tool.
*/
- public function createDefaultToolMaskDecoders(Tool $tool): void
+ public function createDefaultToolMaskDecoders(string $toolName): void
{
foreach (ToolMaskDecoder::DEFAULT_ACTIONS as $action) {
$maskDecoder = $this->maskRepo
- ->findMaskDecoderByToolAndName($tool, $action);
+ ->findMaskDecoderByToolAndName($toolName, $action);
if (is_null($maskDecoder)) {
$maskDecoder = new ToolMaskDecoder();
- $maskDecoder->setTool($tool);
+ $maskDecoder->setTool($toolName);
$maskDecoder->setName($action);
$maskDecoder->setValue(ToolMaskDecoder::DEFAULT_VALUES[$action]);
@@ -51,10 +51,10 @@ public function createDefaultToolMaskDecoders(Tool $tool): void
/**
* Create a specific mask decoder for a tool.
*/
- public function createToolMaskDecoder(Tool $tool, string $action, int $value): void
+ public function createToolMaskDecoder(string $toolName, string $action, int $value): void
{
$maskDecoder = new ToolMaskDecoder();
- $maskDecoder->setTool($tool);
+ $maskDecoder->setTool($toolName);
$maskDecoder->setName($action);
$maskDecoder->setValue($value);
@@ -65,11 +65,11 @@ public function createToolMaskDecoder(Tool $tool, string $action, int $value): v
/**
* Returns an array containing the permission for a mask and a tool.
*/
- public function decodeMask(int $mask, Tool $tool): array
+ public function decodeMask(int $mask, string $toolName): array
{
- $decoders = $this->maskRepo->findMaskDecodersByTool($tool);
$perms = [];
+ $decoders = $this->maskRepo->findMaskDecodersByTool($toolName);
foreach ($decoders as $decoder) {
$perms[$decoder->getName()] = ($mask & $decoder->getValue()) ? true : false;
}
@@ -83,11 +83,12 @@ public function decodeMask(int $mask, Tool $tool): array
*
* array('open' => true, 'edit' => false, ...)
*/
- public function encodeMask(array $perms, Tool $tool): int
+ public function encodeMask(array $perms, string $toolName): int
{
- $decoders = $this->maskRepo->findMaskDecodersByTool($tool);
-
$mask = 0;
+
+ $decoders = $this->maskRepo->findMaskDecodersByTool($toolName);
+
foreach ($decoders as $decoder) {
if (isset($perms[$decoder->getName()])) {
$mask += $perms[$decoder->getName()] ? $decoder->getValue() : 0;
@@ -100,18 +101,18 @@ public function encodeMask(array $perms, Tool $tool): int
/**
* @return ToolMaskDecoder[]
*/
- public function getMaskDecodersByTool(Tool $tool)
+ public function getMaskDecodersByTool(string $toolName)
{
- return $this->maskRepo->findMaskDecodersByTool($tool);
+ return $this->maskRepo->findMaskDecodersByTool($toolName);
}
- public function getMaskDecoderByToolAndName(Tool $tool, string $name): ?ToolMaskDecoder
+ public function getMaskDecoderByToolAndName(string $toolName, string $name): ?ToolMaskDecoder
{
- return $this->maskRepo->findMaskDecoderByToolAndName($tool, $name);
+ return $this->maskRepo->findMaskDecoderByToolAndName($toolName, $name);
}
- public function getCustomMaskDecodersByTool(Tool $tool)
+ public function getCustomMaskDecodersByTool(string $toolName)
{
- return $this->maskRepo->findCustomMaskDecodersByTool($tool);
+ return $this->maskRepo->findCustomMaskDecodersByTool($toolName);
}
}
diff --git a/src/main/core/Manager/Workspace/TransferManager.php b/src/main/core/Manager/Workspace/TransferManager.php
index 39252f9765c..53826f75b0a 100644
--- a/src/main/core/Manager/Workspace/TransferManager.php
+++ b/src/main/core/Manager/Workspace/TransferManager.php
@@ -11,6 +11,7 @@
use Claroline\AppBundle\Log\LoggableTrait;
use Claroline\AppBundle\Manager\File\ArchiveManager;
use Claroline\AppBundle\Persistence\ObjectManager;
+use Claroline\CoreBundle\Component\Context\WorkspaceContext;
use Claroline\CoreBundle\Entity\Role;
use Claroline\CoreBundle\Entity\Tool\AbstractTool;
use Claroline\CoreBundle\Entity\Tool\OrderedTool;
@@ -58,7 +59,7 @@ public function __construct(
$this->crud = $crud;
}
- public function import(string $archivePath, ?Workspace $workspace = null): Workspace
+ public function import(string $archivePath, Workspace $workspace = null): Workspace
{
$archive = new \ZipArchive();
$archive->open($archivePath);
@@ -186,7 +187,7 @@ private function exportRoles(Workspace $workspace): array
}, $workspace->getRoles()->toArray());
}
- private function importRoles(array $data, Workspace $workspace, ?array $defaultRole = null): array
+ private function importRoles(array $data, Workspace $workspace, array $defaultRole = null): array
{
$roles = [];
@@ -221,7 +222,7 @@ private function exportTools(Workspace $workspace, FileBag $fileBag): array
$idx = null;
foreach ($orderedTools as $key => $tool) {
- if ('resources' === $tool->getTool()->getName()) {
+ if ('resources' === $tool->getName()) {
$idx = $key;
}
}
@@ -233,15 +234,15 @@ private function exportTools(Workspace $workspace, FileBag $fileBag): array
array_unshift($orderedTools, $first);
}
- return array_map(function (OrderedTool $orderedTool) use ($fileBag) {
+ return array_map(function (OrderedTool $orderedTool) use ($workspace, $fileBag) {
// get custom tool data
/** @var ExportToolEvent $event */
- $event = $this->dispatcher->dispatch(ToolEvents::getEventName(ToolEvents::EXPORT, AbstractTool::WORKSPACE, $orderedTool->getTool()->getName()), ExportToolEvent::class, [
- $orderedTool->getTool()->getName(), AbstractTool::WORKSPACE, $orderedTool->getWorkspace(), $fileBag,
+ $event = $this->dispatcher->dispatch(ToolEvents::getEventName(ToolEvents::EXPORT, AbstractTool::WORKSPACE, $orderedTool->getName()), ExportToolEvent::class, [
+ $orderedTool->getName(), AbstractTool::WORKSPACE, $workspace, $fileBag,
]);
return [
- 'name' => $orderedTool->getTool()->getName(),
+ 'name' => $orderedTool->getName(),
'orderedTool' => $this->serializer->serialize($orderedTool, [SerializerInterface::SERIALIZE_TRANSFER]),
'rights' => array_map(function (ToolRights $rights) {
return $this->serializer->serialize($rights, [SerializerInterface::SERIALIZE_TRANSFER]);
@@ -257,40 +258,37 @@ private function importTools(array $data, Workspace $workspace, array $roles, Fi
$createdObjects = $roles; // keep a map of old ID => new object for all imported objects
foreach ($data['tools'] as $orderedToolData) {
- $tool = $this->om->getRepository(Tool::class)->findOneBy(['name' => $orderedToolData['name']]);
- if ($tool) {
- $orderedTool = $this->serializer->deserialize($orderedToolData['orderedTool'], new OrderedTool(), [SerializerInterface::REFRESH_UUID]);
- $orderedTool->setWorkspace($workspace);
- $orderedTool->setTool($tool);
- $this->om->persist($orderedTool);
-
- foreach ($orderedToolData['rights'] as $rightsData) {
- if (empty($createdObjects[$rightsData['role']['id']])) {
- continue;
- }
-
- $rights = new ToolRights();
- $rights->setOrderedTool($orderedTool);
- unset($rightsData['orderedToolId']);
+ $orderedTool = new OrderedTool();
+ $orderedTool->setContextName(WorkspaceContext::getName());
+ $orderedTool->setContextId($workspace->getUuid());
- $this->serializer->deserialize(array_merge($rightsData, [
- 'role' => [
- 'id' => $createdObjects[$rightsData['role']['id']]->getUuid(),
- ],
- ]), $rights);
+ $this->crud->create($orderedTool, $orderedToolData['orderedTool'], [SerializerInterface::REFRESH_UUID, Crud::NO_PERMISSIONS, Crud::THROW_EXCEPTION]);
- $this->om->persist($rights);
+ foreach ($orderedToolData['rights'] as $rightsData) {
+ if (empty($createdObjects[$rightsData['role']['id']])) {
+ continue;
}
- /* @var ImportToolEvent $event */
- $event = $this->dispatcher->dispatch(
- ToolEvents::getEventName(ToolEvents::IMPORT, AbstractTool::WORKSPACE, $orderedTool->getTool()->getName()),
- ImportToolEvent::class,
- [$orderedTool->getTool()->getName(), AbstractTool::WORKSPACE, $orderedTool->getWorkspace(), $fileBag, $orderedToolData['data'] ?? [], $createdObjects]
- );
+ $rights = new ToolRights();
+ $rights->setOrderedTool($orderedTool);
+
+ $this->serializer->deserialize(array_merge($rightsData, [
+ 'role' => [
+ 'id' => $createdObjects[$rightsData['role']['id']]->getUuid(),
+ ],
+ ]), $rights);
- $createdObjects = array_merge([], $createdObjects, $event->getCreatedEntities());
+ $this->om->persist($rights);
}
+
+ /* @var ImportToolEvent $event */
+ $event = $this->dispatcher->dispatch(
+ ToolEvents::getEventName(ToolEvents::IMPORT, AbstractTool::WORKSPACE, $orderedTool->getName()),
+ ImportToolEvent::class,
+ [$orderedTool->getName(), AbstractTool::WORKSPACE, $workspace, $fileBag, $orderedToolData['data'] ?? [], $createdObjects]
+ );
+
+ $createdObjects = array_merge([], $createdObjects, $event->getCreatedEntities());
}
$this->om->flush();
diff --git a/src/main/core/Manager/Workspace/WorkspaceManager.php b/src/main/core/Manager/Workspace/WorkspaceManager.php
index 74302957fc7..41f214ae2fd 100644
--- a/src/main/core/Manager/Workspace/WorkspaceManager.php
+++ b/src/main/core/Manager/Workspace/WorkspaceManager.php
@@ -314,7 +314,6 @@ public function getDefaultModel($isPersonal = false, $restore = false): Workspac
['type' => 'tool', 'name' => 'resources'],
['type' => 'tool', 'name' => 'agenda'],
['type' => 'tool', 'name' => 'community'],
- ['type' => 'tool', 'name' => 'dashboard'],
['type' => 'action', 'name' => 'favourite'],
['type' => 'action', 'name' => 'configure'],
['type' => 'action', 'name' => 'impersonation'],
diff --git a/src/main/core/Manager/Workspace/WorkspaceRestrictionsManager.php b/src/main/core/Manager/Workspace/WorkspaceRestrictionsManager.php
index ca39552963a..ff795f20d95 100644
--- a/src/main/core/Manager/Workspace/WorkspaceRestrictionsManager.php
+++ b/src/main/core/Manager/Workspace/WorkspaceRestrictionsManager.php
@@ -22,11 +22,11 @@
class WorkspaceRestrictionsManager
{
public function __construct(
- private EventDispatcherInterface $dispatcher,
- private RequestStack $requestStack,
- private TokenStorageInterface $tokenStorage,
- private WorkspaceManager $workspaceManager,
- private WorkspaceUserQueueManager $workspaceUserQueueManager
+ private readonly EventDispatcherInterface $dispatcher,
+ private readonly RequestStack $requestStack,
+ private readonly TokenStorageInterface $tokenStorage,
+ private readonly WorkspaceManager $workspaceManager,
+ private readonly WorkspaceUserQueueManager $workspaceUserQueueManager
) {
}
diff --git a/src/main/core/Repository/Tool/OrderedToolRepository.php b/src/main/core/Repository/Tool/OrderedToolRepository.php
index 950c2c329ba..2463052b4fd 100644
--- a/src/main/core/Repository/Tool/OrderedToolRepository.php
+++ b/src/main/core/Repository/Tool/OrderedToolRepository.php
@@ -12,174 +12,38 @@
namespace Claroline\CoreBundle\Repository\Tool;
use Claroline\CoreBundle\Entity\Tool\OrderedTool;
-use Claroline\CoreBundle\Entity\Workspace\Workspace;
-use Claroline\CoreBundle\Manager\PluginManager;
-use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
-use Doctrine\Persistence\ManagerRegistry;
+use Doctrine\ORM\EntityRepository;
-class OrderedToolRepository extends ServiceEntityRepository
+class OrderedToolRepository extends EntityRepository
{
- /** @var array */
- private $bundles;
-
- public function __construct(ManagerRegistry $registry, PluginManager $pluginManager)
- {
- $this->bundles = $pluginManager->getEnabled();
-
- parent::__construct($registry, OrderedTool::class);
- }
-
- public function findByName($name)
- {
- return $this->getEntityManager()
- ->createQuery('
- SELECT ot
- FROM Claroline\CoreBundle\Entity\Tool\OrderedTool ot
- JOIN ot.tool t
- WHERE t.name = :name
- ORDER BY ot.order
- ')
- ->setParameter('name', $name)
- ->getResult();
- }
-
- public function findOneByNameAndWorkspace(string $name, ?Workspace $workspace = null): ?OrderedTool
- {
- return $this->getEntityManager()
- ->createQuery('
- SELECT ot
- FROM Claroline\CoreBundle\Entity\Tool\OrderedTool ot
- JOIN ot.tool t
- WHERE ot.workspace = :workspace
- AND t.name = :name
- ORDER BY ot.order
- ')
- ->setParameter('workspace', $workspace)
- ->setParameter('name', $name)
- ->getOneOrNullResult();
- }
-
- /**
- * Returns all the workspace ordered tools.
- *
- * @return OrderedTool[]
- */
- public function findByWorkspace(Workspace $workspace)
- {
- return $this->getEntityManager()
- ->createQuery('
- SELECT ot
- FROM Claroline\CoreBundle\Entity\Tool\OrderedTool AS ot
- JOIN ot.tool AS t
- LEFT JOIN t.plugin AS p
- WHERE ot.workspace = :workspace
- AND (
- CONCAT(p.vendorName, p.bundleName) IN (:bundles)
- OR t.plugin is NULL
- )
- ORDER BY ot.order ASC
- ')
- ->setParameter('workspace', $workspace)
- ->setParameter('bundles', $this->bundles)
- ->getResult();
- }
-
- /**
- * Returns the workspace ordered tools accessible to some given roles.
- *
- * @return OrderedTool[]
- */
- public function findByWorkspaceAndRoles(Workspace $workspace, array $roles)
+ public function findByContext(string $context, string $contextId = null): array
{
- if (0 === count($roles)) {
- return [];
- }
-
return $this->getEntityManager()
->createQuery('
SELECT ot
FROM Claroline\CoreBundle\Entity\Tool\OrderedTool AS ot
- JOIN ot.tool AS t
- LEFT JOIN t.plugin AS p
- JOIN ot.rights AS r
- JOIN r.role AS rr
- WHERE ot.workspace = :workspace
- AND rr.name IN (:roleNames)
- AND BIT_AND(r.mask, 1) = 1
- AND (
- CONCAT(p.vendorName, p.bundleName) IN (:bundles)
- OR t.plugin is NULL
- )
- ORDER BY ot.order ASC
+ WHERE ot.contextName = :contextName
+ AND (ot.contextId IS NULL OR ot.contextId = :contextId)
+ ORDER BY ot.order
')
- ->setParameter('workspace', $workspace)
- ->setParameter('roleNames', $roles)
- ->setParameter('bundles', $this->bundles)
+ ->setParameter('contextName', $context)
+ ->setParameter('contextId', $contextId)
->getResult();
}
- public function findOneByNameAndDesktop(string $name): ?OrderedTool
+ public function findOneByNameAndContext(string $name, string $context, string $contextId = null): ?OrderedTool
{
return $this->getEntityManager()
->createQuery('
SELECT ot
FROM Claroline\CoreBundle\Entity\Tool\OrderedTool ot
- JOIN ot.tool t
- WHERE ot.workspace IS NULL
- AND ot.user IS NULL
- AND t.name = :name
- ORDER BY ot.order
+ WHERE ot.contextName = :contextName
+ AND (ot.contextId IS NULL OR ot.contextId = :contextId)
+ AND ot.name = :name
')
->setParameter('name', $name)
+ ->setParameter('contextName', $context)
+ ->setParameter('contextId', $contextId)
->getOneOrNullResult();
}
-
- public function findByDesktop()
- {
- return $this->getEntityManager()
- ->createQuery('
- SELECT ot
- FROM Claroline\CoreBundle\Entity\Tool\OrderedTool AS ot
- JOIN ot.tool AS t
- LEFT JOIN t.plugin AS p
- WHERE ot.workspace IS NULL
- AND ot.user IS NULL
- AND (
- CONCAT(p.vendorName, p.bundleName) IN (:bundles)
- OR t.plugin is NULL
- )
- ORDER BY ot.order
- ')
- ->setParameter('bundles', $this->bundles)
- ->getResult();
- }
-
- public function findByDesktopAndRoles(array $roles)
- {
- if (0 === count($roles)) {
- return [];
- }
-
- return $this->getEntityManager()
- ->createQuery('
- SELECT ot
- FROM Claroline\CoreBundle\Entity\Tool\OrderedTool AS ot
- JOIN ot.tool AS t
- LEFT JOIN t.plugin AS p
- JOIN ot.rights AS r
- JOIN r.role AS rr
- WHERE ot.workspace IS NULL
- AND ot.user IS NULL
- AND rr.name IN (:roleNames)
- AND BIT_AND(r.mask, 1) = 1
- AND (
- CONCAT(p.vendorName, p.bundleName) IN (:bundles)
- OR t.plugin is NULL
- )
- ORDER BY ot.order
- ')
- ->setParameter('roleNames', $roles)
- ->setParameter('bundles', $this->bundles)
- ->getResult();
- }
}
diff --git a/src/main/core/Repository/Tool/ToolMaskDecoderRepository.php b/src/main/core/Repository/Tool/ToolMaskDecoderRepository.php
index c5b40482f3d..34f30b30c12 100644
--- a/src/main/core/Repository/Tool/ToolMaskDecoderRepository.php
+++ b/src/main/core/Repository/Tool/ToolMaskDecoderRepository.php
@@ -10,7 +10,6 @@
namespace Claroline\CoreBundle\Repository\Tool;
-use Claroline\CoreBundle\Entity\Tool\Tool;
use Claroline\CoreBundle\Entity\Tool\ToolMaskDecoder;
use Doctrine\ORM\EntityRepository;
@@ -18,8 +17,10 @@ class ToolMaskDecoderRepository extends EntityRepository
{
/**
* @return ToolMaskDecoder[]
+ *
+ * @deprecated we don't need a custom repo method for this
*/
- public function findMaskDecodersByTool(Tool $tool)
+ public function findMaskDecodersByTool(string $toolName): array
{
$dql = '
SELECT tmd
@@ -28,17 +29,15 @@ public function findMaskDecodersByTool(Tool $tool)
ORDER BY tmd.value ASC
';
$query = $this->getEntityManager()->createQuery($dql);
- $query->setParameter('tool', $tool);
+ $query->setParameter('tool', $toolName);
return $query->getResult();
}
/**
- * @param string $name
- *
- * @return ToolMaskDecoder|null
+ * @deprecated we don't need a custom repo method for this
*/
- public function findMaskDecoderByToolAndName(Tool $tool, $name)
+ public function findMaskDecoderByToolAndName(string $toolName, string $name): ?ToolMaskDecoder
{
$dql = '
SELECT tmd
@@ -48,13 +47,13 @@ public function findMaskDecoderByToolAndName(Tool $tool, $name)
ORDER BY tmd.value ASC
';
$query = $this->getEntityManager()->createQuery($dql);
- $query->setParameter('tool', $tool);
+ $query->setParameter('tool', $toolName);
$query->setParameter('name', $name);
return $query->getOneOrNullResult();
}
- public function findCustomMaskDecodersByTool(Tool $tool)
+ public function findCustomMaskDecodersByTool(string $toolName): array
{
$dql = '
SELECT tmd
@@ -64,7 +63,7 @@ public function findCustomMaskDecodersByTool(Tool $tool)
ORDER BY tmd.value ASC
';
$query = $this->getEntityManager()->createQuery($dql);
- $query->setParameter('tool', $tool);
+ $query->setParameter('tool', $toolName);
$query->setParameter('defaultActions', ToolMaskDecoder::DEFAULT_ACTIONS);
return $query->getResult();
diff --git a/src/main/core/Repository/Tool/ToolRepository.php b/src/main/core/Repository/Tool/ToolRepository.php
index 75be696d0a8..c72f529776d 100644
--- a/src/main/core/Repository/Tool/ToolRepository.php
+++ b/src/main/core/Repository/Tool/ToolRepository.php
@@ -17,6 +17,9 @@
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
+/**
+ * @deprecated no longer needed
+ */
class ToolRepository extends ServiceEntityRepository
{
/** @var array */
diff --git a/src/main/core/Repository/Tool/ToolRightsRepository.php b/src/main/core/Repository/Tool/ToolRightsRepository.php
index 7a21faab8c7..1bab665a8ae 100644
--- a/src/main/core/Repository/Tool/ToolRightsRepository.php
+++ b/src/main/core/Repository/Tool/ToolRightsRepository.php
@@ -10,8 +10,7 @@
namespace Claroline\CoreBundle\Repository\Tool;
-use Claroline\CoreBundle\Entity\Tool\Tool;
-use Claroline\CoreBundle\Entity\Workspace\Workspace;
+use Claroline\CoreBundle\Entity\Tool\OrderedTool;
use Doctrine\ORM\EntityRepository;
class ToolRightsRepository extends EntityRepository
@@ -19,9 +18,9 @@ class ToolRightsRepository extends EntityRepository
/**
* Returns the maximum rights on a given tool for a set of roles.
*/
- public function findMaximumRights(array $roles, Tool $tool, Workspace $workspace = null): int
+ public function findMaximumRights(array $roles, OrderedTool $orderedTool): int
{
- //add the role anonymous for everyone !
+ // add the role anonymous for everyone !
if (!in_array('ROLE_ANONYMOUS', $roles)) {
$roles[] = 'ROLE_ANONYMOUS';
}
@@ -31,26 +30,15 @@ public function findMaximumRights(array $roles, Tool $tool, Workspace $workspace
FROM Claroline\CoreBundle\Entity\Tool\ToolRights AS tr
JOIN tr.role AS role
JOIN tr.orderedTool AS ot
- JOIN ot.tool AS t
- WHERE t.id = :toolId
+ WHERE ot.id = :toolId
AND role.name IN (:roles)
';
- if (!empty($workspace)) {
- $dql .= ' AND ot.workspace = :workspace';
- } else {
- $dql .= ' AND ot.workspace IS NULL';
- }
-
$query = $this->getEntityManager()
->createQuery($dql)
- ->setParameter('toolId', $tool->getId())
+ ->setParameter('toolId', $orderedTool->getId())
->setParameter('roles', $roles);
- if (!empty($workspace)) {
- $query->setParameter('workspace', $workspace);
- }
-
$results = $query->getResult();
$mask = 0;
diff --git a/src/main/core/Repository/WorkspaceRepository.php b/src/main/core/Repository/WorkspaceRepository.php
index 318ed678934..d01dd4f6ac8 100644
--- a/src/main/core/Repository/WorkspaceRepository.php
+++ b/src/main/core/Repository/WorkspaceRepository.php
@@ -11,6 +11,7 @@
namespace Claroline\CoreBundle\Repository;
+use Claroline\CoreBundle\Component\Context\WorkspaceContext;
use Claroline\CoreBundle\Entity\Workspace\Workspace;
use Doctrine\ORM\EntityRepository;
@@ -73,9 +74,10 @@ public function findByRoles(array $roleNames)
FROM Claroline\CoreBundle\Entity\Tool\OrderedTool ot
JOIN ot.rights otr
JOIN otr.role otrr
- WHERE ot.workspace = w
- AND otrr.name in (:roles)
- AND BIT_AND(otr.mask, 1) = 1
+ WHERE ot.contextName = "workspace"
+ AND ot.contextId = w.uuid
+ AND otrr.name in (:roles)
+ AND BIT_AND(otr.mask, 1) = 1
)
')
@@ -83,16 +85,19 @@ public function findByRoles(array $roleNames)
->getResult();
}
- public function checkAccess(Workspace $workspace, array $roleNames, ?string $toolName = null, ?string $action = 'open')
+ /**
+ * @deprecated
+ */
+ public function checkAccess(Workspace $workspace, array $roleNames, string $toolName = null, ?string $action = 'open')
{
$dql = '
SELECT COUNT(ot)
FROM Claroline\CoreBundle\Entity\Tool\OrderedTool ot
- JOIN ot.workspace w
JOIN ot.tool t
JOIN ot.rights r
JOIN r.role rr
- WHERE w.id = :workspaceId
+ WHERE ot.contextName = :contextName
+ AND ot.contextId = :workspaceId
AND rr.name IN (:roleNames)
AND EXISTS (
SELECT d
@@ -108,7 +113,8 @@ public function checkAccess(Workspace $workspace, array $roleNames, ?string $too
}
$query = $this->getEntityManager()->createQuery($dql);
- $query->setParameter('workspaceId', $workspace->getId());
+ $query->setParameter('workspaceId', $workspace->getUuid());
+ $query->setParameter('contextName', WorkspaceContext::getName());
$query->setParameter('roleNames', $roleNames);
$query->setParameter('action', strtoupper($action));
diff --git a/src/main/core/Resources/config/components.yml b/src/main/core/Resources/config/components.yml
index 56582d270ef..99833132c83 100644
--- a/src/main/core/Resources/config/components.yml
+++ b/src/main/core/Resources/config/components.yml
@@ -1,2 +1,3 @@
imports:
- { resource: components/context.yml }
+ - { resource: components/tool.yml }
diff --git a/src/main/core/Resources/config/components/tool.yml b/src/main/core/Resources/config/components/tool.yml
new file mode 100644
index 00000000000..cbec0df3f4a
--- /dev/null
+++ b/src/main/core/Resources/config/components/tool.yml
@@ -0,0 +1,16 @@
+services:
+ Claroline\CoreBundle\Component\Tool\ParametersTool:
+ parent: Claroline\AppBundle\Component\Tool\AbstractTool
+ tags: [ 'claroline.component.tool' ]
+ arguments:
+ - '@Claroline\CoreBundle\API\Serializer\ParametersSerializer'
+ - '@Claroline\CoreBundle\Manager\LocaleManager'
+
+ Claroline\CoreBundle\Component\Tool\ResourcesTool:
+ parent: Claroline\AppBundle\Component\Tool\AbstractTool
+ tags: [ 'claroline.component.tool' ]
+ arguments:
+ - '@Claroline\AppBundle\Persistence\ObjectManager'
+ - '@event_dispatcher'
+ - '@Claroline\AppBundle\API\SerializerProvider'
+ - '@Claroline\AppBundle\API\Crud'
diff --git a/src/main/core/Resources/config/routing.yml b/src/main/core/Resources/config/routing.yml
index 24ff678f58c..77b53354f53 100644
--- a/src/main/core/Resources/config/routing.yml
+++ b/src/main/core/Resources/config/routing.yml
@@ -3,14 +3,6 @@ claro_authentication:
type: annotation
options: { expose: true }
-claro_workspace:
- resource: "@ClarolineCoreBundle/Controller/WorkspaceController.php"
- type: annotation
-
-claro_admin:
- resource: "@ClarolineCoreBundle/Controller/AdministrationController.php"
- type: annotation
-
claro_resource:
resource: "@ClarolineCoreBundle/Controller/ResourceController.php"
type: annotation
diff --git a/src/main/core/Resources/config/services/controller.yml b/src/main/core/Resources/config/services/controller.yml
index 1d0c983b29e..b1e652230e3 100644
--- a/src/main/core/Resources/config/services/controller.yml
+++ b/src/main/core/Resources/config/services/controller.yml
@@ -2,13 +2,6 @@ services:
_defaults:
public: true # because controller
- Claroline\CoreBundle\Controller\APINew\Log\LogConnectController:
- arguments:
- - '@security.authorization_checker'
- - '@Claroline\AppBundle\API\FinderProvider'
- - '@Claroline\CoreBundle\Manager\LogConnectManager'
- - '@Claroline\CoreBundle\Manager\Tool\ToolManager'
-
Claroline\CoreBundle\Controller\APINew\Platform\PluginController:
parent: Claroline\AppBundle\Controller\AbstractSecurityController
public: true
@@ -69,24 +62,6 @@ services:
- '@Claroline\AppBundle\API\SerializerProvider'
- '@Claroline\CoreBundle\Manager\Template\TemplateManager'
- Claroline\CoreBundle\Controller\APINew\Context\ContextController:
- arguments:
- - '@security.token_storage'
- - '@event_dispatcher'
- - '@Claroline\AppBundle\API\SerializerProvider'
- - '@Claroline\AppBundle\Component\Context\ContextProvider'
-
- Claroline\CoreBundle\Controller\APINew\Context\ToolController:
- arguments:
- - '@security.authorization_checker'
- - '@security.token_storage'
- - '@Claroline\AppBundle\Persistence\ObjectManager'
- - '@event_dispatcher'
- - '@Claroline\AppBundle\API\Crud'
- - '@Claroline\AppBundle\API\SerializerProvider'
- - '@Claroline\CoreBundle\Manager\Tool\ToolManager'
- - '@Claroline\CoreBundle\Manager\LogConnectManager'
-
Claroline\CoreBundle\Controller\APINew\Workspace\RegistrationController:
arguments:
- '@security.authorization_checker'
@@ -110,12 +85,11 @@ services:
arguments:
- '@security.token_storage'
- '@security.authorization_checker'
- - '@Claroline\AppBundle\Event\StrictDispatcher'
- '@messenger.default_bus'
+ - '@Claroline\AppBundle\Manager\File\TempFileManager'
- '@Claroline\CoreBundle\Manager\RoleManager'
- '@Claroline\CoreBundle\Manager\Workspace\WorkspaceManager'
- - '@Claroline\CoreBundle\Manager\LogConnectManager'
- - '@Claroline\AppBundle\Manager\File\TempFileManager'
+ - '@Claroline\CoreBundle\Manager\Workspace\WorkspaceRestrictionsManager'
Claroline\CoreBundle\Controller\APINew\Platform\ConnectionMessageController:
parent: Claroline\AppBundle\Controller\AbstractCrudController
@@ -165,13 +139,6 @@ services:
- '@Claroline\CoreBundle\Manager\WidgetManager'
- '@Claroline\CoreBundle\Manager\DataSourceManager'
- Claroline\CoreBundle\Controller\AdministrationController:
- arguments:
- - '@security.authorization_checker'
- - '@security.token_storage'
- - '@Claroline\CoreBundle\Manager\Tool\ToolManager'
- - '@Claroline\AppBundle\Event\StrictDispatcher'
-
Claroline\CoreBundle\Controller\AuthenticationController:
arguments:
- '@Claroline\CoreBundle\Manager\UserManager'
@@ -208,18 +175,6 @@ services:
- '@Claroline\CoreBundle\Library\Configuration\PlatformConfigurationHandler'
- '@event_dispatcher'
- Claroline\CoreBundle\Controller\WorkspaceController:
- arguments:
- - '@security.authorization_checker'
- - '@Claroline\AppBundle\Persistence\ObjectManager'
- - '@security.token_storage'
- - '@Claroline\AppBundle\API\SerializerProvider'
- - '@Claroline\CoreBundle\Manager\Tool\ToolManager'
- - '@Claroline\CoreBundle\Manager\Workspace\WorkspaceManager'
- - '@Claroline\CoreBundle\Manager\Workspace\WorkspaceRestrictionsManager'
- - '@Claroline\EvaluationBundle\Manager\WorkspaceEvaluationManager'
- - '@Claroline\AppBundle\Event\StrictDispatcher'
-
Claroline\CoreBundle\Controller\APINew\Location\LocationController:
parent: Claroline\AppBundle\Controller\AbstractCrudController
public: true
@@ -238,3 +193,4 @@ services:
public: true
arguments:
- '@security.authorization_checker'
+ - '@Claroline\CoreBundle\Manager\Tool\ToolManager'
diff --git a/src/main/core/Resources/config/services/finder.yml b/src/main/core/Resources/config/services/finder.yml
index 5ed9581bbb5..99a7585aac6 100644
--- a/src/main/core/Resources/config/services/finder.yml
+++ b/src/main/core/Resources/config/services/finder.yml
@@ -41,18 +41,6 @@ services:
- '@security.authorization_checker'
- '@security.token_storage'
- Claroline\CoreBundle\API\Finder\Tool\ToolFinder:
- parent: Claroline\AppBundle\API\Finder\AbstractFinder
- tags: [ claroline.finder ]
- arguments:
- - '@Claroline\CoreBundle\Manager\PluginManager'
-
- Claroline\CoreBundle\API\Finder\Tool\AdminToolFinder:
- parent: Claroline\AppBundle\API\Finder\AbstractFinder
- tags: [ claroline.finder ]
- arguments:
- - '@Claroline\CoreBundle\Manager\PluginManager'
-
Claroline\CoreBundle\API\Finder\Tool\OrderedToolFinder:
parent: Claroline\AppBundle\API\Finder\AbstractFinder
tags: [ claroline.finder ]
diff --git a/src/main/core/Resources/config/services/library.yml b/src/main/core/Resources/config/services/library.yml
index b1fbeee5749..25f55dcedb3 100644
--- a/src/main/core/Resources/config/services/library.yml
+++ b/src/main/core/Resources/config/services/library.yml
@@ -16,23 +16,11 @@ services:
Claroline\CoreBundle\Library\Installation\Plugin\Loader: ~
- Claroline\CoreBundle\Library\Installation\Plugin\Installer:
- arguments:
- - '@claroline.plugin.validator'
- - '@Claroline\CoreBundle\Library\Installation\Plugin\Recorder'
- - '@Claroline\InstallationBundle\Manager\InstallationManager'
- - '@Claroline\AppBundle\Persistence\ObjectManager'
- - '@Claroline\CoreBundle\Manager\PluginManager'
- - '@Claroline\CoreBundle\Manager\VersionManager'
- calls:
- - setLogger: [ '@logger' ]
-
Claroline\CoreBundle\Library\Installation\Plugin\DatabaseWriter:
arguments:
- '@Claroline\AppBundle\Persistence\ObjectManager'
- '@Claroline\CoreBundle\Manager\Resource\MaskManager'
- '@filesystem'
- - '@Claroline\CoreBundle\Manager\Tool\ToolManager'
- '@Claroline\CoreBundle\Manager\Tool\ToolMaskDecoderManager'
- '@Claroline\ThemeBundle\Manager\IconSetBuilderManager'
calls:
@@ -43,17 +31,6 @@ services:
- '@claroline.symfony_yaml'
- '@doctrine.orm.entity_manager'
- Claroline\CoreBundle\Library\Installation\PlatformInstaller:
- arguments:
- - '@kernel'
- - '@Claroline\CoreBundle\Manager\PluginManager'
- - '@Claroline\CoreBundle\Library\Installation\Plugin\Installer'
- - '@Claroline\AppBundle\Persistence\ObjectManager'
- - '@Claroline\InstallationBundle\Manager\InstallationManager'
- - '@service_container'
- calls:
- - setLogger: [ '@logger' ]
-
Claroline\CoreBundle\Library\Mailing\TransportFactory:
arguments:
- '@Claroline\CoreBundle\Library\Configuration\PlatformConfigurationHandler'
diff --git a/src/main/core/Resources/config/services/repository.yml b/src/main/core/Resources/config/services/repository.yml
index ae1e01a3526..91eb440b7d2 100644
--- a/src/main/core/Resources/config/services/repository.yml
+++ b/src/main/core/Resources/config/services/repository.yml
@@ -8,11 +8,6 @@ services:
- '@Doctrine\Persistence\ManagerRegistry'
- '@Claroline\CoreBundle\Manager\PluginManager'
- Claroline\CoreBundle\Repository\Tool\OrderedToolRepository:
- arguments:
- - '@Doctrine\Persistence\ManagerRegistry'
- - '@Claroline\CoreBundle\Manager\PluginManager'
-
Claroline\CoreBundle\Repository\Resource\ResourceActionRepository:
arguments:
- '@Doctrine\Persistence\ManagerRegistry'
diff --git a/src/main/core/Resources/config/services/serializer.yml b/src/main/core/Resources/config/services/serializer.yml
index 0b262736b2b..534a047c62b 100644
--- a/src/main/core/Resources/config/services/serializer.yml
+++ b/src/main/core/Resources/config/services/serializer.yml
@@ -31,9 +31,6 @@ services:
Claroline\CoreBundle\API\Serializer\DataSourceSerializer:
tags: [claroline.serializer]
- Claroline\CoreBundle\API\Serializer\Tool\AdminToolSerializer:
- tags: [claroline.serializer]
-
Claroline\CoreBundle\API\Serializer\Workspace\WorkspaceSerializer:
tags: [claroline.serializer]
arguments:
@@ -118,9 +115,6 @@ services:
- '@Claroline\CoreBundle\Manager\LocaleManager'
- '@request_stack'
- Claroline\CoreBundle\API\Serializer\Tool\ToolSerializer:
- tags: [claroline.serializer]
-
Claroline\CoreBundle\API\Serializer\Tool\ToolRightsSerializer:
tags: [ claroline.serializer ]
arguments:
@@ -214,31 +208,6 @@ services:
- '@Claroline\CoreBundle\API\Serializer\Workspace\WorkspaceSerializer'
- '@Claroline\CoreBundle\API\Serializer\Resource\ResourceNodeSerializer'
- Claroline\CoreBundle\API\Serializer\Log\Connection\LogConnectWorkspaceSerializer:
- tags: [claroline.serializer]
- arguments:
- - '@Claroline\AppBundle\API\SerializerProvider'
-
- Claroline\CoreBundle\API\Serializer\Log\Connection\LogConnectToolSerializer:
- tags: [claroline.serializer]
- arguments:
- - '@Claroline\AppBundle\API\SerializerProvider'
-
- Claroline\CoreBundle\API\Serializer\Log\Connection\LogConnectResourceSerializer:
- tags: [claroline.serializer]
- arguments:
- - '@Claroline\AppBundle\API\SerializerProvider'
-
- Claroline\CoreBundle\API\Serializer\Log\Connection\LogConnectPlatformSerializer:
- tags: [claroline.serializer]
- arguments:
- - '@Claroline\AppBundle\API\SerializerProvider'
-
- Claroline\CoreBundle\API\Serializer\Log\Connection\LogConnectAdminToolSerializer:
- tags: [claroline.serializer]
- arguments:
- - '@Claroline\AppBundle\API\SerializerProvider'
-
Claroline\CoreBundle\API\Serializer\File\PublicFileSerializer:
tags: [claroline.serializer]
arguments:
diff --git a/src/main/core/Resources/config/services/updater.yml b/src/main/core/Resources/config/services/updater.yml
index 1ac4e7b576f..4d9ee767e5a 100644
--- a/src/main/core/Resources/config/services/updater.yml
+++ b/src/main/core/Resources/config/services/updater.yml
@@ -1,12 +1,16 @@
services:
- _defaults:
- tags: [ 'claroline.platform.updater' ]
+ _defaults:
+ tags: [ 'claroline.platform.updater' ]
- Claroline\CoreBundle\Installation\Updater\Updater140000:
- arguments:
- - '@kernel'
- - '@doctrine.dbal.default_connection'
+ Claroline\CoreBundle\Installation\Updater\Updater140000:
+ arguments:
+ - '@kernel'
+ - '@doctrine.dbal.default_connection'
- Claroline\CoreBundle\Installation\Updater\Updater140010:
- arguments:
- - '@doctrine.dbal.default_connection'
+ Claroline\CoreBundle\Installation\Updater\Updater140010:
+ arguments:
+ - '@doctrine.dbal.default_connection'
+
+ Claroline\CoreBundle\Installation\Updater\Updater140100:
+ arguments:
+ - '@Claroline\AppBundle\Persistence\ObjectManager'
diff --git a/src/main/core/Resources/config/services/voter.yml b/src/main/core/Resources/config/services/voter.yml
index eca9a836a14..5e9304f7487 100644
--- a/src/main/core/Resources/config/services/voter.yml
+++ b/src/main/core/Resources/config/services/voter.yml
@@ -8,18 +8,12 @@ services:
Claroline\CoreBundle\Security\Voter\Template\TemplateVoter:
parent: Claroline\AppBundle\Security\Voter\AbstractVoter
- Claroline\CoreBundle\Security\Voter\Tool\ToolVoter:
+ Claroline\CoreBundle\Security\Voter\Tool\OrderedToolVoter:
parent: Claroline\AppBundle\Security\Voter\AbstractVoter
arguments:
- '@Claroline\AppBundle\Persistence\ObjectManager'
- '@Claroline\CoreBundle\Manager\Tool\ToolMaskDecoderManager'
- Claroline\CoreBundle\Security\Voter\Tool\OrderedToolVoter:
- parent: Claroline\AppBundle\Security\Voter\AbstractVoter
-
- Claroline\CoreBundle\Security\Voter\Tool\AdministrationToolVoter:
- parent: Claroline\AppBundle\Security\Voter\AbstractVoter
-
Claroline\CoreBundle\Security\Voter\PublicFileVoter:
parent: Claroline\AppBundle\Security\Voter\AbstractVoter
diff --git a/src/main/core/Resources/modules/account/parameters/index.js b/src/main/core/Resources/modules/account/parameters/index.js
index 666c132b0db..5f964db6f64 100644
--- a/src/main/core/Resources/modules/account/parameters/index.js
+++ b/src/main/core/Resources/modules/account/parameters/index.js
@@ -1,11 +1,9 @@
-import {trans} from '#/main/app/intl/translation'
-
import {ParametersMain} from '#/main/core/account/parameters/containers/main'
export default {
- name: 'parameters',
+ /*name: 'parameters',
icon: 'fa fa-fw fa-cog',
label: trans('parameters'),
- component: ParametersMain,
- order: 2
+ */component: ParametersMain/*,
+ order: 2*/
}
diff --git a/src/main/core/Resources/modules/administration/connection-messages/modals/slide/components/modal.jsx b/src/main/core/Resources/modules/administration/connection-messages/modals/slide/components/modal.jsx
index 3b03609aa46..965ba13ed3d 100644
--- a/src/main/core/Resources/modules/administration/connection-messages/modals/slide/components/modal.jsx
+++ b/src/main/core/Resources/modules/administration/connection-messages/modals/slide/components/modal.jsx
@@ -10,7 +10,8 @@ import {User as UserTypes} from '#/main/community/prop-types'
import {Select} from '#/main/app/input/components/select'
import {getActions} from '#/main/core/desktop'
-import {getTools} from '#/main/core/tools'
+import {getTools} from '#/main/core/tool/utils'
+
const ShortcutRow = (props) => {
let shortcutChoices = {}
if ('action' === props.value.type) {
@@ -68,7 +69,7 @@ class SlideFormModal extends Component {
this.state = {
actions: [],
- tools: Object.keys(getTools(this.props.currentUser)) || []
+ tools: Object.keys(getTools()) || []
}
}
diff --git a/src/main/core/Resources/modules/administration/index.js b/src/main/core/Resources/modules/administration/index.js
deleted file mode 100644
index 262eed9224b..00000000000
--- a/src/main/core/Resources/modules/administration/index.js
+++ /dev/null
@@ -1,32 +0,0 @@
-import identity from 'lodash/identity'
-
-import {getApp, getApps} from '#/main/app/plugins'
-
-function getTool(name) {
- return getApp('administration', name)()
-}
-
-function getActions(user, desktopRefresher = {}) {
- // adds default refresher actions
- const refresher = Object.assign({
- add: identity,
- update: identity,
- delete: identity
- }, desktopRefresher)
-
- // get all actions declared for workspace
- const actions = getApps('actions.administration')
-
- return Promise.all(
- // boot actions applications
- Object.keys(actions).map(action => actions[action]())
- ).then((loadedActions) => loadedActions
- // generate action
- .map(actionModule => actionModule.default(user, refresher))
- )
-}
-
-export {
- getTool,
- getActions
-}
diff --git a/src/main/core/Resources/modules/plugin.js b/src/main/core/Resources/modules/plugin.js
index d4e8571a7cf..243eab3fa1c 100644
--- a/src/main/core/Resources/modules/plugin.js
+++ b/src/main/core/Resources/modules/plugin.js
@@ -39,6 +39,7 @@ registry.add('ClarolineCoreBundle', {
* Provides actions for base Claroline objects.
*/
actions: {
+ account: {},
administration: {},
desktop: {},
@@ -113,7 +114,6 @@ registry.add('ClarolineCoreBundle', {
tools: {
'workspaces' : () => { return import(/* webpackChunkName: "core-tool-workspaces" */ '#/main/core/tools/workspaces') },
'resources' : () => { return import(/* webpackChunkName: "core-tool-resources" */ '#/main/core/tools/resources') },
- 'parameters' : () => { return import(/* webpackChunkName: "core-tool-parameters" */ '#/main/core/tools/parameters') },
'resource_trash' : () => { return import(/* webpackChunkName: "core-tool-trash" */ '#/main/core/tools/trash') },
'locations' : () => { return import(/* webpackChunkName: "core-tool-locations" */ '#/main/core/tools/locations') }
},
diff --git a/src/main/core/Resources/modules/tool/components/main.jsx b/src/main/core/Resources/modules/tool/components/main.jsx
index 513c2b0790d..80974f092ca 100644
--- a/src/main/core/Resources/modules/tool/components/main.jsx
+++ b/src/main/core/Resources/modules/tool/components/main.jsx
@@ -10,9 +10,7 @@ import {ContentLoader} from '#/main/app/content/components/loader'
import {ContentForbidden} from '#/main/app/content/components/forbidden'
import {ContentNotFound} from '#/main/app/content/components/not-found'
-import {constants} from '#/main/core/tool/constants'
-import {getTool} from '#/main/core/tools'
-import {getTool as getAdminTool} from '#/main/core/administration'
+import {getTool} from '#/main/core/tool/utils'
const Tool = props => {
if (props.loaded) {
@@ -116,14 +114,9 @@ class ToolMain extends Component {
if (!this.pendingApp) {
this.setState({appLoaded: false})
- let app
- if (constants.TOOL_ADMINISTRATION === this.props.contextType) {
- app = getAdminTool(this.props.toolName)
- } else {
- app = getTool(this.props.toolName)
- }
-
- this.pendingApp = makeCancelable(app)
+ this.pendingApp = makeCancelable(
+ getTool(this.props.toolName, this.props.contextType)
+ )
this.pendingApp.promise
.then(
diff --git a/src/main/core/Resources/modules/tool/components/menu.jsx b/src/main/core/Resources/modules/tool/components/menu.jsx
index f2862ca87ba..3b9a74a156a 100644
--- a/src/main/core/Resources/modules/tool/components/menu.jsx
+++ b/src/main/core/Resources/modules/tool/components/menu.jsx
@@ -3,22 +3,13 @@ import {PropTypes as T} from 'prop-types'
import {Await} from '#/main/app/components/await'
-import {constants} from '#/main/core/tool/constants'
-import {getTool} from '#/main/core/tools'
-import {getTool as getAdminTool} from '#/main/core/administration'
+import {getTool} from '#/main/core/tool/utils'
const ToolMenu = props => {
- if (props.name && props.loaded) {
- let app
- if (constants.TOOL_ADMINISTRATION === props.contextType) {
- app = getAdminTool(props.name)
- } else {
- app = getTool(props.name)
- }
-
+ if (props.name && props.loaded && !props.notFound) {
return (
{
if (module.default.menu) {
return createElement(module.default.menu, {
@@ -43,6 +34,7 @@ ToolMenu.propTypes = {
name: T.string,
contextType: T.string,
loaded: T.bool.isRequired,
+ notFound: T.bool.isRequired,
// from menu
opened: T.bool.isRequired,
diff --git a/src/main/core/Resources/modules/tool/components/page.jsx b/src/main/core/Resources/modules/tool/components/page.jsx
index 6baedd8933f..3a7fe3e95c0 100644
--- a/src/main/core/Resources/modules/tool/components/page.jsx
+++ b/src/main/core/Resources/modules/tool/components/page.jsx
@@ -83,7 +83,7 @@ ToolPage.propTypes = {
permissions: T.object.isRequired
}),
currentContext: T.shape({
- type: T.oneOf(['administration', 'desktop', 'workspace']),
+ type: T.oneOf(['administration', 'desktop', 'workspace', 'account', 'home']),
data: T.object
}).isRequired,
// the name of the primary action of the tool (if we want to override the default one).
diff --git a/src/main/core/Resources/modules/tool/constants.js b/src/main/core/Resources/modules/tool/constants.js
index 90422392f4b..3f49a29f94c 100644
--- a/src/main/core/Resources/modules/tool/constants.js
+++ b/src/main/core/Resources/modules/tool/constants.js
@@ -5,11 +5,13 @@ const TOOL_HOME = 'home'
const TOOL_DESKTOP = 'desktop'
const TOOL_WORKSPACE = 'workspace'
const TOOL_ADMINISTRATION = 'administration'
+const TOOL_ACCOUNT = 'account'
const TOOL_TYPES = {
[TOOL_DESKTOP]: trans('desktop_tool'),
[TOOL_WORKSPACE]: trans('workspace_tool'),
- [TOOL_ADMINISTRATION]: trans('administration_tool')
+ [TOOL_ADMINISTRATION]: trans('administration_tool'),
+ [TOOL_ACCOUNT]: trans('account_tool')
}
export const constants = {
@@ -17,5 +19,6 @@ export const constants = {
TOOL_HOME,
TOOL_DESKTOP,
TOOL_WORKSPACE,
- TOOL_ADMINISTRATION
+ TOOL_ADMINISTRATION,
+ TOOL_ACCOUNT
}
diff --git a/src/main/core/Resources/modules/tool/containers/menu.jsx b/src/main/core/Resources/modules/tool/containers/menu.jsx
index 664d326809f..46dbcaa237c 100644
--- a/src/main/core/Resources/modules/tool/containers/menu.jsx
+++ b/src/main/core/Resources/modules/tool/containers/menu.jsx
@@ -13,7 +13,8 @@ const ToolMenu = withRouter(
contextType: selectors.contextType(state),
name: selectors.name(state),
path: selectors.path(state),
- loaded: selectors.loaded(state)
+ loaded: selectors.loaded(state),
+ notFound: selectors.notFound(state)
})
)(ToolMenuComponent)
)
diff --git a/src/main/core/Resources/modules/tool/modals/parameters/components/modal.jsx b/src/main/core/Resources/modules/tool/modals/parameters/components/modal.jsx
index 879f6458928..240a9aef5b8 100644
--- a/src/main/core/Resources/modules/tool/modals/parameters/components/modal.jsx
+++ b/src/main/core/Resources/modules/tool/modals/parameters/components/modal.jsx
@@ -8,7 +8,7 @@ import {CALLBACK_BUTTON} from '#/main/app/buttons'
import {Modal} from '#/main/app/overlays/modal/components/modal'
import {FormData} from '#/main/app/content/form/containers/data'
-import {getTool} from '#/main/core/tools'
+import {getTool} from '#/main/core/tool/utils'
import {selectors} from '#/main/core/tool/modals/parameters/store'
class ParametersModal extends Component {
@@ -21,7 +21,7 @@ class ParametersModal extends Component {
}
componentDidMount() {
- getTool(this.props.toolName).then((module) => {
+ getTool(this.props.toolName, this.props.currentContext.type).then((module) => {
let parametersComponent = null
if (module.default && module.default.parameters) {
parametersComponent = module.default.parameters
diff --git a/src/main/core/Resources/modules/tool/store/reducer.js b/src/main/core/Resources/modules/tool/store/reducer.js
index 05dd8e63a6f..df3e62cd7fe 100644
--- a/src/main/core/Resources/modules/tool/store/reducer.js
+++ b/src/main/core/Resources/modules/tool/store/reducer.js
@@ -15,6 +15,7 @@ import {
const reducer = combineReducers({
name: makeReducer(null, {
+ [CONTEXT_OPEN]: () => null,
[TOOL_OPEN]: (state, action) => action.name
}),
diff --git a/src/main/core/Resources/modules/tool/utils.js b/src/main/core/Resources/modules/tool/utils.js
index cb7f71c09f3..cad5c1ad261 100644
--- a/src/main/core/Resources/modules/tool/utils.js
+++ b/src/main/core/Resources/modules/tool/utils.js
@@ -4,7 +4,7 @@ import identity from 'lodash/identity'
import {trans} from '#/main/app/intl/translation'
import {LINK_BUTTON} from '#/main/app/buttons'
import {showBreadcrumb} from '#/main/app/layout/utils'
-import {getApps} from '#/main/app/plugins'
+import {getApp, getApps} from '#/main/app/plugins'
import {constants} from '#/main/core/tool/constants'
@@ -12,6 +12,26 @@ import {route as toolRoute} from '#/main/core/tool/routing'
import {route as workspaceRoute} from '#/main/core/workspace/routing'
import {route as adminRoute} from '#/main/core/administration/routing'
+function getTools(contextType) {
+ if (constants.TOOL_ADMINISTRATION === contextType) {
+ return getApps('administration')
+ } else if (constants.TOOL_ACCOUNT === contextType) {
+ return getApps('account')
+ }
+
+ return getApps('tools')
+}
+
+function getTool(name, contextType) {
+ if (constants.TOOL_ADMINISTRATION === contextType) {
+ return getApp('administration', name)()
+ } else if (constants.TOOL_ACCOUNT === contextType) {
+ return getApp('account', name)()
+ }
+
+ return getApp('tools', name)()
+}
+
function getActions(tool, context, toolRefresher, path, currentUser) {
// adds default refresher actions
const refresher = Object.assign({
@@ -47,6 +67,25 @@ function getToolBreadcrumb(toolName = null, contextType, contextData = {}) {
let path = []
switch (contextType) {
+ case constants.TOOL_ACCOUNT:
+ path = [
+ {
+ type: LINK_BUTTON,
+ label: trans('account'),
+ target: '/account'
+ }
+ ]
+
+ if (toolName) {
+ path.push({
+ type: LINK_BUTTON,
+ label: trans(toolName, {}, 'tools'),
+ target: toolRoute(toolName)
+ })
+ }
+
+ break
+
case constants.TOOL_DESKTOP:
path = [
{
@@ -144,6 +183,8 @@ function showToolBreadcrumb(contextType, contextData) {
}
export {
+ getTools,
+ getTool,
getActions,
getToolBreadcrumb,
showToolBreadcrumb
diff --git a/src/main/core/Resources/modules/tools/index.js b/src/main/core/Resources/modules/tools/index.js
deleted file mode 100644
index 2463e6f8196..00000000000
--- a/src/main/core/Resources/modules/tools/index.js
+++ /dev/null
@@ -1,14 +0,0 @@
-import {getApp, getApps} from '#/main/app/plugins'
-
-function getTools() {
- return getApps('tools')
-}
-
-function getTool(name) {
- return getApp('tools', name)()
-}
-
-export {
- getTools,
- getTool
-}
diff --git a/src/main/core/Resources/modules/tools/parameters/components/menu.jsx b/src/main/core/Resources/modules/tools/parameters/components/menu.jsx
deleted file mode 100644
index 876edbbcd3c..00000000000
--- a/src/main/core/Resources/modules/tools/parameters/components/menu.jsx
+++ /dev/null
@@ -1,56 +0,0 @@
-import React from 'react'
-import {PropTypes as T} from 'prop-types'
-import omit from 'lodash/omit'
-
-import {trans} from '#/main/app/intl/translation'
-import {LINK_BUTTON} from '#/main/app/buttons'
-import {Toolbar} from '#/main/app/action/components/toolbar'
-import {MenuSection} from '#/main/app/layout/menu/components/section'
-
-const ParametersMenu = (props) =>
-
-
-
-
-ParametersMenu.propTypes = {
- path: T.string,
-
- // from menu
- opened: T.bool.isRequired,
- toggle: T.func.isRequired,
- autoClose: T.func.isRequired
-}
-
-export {
- ParametersMenu
-}
diff --git a/src/main/core/Resources/modules/tools/parameters/components/tool.jsx b/src/main/core/Resources/modules/tools/parameters/components/tool.jsx
deleted file mode 100644
index d4f29d3825f..00000000000
--- a/src/main/core/Resources/modules/tools/parameters/components/tool.jsx
+++ /dev/null
@@ -1,31 +0,0 @@
-import React from 'react'
-import {PropTypes as T} from 'prop-types'
-
-import {Routes} from '#/main/app/router'
-
-// TODO : make it dynamic
-import {ExternalTool} from '#/main/core/tools/parameters/external/components/tool'
-import {TokensTool} from '#/main/core/tools/parameters/tokens/containers/tool'
-
-const ParametersTool = (props) =>
-
-
-ParametersTool.propTypes = {
- path: T.string.isRequired
-}
-
-export {
- ParametersTool
-}
diff --git a/src/main/core/Resources/modules/tools/parameters/external/components/tool.jsx b/src/main/core/Resources/modules/tools/parameters/external/components/tool.jsx
deleted file mode 100644
index a698d0b60a4..00000000000
--- a/src/main/core/Resources/modules/tools/parameters/external/components/tool.jsx
+++ /dev/null
@@ -1,26 +0,0 @@
-import React from 'react'
-import {PropTypes as T} from 'prop-types'
-
-import {trans} from '#/main/app/intl/translation'
-import {LINK_BUTTON} from '#/main/app/buttons'
-import {ToolPage} from '#/main/core/tool/containers/page'
-
-const ExternalTool = (props) =>
-
-
-
-
-ExternalTool.propTypes = {
- path: T.string.isRequired
-}
-
-export {
- ExternalTool
-}
diff --git a/src/main/core/Resources/modules/tools/parameters/external/containers/tool.jsx b/src/main/core/Resources/modules/tools/parameters/external/containers/tool.jsx
deleted file mode 100644
index bc0e3daeac4..00000000000
--- a/src/main/core/Resources/modules/tools/parameters/external/containers/tool.jsx
+++ /dev/null
@@ -1,24 +0,0 @@
-import {connect} from 'react-redux'
-
-import {withReducer} from '#/main/app/store/components/withReducer'
-
-import {ExternalTool as ExternalToolComponent} from '#/main/core/tools/parameters/external/components/tool'
-import {actions, reducer, selectors} from '#/main/core/tools/parameters/external/store/actions'
-
-const ExternalTool = withReducer(selectors.STORE_NAME, reducer)(
- connect(
- (state) => ({
- loaded: selectors.loaded(state),
- accounts: selectors.accounts(state)
- }),
- (dispatch) => ({
- loadAccounts() {
- dispatch(actions.fetchAccounts())
- }
- })
- )(ExternalToolComponent)
-)
-
-export {
- ExternalTool
-}
diff --git a/src/main/core/Resources/modules/tools/parameters/external/store/actions.js b/src/main/core/Resources/modules/tools/parameters/external/store/actions.js
deleted file mode 100644
index 847cdee4fab..00000000000
--- a/src/main/core/Resources/modules/tools/parameters/external/store/actions.js
+++ /dev/null
@@ -1,15 +0,0 @@
-import {makeActionCreator} from '#/main/app/store/actions'
-import {API_REQUEST} from '#/main/app/api'
-
-export const USER_LOAD_EXTERNAL_ACCOUNTS = 'USER_LOAD_EXTERNAL_ACCOUNTS'
-
-export const actions = {}
-
-actions.loadAccounts = makeActionCreator(USER_LOAD_EXTERNAL_ACCOUNTS, 'data')
-
-actions.fetchAccounts = () => ({
- [API_REQUEST]: {
- url: [],
- success: (response, dispatch) => dispatch(actions.loadAccounts(response))
- }
-})
diff --git a/src/main/core/Resources/modules/tools/parameters/external/store/index.js b/src/main/core/Resources/modules/tools/parameters/external/store/index.js
deleted file mode 100644
index c4411c7a537..00000000000
--- a/src/main/core/Resources/modules/tools/parameters/external/store/index.js
+++ /dev/null
@@ -1,10 +0,0 @@
-
-import {actions} from '#/main/core/tools/parameters/external/store/actions'
-import {reducer} from '#/main/core/tools/parameters/external/store/reducer'
-import {selectors} from '#/main/core/tools/parameters/external/store/selectors'
-
-export {
- actions,
- reducer,
- selectors
-}
diff --git a/src/main/core/Resources/modules/tools/parameters/external/store/reducer.js b/src/main/core/Resources/modules/tools/parameters/external/store/reducer.js
deleted file mode 100644
index 734f52812da..00000000000
--- a/src/main/core/Resources/modules/tools/parameters/external/store/reducer.js
+++ /dev/null
@@ -1,12 +0,0 @@
-import {makeReducer, combineReducers} from '#/main/app/store/reducer'
-
-import {USER_LOAD_EXTERNAL_ACCOUNTS} from '#/main/core/tools/parameters/external/store/actions'
-
-export const reducer = combineReducers({
- accounts: makeReducer([], {
- [USER_LOAD_EXTERNAL_ACCOUNTS]: (state, action) => action.data
- }),
- loaded: makeReducer(false, {
- [USER_LOAD_EXTERNAL_ACCOUNTS]: () => true
- })
-})
\ No newline at end of file
diff --git a/src/main/core/Resources/modules/tools/parameters/external/store/selectors.js b/src/main/core/Resources/modules/tools/parameters/external/store/selectors.js
deleted file mode 100644
index b02e4b74d32..00000000000
--- a/src/main/core/Resources/modules/tools/parameters/external/store/selectors.js
+++ /dev/null
@@ -1,22 +0,0 @@
-import {createSelector} from 'reselect'
-
-const STORE_NAME = 'userExternalParameters'
-
-const store = (state) => state[STORE_NAME]
-
-const loaded = createSelector(
- [store],
- (store) => store.loaded
-)
-
-const accounts = createSelector(
- [store],
- (store) => store.accounts
-)
-
-export const selectors = {
- STORE_NAME,
-
- loaded,
- accounts
-}
diff --git a/src/main/core/Resources/modules/tools/parameters/index.js b/src/main/core/Resources/modules/tools/parameters/index.js
deleted file mode 100644
index 86db770a9e7..00000000000
--- a/src/main/core/Resources/modules/tools/parameters/index.js
+++ /dev/null
@@ -1,9 +0,0 @@
-import {reducer} from '#/main/core/tools/parameters/store/reducer'
-import {ParametersTool} from '#/main/core/tools/parameters/components/tool'
-import {ParametersMenu} from '#/main/core/tools/parameters/components/menu'
-
-export default {
- menu: ParametersMenu,
- component: ParametersTool,
- store: reducer
-}
diff --git a/src/main/core/Resources/modules/tools/parameters/store/index.js b/src/main/core/Resources/modules/tools/parameters/store/index.js
deleted file mode 100644
index 161a22e0555..00000000000
--- a/src/main/core/Resources/modules/tools/parameters/store/index.js
+++ /dev/null
@@ -1,11 +0,0 @@
-/**
- * Desktop parameters store.
- */
-
-import {reducer} from '#/main/core/tools/parameters/store/reducer'
-import {selectors} from '#/main/core/tools/parameters/store/selectors'
-
-export {
- reducer,
- selectors
-}
diff --git a/src/main/core/Resources/modules/tools/parameters/store/reducer.js b/src/main/core/Resources/modules/tools/parameters/store/reducer.js
deleted file mode 100644
index 412be5c9cf3..00000000000
--- a/src/main/core/Resources/modules/tools/parameters/store/reducer.js
+++ /dev/null
@@ -1,26 +0,0 @@
-import {makeInstanceAction} from '#/main/app/store/actions'
-import {makeFormReducer} from '#/main/app/content/form/store/reducer'
-import {reducer as tokenReducer} from '#/main/core/tools/parameters/tokens/store/reducer'
-import {combineReducers, makeReducer} from '#/main/app/store/reducer'
-
-import {TOOL_LOAD} from '#/main/core/tool/store/actions'
-import {selectors} from '#/main/core/tools/parameters/store/selectors'
-
-const reducer = combineReducers({
- tools: makeReducer([], {
- [makeInstanceAction(TOOL_LOAD, selectors.STORE_NAME)]: (state, action) => action.toolData.tools
- }),
- toolsConfig: makeFormReducer(selectors.STORE_NAME+'.toolsConfig', {}, {
- originalData: makeReducer([], {
- [makeInstanceAction(TOOL_LOAD, selectors.STORE_NAME)]: (state, action) => action.toolData.toolsConfig
- }),
- data: makeReducer([], {
- [makeInstanceAction(TOOL_LOAD, selectors.STORE_NAME)]: (state, action) => action.toolData.toolsConfig
- })
- }),
- tokens: tokenReducer
-})
-
-export {
- reducer
-}
diff --git a/src/main/core/Resources/modules/tools/parameters/store/selectors.js b/src/main/core/Resources/modules/tools/parameters/store/selectors.js
deleted file mode 100644
index 926209d656b..00000000000
--- a/src/main/core/Resources/modules/tools/parameters/store/selectors.js
+++ /dev/null
@@ -1,21 +0,0 @@
-import {createSelector} from 'reselect'
-
-const STORE_NAME = 'parameters'
-
-const store = (state) => state[STORE_NAME]
-
-const tools = createSelector(
- [store],
- (store) => store.tools
-)
-
-const toolsConfig = createSelector(
- [store],
- (store) => store.toolsConfig
-)
-
-export const selectors = {
- STORE_NAME,
- tools,
- toolsConfig
-}
diff --git a/src/main/core/Resources/modules/tools/parameters/tokens/components/token.jsx b/src/main/core/Resources/modules/tools/parameters/tokens/components/token.jsx
deleted file mode 100644
index 35a76cf2a5f..00000000000
--- a/src/main/core/Resources/modules/tools/parameters/tokens/components/token.jsx
+++ /dev/null
@@ -1,58 +0,0 @@
-import React from 'react'
-import {PropTypes as T} from 'prop-types'
-import {connect} from 'react-redux'
-
-import {trans} from '#/main/app/intl/translation'
-import {FormData} from '#/main/app/content/form/containers/data'
-import {LINK_BUTTON} from '#/main/app/buttons'
-import {selectors as toolSelectors} from '#/main/core/tool/store'
-
-import {selectors} from '#/main/core/tools/parameters/store/selectors'
-
-const TokenForm = (props) =>
- ['apiv2_apitoken_update', {id: token.id}]}
- cancel={{
- type: LINK_BUTTON,
- target: props.path + '/tokens',
- exact: true
- }}
- sections={[
- {
- title: trans('general'),
- primary: true,
- fields: [
- {
- name: 'description',
- type: 'string',
- label: trans('description'),
- required: true
- },
- {
- name: 'token',
- type: 'string',
- label: trans('token'),
- required: true,
- disabled: true
- }
- ]
- }
- ]}
- />
-
-TokenForm.propTypes = {
- path: T.string.isRequired
-}
-
-const Token = connect(
- state => ({
- path: toolSelectors.path(state)
- })
-)(TokenForm)
-
-export {
- Token
-}
diff --git a/src/main/core/Resources/modules/tools/parameters/tokens/components/tokens.jsx b/src/main/core/Resources/modules/tools/parameters/tokens/components/tokens.jsx
deleted file mode 100644
index be480668841..00000000000
--- a/src/main/core/Resources/modules/tools/parameters/tokens/components/tokens.jsx
+++ /dev/null
@@ -1,43 +0,0 @@
-import React from 'react'
-
-import {trans} from '#/main/app/intl/translation'
-import {LINK_BUTTON} from '#/main/app/buttons'
-import {ListData} from '#/main/app/content/list/containers/data'
-
-import {selectors} from '#/main/core/tools/parameters/store/selectors'
-
-const Tokens = () =>
- ({
- type: LINK_BUTTON,
- target: `/tokens/${row.id}`,
- label: trans('edit', {}, 'actions')
- })}
- delete={{
- url: ['apiv2_apitoken_delete_bulk']
- }}
- definition={[
- {
- name: 'token',
- type: 'string',
- label: trans('token'),
- displayed: true,
- primary: true
- },
- {
- name: 'description',
- type: 'string',
- label: trans('description'),
- displayed: true
- }
- ]}
- />
-
-export {
- Tokens
-}
diff --git a/src/main/core/Resources/modules/tools/parameters/tokens/components/tool.jsx b/src/main/core/Resources/modules/tools/parameters/tokens/components/tool.jsx
deleted file mode 100644
index a6ff2347118..00000000000
--- a/src/main/core/Resources/modules/tools/parameters/tokens/components/tool.jsx
+++ /dev/null
@@ -1,54 +0,0 @@
-import React from 'react'
-import {PropTypes as T} from 'prop-types'
-
-import {trans} from '#/main/app/intl/translation'
-import {Routes} from '#/main/app/router'
-import {LINK_BUTTON} from '#/main/app/buttons'
-import {ToolPage} from '#/main/core/tool/containers/page'
-
-import {Tokens} from '#/main/core/tools/parameters/tokens/components/tokens'
-import {Token} from '#/main/core/tools/parameters/tokens/components/token'
-
-const TokensTool = props =>
-
- props.openForm(params.id)
- }
- ]}
- />
-
-
-TokensTool.propTypes = {
- path: T.string.isRequired,
- openForm: T.func.isRequired
-}
-
-export {
- TokensTool
-}
diff --git a/src/main/core/Resources/modules/tools/parameters/tokens/containers/tool.jsx b/src/main/core/Resources/modules/tools/parameters/tokens/containers/tool.jsx
deleted file mode 100644
index 5f2ad5693a3..00000000000
--- a/src/main/core/Resources/modules/tools/parameters/tokens/containers/tool.jsx
+++ /dev/null
@@ -1,22 +0,0 @@
-import {connect} from 'react-redux'
-
-import {selectors as toolSelectors} from '#/main/core/tool/store'
-
-import {selectors} from '#/main/core/tools/parameters/store/selectors'
-import {TokensTool as TokensToolComponent} from '#/main/core/tools/parameters/tokens/components/tool'
-import {actions} from '#/main/core/tools/parameters/tokens/store/actions'
-
-const TokensTool = connect(
- (state) => ({
- path: toolSelectors.path(state)
- }),
- dispatch => ({
- openForm(id) {
- dispatch(actions.open(selectors.STORE_NAME+'.tokens.current', id))
- }
- })
-)(TokensToolComponent)
-
-export {
- TokensTool
-}
diff --git a/src/main/core/Resources/modules/tools/parameters/tokens/store/actions.js b/src/main/core/Resources/modules/tools/parameters/tokens/store/actions.js
deleted file mode 100644
index 33bdbc46bef..00000000000
--- a/src/main/core/Resources/modules/tools/parameters/tokens/store/actions.js
+++ /dev/null
@@ -1,33 +0,0 @@
-import {url} from '#/main/app/api/router'
-
-import {API_REQUEST} from '#/main/app/api'
-import {actions as listActions} from '#/main/app/content/list/store/actions'
-import {actions as formActions} from '#/main/app/content/form/store/actions'
-
-import {selectors} from '#/main/core/tools/parameters/store/selectors'
-
-export const actions = {}
-
-actions.create = () => ({
- [API_REQUEST]: {
- url: url(['apiv2_apitoken_create']),
- request: {
- method: 'POST',
- body: JSON.stringify({})
- },
- success: (data, dispatch) => {
- dispatch(listActions.invalidateData(selectors.STORE_NAME+'tokens.list'))
- }
- }
-})
-
-actions.open = (formName, id) => {
- if (id) {
- return {
- [API_REQUEST]: {
- url: ['apiv2_apitoken_get', {id}],
- success: (response, dispatch) => dispatch(formActions.resetForm(formName, response, false))
- }
- }
- }
-}
diff --git a/src/main/core/Resources/modules/tools/parameters/tokens/store/index.js b/src/main/core/Resources/modules/tools/parameters/tokens/store/index.js
deleted file mode 100644
index c5eaa9374a1..00000000000
--- a/src/main/core/Resources/modules/tools/parameters/tokens/store/index.js
+++ /dev/null
@@ -1,11 +0,0 @@
-/**
- * Desktop parameters store.
- */
-
-import {reducer} from '#/main/core/tools/parameters/tokens/store/reducer'
-import {selectors} from '#/main/core/tools/parameters/tokens/store/selectors'
-
-export {
- reducer,
- selectors
-}
diff --git a/src/main/core/Resources/modules/tools/parameters/tokens/store/reducer.js b/src/main/core/Resources/modules/tools/parameters/tokens/store/reducer.js
deleted file mode 100644
index 8fe1a82d20f..00000000000
--- a/src/main/core/Resources/modules/tools/parameters/tokens/store/reducer.js
+++ /dev/null
@@ -1,20 +0,0 @@
-import {makeListReducer} from '#/main/app/content/list/store'
-import {combineReducers, makeReducer} from '#/main/app/store/reducer'
-import {makeFormReducer} from '#/main/app/content/form/store/reducer'
-import {makeInstanceAction} from '#/main/app/store/actions'
-
-import {TOOL_LOAD} from '#/main/core/tool/store/actions'
-import {selectors} from '#/main/core/tools/parameters/store/selectors'
-
-const reducer = combineReducers({
- list: makeListReducer(selectors.STORE_NAME+'.tokens.list', {}, {
- invalidated: makeReducer(false, {
- [makeInstanceAction(TOOL_LOAD, selectors.STORE_NAME)]: () => true
- })
- }),
- current: makeFormReducer(selectors.STORE_NAME+'.tokens.current')
-})
-
-export {
- reducer
-}
diff --git a/src/main/core/Security/Voter/ResourceVoter.php b/src/main/core/Security/Voter/ResourceVoter.php
index e5d07ec221e..1ed7523ba2d 100644
--- a/src/main/core/Security/Voter/ResourceVoter.php
+++ b/src/main/core/Security/Voter/ResourceVoter.php
@@ -201,12 +201,12 @@ private function checkAction(string $action, array $nodes, TokenInterface $token
}
}
- //the workspace manager he can do w/e he wants
+ // the workspace manager he can do w/e he wants
if ($haveSameWorkspace && $ws && $this->workspaceManager->isManager($ws, $token)) {
return [];
}
- //the resource creator can do w/e he wants
+ // the resource creator can do w/e he wants
$timesCreator = 0;
foreach ($nodes as $node) {
@@ -215,12 +215,12 @@ private function checkAction(string $action, array $nodes, TokenInterface $token
}
}
- //but it only work if he's not usurping a workspace role to see if everything is good
+ // but it only works if he's not usurping a workspace role to see if everything is good
if ($timesCreator === count($nodes) && !$this->workspaceManager->isImpersonated($token)) {
return [];
}
- //check if the action is possible on the node
+ // check if the action is possible on the node
$errors = [];
$action = strtolower($action);
@@ -233,11 +233,11 @@ private function checkAction(string $action, array $nodes, TokenInterface $token
$adminDecoder = $this->maskManager->getDecoder($type, 'administrate');
$canAdministrate = $adminDecoder ? (0 !== ($mask & $adminDecoder->getValue())) : false;
// If user can administrate OR resource is open then check action
- if ($canAdministrate ||
- ($this->restrictionsManager->isStarted($node) &&
- !$this->restrictionsManager->isEnded($node) &&
- $node->isPublished())) {
- //gotta check
+ if ($canAdministrate
+ || ($this->restrictionsManager->isStarted($node)
+ && !$this->restrictionsManager->isEnded($node)
+ && $node->isPublished())) {
+ // gotta check
if (!$decoder) {
return ['The permission '.$action.' does not exists for the type '.$type->getName()];
}
@@ -276,7 +276,7 @@ private function checkCreation($type, ResourceNode $node, TokenInterface $token)
return $errors;
}
- //otherwise we need to check
+ // otherwise we need to check
$rightsCreation = $this->repository->findCreationRights($token->getRoleNames(), $node);
if (!$this->canCreate($rightsCreation, $type)) {
@@ -306,16 +306,16 @@ private function checkMove(ResourceNode $parent, array $nodes, TokenInterface $t
{
$errors = [];
- //first I need to know if I can create
+ // first I need to know if I can create
foreach ($nodes as $node) {
$type = $node->getResourceType()->getName();
$errors = array_merge($errors, $this->checkCreation($type, $parent, $token));
}
- //then I need to know if I can copy
+ // then I need to know if I can copy
$errors = array_merge($errors, $this->checkCopy($parent, $nodes, $token));
- //and finally I need to know if I can delete
+ // and finally I need to know if I can delete
$errors = array_merge($errors, $this->checkAction('DELETE', $nodes, $token));
return $errors;
@@ -329,7 +329,7 @@ private function checkMove(ResourceNode $parent, array $nodes, TokenInterface $t
*/
private function checkCopy(ResourceNode $parent, array $nodes, TokenInterface $token): array
{
- //first I need to know if I can create what I want in the parent directory
+ // first I need to know if I can create what I want in the parent directory
$errors = [];
foreach ($nodes as $node) {
@@ -337,7 +337,7 @@ private function checkCopy(ResourceNode $parent, array $nodes, TokenInterface $t
$errors = array_merge($errors, $this->checkCreation($type, $parent, $token));
}
- //then we need to know if we can copy
+ // then we need to know if we can copy
$errors = array_merge($errors, $this->checkAction('COPY', $nodes, $token));
return $errors;
diff --git a/src/main/core/Security/Voter/Tool/AdministrationToolVoter.php b/src/main/core/Security/Voter/Tool/AdministrationToolVoter.php
deleted file mode 100644
index 00ad03b1f51..00000000000
--- a/src/main/core/Security/Voter/Tool/AdministrationToolVoter.php
+++ /dev/null
@@ -1,49 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Claroline\CoreBundle\Security\Voter\Tool;
-
-use Claroline\AppBundle\Security\Voter\AbstractVoter;
-use Claroline\CoreBundle\Entity\Tool\AdminTool;
-use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
-use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
-
-class AdministrationToolVoter extends AbstractVoter
-{
- /**
- * @param AdminTool $object
- */
- public function checkPermission(TokenInterface $token, $object, array $attributes, array $options): int
- {
- $roles = $object->getRoles();
- $tokenRoles = $token->getRoleNames();
- foreach ($tokenRoles as $tokenRole) {
- foreach ($roles as $role) {
- if ($role->getRole() === $tokenRole) {
- return VoterInterface::ACCESS_GRANTED;
- }
- }
- }
-
- return VoterInterface::ACCESS_DENIED;
- }
-
- public function getClass(): string
- {
- return AdminTool::class;
- }
-
- public function getSupportedActions(): ?array
- {
- //atm, null means "everything is supported... implement this later"
- return null;
- }
-}
diff --git a/src/main/core/Security/Voter/Tool/OrderedToolVoter.php b/src/main/core/Security/Voter/Tool/OrderedToolVoter.php
index 6934e4d06aa..58e8cd777da 100644
--- a/src/main/core/Security/Voter/Tool/OrderedToolVoter.php
+++ b/src/main/core/Security/Voter/Tool/OrderedToolVoter.php
@@ -11,9 +11,12 @@
namespace Claroline\CoreBundle\Security\Voter\Tool;
+use Claroline\AppBundle\Persistence\ObjectManager;
use Claroline\AppBundle\Security\Voter\AbstractVoter;
use Claroline\CoreBundle\Entity\Tool\OrderedTool;
-use Claroline\CoreBundle\Security\ToolPermissions;
+use Claroline\CoreBundle\Entity\Tool\ToolRights;
+use Claroline\CoreBundle\Manager\Tool\ToolMaskDecoderManager;
+use Claroline\CoreBundle\Repository\Tool\ToolRightsRepository;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
@@ -23,24 +26,35 @@
*/
class OrderedToolVoter extends AbstractVoter
{
+ private ToolMaskDecoderManager $maskManager;
+ private ToolRightsRepository $rightsRepository;
+
+ public function __construct(
+ ObjectManager $om,
+ ToolMaskDecoderManager $maskManager
+ ) {
+ $this->maskManager = $maskManager;
+ $this->rightsRepository = $om->getRepository(ToolRights::class);
+ }
+
/**
* @param OrderedTool $object
*/
public function checkPermission(TokenInterface $token, $object, array $attributes, array $options): int
{
- if (!empty($object->getWorkspace())) {
- // let the workspace voter decide
- $isGranted = $this->isGranted(ToolPermissions::getPermission($object->getTool()->getName(), $attributes[0]), $object->getWorkspace());
- } else {
- // let the base tool voter decide
- $isGranted = $this->isGranted($attributes[0], $object->getTool());
- }
+ // FIXME : admin bypass will not work
+ $decoder = $this->maskManager->getMaskDecoderByToolAndName($object->getName(), $attributes[0]);
+ if ($decoder) {
+ $mask = $this->rightsRepository->findMaximumRights($token->getRoleNames(), $object);
+
+ if ($mask & $decoder->getValue()) {
+ return VoterInterface::ACCESS_GRANTED;
+ }
- if ($isGranted) {
- return VoterInterface::ACCESS_GRANTED;
+ return VoterInterface::ACCESS_DENIED;
}
- return VoterInterface::ACCESS_DENIED;
+ return VoterInterface::ACCESS_ABSTAIN;
}
public function getClass(): string
@@ -50,7 +64,7 @@ public function getClass(): string
public function getSupportedActions(): ?array
{
- //atm, null means "everything is supported... implement this later"
+ // atm, null means "everything is supported... implement this later"
return null;
}
}
diff --git a/src/main/core/Security/Voter/Tool/ToolVoter.php b/src/main/core/Security/Voter/Tool/ToolVoter.php
deleted file mode 100644
index 3d278903252..00000000000
--- a/src/main/core/Security/Voter/Tool/ToolVoter.php
+++ /dev/null
@@ -1,65 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Claroline\CoreBundle\Security\Voter\Tool;
-
-use Claroline\AppBundle\Persistence\ObjectManager;
-use Claroline\AppBundle\Security\Voter\AbstractVoter;
-use Claroline\CoreBundle\Entity\Tool\Tool;
-use Claroline\CoreBundle\Entity\Tool\ToolRights;
-use Claroline\CoreBundle\Manager\Tool\ToolMaskDecoderManager;
-use Claroline\CoreBundle\Repository\Tool\ToolRightsRepository;
-use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
-use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
-
-/**
- * ATTENTION : it does not work with Workspace tools. For them, it's the OrderedToolVoter or WorkspaceVoter.
- */
-class ToolVoter extends AbstractVoter
-{
- private ToolMaskDecoderManager $maskManager;
- private ToolRightsRepository $rightsRepository;
-
- public function __construct(
- ObjectManager $om,
- ToolMaskDecoderManager $maskManager
- ) {
- $this->maskManager = $maskManager;
- $this->rightsRepository = $om->getRepository(ToolRights::class);
- }
-
- public function checkPermission(TokenInterface $token, $object, array $attributes, array $options): int
- {
- $decoder = $this->maskManager->getMaskDecoderByToolAndName($object, $attributes[0]);
- if ($decoder) {
- $mask = $this->rightsRepository->findMaximumRights($token->getRoleNames(), $object);
-
- if ($mask & $decoder->getValue()) {
- return VoterInterface::ACCESS_GRANTED;
- }
-
- return VoterInterface::ACCESS_DENIED;
- }
-
- return VoterInterface::ACCESS_ABSTAIN;
- }
-
- public function getClass(): string
- {
- return Tool::class;
- }
-
- public function getSupportedActions(): ?array
- {
- // atm, null means "everything is supported... implement this later"
- return null;
- }
-}
diff --git a/src/main/core/Tests/Repository/Tool/OrderedToolRepositoryTest.php b/src/main/core/Tests/Repository/Tool/OrderedToolRepositoryTest.php
deleted file mode 100644
index 70b397b3afd..00000000000
--- a/src/main/core/Tests/Repository/Tool/OrderedToolRepositoryTest.php
+++ /dev/null
@@ -1,40 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Claroline\CoreBundle\Tests\Repository\Tool;
-
-use Claroline\CoreBundle\Entity\Tool\OrderedTool;
-use Claroline\CoreBundle\Library\Testing\RepositoryTestCase;
-
-class OrderedToolRepositoryTest extends RepositoryTestCase
-{
- public static $repo;
-
- public static function setUpBeforeClass(): void
- {
- parent::setUpBeforeClass();
- self::$repo = self::getRepository(OrderedTool::class);
-
- self::createWorkspace('ws_1');
- self::createRole('ROLE_1', self::get('ws_1'));
- self::createRole('ROLE_2', self::get('ws_1'));
- self::createTool('tool_1');
- self::createTool('tool_2');
- self::createWorkspaceTool(self::get('tool_1'), self::get('ws_1'), [self::get('ROLE_1')], 1);
- self::createWorkspaceTool(self::get('tool_2'), self::get('ws_1'), [self::get('ROLE_2')], 1);
- }
-
- public function testFindByWorkspaceAndRole()
- {
- $tools = self::$repo->findByWorkspaceAndRoles(self::get('ws_1'), ['ROLE_1', 'ROLE_2']);
- $this->assertEquals(2, count($tools));
- }
-}
diff --git a/src/main/core/Tests/Repository/Tool/ToolRepositoryTest.php b/src/main/core/Tests/Repository/Tool/ToolRepositoryTest.php
deleted file mode 100644
index 381ee2d3359..00000000000
--- a/src/main/core/Tests/Repository/Tool/ToolRepositoryTest.php
+++ /dev/null
@@ -1,58 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Claroline\CoreBundle\Tests\Repository\Tool;
-
-use Claroline\CoreBundle\Entity\Tool\Tool;
-use Claroline\CoreBundle\Library\Testing\RepositoryTestCase;
-
-class ToolRepositoryTest extends RepositoryTestCase
-{
- /** @var ToolRepository */
- private static $repo;
-
- public static function setUpBeforeClass(): void
- {
- parent::setUpBeforeClass();
-
- self::$repo = self::getRepository(Tool::class);
-
- self::createUser('john');
- self::createWorkspace('ws_1');
- self::createTool('tool_1');
- self::createTool('tool_2');
- self::createRole('ROLE_1', self::get('ws_1'));
- self::createRole('ROLE_2', self::get('ws_1'));
- self::createWorkspaceTool(self::get('tool_1'), self::get('ws_1'), [self::get('ROLE_1')], 1);
- self::createWorkspaceTool(self::get('tool_2'), self::get('ws_1'), [self::get('ROLE_2')], 1);
- self::createDesktopTool(self::get('tool_2'), self::get('john'), 1);
- }
-
- public function testFindUndisplayedToolsByWorkspace()
- {
- $result = self::$repo->findUndisplayedToolsByWorkspace(self::get('ws_1'));
- $toolNames = array_map(function (Tool $tool) {
- return $tool->getName();
- }, $result);
-
- // I cannot check the number of tools returned because it can change over time.
- // Also the claroline instance can contain plugins which inject tools from the outside of the distribution bundle.
- // Instead I will just check for some of the expected tools from the core
- $this->assertTrue(in_array('home', $toolNames));
- $this->assertTrue(in_array('community', $toolNames));
- $this->assertTrue(in_array('resources', $toolNames));
- }
-
- public function testCountDisplayedToolsByWorkspace()
- {
- $this->assertEquals(2, self::$repo->countDisplayedToolsByWorkspace(self::get('ws_1')));
- }
-}
diff --git a/src/main/core/Tests/Repository/WorkspaceRepositoryTest.php b/src/main/core/Tests/Repository/WorkspaceRepositoryTest.php
index 92b65cc6e04..df7adce01a4 100644
--- a/src/main/core/Tests/Repository/WorkspaceRepositoryTest.php
+++ b/src/main/core/Tests/Repository/WorkspaceRepositoryTest.php
@@ -35,14 +35,9 @@ public static function setUpBeforeClass(): void
self::createRole('ROLE_4', self::get('ws_4'));
self::createRole('ROLE_5', self::get('ws_5'));
self::createRole('ROLE_ANONYMOUS');
- self::createTool('tool_1');
- self::createTool('tool_2');
- self::createWorkspaceTool(self::get('tool_1'), self::get('ws_1'), [self::get('ROLE_ANONYMOUS')], 1);
- self::createWorkspaceTool(self::get('tool_2'), self::get('ws_2'), [self::get('ROLE_2')], 1);
+ self::createWorkspaceTool('tool_1', self::get('ws_1'), [self::get('ROLE_ANONYMOUS')], 1);
+ self::createWorkspaceTool('tool_2', self::get('ws_2'), [self::get('ROLE_2')], 1);
self::createUser('john', [self::get('ROLE_1'), self::get('ROLE_2')], self::get('ws_1'));
- self::createLog(self::get('john'), 'workspace-tool-read', self::get('ws_1'));
- self::sleep(1); // dates involved
- self::createLog(self::get('john'), 'workspace-tool-read', self::get('ws_2'));
self::createResourceType('t_dir', 'Directory');
self::createDirectory('dir_1', self::get('t_dir'), self::get('john'), self::get('ws_2'));
self::createDirectory('dir_2', self::get('t_dir'), self::get('john'), self::get('ws_2'));
diff --git a/src/main/dev/DependencyInjection/ClarolineDevExtension.php b/src/main/dev/DependencyInjection/ClarolineDevExtension.php
index 54212ba0ced..34f69b3e1a2 100644
--- a/src/main/dev/DependencyInjection/ClarolineDevExtension.php
+++ b/src/main/dev/DependencyInjection/ClarolineDevExtension.php
@@ -21,10 +21,7 @@
*/
class ClarolineDevExtension extends Extension
{
- /**
- * {@inheritdoc}
- */
- public function load(array $configs, ContainerBuilder $container)
+ public function load(array $configs, ContainerBuilder $container): void
{
$locator = new FileLocator(__DIR__.'/../Resources/config');
$loader = new YamlFileLoader($container, $locator);
diff --git a/src/main/evaluation/Controller/WorkspaceEvaluationController.php b/src/main/evaluation/Controller/WorkspaceEvaluationController.php
index d64d0e8c40c..ee75c2adeb2 100644
--- a/src/main/evaluation/Controller/WorkspaceEvaluationController.php
+++ b/src/main/evaluation/Controller/WorkspaceEvaluationController.php
@@ -17,13 +17,15 @@
use Claroline\AppBundle\API\SerializerProvider;
use Claroline\AppBundle\Controller\RequestDecoderTrait;
use Claroline\AppBundle\Persistence\ObjectManager;
+use Claroline\CoreBundle\Component\Context\DesktopContext;
+use Claroline\CoreBundle\Component\Context\WorkspaceContext;
use Claroline\CoreBundle\Entity\Resource\ResourceNode;
use Claroline\CoreBundle\Entity\Resource\ResourceUserEvaluation;
-use Claroline\CoreBundle\Entity\Tool\OrderedTool;
use Claroline\CoreBundle\Entity\User;
use Claroline\CoreBundle\Entity\Workspace\Evaluation;
use Claroline\CoreBundle\Entity\Workspace\Workspace;
use Claroline\CoreBundle\Library\Normalizer\TextNormalizer;
+use Claroline\CoreBundle\Manager\Tool\ToolManager;
use Claroline\CoreBundle\Security\PermissionCheckerTrait;
use Claroline\EvaluationBundle\Manager\PdfManager;
use Claroline\EvaluationBundle\Manager\WorkspaceEvaluationManager;
@@ -46,14 +48,15 @@ class WorkspaceEvaluationController
use PermissionCheckerTrait;
public function __construct(
- private TokenStorageInterface $tokenStorage,
AuthorizationCheckerInterface $authorization,
- private ObjectManager $om,
- private Crud $crud,
- private FinderProvider $finder,
- private SerializerProvider $serializer,
- private WorkspaceEvaluationManager $manager,
- private PdfManager $pdfManager
+ private readonly TokenStorageInterface $tokenStorage,
+ private readonly ObjectManager $om,
+ private readonly Crud $crud,
+ private readonly FinderProvider $finder,
+ private readonly SerializerProvider $serializer,
+ private readonly WorkspaceEvaluationManager $manager,
+ private readonly PdfManager $pdfManager,
+ private readonly ToolManager $toolManager
) {
$this->authorization = $authorization;
}
@@ -339,7 +342,7 @@ public function removeRequiredResourcesAction(Workspace $workspace, Request $req
$resources = $this->decodeIdsString($request, ResourceNode::class);
- // we can not do it inside a flush suite because it will trigger the Workspace to recompute its evaluation
+ // we can not do it inside a flush suite because it will trigger the Workspace to recompute its evaluation,
// and it requires to have all the data recorded inside the db.
// we can create a messenger message for it later if there are performances issues.
foreach ($resources as $resource) {
@@ -358,9 +361,9 @@ public function removeRequiredResourcesAction(Workspace $workspace, Request $req
private function checkToolAccess(string $permission, Workspace $workspace = null, bool $exception = true): bool
{
if (!empty($workspace)) {
- $evaluationTool = $this->om->getRepository(OrderedTool::class)->findOneByNameAndWorkspace('evaluation', $workspace);
+ $evaluationTool = $this->toolManager->getOrderedTool('evaluation', WorkspaceContext::getName(), $workspace->getUuid());
} else {
- $evaluationTool = $this->om->getRepository(OrderedTool::class)->findOneByNameAndDesktop('evaluation');
+ $evaluationTool = $this->toolManager->getOrderedTool('evaluation', DesktopContext::getName());
}
return $this->checkPermission($permission, $evaluationTool, [], $exception);
diff --git a/src/main/evaluation/DependencyInjection/ClarolineEvaluationExtension.php b/src/main/evaluation/DependencyInjection/ClarolineEvaluationExtension.php
index 87ce2ccdcdf..8447be546d3 100644
--- a/src/main/evaluation/DependencyInjection/ClarolineEvaluationExtension.php
+++ b/src/main/evaluation/DependencyInjection/ClarolineEvaluationExtension.php
@@ -18,7 +18,7 @@
class ClarolineEvaluationExtension extends Extension
{
- public function load(array $configs, ContainerBuilder $container)
+ public function load(array $configs, ContainerBuilder $container): void
{
$locator = new FileLocator(__DIR__.'/../Resources/config');
$loader = new YamlFileLoader($container, $locator);
diff --git a/src/main/evaluation/Installation/ClarolineEvaluationInstaller.php b/src/main/evaluation/Installation/ClarolineEvaluationInstaller.php
index 045b3daffb1..048fa872cf0 100644
--- a/src/main/evaluation/Installation/ClarolineEvaluationInstaller.php
+++ b/src/main/evaluation/Installation/ClarolineEvaluationInstaller.php
@@ -19,9 +19,4 @@ public function hasFixtures(): bool
{
return true;
}
-
- public function hasMigrations(): bool
- {
- return false;
- }
}
diff --git a/src/main/evaluation/Resources/config/services/controller.yml b/src/main/evaluation/Resources/config/services/controller.yml
index 8f922b39506..bd8d3c27c2f 100644
--- a/src/main/evaluation/Resources/config/services/controller.yml
+++ b/src/main/evaluation/Resources/config/services/controller.yml
@@ -4,14 +4,15 @@ services:
Claroline\EvaluationBundle\Controller\WorkspaceEvaluationController:
arguments:
- - '@security.token_storage'
- '@security.authorization_checker'
+ - '@security.token_storage'
- '@Claroline\AppBundle\Persistence\ObjectManager'
- '@Claroline\AppBundle\API\Crud'
- '@Claroline\AppBundle\API\FinderProvider'
- '@Claroline\AppBundle\API\SerializerProvider'
- '@Claroline\EvaluationBundle\Manager\WorkspaceEvaluationManager'
- '@Claroline\EvaluationBundle\Manager\PdfManager'
+ - '@Claroline\CoreBundle\Manager\Tool\ToolManager'
Claroline\EvaluationBundle\Controller\ResourceUserEvaluationController:
arguments:
diff --git a/src/main/evaluation/Tests/Library/Checker/ProgressionCheckerTest.php b/src/main/evaluation/Tests/Library/Checker/ProgressionCheckerTest.php
new file mode 100644
index 00000000000..74e6c7af8bf
--- /dev/null
+++ b/src/main/evaluation/Tests/Library/Checker/ProgressionCheckerTest.php
@@ -0,0 +1,55 @@
+expectException(\InvalidArgumentException::class);
+ new ProgressionChecker(-1);
+ }
+
+ public function testThresholdOverHundredThrowsException(): void
+ {
+ $this->expectException(\InvalidArgumentException::class);
+ new ProgressionChecker(300);
+ }
+
+ public function testSupportEvaluation(): void
+ {
+ $checker = new ProgressionChecker(100);
+
+ $evaluation = new GenericEvaluation(100);
+ $this->assertTrue($checker->supports($evaluation));
+ }
+
+ public function testVoteNotAttempted(): void
+ {
+ $checker = new ProgressionChecker(70);
+
+ $notAttemptedEvaluation = new GenericEvaluation(0);
+ $this->assertEquals(EvaluationStatus::NOT_ATTEMPTED, $checker->vote($notAttemptedEvaluation));
+ }
+
+ public function testVoteIncomplete(): void
+ {
+ $checker = new ProgressionChecker(70);
+
+ $incompleteEvaluation = new GenericEvaluation(69);
+ $this->assertEquals(EvaluationStatus::INCOMPLETE, $checker->vote($incompleteEvaluation));
+ }
+
+ public function testVotePassed(): void
+ {
+ $checker = new ProgressionChecker();
+
+ $endedEvaluation = new GenericEvaluation(100);
+ $this->assertEquals(EvaluationStatus::COMPLETED, $checker->vote($endedEvaluation));
+ }
+}
diff --git a/src/main/evaluation/Tests/Library/Checker/ScoreCheckerTest.php b/src/main/evaluation/Tests/Library/Checker/ScoreCheckerTest.php
index 5f361f863d6..b7dd154db0c 100644
--- a/src/main/evaluation/Tests/Library/Checker/ScoreCheckerTest.php
+++ b/src/main/evaluation/Tests/Library/Checker/ScoreCheckerTest.php
@@ -2,26 +2,26 @@
namespace Claroline\EvaluationBundle\Tests\Library;
-use Claroline\EvaluationBundle\Entity\AbstractEvaluation;
use Claroline\EvaluationBundle\Library\Checker\ScoreChecker;
+use Claroline\EvaluationBundle\Library\EvaluationStatus;
use Claroline\EvaluationBundle\Library\GenericEvaluation;
use PHPUnit\Framework\TestCase;
final class ScoreCheckerTest extends TestCase
{
- public function testSuccessScoreUnderZeroThrowsException()
+ public function testSuccessScoreUnderZeroThrowsException(): void
{
$this->expectException(\InvalidArgumentException::class);
new ScoreChecker(-1);
}
- public function testSuccessScoreOverHundredThrowsException()
+ public function testSuccessScoreOverHundredThrowsException(): void
{
$this->expectException(\InvalidArgumentException::class);
new ScoreChecker(300);
}
- public function testSupportEvaluationWithScore()
+ public function testSupportEvaluationWithScore(): void
{
$checker = new ScoreChecker(100);
@@ -29,7 +29,7 @@ public function testSupportEvaluationWithScore()
$this->assertTrue($checker->supports($evaluationWithScore));
}
- public function testDontSupportEvaluationWithoutScore()
+ public function testDontSupportEvaluationWithoutScore(): void
{
$checker = new ScoreChecker(100);
@@ -37,14 +37,14 @@ public function testDontSupportEvaluationWithoutScore()
$this->assertFalse($checker->supports($evaluationWithoutScore));
}
- public function testDontVoteIfNoSuccessScore()
+ public function testDontVoteIfNoSuccessScore(): void
{
$checker = new ScoreChecker(0);
$this->assertNull($checker->vote(new GenericEvaluation(100, 10)));
}
- public function testDontVoteForNonTerminatedEvaluation()
+ public function testDontVoteForNonTerminatedEvaluation(): void
{
$checker = new ScoreChecker(100);
@@ -52,7 +52,7 @@ public function testDontVoteForNonTerminatedEvaluation()
$this->assertNull($checker->vote($nonTerminatedEvaluation));
}
- public function testVoteForTerminatedEvaluationWithScore()
+ public function testVoteForTerminatedEvaluationWithScore(): void
{
$checker = new ScoreChecker(100);
@@ -60,19 +60,19 @@ public function testVoteForTerminatedEvaluationWithScore()
$this->assertNotNull($checker->vote($terminatedEvaluation));
}
- public function testVotePassed()
+ public function testVotePassed(): void
{
$checker = new ScoreChecker(70);
$passedEvaluation = new GenericEvaluation(100, 100, 70);
- $this->assertEquals(AbstractEvaluation::STATUS_PASSED, $checker->vote($passedEvaluation));
+ $this->assertEquals(EvaluationStatus::PASSED, $checker->vote($passedEvaluation));
}
- public function testVoteFailed()
+ public function testVoteFailed(): void
{
$checker = new ScoreChecker(70);
$failedEvaluation = new GenericEvaluation(100, 100, 60);
- $this->assertEquals(AbstractEvaluation::STATUS_PASSED, $checker->vote($failedEvaluation));
+ $this->assertEquals(EvaluationStatus::FAILED, $checker->vote($failedEvaluation));
}
}
diff --git a/src/main/evaluation/Tests/Library/GenericEvaluationTest.php b/src/main/evaluation/Tests/Library/GenericEvaluationTest.php
index de09a429e81..6fb759cb469 100644
--- a/src/main/evaluation/Tests/Library/GenericEvaluationTest.php
+++ b/src/main/evaluation/Tests/Library/GenericEvaluationTest.php
@@ -7,43 +7,43 @@
final class GenericEvaluationTest extends TestCase
{
- public function testProgressionUnderZeroThrowsException()
+ public function testProgressionUnderZeroThrowsException(): void
{
$this->expectException(\InvalidArgumentException::class);
new GenericEvaluation(-1);
}
- public function testProgressionOverHundredThrowsException()
+ public function testProgressionOverHundredThrowsException(): void
{
$this->expectException(\InvalidArgumentException::class);
new GenericEvaluation(300);
}
- public function testGetProgression()
+ public function testGetProgression(): void
{
$evaluation = new GenericEvaluation(1);
$this->assertEquals(1, $evaluation->getProgression());
}
- public function testGetScoreMax()
+ public function testGetScoreMax(): void
{
$evaluation = new GenericEvaluation(100, 5);
$this->assertEquals(5, $evaluation->getScoreMax());
}
- public function testGetScore()
+ public function testGetScore(): void
{
$evaluation = new GenericEvaluation(100, 5, 2);
$this->assertEquals(2, $evaluation->getScore());
}
- public function testIsTerminatedIfProgressionIsHundred()
+ public function testIsTerminatedIfProgressionIsHundred(): void
{
$evaluation = new GenericEvaluation(100, 5, 2);
$this->assertTrue($evaluation->isTerminated());
}
- public function testIsNotTerminatedIfProgressionIsNotHundred()
+ public function testIsNotTerminatedIfProgressionIsNotHundred(): void
{
$evaluation = new GenericEvaluation(50, 5, 2);
$this->assertFalse($evaluation->isTerminated());
diff --git a/src/main/installation/Additional/AdditionalInstaller.php b/src/main/installation/Additional/AdditionalInstaller.php
index 67d16b6649e..9a17ff0248d 100644
--- a/src/main/installation/Additional/AdditionalInstaller.php
+++ b/src/main/installation/Additional/AdditionalInstaller.php
@@ -11,46 +11,36 @@
namespace Claroline\InstallationBundle\Additional;
-use Claroline\AppBundle\Log\LoggableTrait;
use Claroline\AppBundle\Persistence\ObjectManager;
use Claroline\CoreBundle\Entity\Update\UpdaterExecution;
use Claroline\InstallationBundle\Repository\UpdaterExecutionRepository;
use Claroline\InstallationBundle\Updater\NonReplayableUpdaterInterface;
use Psr\Container\ContainerInterface;
use Psr\Log\LoggerAwareInterface;
+use Psr\Log\LoggerAwareTrait;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerAwareTrait;
-abstract class AdditionalInstaller implements LoggerAwareInterface, ContainerAwareInterface, AdditionalInstallerInterface
+abstract class AdditionalInstaller implements AdditionalInstallerInterface, ContainerAwareInterface, LoggerAwareInterface
{
- use LoggableTrait;
use ContainerAwareTrait;
+ use LoggerAwareTrait;
/**
- * @var string
+ * Whether updaters should be executed even if they have been already.
*/
- protected $environment;
+ private bool $shouldReplayUpdaters = false;
/**
- * @var bool whether updaters should be executed even if they have been already
+ * A scoped container allowing to load Updater services.
*/
- private $shouldReplayUpdaters = false;
-
- /**
- * @var ContainerInterface|null a scoped container allowing to load Updater services
- */
- private $updaterLocator;
+ private ?ContainerInterface $updaterLocator;
public function __construct(ContainerInterface $updaterLocator = null)
{
$this->updaterLocator = $updaterLocator;
}
- public function setEnvironment($environment)
- {
- $this->environment = $environment;
- }
-
public function setShouldReplayUpdaters(bool $shouldReplayUpdaters): void
{
$this->shouldReplayUpdaters = $shouldReplayUpdaters;
@@ -63,7 +53,7 @@ public function shouldReplayUpdaters(): bool
public function hasMigrations(): bool
{
- return true; // should be false by default
+ return false;
}
public function hasFixtures(): bool
@@ -71,15 +61,15 @@ public function hasFixtures(): bool
return false;
}
- public function preInstall()
+ public function preInstall(): void
{
}
- public function postInstall()
+ public function postInstall(): void
{
}
- public function preUpdate($currentVersion, $targetVersion)
+ public function preUpdate(string $currentVersion, string $targetVersion): void
{
/** @var UpdaterExecutionRepository $updaterExecutionRepository */
$updaterExecutionRepository = $this->container->get(ObjectManager::class)->getRepository(UpdaterExecution::class);
@@ -91,17 +81,17 @@ public function preUpdate($currentVersion, $targetVersion)
$hasBeenExecuted = $updaterExecutionRepository->hasBeenExecuted($updaterClass);
if ($hasBeenExecuted && (!$this->shouldReplayUpdaters() || \is_subclass_of($updaterClass, NonReplayableUpdaterInterface::class))) {
- $this->log(sprintf('Skipping "%s" because it has been already executed.', $updaterClass));
+ $this->logger->info(sprintf('Skipping "%s" because it has been already executed.', $updaterClass));
continue;
}
- $this->log(sprintf('Executing "%s" preUpdate.', $updaterClass));
+ $this->logger->info(sprintf('Executing "%s" preUpdate.', $updaterClass));
$updater = $this->updaterLocator->get($updaterClass);
$updater->preUpdate();
}
}
- public function postUpdate($currentVersion, $targetVersion)
+ public function postUpdate(string $currentVersion, string $targetVersion): void
{
/** @var UpdaterExecutionRepository $updaterExecutionRepository */
$updaterExecutionRepository = $this->container->get(ObjectManager::class)->getRepository(UpdaterExecution::class);
@@ -117,7 +107,7 @@ public function postUpdate($currentVersion, $targetVersion)
return;
}
- $this->log(sprintf('Executing "%s" postUpdate.', $updaterClass));
+ $this->logger->info(sprintf('Executing "%s" postUpdate.', $updaterClass));
$updater = $this->updaterLocator->get($updaterClass);
$updater->postUpdate();
@@ -127,15 +117,15 @@ public function postUpdate($currentVersion, $targetVersion)
}
}
- public function preUninstall()
+ public function preUninstall(): void
{
}
- public function postUninstall()
+ public function postUninstall(): void
{
}
- public function end($currentVersion, $targetVersion)
+ public function end(string $currentVersion, string $targetVersion): void
{
}
diff --git a/src/main/installation/Additional/AdditionalInstallerInterface.php b/src/main/installation/Additional/AdditionalInstallerInterface.php
index 702feea4972..3170425c59a 100644
--- a/src/main/installation/Additional/AdditionalInstallerInterface.php
+++ b/src/main/installation/Additional/AdditionalInstallerInterface.php
@@ -11,29 +11,25 @@
namespace Claroline\InstallationBundle\Additional;
-use Psr\Log\LoggerAwareInterface;
-
-interface AdditionalInstallerInterface extends LoggerAwareInterface
+interface AdditionalInstallerInterface
{
- public function setEnvironment($environment);
-
public function setShouldReplayUpdaters(bool $shouldReplayUpdaters): void;
public function shouldReplayUpdaters(): bool;
- public function preInstall();
+ public function preInstall(): void;
- public function postInstall();
+ public function postInstall(): void;
- public function preUpdate($currentVersion, $targetVersion);
+ public function preUpdate(string $currentVersion, string $targetVersion): void;
- public function postUpdate($currentVersion, $targetVersion);
+ public function postUpdate(string $currentVersion, string $targetVersion);
- public function preUninstall();
+ public function preUninstall(): void;
- public function postUninstall();
+ public function postUninstall(): void;
- public function end($currentVersion, $targetVersion);
+ public function end(string $currentVersion, string $targetVersion);
/**
* @return string[] An array of Updater service identifiers (i.e. FQCN) indexed by version
diff --git a/src/main/installation/Command/AbstractPluginCommand.php b/src/main/installation/Command/AbstractPluginCommand.php
index b3e9cff05e8..116c2032f22 100644
--- a/src/main/installation/Command/AbstractPluginCommand.php
+++ b/src/main/installation/Command/AbstractPluginCommand.php
@@ -11,7 +11,7 @@
namespace Claroline\InstallationBundle\Command;
-use Claroline\CoreBundle\Library\Installation\Plugin\Installer;
+use Claroline\InstallationBundle\Manager\PluginManager;
use Claroline\KernelBundle\Bundle\PluginBundle;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\ArrayInput;
@@ -24,28 +24,28 @@
*/
abstract class AbstractPluginCommand extends Command
{
- protected $pluginInstaller;
+ protected PluginManager $pluginInstaller;
- public function __construct(Installer $pluginInstaller)
+ public function __construct(PluginManager $pluginInstaller)
{
$this->pluginInstaller = $pluginInstaller;
parent::__construct();
}
- protected function configure()
+ protected function configure(): void
{
$this->addArgument('bundle', InputArgument::REQUIRED, 'The bundle name');
}
- protected function getPlugin(InputInterface $input)
+ protected function getPlugin(InputInterface $input): PluginBundle
{
$bundleName = $input->getArgument('bundle');
$kernel = $this->getApplication()->getKernel();
$bundle = $kernel->getBundle($bundleName);
if (empty($bundle)) {
- throw new \Exception("Cannot found bundle '{$bundleName}' in the bundles.ini");
+ throw new \Exception("Cannot find bundle '{$bundleName}' in the bundles.ini");
}
if (!$bundle instanceof PluginBundle) {
@@ -58,7 +58,7 @@ protected function getPlugin(InputInterface $input)
/**
* Clears the cache (mandatory after plugin installation/uninstallation).
*/
- protected function resetCache(OutputInterface $output)
+ protected function resetCache(OutputInterface $output): void
{
$command = $this->getApplication()->get('cache:clear');
diff --git a/src/main/installation/Command/PlatformUpdateCommand.php b/src/main/installation/Command/PlatformUpdateCommand.php
index 347bd1d31ad..e5e6ddcc3b3 100644
--- a/src/main/installation/Command/PlatformUpdateCommand.php
+++ b/src/main/installation/Command/PlatformUpdateCommand.php
@@ -12,9 +12,9 @@
namespace Claroline\InstallationBundle\Command;
use Claroline\CoreBundle\Library\Configuration\PlatformConfigurationHandler;
-use Claroline\CoreBundle\Library\Installation\PlatformInstaller;
use Claroline\CoreBundle\Library\Maintenance\MaintenanceHandler;
use Claroline\CoreBundle\Manager\VersionManager;
+use Claroline\InstallationBundle\Manager\PlatformManager;
use Claroline\InstallationBundle\Manager\RefreshManager;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
@@ -35,7 +35,7 @@ class PlatformUpdateCommand extends Command
public function __construct(
RefreshManager $refresher,
- PlatformInstaller $installer,
+ PlatformManager $installer,
VersionManager $versionManager,
PlatformConfigurationHandler $config,
string $environment
diff --git a/src/main/installation/Command/PluginInstallCommand.php b/src/main/installation/Command/PluginInstallCommand.php
index 71da0450c79..030911eb09d 100644
--- a/src/main/installation/Command/PluginInstallCommand.php
+++ b/src/main/installation/Command/PluginInstallCommand.php
@@ -19,7 +19,7 @@
*/
class PluginInstallCommand extends AbstractPluginCommand
{
- protected function configure()
+ protected function configure(): void
{
parent::configure();
diff --git a/src/main/installation/Command/PluginUninstallCommand.php b/src/main/installation/Command/PluginUninstallCommand.php
index 5547a85a772..7bf878ea4ef 100644
--- a/src/main/installation/Command/PluginUninstallCommand.php
+++ b/src/main/installation/Command/PluginUninstallCommand.php
@@ -19,7 +19,7 @@
*/
class PluginUninstallCommand extends AbstractPluginCommand
{
- protected function configure()
+ protected function configure(): void
{
parent::configure();
diff --git a/src/main/installation/Fixtures/FixtureLoader.php b/src/main/installation/Fixtures/FixtureLoader.php
index acb1c9955ca..3376a5da5cc 100644
--- a/src/main/installation/Fixtures/FixtureLoader.php
+++ b/src/main/installation/Fixtures/FixtureLoader.php
@@ -11,10 +11,10 @@
namespace Claroline\InstallationBundle\Fixtures;
-use Claroline\AppBundle\Log\LoggableTrait;
use Doctrine\Common\DataFixtures\Executor\ORMExecutor;
use Psr\Container\ContainerInterface;
use Psr\Log\LoggerAwareInterface;
+use Psr\Log\LoggerAwareTrait;
use Symfony\Component\HttpKernel\Bundle\BundleInterface;
/**
@@ -22,7 +22,7 @@
*/
class FixtureLoader implements LoggerAwareInterface
{
- use LoggableTrait;
+ use LoggerAwareTrait;
private $container;
private $executor;
@@ -50,7 +50,7 @@ public function load(BundleInterface $bundle, string $event): bool
$toLoad = [];
foreach ($fixtures as $fixture) {
if ($fixture instanceof $event) {
- $this->log(sprintf('Found %s fixture to load', get_class($fixture)));
+ $this->logger->info(sprintf('Found %s fixture to load', get_class($fixture)));
if (method_exists($fixture, 'setLogger')) {
$fixture->setLogger($this->logger);
diff --git a/src/main/installation/Manager/InstallationManager.php b/src/main/installation/Manager/BundleManager.php
similarity index 75%
rename from src/main/installation/Manager/InstallationManager.php
rename to src/main/installation/Manager/BundleManager.php
index 35400097ac9..d04ea1e3a78 100644
--- a/src/main/installation/Manager/InstallationManager.php
+++ b/src/main/installation/Manager/BundleManager.php
@@ -11,7 +11,6 @@
namespace Claroline\InstallationBundle\Manager;
-use Claroline\AppBundle\Log\LoggableTrait;
use Claroline\CoreBundle\Library\Installation\Plugin\Recorder;
use Claroline\InstallationBundle\Additional\AdditionalInstallerInterface;
use Claroline\InstallationBundle\Bundle\InstallableInterface;
@@ -24,12 +23,16 @@
use Claroline\MigrationBundle\Manager\Manager;
use Claroline\MigrationBundle\Migrator\Migrator;
use Psr\Log\LoggerAwareInterface;
+use Psr\Log\LoggerAwareTrait;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
-class InstallationManager implements LoggerAwareInterface
+/**
+ * Manages installation for Installable bundles.
+ */
+class BundleManager implements LoggerAwareInterface
{
- use LoggableTrait;
+ use LoggerAwareTrait;
/**
* Whether additional installers should re-execute updaters that have been previously executed.
@@ -40,20 +43,19 @@ public function __construct(
private readonly ContainerInterface $container,
private readonly Manager $migrationManager,
private readonly FixtureLoader $fixtureLoader,
- private readonly Recorder $recorder,
- private readonly string $environment
+ private readonly Recorder $recorder
) {
}
public function install(InstallableInterface $bundle): void
{
- $this->log(sprintf('Installing %s %s... ', $bundle->getName(), $bundle->getVersion()));
+ $this->logger->info(sprintf('Installing %s %s...>', $bundle->getName(), $bundle->getVersion()));
$additionalInstaller = $this->getAdditionalInstaller($bundle);
if (!$additionalInstaller) {
// Load configuration
if ($bundle instanceof PluginBundleInterface) {
- $this->log('Saving configuration...');
+ $this->logger->info('Saving configuration...');
$this->recorder->register($bundle);
}
@@ -61,43 +63,43 @@ public function install(InstallableInterface $bundle): void
return;
}
- $this->log('Launching pre-installation actions...');
+ $this->logger->info('Launching pre-installation actions...');
$additionalInstaller->preInstall();
if ($additionalInstaller->hasMigrations()) {
- $this->log('Executing migrations...');
+ $this->logger->info('Executing migrations...');
$this->migrationManager->upgradeBundle($bundle, Migrator::VERSION_LATEST);
}
if ($additionalInstaller->hasFixtures()) {
- $this->log('Loading pre-install fixtures...');
+ $this->logger->info('Loading pre-install fixtures...');
$this->fixtureLoader->load($bundle, PreInstallInterface::class);
}
// Load configuration
if ($bundle instanceof PluginBundleInterface) {
- $this->log('Saving configuration...');
+ $this->logger->info('Saving configuration...');
$this->recorder->register($bundle);
}
- $this->log('Launching post-installation actions...');
+ $this->logger->info('Launching post-installation actions...');
$additionalInstaller->postInstall();
if ($additionalInstaller->hasFixtures()) {
- $this->log('Loading post-install fixtures...');
+ $this->logger->info('Loading post-install fixtures...');
$this->fixtureLoader->load($bundle, PostInstallInterface::class);
}
}
public function update(InstallableInterface $bundle, $currentVersion, $targetVersion): void
{
- $this->log(sprintf('Updating %s from %s to %s...', $bundle->getName(), $currentVersion, $targetVersion));
+ $this->logger->info(sprintf('Updating %s from %s to %s...', $bundle->getName(), $currentVersion, $targetVersion));
$additionalInstaller = $this->getAdditionalInstaller($bundle);
if (!$additionalInstaller) {
// Update configuration
if ($bundle instanceof PluginBundleInterface) {
- $this->log('Updating configuration...');
+ $this->logger->info('Updating configuration...');
$this->recorder->update($bundle);
}
@@ -105,31 +107,31 @@ public function update(InstallableInterface $bundle, $currentVersion, $targetVer
return;
}
- $this->log('Launching pre-update actions...');
+ $this->logger->info('Launching pre-update actions...');
$additionalInstaller->setShouldReplayUpdaters($this->shouldReplayUpdaters);
$additionalInstaller->preUpdate($currentVersion, $targetVersion);
if ($additionalInstaller->hasMigrations()) {
- $this->log('Executing migrations...');
+ $this->logger->info('Executing migrations...');
$this->migrationManager->upgradeBundle($bundle, Migrator::VERSION_LATEST);
}
if ($additionalInstaller->hasFixtures()) {
- $this->log('Loading pre-update fixtures...');
+ $this->logger->info('Loading pre-update fixtures...');
$this->fixtureLoader->load($bundle, PreUpdateInterface::class);
}
// Update configuration
if ($bundle instanceof PluginBundleInterface) {
- $this->log('Updating configuration...');
+ $this->logger->info('Updating configuration...');
$this->recorder->update($bundle);
}
- $this->log('Launching post-update actions...');
+ $this->logger->info('Launching post-update actions...');
$additionalInstaller->postUpdate($currentVersion, $targetVersion);
if ($additionalInstaller->hasFixtures()) {
- $this->log('Loading post-update fixtures...');
+ $this->logger->info('Loading post-update fixtures...');
$this->fixtureLoader->load($bundle, PostUpdateInterface::class);
}
}
@@ -148,7 +150,7 @@ public function end(InstallableInterface $bundle, $currentVersion = null, $targe
public function uninstall(InstallableInterface $bundle): void
{
- $this->log(sprintf('Uninstalling %s...', $bundle->getName()));
+ $this->logger->info(sprintf('Uninstalling %s...', $bundle->getName()));
$additionalInstaller = $this->getAdditionalInstaller($bundle);
if (!$additionalInstaller) {
@@ -156,15 +158,15 @@ public function uninstall(InstallableInterface $bundle): void
return;
}
- $this->log('Launching pre-uninstallation actions...');
+ $this->logger->info('Launching pre-uninstallation actions...');
$additionalInstaller->preUninstall();
if ($additionalInstaller->hasMigrations()) {
- $this->log('Executing migrations...');
+ $this->logger->info('Executing migrations...');
$this->migrationManager->downgradeBundle($bundle, Migrator::VERSION_LATEST);
}
- $this->log('Launching post-uninstallation actions...');
+ $this->logger->info('Launching post-uninstallation actions...');
$additionalInstaller->postUninstall();
}
@@ -178,8 +180,9 @@ private function getAdditionalInstaller(InstallableInterface $bundle): ?Addition
$installer = $bundle->getAdditionalInstaller();
if ($installer instanceof AdditionalInstallerInterface) {
- $installer->setEnvironment($this->environment);
- $installer->setLogger($this->logger);
+ if ($installer instanceof LoggerAwareInterface) {
+ $installer->setLogger($this->logger);
+ }
if ($installer instanceof ContainerAwareInterface) {
$installer->setContainer($this->container);
diff --git a/src/main/core/Library/Installation/PlatformInstaller.php b/src/main/installation/Manager/PlatformManager.php
similarity index 70%
rename from src/main/core/Library/Installation/PlatformInstaller.php
rename to src/main/installation/Manager/PlatformManager.php
index 076534e54e9..7d051cf10c6 100644
--- a/src/main/core/Library/Installation/PlatformInstaller.php
+++ b/src/main/installation/Manager/PlatformManager.php
@@ -9,18 +9,15 @@
* file that was distributed with this source code.
*/
-namespace Claroline\CoreBundle\Library\Installation;
+namespace Claroline\InstallationBundle\Manager;
-use Claroline\AppBundle\Log\LoggableTrait;
use Claroline\AppBundle\Persistence\ObjectManager;
use Claroline\CoreBundle\Entity\Plugin;
-use Claroline\CoreBundle\Library\Installation\Plugin\Installer;
-use Claroline\CoreBundle\Manager\PluginManager;
use Claroline\InstallationBundle\Bundle\InstallableInterface;
-use Claroline\InstallationBundle\Manager\InstallationManager;
use Doctrine\Bundle\DoctrineBundle\Command\CreateDatabaseDoctrineCommand;
use Doctrine\DBAL\Exception\TableNotFoundException;
use Psr\Log\LoggerAwareInterface;
+use Psr\Log\LoggerAwareTrait;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Output\NullOutput;
use Symfony\Component\Console\Output\OutputInterface;
@@ -31,32 +28,19 @@
* Entry point of platform installation/update, ensuring that minimal requirements
* (e.g. existing database) are met before executing operations.
*/
-class PlatformInstaller implements LoggerAwareInterface
+class PlatformManager implements LoggerAwareInterface
{
- use LoggableTrait;
+ use LoggerAwareTrait;
- private $kernel;
- private $pluginManager;
- private $pluginInstaller;
- private $om;
- private $baseInstaller;
- private $container;
- private $output;
+ private OutputInterface $output;
public function __construct(
- KernelInterface $kernel,
- PluginManager $pluginManager,
- Installer $pluginInstaller,
- ObjectManager $om,
- InstallationManager $baseInstaller,
- ContainerInterface $container
+ private readonly ContainerInterface $container,
+ private readonly KernelInterface $kernel,
+ private readonly ObjectManager $om,
+ private readonly BundleManager $baseInstaller,
+ private readonly PluginManager $pluginInstaller
) {
- $this->kernel = $kernel;
- $this->pluginManager = $pluginManager;
- $this->pluginInstaller = $pluginInstaller;
- $this->om = $om;
- $this->baseInstaller = $baseInstaller;
- $this->container = $container;
}
public function setShouldReplayUpdaters(bool $shouldReplayUpdaters): void
@@ -64,7 +48,7 @@ public function setShouldReplayUpdaters(bool $shouldReplayUpdaters): void
$this->baseInstaller->setShouldReplayUpdaters($shouldReplayUpdaters);
}
- public function setOutput(OutputInterface $output)
+ public function setOutput(OutputInterface $output): void
{
$this->output = $output;
}
@@ -72,7 +56,7 @@ public function setOutput(OutputInterface $output)
/**
* Installs platform packages based on the bundles configuration (INI file).
*/
- public function installAll()
+ public function installAll(): void
{
$this->launchPreInstallActions();
@@ -82,7 +66,7 @@ public function installAll()
$this->end($bundles);
}
- public function updateAll($from, $to)
+ public function updateAll($from, $to): void
{
$bundles = $this->getInstallableBundles();
@@ -90,7 +74,7 @@ public function updateAll($from, $to)
$this->end($bundles, $from, $to);
}
- public function execute(array $bundles, ?string $fromVersion = null, ?string $toVersion = null)
+ public function execute(array $bundles, ?string $fromVersion = null, ?string $toVersion = null): void
{
$isFreshInstall = !$fromVersion && !$toVersion;
@@ -105,9 +89,9 @@ public function execute(array $bundles, ?string $fromVersion = null, ?string $to
}
}
- private function end(array $bundles, ?string $fromVersion = null, ?string $toVersion = null)
+ private function end(array $bundles, ?string $fromVersion = null, ?string $toVersion = null): void
{
- $this->log('Ending operations...');
+ $this->logger->info('Ending operations...');
$isFreshInstall = !$fromVersion && !$toVersion;
@@ -122,42 +106,43 @@ private function end(array $bundles, ?string $fromVersion = null, ?string $toVer
private function getInstallableBundles(): array
{
- // during the install/update process all the available bundles are loaded in the kernel
+ // during the installation/update process all the available bundles are loaded in the kernel
// @see Claroline\KernelBundle\Kernel::registerBundles()
return array_filter($this->kernel->getBundles(), function ($bundle) {
return $bundle instanceof InstallableInterface;
});
}
- private function isBundleAlreadyInstalled($bundleFqcn, $checkCoreBundle = true)
+ private function isBundleAlreadyInstalled(string $bundleFqcn, bool $checkCoreBundle = true): bool
{
if ('Claroline\CoreBundle\ClarolineCoreBundle' === $bundleFqcn && !$checkCoreBundle) {
return true;
}
try {
- return $this->om->getRepository(Plugin::class)->findOneByBundleFQCN($bundleFqcn);
+ return !empty($this->om->getRepository(Plugin::class)->findOneByBundleFQCN($bundleFqcn));
} catch (TableNotFoundException $e) {
// we're probably installing the platform because the database isn't here yet do... return false
return false;
}
}
- private function launchPreInstallActions()
+ private function launchPreInstallActions(): void
{
$this->createDatabaseIfNotExists();
}
- private function createDatabaseIfNotExists()
+ private function createDatabaseIfNotExists(): void
{
try {
- $this->log('Checking database connection...');
- $cn = $this->container->get('doctrine.dbal.default_connection');
+ $this->logger->info('Checking database connection...');
+ $cn = $this->container->get('doctrine.dbal.default_connection');
// see http://stackoverflow.com/questions/3668506/efficient-sql-test-query-or-validation-query-that-will-work-across-all-or-most
$cn->query('SELECT 1');
} catch (\Exception $ex) {
- $this->log('Unable to connect to database: trying to create database...');
+ $this->logger->notice('Unable to connect to database: trying to create database...');
+
$command = new CreateDatabaseDoctrineCommand($this->container->get('doctrine'));
$code = $command->run(new ArrayInput([]), $this->output ?: new NullOutput());
diff --git a/src/main/installation/Manager/PluginManager.php b/src/main/installation/Manager/PluginManager.php
new file mode 100644
index 00000000000..7f7d726036e
--- /dev/null
+++ b/src/main/installation/Manager/PluginManager.php
@@ -0,0 +1,106 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Claroline\InstallationBundle\Manager;
+
+use Claroline\AppBundle\Persistence\ObjectManager;
+use Claroline\CoreBundle\Library\Installation\Plugin\Recorder;
+use Claroline\CoreBundle\Library\Installation\Plugin\Validator;
+use Claroline\CoreBundle\Manager\PluginManager as BasePluginManager;
+use Claroline\CoreBundle\Manager\VersionManager;
+use Claroline\KernelBundle\Bundle\PluginBundleInterface;
+use Psr\Log\LoggerAwareInterface;
+use Psr\Log\LoggerAwareTrait;
+
+/**
+ * This class is used to perform the (un-)installation of a plugin.
+ */
+class PluginManager implements LoggerAwareInterface
+{
+ use LoggerAwareTrait;
+
+ public function __construct(
+ private readonly Validator $validator,
+ private readonly Recorder $recorder,
+ private readonly BundleManager $baseInstaller,
+ private readonly ObjectManager $om,
+ private readonly BasePluginManager $pluginManager,
+ private readonly VersionManager $versionManager
+ ) {
+ }
+
+ public function install(PluginBundleInterface $plugin): void
+ {
+ $this->baseInstaller->install($plugin);
+
+ $pluginEntity = $this->pluginManager->getPluginByShortName(
+ $plugin->getName()
+ );
+
+ if (!$this->pluginManager->isReady($pluginEntity)) {
+ $errors = $this->pluginManager->getMissingRequirements($pluginEntity);
+
+ foreach ($errors['extensions'] as $extension) {
+ $this->logger->error(sprintf('Extension %s missing for %s !', $extension, $plugin->getName()));
+ }
+
+ foreach ($errors['plugins'] as $bundle) {
+ $this->logger->error(sprintf('The plugin %s is required for %s ! You must enable it first to use %s.', $bundle, $plugin->getName(), $plugin->getName()));
+ }
+
+ foreach ($errors['extras'] as $extra) {
+ $this->logger->error(sprintf('The plugin %s has extra requirements ! %s.', $plugin->getName(), $extra));
+ }
+
+ $this->logger->critical(sprintf('Disabling %s...', $plugin->getName()));
+ $this->pluginManager->disable($pluginEntity);
+ }
+
+ $version = $this->versionManager->register($plugin);
+ $this->versionManager->execute($version);
+ }
+
+ public function uninstall(PluginBundleInterface $plugin): void
+ {
+ $this->checkInstallationStatus($plugin, true);
+
+ $this->logger->info('Removing plugin configuration...');
+ $this->recorder->unregister($plugin);
+ $this->baseInstaller->uninstall($plugin);
+ }
+
+ public function update(PluginBundleInterface $plugin, string $currentVersion, string $targetVersion): void
+ {
+ $this->checkInstallationStatus($plugin, true);
+
+ $this->baseInstaller->update($plugin, $currentVersion, $targetVersion);
+
+ // updates plugin version
+ $version = $this->versionManager->register($plugin);
+ $this->versionManager->execute($version);
+ }
+
+ public function end(PluginBundleInterface $plugin, string $currentVersion = null, string $targetVersion = null): void
+ {
+ $this->baseInstaller->end($plugin, $currentVersion, $targetVersion);
+ }
+
+ private function checkInstallationStatus(PluginBundleInterface $plugin, $shouldBeInstalled = true): void
+ {
+ $this->logger->info(sprintf('Checking installation status for plugin %s', $plugin->getName()));
+
+ if ($this->recorder->isRegistered($plugin) !== $shouldBeInstalled) {
+ $stateDiscr = $shouldBeInstalled ? 'not' : 'already';
+
+ throw new \LogicException("Plugin '{$plugin->getName()}' is {$stateDiscr} installed.");
+ }
+ }
+}
diff --git a/src/main/installation/Manager/RefreshManager.php b/src/main/installation/Manager/RefreshManager.php
index 89aac2205e0..34d9b11b5db 100644
--- a/src/main/installation/Manager/RefreshManager.php
+++ b/src/main/installation/Manager/RefreshManager.php
@@ -11,61 +11,36 @@
namespace Claroline\InstallationBundle\Manager;
-use Claroline\AppBundle\Manager\CommandManager;
use Psr\Log\LogLevel;
+use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Output\NullOutput;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Filesystem\Filesystem;
+use Symfony\Component\HttpKernel\KernelInterface;
class RefreshManager
{
- /** @var Filesystem */
- private $filesystem;
- /** @var CommandManager */
- private $commandManager;
-
- /** @var string */
- private $projectDir;
- /** @var string */
- private $cacheDir;
- /** @var string */
- private $publicDir;
- /** @var string */
- private $publicDataDir;
- /** @var string */
- private $filesDataDir;
-
- /** @var OutputInterface */
- private $output;
+ private OutputInterface $output;
public function __construct(
- Filesystem $filesystem,
- CommandManager $commandManager,
- string $projectDir,
- string $cacheDir,
- string $publicDir,
- string $publicDataDir,
- string $filesDataDir
+ private readonly KernelInterface $kernel,
+ private readonly Filesystem $filesystem,
+ private readonly string $projectDir,
+ private readonly string $cacheDir,
+ private readonly string $publicDir,
+ private readonly string $publicDataDir,
+ private readonly string $filesDataDir
) {
- $this->filesystem = $filesystem;
- $this->commandManager = $commandManager;
-
- $this->projectDir = $projectDir;
- $this->cacheDir = $cacheDir;
- $this->publicDir = $publicDir;
- $this->publicDataDir = $publicDataDir;
- $this->filesDataDir = $filesDataDir;
-
$this->output = new NullOutput();
}
- public function setOutput(OutputInterface $output)
+ public function setOutput(OutputInterface $output): void
{
$this->output = $output;
}
- public function refresh($environment)
+ public function refresh(string $environment): void
{
$this->buildSymlinks();
$this->installAssets();
@@ -73,18 +48,18 @@ public function refresh($environment)
$this->clearCache($environment);
}
- public function installAssets()
+ public function installAssets(): void
{
- $this->commandManager->run(new ArrayInput([
+ $this->runCommand(new ArrayInput([
'command' => 'assets:install',
'target' => $this->publicDir,
'--symlink' => true,
]), $this->output);
}
- public function dumpAssets()
+ public function dumpAssets(): void
{
- $this->commandManager->run(new ArrayInput([
+ $this->runCommand(new ArrayInput([
'command' => 'bazinga:js-translation:dump',
'target' => $this->publicDir.DIRECTORY_SEPARATOR.'js',
'--format' => ['js'],
@@ -92,29 +67,27 @@ public function dumpAssets()
]), $this->output);
}
- public function buildThemes()
+ public function buildThemes(): void
{
- $this->commandManager->run(new ArrayInput([
+ $this->runCommand(new ArrayInput([
'command' => 'claroline:theme:build',
]), $this->output);
}
- public function buildSymlinks()
+ public function buildSymlinks(): void
{
$this->linkPublicFiles();
$this->linkPackageFiles();
}
- public function clearCache(string $environment)
+ public function clearCache(string $environment): void
{
- if ($this->output) {
- $this->output->writeln('Clearing the cache...');
- }
+ $this->output->writeln('Clearing the cache...');
$this->removeContentFrom($this->cacheDir.DIRECTORY_SEPARATOR.$environment);
}
- private function removeContentFrom($directory)
+ private function removeContentFrom($directory): void
{
if (is_dir($directory)) {
$cacheIterator = new \DirectoryIterator($directory);
@@ -127,7 +100,7 @@ private function removeContentFrom($directory)
}
}
- private function linkPublicFiles()
+ private function linkPublicFiles(): void
{
if (!$this->filesystem->exists($this->publicDataDir)) {
$this->output->writeln('Creating symlink to public directory of files directory in public directory...');
@@ -142,7 +115,7 @@ private function linkPublicFiles()
}
}
- private function linkPackageFiles()
+ private function linkPackageFiles(): void
{
$packageDir = $this->publicDir.DIRECTORY_SEPARATOR.'packages';
@@ -150,7 +123,14 @@ private function linkPackageFiles()
$this->output->writeln('Creating symlink to '.$packageDir);
$this->filesystem->symlink($this->projectDir.DIRECTORY_SEPARATOR.'node_modules', $packageDir);
} elseif (!is_link($packageDir)) {
- $this->output->writeln('Couldn\'t create symlink from node_modules to public/packages. You must remove public/packages or create the link manually');
+ $this->output->writeln('Cannot create symlink from node_modules to public/packages. You must remove public/packages or create the link manually');
}
}
+
+ private function runCommand(ArrayInput $input, $output): void
+ {
+ $application = new Application($this->kernel);
+ $application->setAutoExit(false);
+ $application->run($input, $output);
+ }
}
diff --git a/src/main/installation/Resources/config/services/command.yml b/src/main/installation/Resources/config/services/command.yml
index a85a1a7c04e..ac50b4da8a0 100644
--- a/src/main/installation/Resources/config/services/command.yml
+++ b/src/main/installation/Resources/config/services/command.yml
@@ -18,7 +18,7 @@ services:
Claroline\InstallationBundle\Command\PlatformUpdateCommand:
arguments:
- '@Claroline\InstallationBundle\Manager\RefreshManager'
- - '@Claroline\CoreBundle\Library\Installation\PlatformInstaller'
+ - '@Claroline\InstallationBundle\Manager\PlatformManager'
- '@Claroline\CoreBundle\Manager\VersionManager'
- '@Claroline\CoreBundle\Library\Configuration\PlatformConfigurationHandler'
- '%kernel.environment%'
@@ -35,12 +35,12 @@ services:
Claroline\InstallationBundle\Command\PluginInstallCommand:
arguments:
- - '@Claroline\CoreBundle\Library\Installation\Plugin\Installer'
+ - '@Claroline\InstallationBundle\Manager\PluginManager'
tags:
- { name: 'console.command', command: 'claroline:plugin:install' }
Claroline\InstallationBundle\Command\PluginUninstallCommand:
arguments:
- - '@Claroline\CoreBundle\Library\Installation\Plugin\Installer'
+ - '@Claroline\InstallationBundle\Manager\PluginManager'
tags:
- { name: 'console.command', command: 'claroline:plugin:uninstall' }
diff --git a/src/main/installation/Resources/config/services/manager.yml b/src/main/installation/Resources/config/services/manager.yml
index e6cc46a8bf5..183faf56dea 100644
--- a/src/main/installation/Resources/config/services/manager.yml
+++ b/src/main/installation/Resources/config/services/manager.yml
@@ -1,18 +1,38 @@
services:
- Claroline\InstallationBundle\Manager\InstallationManager:
+ Claroline\InstallationBundle\Manager\BundleManager:
arguments:
- '@service_container'
- '@claroline.migration.manager'
- '@claroline.installation.fixture_loader'
- '@Claroline\CoreBundle\Library\Installation\Plugin\Recorder'
- - '%kernel.environment%'
+ calls:
+ - setLogger: [ '@logger' ]
+
+ Claroline\InstallationBundle\Manager\PluginManager:
+ arguments:
+ - '@claroline.plugin.validator'
+ - '@Claroline\CoreBundle\Library\Installation\Plugin\Recorder'
+ - '@Claroline\InstallationBundle\Manager\BundleManager'
+ - '@Claroline\AppBundle\Persistence\ObjectManager'
+ - '@Claroline\CoreBundle\Manager\PluginManager'
+ - '@Claroline\CoreBundle\Manager\VersionManager'
+ calls:
+ - setLogger: [ '@logger' ]
+
+ Claroline\InstallationBundle\Manager\PlatformManager:
+ arguments:
+ - '@service_container'
+ - '@kernel'
+ - '@Claroline\AppBundle\Persistence\ObjectManager'
+ - '@Claroline\InstallationBundle\Manager\BundleManager'
+ - '@Claroline\InstallationBundle\Manager\PluginManager'
calls:
- setLogger: [ '@logger' ]
Claroline\InstallationBundle\Manager\RefreshManager:
arguments:
+ - '@kernel'
- '@filesystem'
- - '@Claroline\AppBundle\Manager\CommandManager'
- '%kernel.project_dir%'
- '%kernel.cache_dir%'
- '%claroline.param.public_directory%'
diff --git a/src/main/installation/Updater/Updater.php b/src/main/installation/Updater/Updater.php
index 94610abf432..679ecdc8bf3 100644
--- a/src/main/installation/Updater/Updater.php
+++ b/src/main/installation/Updater/Updater.php
@@ -11,18 +11,18 @@
namespace Claroline\InstallationBundle\Updater;
-use Claroline\AppBundle\Log\LoggableTrait;
use Psr\Log\LoggerAwareInterface;
+use Psr\Log\LoggerAwareTrait;
abstract class Updater implements LoggerAwareInterface
{
- use LoggableTrait;
+ use LoggerAwareTrait;
- public function preUpdate()
+ public function preUpdate(): void
{
}
- public function postUpdate()
+ public function postUpdate(): void
{
}
}
diff --git a/src/main/kernel/Recorder/BundleFileLoader.php b/src/main/kernel/Recorder/BundleFileLoader.php
index 26fefd9f780..522930dea0a 100644
--- a/src/main/kernel/Recorder/BundleFileLoader.php
+++ b/src/main/kernel/Recorder/BundleFileLoader.php
@@ -11,24 +11,20 @@
namespace Claroline\KernelBundle\Recorder;
-use Claroline\AppBundle\Log\LoggableTrait;
use Claroline\KernelBundle\Bundle\AutoConfigurableInterface;
-use Psr\Log\LoggerAwareInterface;
use Symfony\Component\HttpKernel\Bundle\BundleInterface;
/**
* Loads the list of Bundles registered in the Claroline Kernel from an INI file.
*/
-class BundleFileLoader implements LoggerAwareInterface
+class BundleFileLoader
{
- use LoggableTrait;
-
- private $env;
- private $bundlesFile;
+ private string $env;
+ private string $bundlesFile;
private static $selfInstance;
- public static function initialize(string $env, string $bundlesFile)
+ public static function initialize(string $env, string $bundlesFile): void
{
static::$selfInstance = new self($env, $bundlesFile);
}
@@ -62,8 +58,6 @@ public function getActiveBundles(?bool $fetchAll = false): array
$bundles[\get_class($requiredBundle)] = $requiredBundle;
}
}
- } else {
- $this->log("Class {$bundleClass} was not loaded");
}
}
}
@@ -71,7 +65,7 @@ public function getActiveBundles(?bool $fetchAll = false): array
return $bundles;
}
- private function __construct(string $env, $bundlesFile)
+ private function __construct(string $env, string $bundlesFile)
{
if (!file_exists($bundlesFile)) {
throw new \InvalidArgumentException("'{$bundlesFile}' does not exist");
diff --git a/src/main/log/Component/Tool/LogsTool.php b/src/main/log/Component/Tool/LogsTool.php
new file mode 100644
index 00000000000..0903b8b5ce2
--- /dev/null
+++ b/src/main/log/Component/Tool/LogsTool.php
@@ -0,0 +1,34 @@
+load('services.yml');
+ $loader->load('components.yml');
}
}
diff --git a/src/main/log/Installation/ClarolineLogInstaller.php b/src/main/log/Installation/ClarolineLogInstaller.php
index 07a8fa5f4b8..dbe159f47d7 100644
--- a/src/main/log/Installation/ClarolineLogInstaller.php
+++ b/src/main/log/Installation/ClarolineLogInstaller.php
@@ -15,4 +15,8 @@
class ClarolineLogInstaller extends AdditionalInstaller
{
+ public function hasMigrations(): bool
+ {
+ return true;
+ }
}
diff --git a/src/main/log/Resources/config/components.yml b/src/main/log/Resources/config/components.yml
new file mode 100644
index 00000000000..cc128a70a3d
--- /dev/null
+++ b/src/main/log/Resources/config/components.yml
@@ -0,0 +1,2 @@
+imports:
+ - { resource: components/tool.yml }
diff --git a/src/main/log/Resources/config/components/tool.yml b/src/main/log/Resources/config/components/tool.yml
new file mode 100644
index 00000000000..2b2e3e8a040
--- /dev/null
+++ b/src/main/log/Resources/config/components/tool.yml
@@ -0,0 +1,4 @@
+services:
+ Claroline\LogBundle\Component\Tool\LogsTool:
+ parent: Claroline\AppBundle\Component\Tool\AbstractTool
+ tags: [ 'claroline.component.tool' ]
diff --git a/src/main/log/Resources/config/services/subscriber.yml b/src/main/log/Resources/config/services/subscriber.yml
index 009db1ce157..0746df836da 100644
--- a/src/main/log/Resources/config/services/subscriber.yml
+++ b/src/main/log/Resources/config/services/subscriber.yml
@@ -6,10 +6,6 @@ services:
tags:
- { name: kernel.event_subscriber }
- Claroline\LogBundle\Subscriber\Administration\LogsSubscriber:
- tags:
- - { name: kernel.event_subscriber }
-
# move those subscribers in their respective plugin when old log system will be removed
Claroline\LogBundle\Subscriber\Functional\GroupLogSubscriber:
arguments:
diff --git a/src/main/log/Resources/modules/account/logs/index.js b/src/main/log/Resources/modules/account/logs/index.js
index 2c4b6cf0273..b947659e9bf 100644
--- a/src/main/log/Resources/modules/account/logs/index.js
+++ b/src/main/log/Resources/modules/account/logs/index.js
@@ -1,10 +1,8 @@
-import {trans} from '#/main/app/intl/translation'
-
import {LogsMain} from '#/main/log/account/logs/containers/main'
export default {
- name: 'logs',
+ /*name: 'logs',
icon: 'fa fa-fw fa-shoe-prints',
label: trans('logs', {}, 'tools'),
- component: LogsMain
+ */component: LogsMain
}
diff --git a/src/main/log/Subscriber/Administration/LogsSubscriber.php b/src/main/log/Subscriber/Administration/LogsSubscriber.php
deleted file mode 100644
index 25037acd56c..00000000000
--- a/src/main/log/Subscriber/Administration/LogsSubscriber.php
+++ /dev/null
@@ -1,26 +0,0 @@
- 'onOpen',
- ];
- }
-
- public function onOpen(OpenToolEvent $event)
- {
- $event->setData([]);
- $event->stopPropagation();
- }
-}
diff --git a/src/main/log/Subscriber/FunctionalLogSubscriber.php b/src/main/log/Subscriber/FunctionalLogSubscriber.php
index 9809d608feb..f0a1244ed3e 100644
--- a/src/main/log/Subscriber/FunctionalLogSubscriber.php
+++ b/src/main/log/Subscriber/FunctionalLogSubscriber.php
@@ -2,6 +2,7 @@
namespace Claroline\LogBundle\Subscriber;
+use Claroline\CoreBundle\Event\CatalogEvents\ContextEvents;
use Claroline\CoreBundle\Event\CatalogEvents\ResourceEvents;
use Claroline\CoreBundle\Event\CatalogEvents\ToolEvents;
use Claroline\EvaluationBundle\Event\EvaluationEvents;
@@ -32,7 +33,8 @@ public static function getSubscribedEvents(): array
return [
EvaluationEvents::RESOURCE_EVALUATION => ['logEvaluation', 10],
ResourceEvents::RESOURCE_OPEN => ['logEvent', 10],
- ToolEvents::OPEN => ['logEvent', 10],
+ // ContextEvents::OPEN => ['logEvent', 10],
+ // ToolEvents::OPEN => ['logEvent', 10],
];
}
diff --git a/src/main/privacy/Component/Tool/PrivacyTool.php b/src/main/privacy/Component/Tool/PrivacyTool.php
new file mode 100644
index 00000000000..ccd391af1f3
--- /dev/null
+++ b/src/main/privacy/Component/Tool/PrivacyTool.php
@@ -0,0 +1,49 @@
+serializer->serialize();
+
+ return [
+ 'lockedParameters' => $parameters['lockedParameters'] ?? [],
+ 'parameters' => $parameters,
+ ];
+ }
+
+ return [];
+ }
+
+ public function configure(string $context, ContextSubjectInterface $contextSubject = null, array $configData = []): ?array
+ {
+ return [];
+ }
+}
diff --git a/src/main/app/Controller/Platform/TermsOfServiceController.php b/src/main/privacy/Controller/TermsOfServiceController.php
similarity index 73%
rename from src/main/app/Controller/Platform/TermsOfServiceController.php
rename to src/main/privacy/Controller/TermsOfServiceController.php
index 943b6cf98b4..e72cd37f49f 100644
--- a/src/main/app/Controller/Platform/TermsOfServiceController.php
+++ b/src/main/privacy/Controller/TermsOfServiceController.php
@@ -1,6 +1,6 @@
om = $om;
- $this->serializer = $serializer;
- $this->manager = $manager;
}
/**
* @Route("/", name="apiv2_platform_terms_of_service", methods={"GET"})
*/
- public function getCurrentAction(Request $request)
+ public function getCurrentAction(Request $request): JsonResponse
{
$terms = null;
if ($this->manager->isActive()) {
diff --git a/src/main/privacy/DependencyInjection/ClarolinePrivacyExtension.php b/src/main/privacy/DependencyInjection/ClarolinePrivacyExtension.php
index e1db2082fc4..7fd6b324de2 100644
--- a/src/main/privacy/DependencyInjection/ClarolinePrivacyExtension.php
+++ b/src/main/privacy/DependencyInjection/ClarolinePrivacyExtension.php
@@ -11,7 +11,6 @@
namespace Claroline\PrivacyBundle\DependencyInjection;
-use Exception;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
@@ -19,15 +18,12 @@
class ClarolinePrivacyExtension extends Extension
{
- /**
- * {@inheritdoc}
- *
- * @throws Exception
- */
- public function load(array $configs, ContainerBuilder $container)
+ public function load(array $configs, ContainerBuilder $container): void
{
$locator = new FileLocator(__DIR__.'/../Resources/config');
$loader = new YamlFileLoader($container, $locator);
+
$loader->load('services.yml');
+ $loader->load('components.yml');
}
}
diff --git a/src/main/privacy/Resources/config/components.yml b/src/main/privacy/Resources/config/components.yml
new file mode 100644
index 00000000000..cc128a70a3d
--- /dev/null
+++ b/src/main/privacy/Resources/config/components.yml
@@ -0,0 +1,2 @@
+imports:
+ - { resource: components/tool.yml }
diff --git a/src/main/privacy/Resources/config/components/tool.yml b/src/main/privacy/Resources/config/components/tool.yml
new file mode 100644
index 00000000000..6aeb75c8c4a
--- /dev/null
+++ b/src/main/privacy/Resources/config/components/tool.yml
@@ -0,0 +1,4 @@
+services:
+ Claroline\PrivacyBundle\Component\Tool\PrivacyTool:
+ parent: Claroline\AppBundle\Component\Tool\AbstractTool
+ tags: [ 'claroline.component.tool' ]
diff --git a/src/main/privacy/Resources/config/services.yml b/src/main/privacy/Resources/config/services.yml
index be8e54d4076..82897926eb6 100644
--- a/src/main/privacy/Resources/config/services.yml
+++ b/src/main/privacy/Resources/config/services.yml
@@ -1,4 +1,3 @@
imports:
- { resource: services/controller.yml }
- - { resource: services/subscriber.yml }
- { resource: services/serializer.yml }
diff --git a/src/main/privacy/Resources/config/services/controller.yml b/src/main/privacy/Resources/config/services/controller.yml
index aa3f636b215..be31cf6e73b 100644
--- a/src/main/privacy/Resources/config/services/controller.yml
+++ b/src/main/privacy/Resources/config/services/controller.yml
@@ -1,4 +1,7 @@
services:
+ _defaults:
+ public: true # required by controllers
+
Claroline\PrivacyBundle\Controller\PrivacyController:
parent: Claroline\AppBundle\Controller\AbstractSecurityController
public: true
@@ -6,3 +9,9 @@ services:
- '@security.authorization_checker'
- '@Claroline\CoreBundle\Library\Configuration\PlatformConfigurationHandler'
- '@Claroline\CoreBundle\API\Serializer\ParametersSerializer'
+
+ Claroline\PrivacyBundle\Controller\TermsOfServiceController:
+ arguments:
+ - '@Claroline\AppBundle\Persistence\ObjectManager'
+ - '@Claroline\AppBundle\API\SerializerProvider'
+ - '@Claroline\AppBundle\Manager\TermsOfServiceManager'
diff --git a/src/main/privacy/Resources/config/services/subscriber.yml b/src/main/privacy/Resources/config/services/subscriber.yml
deleted file mode 100644
index 9c7bb2cc895..00000000000
--- a/src/main/privacy/Resources/config/services/subscriber.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-services:
- Claroline\PrivacyBundle\Subscriber\Administration\PrivacySubscriber:
- tags: [ kernel.event_subscriber ]
- arguments:
- - '@Claroline\CoreBundle\API\Serializer\ParametersSerializer'
diff --git a/src/main/privacy/Resources/modules/account/privacy/index.js b/src/main/privacy/Resources/modules/account/privacy/index.js
index 2d68006e96a..638a8dfaaaa 100644
--- a/src/main/privacy/Resources/modules/account/privacy/index.js
+++ b/src/main/privacy/Resources/modules/account/privacy/index.js
@@ -1,11 +1,9 @@
-import {trans} from '#/main/app/intl/translation'
-
import {PrivacyMain} from '#/main/privacy/account/privacy/containers/main'
export default {
+ component: PrivacyMain/*,
name: 'privacy',
icon: 'fa fa-fw fa-user-shield',
label: trans('privacy'),
- component: PrivacyMain,
- order: 3
+ order: 3*/
}
diff --git a/src/main/privacy/Subscriber/Administration/PrivacySubscriber.php b/src/main/privacy/Subscriber/Administration/PrivacySubscriber.php
deleted file mode 100644
index 6cc14b7fd6d..00000000000
--- a/src/main/privacy/Subscriber/Administration/PrivacySubscriber.php
+++ /dev/null
@@ -1,39 +0,0 @@
-serializer = $serializer;
- }
-
- public static function getSubscribedEvents(): array
- {
- return [
- ToolEvents::getEventName(ToolEvents::OPEN, Tool::ADMINISTRATION, static::NAME) => 'onOpen',
- ];
- }
-
- public function onOpen(OpenToolEvent $event): void
- {
- $parameters = $this->serializer->serialize();
-
- $event->setData([
- 'lockedParameters' => $parameters['lockedParameters'] ?? [],
- 'parameters' => $parameters,
- ]);
- }
-}
diff --git a/src/main/scheduler/Installation/ClarolineSchedulerInstaller.php b/src/main/scheduler/Installation/ClarolineSchedulerInstaller.php
index 98c801c2bf0..87f2cfb005b 100644
--- a/src/main/scheduler/Installation/ClarolineSchedulerInstaller.php
+++ b/src/main/scheduler/Installation/ClarolineSchedulerInstaller.php
@@ -15,4 +15,8 @@
class ClarolineSchedulerInstaller extends AdditionalInstaller
{
+ public function hasMigrations(): bool
+ {
+ return true;
+ }
}
diff --git a/src/main/theme/Installation/ClarolineThemeInstaller.php b/src/main/theme/Installation/ClarolineThemeInstaller.php
index 21b6d29384f..306a4c30e02 100644
--- a/src/main/theme/Installation/ClarolineThemeInstaller.php
+++ b/src/main/theme/Installation/ClarolineThemeInstaller.php
@@ -6,4 +6,8 @@
class ClarolineThemeInstaller extends AdditionalInstaller
{
+ public function hasMigrations(): bool
+ {
+ return true;
+ }
}
diff --git a/src/main/transfer/Installation/ClarolineTransferInstaller.php b/src/main/transfer/Installation/ClarolineTransferInstaller.php
index 29c3b645084..c805a373fa6 100644
--- a/src/main/transfer/Installation/ClarolineTransferInstaller.php
+++ b/src/main/transfer/Installation/ClarolineTransferInstaller.php
@@ -15,4 +15,8 @@
class ClarolineTransferInstaller extends AdditionalInstaller
{
+ public function hasMigrations(): bool
+ {
+ return true;
+ }
}
diff --git a/src/plugin/agenda/Installation/ClarolineAgendaInstaller.php b/src/plugin/agenda/Installation/ClarolineAgendaInstaller.php
index 5e8c23bcfed..e3f509836bf 100644
--- a/src/plugin/agenda/Installation/ClarolineAgendaInstaller.php
+++ b/src/plugin/agenda/Installation/ClarolineAgendaInstaller.php
@@ -6,6 +6,11 @@
class ClarolineAgendaInstaller extends AdditionalInstaller
{
+ public function hasMigrations(): bool
+ {
+ return true;
+ }
+
public function hasFixtures(): bool
{
return true;
diff --git a/src/plugin/agenda/Security/Voter/AbstractEventVoter.php b/src/plugin/agenda/Security/Voter/AbstractEventVoter.php
index d51e8c8c938..c89fbde6048 100644
--- a/src/plugin/agenda/Security/Voter/AbstractEventVoter.php
+++ b/src/plugin/agenda/Security/Voter/AbstractEventVoter.php
@@ -12,10 +12,6 @@
namespace Claroline\AgendaBundle\Security\Voter;
use Claroline\AppBundle\Security\Voter\AbstractVoter;
-use Claroline\CoreBundle\Entity\Planning\AbstractPlanned;
-use Claroline\CoreBundle\Entity\Tool\OrderedTool;
-use Claroline\CoreBundle\Entity\User;
-use Claroline\CoreBundle\Repository\Tool\OrderedToolRepository;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
@@ -27,39 +23,15 @@ public function checkPermission(TokenInterface $token, $object, array $attribute
case self::CREATE:
case self::EDIT:
case self::DELETE:
- return $this->checkEdit($token, $object);
- }
-
- return VoterInterface::ACCESS_ABSTAIN;
- }
-
- public function checkEdit(TokenInterface $token, AbstractPlanned $object): int
- {
- $workspace = $object->getWorkspace();
-
- $currentUser = $token->getUser();
- $user = $object->getCreator();
+ $workspace = $object->getWorkspace();
+ if ($this->isToolGranted('EDIT', 'agenda', $workspace)) {
+ return VoterInterface::ACCESS_GRANTED;
+ }
- // the user is the creator of the event
- if ($currentUser instanceof User && (!$user || $currentUser->getUuid() === $user->getUuid())) {
- return VoterInterface::ACCESS_GRANTED;
+ return VoterInterface::ACCESS_DENIED;
}
- // the user has EDIT right on the corresponding tool
- /** @var OrderedToolRepository $orderedToolRepo */
- $orderedToolRepo = $this->getObjectManager()->getRepository(OrderedTool::class);
-
- if (!empty($workspace)) {
- $agendaTool = $orderedToolRepo->findOneByNameAndWorkspace('agenda', $workspace);
- } else {
- $agendaTool = $orderedToolRepo->findOneByNameAndDesktop('agenda');
- }
-
- if ($this->isGranted('EDIT', $agendaTool)) {
- return VoterInterface::ACCESS_GRANTED;
- }
-
- return VoterInterface::ACCESS_DENIED;
+ return VoterInterface::ACCESS_ABSTAIN;
}
public function getSupportedActions(): array
diff --git a/src/plugin/analytics/Installation/ClarolineAnalyticsInstaller.php b/src/plugin/analytics/Installation/ClarolineAnalyticsInstaller.php
index adcbe9562ba..c3c58aac905 100644
--- a/src/plugin/analytics/Installation/ClarolineAnalyticsInstaller.php
+++ b/src/plugin/analytics/Installation/ClarolineAnalyticsInstaller.php
@@ -6,8 +6,4 @@
class ClarolineAnalyticsInstaller extends AdditionalInstaller
{
- public function hasMigrations(): bool
- {
- return false;
- }
}
diff --git a/src/plugin/announcement/Installation/ClarolineAnnouncementInstaller.php b/src/plugin/announcement/Installation/ClarolineAnnouncementInstaller.php
index 10047d4c966..e954e09ba91 100644
--- a/src/plugin/announcement/Installation/ClarolineAnnouncementInstaller.php
+++ b/src/plugin/announcement/Installation/ClarolineAnnouncementInstaller.php
@@ -15,6 +15,11 @@
class ClarolineAnnouncementInstaller extends AdditionalInstaller
{
+ public function hasMigrations(): bool
+ {
+ return true;
+ }
+
public function hasFixtures(): bool
{
return true;
diff --git a/src/plugin/audio-player/Installation/ClarolineAudioPlayerInstaller.php b/src/plugin/audio-player/Installation/ClarolineAudioPlayerInstaller.php
index e1817ff5637..ca9e9a9732b 100644
--- a/src/plugin/audio-player/Installation/ClarolineAudioPlayerInstaller.php
+++ b/src/plugin/audio-player/Installation/ClarolineAudioPlayerInstaller.php
@@ -6,4 +6,8 @@
class ClarolineAudioPlayerInstaller extends AdditionalInstaller
{
+ public function hasMigrations(): bool
+ {
+ return true;
+ }
}
diff --git a/src/plugin/bibliography/Installation/IcapBibliographyInstaller.php b/src/plugin/bibliography/Installation/IcapBibliographyInstaller.php
index 8bda36a1305..718a2003a34 100644
--- a/src/plugin/bibliography/Installation/IcapBibliographyInstaller.php
+++ b/src/plugin/bibliography/Installation/IcapBibliographyInstaller.php
@@ -6,4 +6,8 @@
class IcapBibliographyInstaller extends AdditionalInstaller
{
+ public function hasMigrations(): bool
+ {
+ return true;
+ }
}
diff --git a/src/plugin/blog/Installation/IcapBlogInstaller.php b/src/plugin/blog/Installation/IcapBlogInstaller.php
index b86dcd8838e..0857b0d5b74 100644
--- a/src/plugin/blog/Installation/IcapBlogInstaller.php
+++ b/src/plugin/blog/Installation/IcapBlogInstaller.php
@@ -6,4 +6,8 @@
class IcapBlogInstaller extends AdditionalInstaller
{
+ public function hasMigrations(): bool
+ {
+ return true;
+ }
}
diff --git a/src/plugin/claco-form/Installation/ClarolineClacoFormInstaller.php b/src/plugin/claco-form/Installation/ClarolineClacoFormInstaller.php
index f6513ed0455..a9faeebc2d4 100644
--- a/src/plugin/claco-form/Installation/ClarolineClacoFormInstaller.php
+++ b/src/plugin/claco-form/Installation/ClarolineClacoFormInstaller.php
@@ -15,4 +15,8 @@
class ClarolineClacoFormInstaller extends AdditionalInstaller
{
+ public function hasMigrations(): bool
+ {
+ return true;
+ }
}
diff --git a/src/plugin/claco-form/Manager/ClacoFormManager.php b/src/plugin/claco-form/Manager/ClacoFormManager.php
index c901c700e2c..60e076593f8 100644
--- a/src/plugin/claco-form/Manager/ClacoFormManager.php
+++ b/src/plugin/claco-form/Manager/ClacoFormManager.php
@@ -11,7 +11,6 @@
namespace Claroline\ClacoFormBundle\Manager;
-use Claroline\AppBundle\Log\LoggableTrait;
use Claroline\AppBundle\Persistence\ObjectManager;
use Claroline\ClacoFormBundle\Entity\Category;
use Claroline\ClacoFormBundle\Entity\ClacoForm;
@@ -43,7 +42,6 @@
use Claroline\CoreBundle\Entity\User;
use Claroline\CoreBundle\Messenger\Message\SendMessage;
use Doctrine\Common\Collections\ArrayCollection;
-use Psr\Log\LoggerAwareInterface;
use Ramsey\Uuid\Uuid;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\File\UploadedFile;
@@ -55,10 +53,8 @@
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use Symfony\Contracts\Translation\TranslatorInterface;
-class ClacoFormManager implements LoggerAwareInterface
+class ClacoFormManager
{
- use LoggableTrait;
-
/** @var AuthorizationCheckerInterface */
private $authorization;
/** @var EventDispatcherInterface */
diff --git a/src/plugin/claco-form/Resources/config/services/manager.yml b/src/plugin/claco-form/Resources/config/services/manager.yml
index 3b0636d1e73..cf3dbd731c0 100644
--- a/src/plugin/claco-form/Resources/config/services/manager.yml
+++ b/src/plugin/claco-form/Resources/config/services/manager.yml
@@ -15,8 +15,6 @@ services:
- '@translator'
- '@messenger.default_bus'
- '@Claroline\ClacoFormBundle\Manager\CategoryManager'
- calls:
- - setLogger: [ '@logger' ]
Claroline\ClacoFormBundle\Manager\CategoryManager:
arguments:
diff --git a/src/plugin/competency/Controller/CompetencyController.php b/src/plugin/competency/Controller/CompetencyController.php
index 1ca5356a893..c294834c2c1 100644
--- a/src/plugin/competency/Controller/CompetencyController.php
+++ b/src/plugin/competency/Controller/CompetencyController.php
@@ -13,6 +13,7 @@
use Claroline\AppBundle\API\Options;
use Claroline\AppBundle\Controller\AbstractCrudController;
+use Claroline\CoreBundle\Component\Context\DesktopContext;
use Claroline\CoreBundle\Entity\Resource\ResourceNode;
use Claroline\CoreBundle\Manager\Tool\ToolManager;
use Claroline\CoreBundle\Security\PermissionCheckerTrait;
@@ -89,6 +90,7 @@ public function competenciesRootListAction(Request $request): JsonResponse
* "/competency/{id}/list",
* name="apiv2_competency_tree_list"
* )
+ *
* @EXT\ParamConverter(
* "competency",
* class="HeVinci\CompetencyBundle\Entity\Competency",
@@ -118,6 +120,7 @@ public function competenciesTreeListAction(Competency $competency, Request $requ
* "/framework/{id}/export",
* name="apiv2_competency_framework_export"
* )
+ *
* @EXT\ParamConverter(
* "framework",
* class="HeVinci\CompetencyBundle\Entity\Competency",
@@ -185,6 +188,7 @@ public function frameworkImportAction(Request $request): JsonResponse
* "/node/{node}/competencies/fetch",
* name="apiv2_competency_resource_competencies_list"
* )
+ *
* @EXT\ParamConverter(
* "node",
* class="Claroline\CoreBundle\Entity\Resource\ResourceNode",
@@ -210,6 +214,7 @@ public function resourceCompetenciesFetchAction(ResourceNode $node): JsonRespons
* name="apiv2_competency_resource_associate",
* methods={"POST"}
* )
+ *
* @EXT\ParamConverter(
* "node",
* class="Claroline\CoreBundle\Entity\Resource\ResourceNode",
@@ -239,6 +244,7 @@ public function resourceCompetencyAssociateAction(ResourceNode $node, Competency
* name="apiv2_competency_resource_dissociate",
* methods={"DELETE"}
* )
+ *
* @EXT\ParamConverter(
* "node",
* class="Claroline\CoreBundle\Entity\Resource\ResourceNode",
@@ -268,7 +274,7 @@ public static function getOptions(): array
private function checkToolAccess(string $rights = 'OPEN'): void
{
- $competenciesTool = $this->toolManager->getAdminToolByName('competencies');
+ $competenciesTool = $this->toolManager->getOrderedTool('competencies', DesktopContext::getName());
if (is_null($competenciesTool) || !$this->authorization->isGranted($rights, $competenciesTool)) {
throw new AccessDeniedException();
diff --git a/src/plugin/competency/Installation/HeVinciCompetencyInstaller.php b/src/plugin/competency/Installation/HeVinciCompetencyInstaller.php
index cec305c292e..cbd12f9ac30 100644
--- a/src/plugin/competency/Installation/HeVinciCompetencyInstaller.php
+++ b/src/plugin/competency/Installation/HeVinciCompetencyInstaller.php
@@ -6,4 +6,8 @@
class HeVinciCompetencyInstaller extends AdditionalInstaller
{
+ public function hasMigrations(): bool
+ {
+ return true;
+ }
}
diff --git a/src/plugin/cursus/Installation/ClarolineCursusInstaller.php b/src/plugin/cursus/Installation/ClarolineCursusInstaller.php
index 470d62fb631..d75ffc3b967 100644
--- a/src/plugin/cursus/Installation/ClarolineCursusInstaller.php
+++ b/src/plugin/cursus/Installation/ClarolineCursusInstaller.php
@@ -6,6 +6,11 @@
class ClarolineCursusInstaller extends AdditionalInstaller
{
+ public function hasMigrations(): bool
+ {
+ return true;
+ }
+
public function hasFixtures(): bool
{
return true;
diff --git a/src/plugin/cursus/Security/Voter/CourseVoter.php b/src/plugin/cursus/Security/Voter/CourseVoter.php
index 20e5a3c4d9a..53bd61560ad 100644
--- a/src/plugin/cursus/Security/Voter/CourseVoter.php
+++ b/src/plugin/cursus/Security/Voter/CourseVoter.php
@@ -12,15 +12,13 @@
namespace Claroline\CursusBundle\Security\Voter;
use Claroline\AppBundle\Security\Voter\AbstractVoter;
-use Claroline\CoreBundle\Entity\Tool\OrderedTool;
-use Claroline\CoreBundle\Repository\Tool\OrderedToolRepository;
use Claroline\CursusBundle\Entity\Course;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
class CourseVoter extends AbstractVoter
{
- const REGISTER = 'REGISTER';
+ public const REGISTER = 'REGISTER';
public function getClass(): string
{
@@ -32,14 +30,9 @@ public function getClass(): string
*/
public function checkPermission(TokenInterface $token, $object, array $attributes, array $options): int
{
- /** @var OrderedToolRepository $orderedToolRepo */
- $orderedToolRepo = $this->getObjectManager()->getRepository(OrderedTool::class);
-
- $trainingsTool = $orderedToolRepo->findOneByNameAndDesktop('trainings');
-
switch ($attributes[0]) {
case self::CREATE: // EDIT right on tool
- if ($this->isGranted('EDIT', $trainingsTool)) {
+ if ($this->isToolGranted('EDIT', 'trainings')) {
return VoterInterface::ACCESS_GRANTED;
}
@@ -48,7 +41,7 @@ public function checkPermission(TokenInterface $token, $object, array $attribute
case self::EDIT: // admin of organization | EDIT right on tool
case self::PATCH:
case self::DELETE:
- if ($this->isGranted('EDIT', $trainingsTool)) {
+ if ($this->isToolGranted('EDIT', 'trainings')) {
return VoterInterface::ACCESS_GRANTED;
}
@@ -56,14 +49,14 @@ public function checkPermission(TokenInterface $token, $object, array $attribute
case self::OPEN: // member of organization & OPEN right on tool
case self::VIEW:
- if ($this->isGranted('OPEN', $trainingsTool)) {
+ if ($this->isToolGranted('OPEN', 'trainings')) {
return VoterInterface::ACCESS_GRANTED;
}
return VoterInterface::ACCESS_DENIED;
case self::REGISTER:
- if ($this->isGranted('REGISTER', $trainingsTool)) {
+ if ($this->isToolGranted('REGISTER', 'trainings')) {
return VoterInterface::ACCESS_GRANTED;
}
diff --git a/src/plugin/cursus/Security/Voter/EventVoter.php b/src/plugin/cursus/Security/Voter/EventVoter.php
index dd210ef2736..2318c125b6e 100644
--- a/src/plugin/cursus/Security/Voter/EventVoter.php
+++ b/src/plugin/cursus/Security/Voter/EventVoter.php
@@ -12,15 +12,13 @@
namespace Claroline\CursusBundle\Security\Voter;
use Claroline\AppBundle\Security\Voter\AbstractVoter;
-use Claroline\CoreBundle\Entity\Tool\OrderedTool;
-use Claroline\CoreBundle\Repository\Tool\OrderedToolRepository;
use Claroline\CursusBundle\Entity\Event;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
class EventVoter extends AbstractVoter
{
- const REGISTER = 'REGISTER';
+ public const REGISTER = 'REGISTER';
public function getClass(): string
{
@@ -32,20 +30,15 @@ public function getClass(): string
*/
public function checkPermission(TokenInterface $token, $object, array $attributes, array $options): int
{
- /** @var OrderedToolRepository $orderedToolRepo */
- $orderedToolRepo = $this->getObjectManager()->getRepository(OrderedTool::class);
-
+ $workspace = null;
if ($object->getSession() && $object->getSession()->getWorkspace()) {
- $trainingsTool = $orderedToolRepo->findOneByNameAndWorkspace('training_events', $object->getSession()->getWorkspace());
- } else {
- $trainingsTool = $orderedToolRepo->findOneByNameAndDesktop('trainings');
+ $workspace = $object->getSession()->getWorkspace();
}
- $toolEdit = $this->isGranted('EDIT', $trainingsTool);
-
switch ($attributes[0]) {
case self::CREATE: // EDIT right on tool
- if ($toolEdit) {
+ if ($this->isToolGranted('EDIT', 'training_events', $workspace)
+ || $this->isToolGranted('EDIT', 'trainings')) {
return VoterInterface::ACCESS_GRANTED;
}
@@ -54,21 +47,24 @@ public function checkPermission(TokenInterface $token, $object, array $attribute
case self::EDIT:
case self::DELETE:
case self::PATCH:
- if ($toolEdit || ($object->getSession() && $this->isGranted('EDIT', $object->getSession()))) {
+ if ($this->isToolGranted('EDIT', 'training_events', $workspace)
+ || ($object->getSession() && $this->isGranted('EDIT', $object->getSession()))) {
return VoterInterface::ACCESS_GRANTED;
}
return VoterInterface::ACCESS_DENIED;
case self::OPEN:
case self::VIEW:
- if ($this->isGranted('OPEN', $trainingsTool) || ($object->getSession() && $this->isGranted('OPEN', $object->getSession()))) {
+ if ($this->isToolGranted('OPEN', 'training_events', $workspace)
+ || ($object->getSession() && $this->isGranted('OPEN', $object->getSession()))) {
return VoterInterface::ACCESS_GRANTED;
}
return VoterInterface::ACCESS_DENIED;
case self::REGISTER:
- if ($this->isGranted('REGISTER', $trainingsTool) || ($object->getSession() && $this->isGranted('REGISTER', $object->getSession()))) {
+ if ($this->isToolGranted('REGISTER', 'training_events', $workspace)
+ || ($object->getSession() && $this->isGranted('REGISTER', $object->getSession()))) {
return VoterInterface::ACCESS_GRANTED;
}
diff --git a/src/plugin/drop-zone/Installation/ClarolineDropZoneInstaller.php b/src/plugin/drop-zone/Installation/ClarolineDropZoneInstaller.php
index ba511516148..679ffbc5677 100644
--- a/src/plugin/drop-zone/Installation/ClarolineDropZoneInstaller.php
+++ b/src/plugin/drop-zone/Installation/ClarolineDropZoneInstaller.php
@@ -15,4 +15,8 @@
class ClarolineDropZoneInstaller extends AdditionalInstaller
{
+ public function hasMigrations(): bool
+ {
+ return true;
+ }
}
diff --git a/src/plugin/exo/Installation/UJMExoInstaller.php b/src/plugin/exo/Installation/UJMExoInstaller.php
index 9ab458617ab..1578a13af97 100644
--- a/src/plugin/exo/Installation/UJMExoInstaller.php
+++ b/src/plugin/exo/Installation/UJMExoInstaller.php
@@ -6,4 +6,8 @@
class UJMExoInstaller extends AdditionalInstaller
{
+ public function hasMigrations(): bool
+ {
+ return true;
+ }
}
diff --git a/src/plugin/favourite/Installation/HeVinciFavouriteInstaller.php b/src/plugin/favourite/Installation/HeVinciFavouriteInstaller.php
index 93df521d308..e4ce237a6f2 100644
--- a/src/plugin/favourite/Installation/HeVinciFavouriteInstaller.php
+++ b/src/plugin/favourite/Installation/HeVinciFavouriteInstaller.php
@@ -6,4 +6,8 @@
class HeVinciFavouriteInstaller extends AdditionalInstaller
{
+ public function hasMigrations(): bool
+ {
+ return true;
+ }
}
diff --git a/src/plugin/forum/Installation/ClarolineForumInstaller.php b/src/plugin/forum/Installation/ClarolineForumInstaller.php
index ff395d796c0..111687b3f6e 100644
--- a/src/plugin/forum/Installation/ClarolineForumInstaller.php
+++ b/src/plugin/forum/Installation/ClarolineForumInstaller.php
@@ -6,6 +6,11 @@
class ClarolineForumInstaller extends AdditionalInstaller
{
+ public function hasMigrations(): bool
+ {
+ return true;
+ }
+
public function hasFixtures(): bool
{
return true;
diff --git a/src/plugin/history/Command/CleanHistoryCommand.php b/src/plugin/history/Command/CleanHistoryCommand.php
deleted file mode 100644
index 796f824de8e..00000000000
--- a/src/plugin/history/Command/CleanHistoryCommand.php
+++ /dev/null
@@ -1,32 +0,0 @@
-historyManager = $historyManager;
-
- parent::__construct();
- }
-
- protected function configure()
- {
- $this->setDescription('Cleans the recent workspaces and resources table of obsolete entries');
- }
-
- protected function execute(InputInterface $input, OutputInterface $output): int
- {
- $this->historyManager->cleanRecent();
-
- return 0;
- }
-}
diff --git a/src/plugin/history/Installation/ClarolineHistoryInstaller.php b/src/plugin/history/Installation/ClarolineHistoryInstaller.php
index df313a44dc0..839d6202d1d 100644
--- a/src/plugin/history/Installation/ClarolineHistoryInstaller.php
+++ b/src/plugin/history/Installation/ClarolineHistoryInstaller.php
@@ -6,4 +6,8 @@
class ClarolineHistoryInstaller extends AdditionalInstaller
{
+ public function hasMigrations(): bool
+ {
+ return true;
+ }
}
diff --git a/src/plugin/history/Manager/HistoryManager.php b/src/plugin/history/Manager/HistoryManager.php
index 9923a9efcd3..9de19bd2b1d 100644
--- a/src/plugin/history/Manager/HistoryManager.php
+++ b/src/plugin/history/Manager/HistoryManager.php
@@ -2,7 +2,6 @@
namespace Claroline\HistoryBundle\Manager;
-use Claroline\AppBundle\Log\LoggableTrait;
use Claroline\AppBundle\Persistence\ObjectManager;
use Claroline\CoreBundle\Entity\Resource\ResourceNode;
use Claroline\CoreBundle\Entity\User;
@@ -12,25 +11,20 @@
use Claroline\HistoryBundle\Repository\ResourceRecentRepository;
use Claroline\HistoryBundle\Repository\WorkspaceRecentRepository;
use Psr\Log\LoggerAwareInterface;
+use Psr\Log\LoggerAwareTrait;
class HistoryManager implements LoggerAwareInterface
{
- use LoggableTrait;
+ use LoggerAwareTrait;
/**
* The number of results to fetch when retrieving user history.
*/
- const HISTORY_RESULTS = 5;
+ public const HISTORY_RESULTS = 5;
- /** @var ObjectManager */
- private $om;
-
- /**
- * HistoryManager constructor.
- */
- public function __construct(ObjectManager $om)
- {
- $this->om = $om;
+ public function __construct(
+ private readonly ObjectManager $om
+ ) {
}
/**
@@ -38,7 +32,7 @@ public function __construct(ObjectManager $om)
*
* @return Workspace[]
*/
- public function getWorkspaces(User $user)
+ public function getWorkspaces(User $user): array
{
/** @var WorkspaceRecentRepository $repo */
$repo = $this->om->getRepository(WorkspaceRecent::class);
@@ -55,7 +49,7 @@ public function getWorkspaces(User $user)
*
* @return ResourceNode[]
*/
- public function getResources(User $user)
+ public function getResources(User $user): array
{
/** @var ResourceRecentRepository $repo */
$repo = $this->om->getRepository(ResourceRecent::class);
@@ -70,7 +64,7 @@ public function getResources(User $user)
/**
* Add a workspace to the user history.
*/
- public function addWorkspace(Workspace $workspace, User $user)
+ public function addWorkspace(Workspace $workspace, User $user): void
{
// If object already in recent workspaces, update date
$recentWorkspace = $this->om
@@ -95,7 +89,7 @@ public function addWorkspace(Workspace $workspace, User $user)
/**
* Add a resource to the user history.
*/
- public function addResource(ResourceNode $resource, User $user)
+ public function addResource(ResourceNode $resource, User $user): void
{
// If object already in recent workspaces, update date
$recentResource = $this->om
@@ -116,22 +110,4 @@ public function addResource(ResourceNode $resource, User $user)
$this->om->persist($recentResource);
$this->om->flush();
}
-
- /**
- * Clean all recent workspaces and resources that are more than 6 months old.
- */
- public function cleanRecent()
- {
- $this->log('Cleaning recent workspaces entries that are older than six months');
-
- /** @var WorkspaceRecentRepository $recentWorkspaceRepo */
- $recentWorkspaceRepo = $this->om->getRepository(WorkspaceRecent::class);
- $recentWorkspaceRepo->removeAllEntriesBefore(new \DateTime('-6 months'));
-
- $this->log('Cleaning recent resources entries that are older than six months');
-
- /** @var ResourceRecentRepository $recentResourceRepo */
- $recentResourceRepo = $this->om->getRepository(ResourceRecent::class);
- $recentResourceRepo->removeAllEntriesBefore(new \DateTime('-6 months'));
- }
}
diff --git a/src/plugin/history/Repository/ResourceRecentRepository.php b/src/plugin/history/Repository/ResourceRecentRepository.php
index c21e21a2f37..f25ceca8a74 100644
--- a/src/plugin/history/Repository/ResourceRecentRepository.php
+++ b/src/plugin/history/Repository/ResourceRecentRepository.php
@@ -18,15 +18,4 @@ public function findEntries(User $user, int $nbResults)
->getQuery()
->getResult();
}
-
- public function removeAllEntriesBefore($date)
- {
- $qb = $this
- ->createQueryBuilder('rw')
- ->delete()
- ->andWhere('rw.createdAt <= :date')
- ->setParameter('date', $date);
-
- return $qb->getQuery()->getResult();
- }
}
diff --git a/src/plugin/history/Repository/WorkspaceRecentRepository.php b/src/plugin/history/Repository/WorkspaceRecentRepository.php
index 62ef49c65d3..c7032f78019 100644
--- a/src/plugin/history/Repository/WorkspaceRecentRepository.php
+++ b/src/plugin/history/Repository/WorkspaceRecentRepository.php
@@ -18,15 +18,4 @@ public function findEntries(User $user, int $nbResults)
->getQuery()
->getResult();
}
-
- public function removeAllEntriesBefore($date)
- {
- $qb = $this
- ->createQueryBuilder('rw')
- ->delete()
- ->andWhere('rw.createdAt <= :date')
- ->setParameter('date', $date);
-
- return $qb->getQuery()->getResult();
- }
}
diff --git a/src/plugin/history/Resources/config/services.yml b/src/plugin/history/Resources/config/services.yml
index aee369a1012..b6d4b0ab6e0 100644
--- a/src/plugin/history/Resources/config/services.yml
+++ b/src/plugin/history/Resources/config/services.yml
@@ -30,11 +30,3 @@ services:
arguments:
- '@Claroline\AppBundle\API\SerializerProvider'
- '@Claroline\HistoryBundle\Manager\HistoryManager'
-
- # Console commands
-
- Claroline\HistoryBundle\Command\CleanHistoryCommand:
- arguments:
- - '@Claroline\HistoryBundle\Manager\HistoryManager'
- tags:
- - { name: console.command, command: claroline:history:clean }
diff --git a/src/plugin/history/Resources/translations/history.en.json b/src/plugin/history/Resources/translations/history.en.json
index 7e98a6e8987..b5609b1e6ef 100644
--- a/src/plugin/history/Resources/translations/history.en.json
+++ b/src/plugin/history/Resources/translations/history.en.json
@@ -5,5 +5,6 @@
"empty_workspaces": "You have not viewed any workspace",
"empty_workspaces_help": "Browse your workspaces to see them appear here",
"empty_resources": "You have not viewed any resource",
- "empty_resources_help": "Browse your resources to see them appear here"
+ "empty_resources_help": "Browse your resources to see them appear here",
+ "history_loading": "We are loading your history..."
}
diff --git a/src/plugin/history/Resources/translations/history.fr.json b/src/plugin/history/Resources/translations/history.fr.json
index d17730f377e..d90f67fbde4 100644
--- a/src/plugin/history/Resources/translations/history.fr.json
+++ b/src/plugin/history/Resources/translations/history.fr.json
@@ -5,5 +5,6 @@
"empty_workspaces": "Vous n'avez consulté aucun espace d'activité",
"empty_workspaces_help": "Parcourez vos espaces d'activités pour les voir apparaître ici",
"empty_resources": "Vous n'avez consulté aucune ressource",
- "empty_resources_help": "Parcourez vos ressources pour les voir apparaître ici"
+ "empty_resources_help": "Parcourez vos ressources pour les voir apparaître ici",
+ "history_loading": "Nous chargeons votre historique..."
}
diff --git a/src/plugin/home/Controller/HomeController.php b/src/plugin/home/Controller/HomeController.php
index 18fb84fde50..bbcb0400fb7 100644
--- a/src/plugin/home/Controller/HomeController.php
+++ b/src/plugin/home/Controller/HomeController.php
@@ -15,9 +15,10 @@
use Claroline\AppBundle\API\FinderProvider;
use Claroline\AppBundle\Controller\RequestDecoderTrait;
use Claroline\AppBundle\Persistence\ObjectManager;
-use Claroline\CoreBundle\Entity\Tool\OrderedTool;
+use Claroline\CoreBundle\Component\Context\DesktopContext;
use Claroline\CoreBundle\Entity\User;
use Claroline\CoreBundle\Manager\LockManager;
+use Claroline\CoreBundle\Manager\Tool\ToolManager;
use Claroline\HomeBundle\Entity\HomeTab;
use Claroline\HomeBundle\Manager\HomeManager;
use Claroline\HomeBundle\Serializer\HomeTabSerializer;
@@ -30,46 +31,24 @@
/**
* @Route("/home")
+ *
+ * @deprecated should be merged with HomeTabController
*/
class HomeController
{
use RequestDecoderTrait;
- /** @var TokenStorageInterface */
- private $tokenStorage;
- /** @var AuthorizationCheckerInterface */
- private $authorization;
- /** @var ObjectManager */
- private $om;
- /** @var FinderProvider */
- private $finder;
- /** @var Crud */
- private $crud;
- /** @var HomeTabSerializer */
- private $serializer;
- /** @var LockManager */
- private $lockManager;
- /** @var HomeManager */
- private $manager;
-
public function __construct(
- TokenStorageInterface $tokenStorage,
- AuthorizationCheckerInterface $authorization,
- ObjectManager $om,
- FinderProvider $finder,
- Crud $crud,
- LockManager $lockManager,
- HomeTabSerializer $serializer,
- HomeManager $manager
+ private readonly TokenStorageInterface $tokenStorage,
+ private readonly AuthorizationCheckerInterface $authorization,
+ private readonly ObjectManager $om,
+ private readonly FinderProvider $finder,
+ private readonly Crud $crud,
+ private readonly LockManager $lockManager,
+ private readonly ToolManager $toolManager,
+ private readonly HomeTabSerializer $serializer,
+ private readonly HomeManager $manager
) {
- $this->tokenStorage = $tokenStorage;
- $this->authorization = $authorization;
- $this->om = $om;
- $this->finder = $finder;
- $this->crud = $crud;
- $this->lockManager = $lockManager;
- $this->serializer = $serializer;
- $this->manager = $manager;
}
/**
@@ -234,7 +213,7 @@ public function adminTabsFetchAction(): JsonResponse
);
}
- private function cleanDatabase(array $installedTabs, array $ids)
+ private function cleanDatabase(array $installedTabs, array $ids): void
{
foreach ($installedTabs as $installedTab) {
$this->lockManager->unlock(HomeTab::class, $installedTab->getUuid());
@@ -246,9 +225,9 @@ private function cleanDatabase(array $installedTabs, array $ids)
}
}
- private function checkDesktopPermissions(string $perm)
+ private function checkDesktopPermissions(string $perm): void
{
- $homeTool = $this->om->getRepository(OrderedTool::class)->findOneByNameAndDesktop('home');
+ $homeTool = $this->toolManager->getOrderedTool('home', DesktopContext::getName());
if (!$homeTool || !$this->authorization->isGranted($perm, $homeTool)) {
throw new AccessDeniedException();
}
diff --git a/src/plugin/home/Installation/ClarolineHomeInstaller.php b/src/plugin/home/Installation/ClarolineHomeInstaller.php
index 6b50ce3b1bd..4257b63dc75 100644
--- a/src/plugin/home/Installation/ClarolineHomeInstaller.php
+++ b/src/plugin/home/Installation/ClarolineHomeInstaller.php
@@ -6,6 +6,11 @@
class ClarolineHomeInstaller extends AdditionalInstaller
{
+ public function hasMigrations(): bool
+ {
+ return true;
+ }
+
public function hasFixtures(): bool
{
return true;
diff --git a/src/plugin/home/Resources/config/services/controller.yml b/src/plugin/home/Resources/config/services/controller.yml
index 0159e919f30..fe2d72d29f5 100644
--- a/src/plugin/home/Resources/config/services/controller.yml
+++ b/src/plugin/home/Resources/config/services/controller.yml
@@ -10,6 +10,7 @@ services:
- '@Claroline\AppBundle\API\FinderProvider'
- '@Claroline\AppBundle\API\Crud'
- '@Claroline\CoreBundle\Manager\LockManager'
+ - '@Claroline\CoreBundle\Manager\Tool\ToolManager'
- '@Claroline\HomeBundle\Serializer\HomeTabSerializer'
- '@Claroline\HomeBundle\Manager\HomeManager'
diff --git a/src/plugin/home/Resources/config/services/voter.yml b/src/plugin/home/Resources/config/services/voter.yml
index 8461a3c6577..adf742055ea 100644
--- a/src/plugin/home/Resources/config/services/voter.yml
+++ b/src/plugin/home/Resources/config/services/voter.yml
@@ -4,5 +4,3 @@ services:
Claroline\HomeBundle\Security\Voter\HomeTabVoter:
parent: Claroline\AppBundle\Security\Voter\AbstractVoter
- arguments:
- - '@Claroline\AppBundle\Persistence\ObjectManager'
diff --git a/src/plugin/home/Security/Voter/HomeTabVoter.php b/src/plugin/home/Security/Voter/HomeTabVoter.php
index 9d0dc6c97dd..7f612a96ab0 100644
--- a/src/plugin/home/Security/Voter/HomeTabVoter.php
+++ b/src/plugin/home/Security/Voter/HomeTabVoter.php
@@ -11,31 +11,14 @@
namespace Claroline\HomeBundle\Security\Voter;
-use Claroline\AppBundle\Persistence\ObjectManager;
use Claroline\AppBundle\Security\Voter\AbstractVoter;
-use Claroline\CoreBundle\Entity\Tool\OrderedTool;
use Claroline\CoreBundle\Entity\User;
-use Claroline\CoreBundle\Repository\Tool\OrderedToolRepository;
-use Claroline\CoreBundle\Security\ToolPermissions;
use Claroline\HomeBundle\Entity\HomeTab;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
class HomeTabVoter extends AbstractVoter
{
- /** @var ObjectManager */
- private $om;
-
- /** @var OrderedToolRepository */
- private $orderedToolRepo;
-
- public function __construct(ObjectManager $om)
- {
- $this->om = $om;
-
- $this->orderedToolRepo = $this->om->getRepository(OrderedTool::class);
- }
-
public function checkPermission(TokenInterface $token, $object, array $attributes, array $options): int
{
switch ($attributes[0]) {
@@ -62,20 +45,17 @@ private function check(TokenInterface $token, HomeTab $object): int
break;
case HomeTab::TYPE_DESKTOP:
- $homeTool = $this->orderedToolRepo->findOneByNameAndDesktop('home');
$isOwner = $object->getUser() && $token->getUser() instanceof User && $object->getUser()->getId() === $token->getUser()->getId();
- $granted = $isOwner && $homeTool && $this->isGranted(self::OPEN, $homeTool);
+ $granted = $isOwner && $this->isToolGranted(self::OPEN, 'home');
break;
case HomeTab::TYPE_ADMIN_DESKTOP:
- $homeTool = $this->orderedToolRepo->findOneByNameAndDesktop('home');
-
- $granted = $homeTool && $this->isGranted(self::OPEN, $homeTool);
+ $granted = $this->isToolGranted(self::OPEN, 'home');
break;
case HomeTab::TYPE_WORKSPACE:
- $granted = $object->getWorkspace() && $this->isGranted(ToolPermissions::getPermission('home', self::OPEN), $object->getWorkspace());
+ $granted = $object->getWorkspace() && $this->isToolGranted(self::OPEN, 'home', $object->getWorkspace());
break;
}
@@ -99,20 +79,17 @@ private function checkEdit(TokenInterface $token, HomeTab $object): int
break;
case HomeTab::TYPE_DESKTOP:
- $homeTool = $this->orderedToolRepo->findOneByNameAndDesktop('home');
$isOwner = $object->getUser() && $token->getUser() instanceof User && $object->getUser()->getId() === $token->getUser()->getId();
- $granted = $isOwner && $homeTool && $this->isGranted(self::EDIT, $homeTool);
+ $granted = $isOwner && $this->isToolGranted(self::EDIT, 'home');
break;
case HomeTab::TYPE_ADMIN_DESKTOP:
- $homeTool = $this->orderedToolRepo->findOneByNameAndDesktop('home');
-
- $granted = $homeTool && $this->isGranted(self::ADMINISTRATE, $homeTool);
+ $granted = $this->isToolGranted(self::ADMINISTRATE, 'home');
break;
case HomeTab::TYPE_WORKSPACE:
- $granted = $object->getWorkspace() && $this->isGranted(ToolPermissions::getPermission('home', self::EDIT), $object->getWorkspace());
+ $granted = $object->getWorkspace() && $this->isToolGranted(self::EDIT, 'home', $object->getWorkspace());
break;
}
diff --git a/src/plugin/lesson/Installation/IcapLessonInstaller.php b/src/plugin/lesson/Installation/IcapLessonInstaller.php
index c2d31e3cae7..54aec4f419d 100644
--- a/src/plugin/lesson/Installation/IcapLessonInstaller.php
+++ b/src/plugin/lesson/Installation/IcapLessonInstaller.php
@@ -6,4 +6,8 @@
class IcapLessonInstaller extends AdditionalInstaller
{
+ public function hasMigrations(): bool
+ {
+ return true;
+ }
}
diff --git a/src/plugin/link/Installation/ClarolineLinkInstaller.php b/src/plugin/link/Installation/ClarolineLinkInstaller.php
index 0f4408d9b3d..a4066b2617d 100644
--- a/src/plugin/link/Installation/ClarolineLinkInstaller.php
+++ b/src/plugin/link/Installation/ClarolineLinkInstaller.php
@@ -6,4 +6,8 @@
class ClarolineLinkInstaller extends AdditionalInstaller
{
+ public function hasMigrations(): bool
+ {
+ return true;
+ }
}
diff --git a/src/plugin/message/Installation/ClarolineMessageInstaller.php b/src/plugin/message/Installation/ClarolineMessageInstaller.php
index b58aedc726a..ed5b7058c6c 100644
--- a/src/plugin/message/Installation/ClarolineMessageInstaller.php
+++ b/src/plugin/message/Installation/ClarolineMessageInstaller.php
@@ -6,4 +6,8 @@
class ClarolineMessageInstaller extends AdditionalInstaller
{
+ public function hasMigrations(): bool
+ {
+ return true;
+ }
}
diff --git a/src/plugin/notification/Component/Tool/NotificationsTool.php b/src/plugin/notification/Component/Tool/NotificationsTool.php
new file mode 100644
index 00000000000..95f0a3255c5
--- /dev/null
+++ b/src/plugin/notification/Component/Tool/NotificationsTool.php
@@ -0,0 +1,30 @@
+load('services.yml');
+ $loader->load('components.yml');
}
}
diff --git a/src/plugin/notification/Installation/IcapNotificationInstaller.php b/src/plugin/notification/Installation/IcapNotificationInstaller.php
index 614255f1295..05ba84e9e54 100644
--- a/src/plugin/notification/Installation/IcapNotificationInstaller.php
+++ b/src/plugin/notification/Installation/IcapNotificationInstaller.php
@@ -6,4 +6,8 @@
class IcapNotificationInstaller extends AdditionalInstaller
{
+ public function hasMigrations(): bool
+ {
+ return true;
+ }
}
diff --git a/src/plugin/notification/Resources/config/components.yml b/src/plugin/notification/Resources/config/components.yml
new file mode 100644
index 00000000000..cc128a70a3d
--- /dev/null
+++ b/src/plugin/notification/Resources/config/components.yml
@@ -0,0 +1,2 @@
+imports:
+ - { resource: components/tool.yml }
diff --git a/src/plugin/notification/Resources/config/components/tool.yml b/src/plugin/notification/Resources/config/components/tool.yml
new file mode 100644
index 00000000000..9d02a516f56
--- /dev/null
+++ b/src/plugin/notification/Resources/config/components/tool.yml
@@ -0,0 +1,4 @@
+services:
+ Icap\NotificationBundle\Component\Tool\NotificationsTool:
+ parent: Claroline\AppBundle\Component\Tool\AbstractTool
+ tags: [ 'claroline.component.tool' ]
diff --git a/src/plugin/notification/Resources/modules/account/notifications/index.js b/src/plugin/notification/Resources/modules/account/notifications/index.js
index 5d09b805fbf..417468d8eb8 100644
--- a/src/plugin/notification/Resources/modules/account/notifications/index.js
+++ b/src/plugin/notification/Resources/modules/account/notifications/index.js
@@ -1,10 +1,8 @@
-import {trans} from '#/main/app/intl'
-
import {NotificationMain} from '#/plugin/notification/account/notifications/containers/main'
export default {
- name: 'notifications',
+ /*name: 'notifications',
icon: 'fa fa-fw fa-bell',
label: trans('notifications'),
- component: NotificationMain
+ */component: NotificationMain
}
diff --git a/src/plugin/notification/Resources/translations/tools.en.json b/src/plugin/notification/Resources/translations/tools.en.json
new file mode 100644
index 00000000000..7740761896c
--- /dev/null
+++ b/src/plugin/notification/Resources/translations/tools.en.json
@@ -0,0 +1,3 @@
+{
+ "notifications": "Notifications"
+}
diff --git a/src/plugin/notification/Resources/translations/tools.fr.json b/src/plugin/notification/Resources/translations/tools.fr.json
new file mode 100644
index 00000000000..7740761896c
--- /dev/null
+++ b/src/plugin/notification/Resources/translations/tools.fr.json
@@ -0,0 +1,3 @@
+{
+ "notifications": "Notifications"
+}
diff --git a/src/plugin/open-badge/Component/Tool/BadgesTool.php b/src/plugin/open-badge/Component/Tool/BadgesTool.php
new file mode 100644
index 00000000000..2eea60ea0b5
--- /dev/null
+++ b/src/plugin/open-badge/Component/Tool/BadgesTool.php
@@ -0,0 +1,107 @@
+om->getRepository(BadgeClass::class)->findBy(['workspace' => $contextSubject]);
+
+ $badgesData = [];
+ /** @var BadgeClass $badge */
+ foreach ($badges as $badge) {
+ $badgesData[] = $this->serializer->serialize($badge);
+
+ if (!empty($badge->getImage())) {
+ $fileBag->add($badge->getUuid(), $badge->getImage());
+ }
+ }
+
+ return [
+ 'badges' => $badgesData,
+ ];
+ }
+
+ public function import(string $context, ContextSubjectInterface $contextSubject = null, FileBag $fileBag = null, array $data = [], array $entities = []): ?array
+ {
+ if (WorkspaceContext::getName() !== $context) {
+ return [];
+ }
+
+ if (empty($data['badges'])) {
+ return [];
+ }
+
+ $this->om->startFlushSuite();
+ foreach ($data['badges'] as $badgeData) {
+ if (isset($badgeData['workspace'])) {
+ unset($badgeData['workspace']);
+ }
+
+ $new = new BadgeClass();
+ $new->setWorkspace($contextSubject);
+
+ $badgeImage = $fileBag->get($badgeData['id']);
+ if ($badgeImage && !$this->fileManager->exists($badgeImage)) {
+ $file = $this->fileManager->createFile(new File($badgeImage));
+ $badgeData['image'] = $file->getUrl();
+ }
+
+ $this->crud->create($new, $badgeData, [Crud::NO_PERMISSIONS, Crud::NO_VALIDATION, Options::REFRESH_UUID]);
+
+ $entities[$badgeData['id']] = $new;
+ }
+ $this->om->endFlushSuite();
+
+ return [];
+ }
+}
diff --git a/src/plugin/open-badge/DependencyInjection/ClarolineOpenBadgeExtension.php b/src/plugin/open-badge/DependencyInjection/ClarolineOpenBadgeExtension.php
index f7db29f45b8..4afac9796fa 100644
--- a/src/plugin/open-badge/DependencyInjection/ClarolineOpenBadgeExtension.php
+++ b/src/plugin/open-badge/DependencyInjection/ClarolineOpenBadgeExtension.php
@@ -16,18 +16,14 @@
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
-/**
- * Loads the core services configuration files.
- */
class ClarolineOpenBadgeExtension extends Extension
{
- /**
- * {@inheritdoc}
- */
- public function load(array $configs, ContainerBuilder $container)
+ public function load(array $configs, ContainerBuilder $container): void
{
$locator = new FileLocator(__DIR__.'/../Resources/config');
$loader = new YamlFileLoader($container, $locator);
+
$loader->load('services.yml');
+ $loader->load('components.yml');
}
}
diff --git a/src/plugin/open-badge/Finder/AssertionFinder.php b/src/plugin/open-badge/Finder/AssertionFinder.php
index baa80d61136..757739dd497 100644
--- a/src/plugin/open-badge/Finder/AssertionFinder.php
+++ b/src/plugin/open-badge/Finder/AssertionFinder.php
@@ -116,11 +116,9 @@ public function configureQueryBuilder(QueryBuilder $qb, array $searches = [], ar
$subQb = $this->om->createQueryBuilder()
->select('ot')
->from('Claroline\CoreBundle\Entity\Tool\OrderedTool', 'ot')
- ->leftJoin('ot.workspace', 'otw')
->join('ot.rights', 'r')
->join('r.role', 'rr')
- ->where('ot.user IS NULL')
- ->andWhere('((w.id IS NULL AND ot.workspace IS NULL) OR otw.id = w.id)')
+ ->where('(ot.contextId IS NULL OR ot.contextId = w.uuid)')
->andWhere('BIT_AND(r.mask, :grantMask) = :grantMask')
->andWhere('rr.name IN (:userRoles)')
->getDQL()
@@ -149,7 +147,7 @@ public function configureQueryBuilder(QueryBuilder $qb, array $searches = [], ar
break;
default:
- $this->setDefaults($qb, $filterName, $filterValue);
+ $this->setDefaults($qb, $filterName, $filterValue);
}
}
diff --git a/src/plugin/open-badge/Finder/BadgeClassFinder.php b/src/plugin/open-badge/Finder/BadgeClassFinder.php
index de697c6c4ba..9872ee30363 100644
--- a/src/plugin/open-badge/Finder/BadgeClassFinder.php
+++ b/src/plugin/open-badge/Finder/BadgeClassFinder.php
@@ -89,11 +89,9 @@ public function configureQueryBuilder(QueryBuilder $qb, array $searches = [], ar
$subQb = $this->om->createQueryBuilder()
->select('ot')
->from('Claroline\CoreBundle\Entity\Tool\OrderedTool', 'ot')
- ->leftJoin('ot.workspace', 'otw')
->join('ot.rights', 'r')
->join('r.role', 'rr')
- ->where('ot.user IS NULL')
- ->andWhere('((w.id IS NULL AND ot.workspace IS NULL) OR otw.id = w.id)')
+ ->where('(ot.contextId IS NULL OR ot.contextId = w.uuid)')
->andWhere('BIT_AND(r.mask, :grantMask) = :grantMask')
->andWhere('rr.name IN (:userRoles)')
->getDQL()
diff --git a/src/plugin/open-badge/Installation/ClarolineOpenBadgeInstaller.php b/src/plugin/open-badge/Installation/ClarolineOpenBadgeInstaller.php
index dd6c1d55e70..e5c445e3105 100644
--- a/src/plugin/open-badge/Installation/ClarolineOpenBadgeInstaller.php
+++ b/src/plugin/open-badge/Installation/ClarolineOpenBadgeInstaller.php
@@ -6,6 +6,11 @@
class ClarolineOpenBadgeInstaller extends AdditionalInstaller
{
+ public function hasMigrations(): bool
+ {
+ return true;
+ }
+
public function hasFixtures(): bool
{
return true;
diff --git a/src/plugin/open-badge/Resources/config/components.yml b/src/plugin/open-badge/Resources/config/components.yml
new file mode 100644
index 00000000000..cc128a70a3d
--- /dev/null
+++ b/src/plugin/open-badge/Resources/config/components.yml
@@ -0,0 +1,2 @@
+imports:
+ - { resource: components/tool.yml }
diff --git a/src/plugin/open-badge/Resources/config/components/tool.yml b/src/plugin/open-badge/Resources/config/components/tool.yml
new file mode 100644
index 00000000000..dd6cd3ece59
--- /dev/null
+++ b/src/plugin/open-badge/Resources/config/components/tool.yml
@@ -0,0 +1,9 @@
+services:
+ Claroline\OpenBadgeBundle\Component\Tool\BadgesTool:
+ parent: Claroline\AppBundle\Component\Tool\AbstractTool
+ tags: [ 'claroline.component.tool' ]
+ arguments:
+ - '@Claroline\AppBundle\Persistence\ObjectManager'
+ - '@Claroline\AppBundle\API\SerializerProvider'
+ - '@Claroline\AppBundle\API\Crud'
+ - '@Claroline\CoreBundle\Manager\FileManager'
diff --git a/src/plugin/open-badge/Resources/config/services/subscriber.yml b/src/plugin/open-badge/Resources/config/services/subscriber.yml
index 761e6000155..94aa466e206 100644
--- a/src/plugin/open-badge/Resources/config/services/subscriber.yml
+++ b/src/plugin/open-badge/Resources/config/services/subscriber.yml
@@ -13,13 +13,6 @@ services:
- '@Claroline\AppBundle\Persistence\ObjectManager'
- '@Claroline\AppBundle\API\Crud'
- Claroline\OpenBadgeBundle\Subscriber\Tool\BadgesSubscriber:
- arguments:
- - '@Claroline\AppBundle\Persistence\ObjectManager'
- - '@Claroline\AppBundle\API\SerializerProvider'
- - '@Claroline\AppBundle\API\Crud'
- - '@Claroline\CoreBundle\Manager\FileManager'
-
Claroline\OpenBadgeBundle\Subscriber\BadgeLogSubscriber:
arguments:
- '@translator'
diff --git a/src/plugin/open-badge/Resources/modules/account/badges/index.js b/src/plugin/open-badge/Resources/modules/account/badges/index.js
index 9757d37af6e..d07e97584d6 100644
--- a/src/plugin/open-badge/Resources/modules/account/badges/index.js
+++ b/src/plugin/open-badge/Resources/modules/account/badges/index.js
@@ -1,11 +1,9 @@
-import {trans} from '#/main/app/intl/translation'
-
import {BadgesMain} from '#/plugin/open-badge/account/badges/containers/main'
export default {
- name: 'badges',
+ /*name: 'badges',
icon: 'fa fa-fw fa-trophy',
- label: trans('my_badges', {}, 'badge'),
+ label: trans('my_badges', {}, 'badge'),*/
component: BadgesMain,
styles: ['claroline-distribution-plugin-open-badge-badges-tool']
}
diff --git a/src/plugin/open-badge/Subscriber/Tool/BadgesSubscriber.php b/src/plugin/open-badge/Subscriber/Tool/BadgesSubscriber.php
deleted file mode 100644
index 77ceabb63f0..00000000000
--- a/src/plugin/open-badge/Subscriber/Tool/BadgesSubscriber.php
+++ /dev/null
@@ -1,127 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Claroline\OpenBadgeBundle\Subscriber\Tool;
-
-use Claroline\AppBundle\API\Crud;
-use Claroline\AppBundle\API\Options;
-use Claroline\AppBundle\API\SerializerProvider;
-use Claroline\AppBundle\Persistence\ObjectManager;
-use Claroline\CoreBundle\Entity\Tool\AbstractTool;
-use Claroline\CoreBundle\Event\CatalogEvents\ToolEvents;
-use Claroline\CoreBundle\Event\Tool\ExportToolEvent;
-use Claroline\CoreBundle\Event\Tool\ImportToolEvent;
-use Claroline\CoreBundle\Event\Tool\OpenToolEvent;
-use Claroline\CoreBundle\Manager\FileManager;
-use Claroline\OpenBadgeBundle\Entity\BadgeClass;
-use Symfony\Component\EventDispatcher\EventSubscriberInterface;
-use Symfony\Component\HttpFoundation\File\File;
-
-/**
- * Badge tool.
- */
-class BadgesSubscriber implements EventSubscriberInterface
-{
- public const NAME = 'badges';
-
- /** @var ObjectManager */
- private $om;
- /** @var SerializerProvider */
- private $serializer;
- /** @var Crud */
- private $crud;
- /** @var FileManager */
- private $fileManager;
-
- public function __construct(
- ObjectManager $om,
- SerializerProvider $serializer,
- Crud $crud,
- FileManager $fileManager
- ) {
- $this->om = $om;
- $this->serializer = $serializer;
- $this->crud = $crud;
- $this->fileManager = $fileManager;
- }
-
- public static function getSubscribedEvents(): array
- {
- return [
- ToolEvents::getEventName(ToolEvents::OPEN, AbstractTool::DESKTOP, static::NAME) => 'onOpenDesktop',
- ToolEvents::getEventName(ToolEvents::OPEN, AbstractTool::WORKSPACE, static::NAME) => 'onOpenWorkspace',
- ToolEvents::getEventName(ToolEvents::EXPORT, AbstractTool::WORKSPACE, static::NAME) => 'onExportWorkspace',
- ToolEvents::getEventName(ToolEvents::IMPORT, AbstractTool::WORKSPACE, static::NAME) => 'onImportWorkspace',
- ];
- }
-
- public function onOpenDesktop(OpenToolEvent $event)
- {
- $event->setData([]);
-
- $event->stopPropagation();
- }
-
- public function onOpenWorkspace(OpenToolEvent $event)
- {
- $event->setData([]);
-
- $event->stopPropagation();
- }
-
- public function onExportWorkspace(ExportToolEvent $event)
- {
- $badges = $this->om->getRepository(BadgeClass::class)->findBy(['workspace' => $event->getWorkspace()]);
-
- $badgesData = [];
- /** @var BadgeClass $badge */
- foreach ($badges as $badge) {
- $badgesData[] = $this->serializer->serialize($badge);
-
- if (!empty($badge->getImage())) {
- $event->addFile($badge->getUuid(), $badge->getImage());
- }
- }
-
- $event->setData([
- 'badges' => $badgesData,
- ]);
- }
-
- public function onImportWorkspace(ImportToolEvent $event)
- {
- $data = $event->getData();
- if (empty($data['badges'])) {
- return;
- }
-
- $this->om->startFlushSuite();
- foreach ($data['badges'] as $badgeData) {
- if (isset($badgeData['workspace'])) {
- unset($badgeData['workspace']);
- }
-
- $new = new BadgeClass();
- $new->setWorkspace($event->getWorkspace());
-
- $badgeImage = $event->getFile($badgeData['id']);
- if ($badgeImage && !$this->fileManager->exists($badgeImage)) {
- $file = $this->fileManager->createFile(new File($badgeImage));
- $badgeData['image'] = $file->getUrl();
- }
-
- $this->crud->create($new, $badgeData, [Crud::NO_PERMISSIONS, Crud::NO_VALIDATION, Options::REFRESH_UUID]);
-
- $event->addCreatedEntity($badgeData['id'], $new);
- }
- $this->om->endFlushSuite();
- }
-}
diff --git a/src/plugin/path/Installation/InnovaPathInstaller.php b/src/plugin/path/Installation/InnovaPathInstaller.php
index a872429cb50..00d3fa0686d 100644
--- a/src/plugin/path/Installation/InnovaPathInstaller.php
+++ b/src/plugin/path/Installation/InnovaPathInstaller.php
@@ -6,4 +6,8 @@
class InnovaPathInstaller extends AdditionalInstaller
{
+ public function hasMigrations(): bool
+ {
+ return true;
+ }
}
diff --git a/src/plugin/rss/Installation/ClarolineRssInstaller.php b/src/plugin/rss/Installation/ClarolineRssInstaller.php
index cc0ca375f2b..2a85f547bfe 100644
--- a/src/plugin/rss/Installation/ClarolineRssInstaller.php
+++ b/src/plugin/rss/Installation/ClarolineRssInstaller.php
@@ -6,4 +6,8 @@
class ClarolineRssInstaller extends AdditionalInstaller
{
+ public function hasMigrations(): bool
+ {
+ return true;
+ }
}
diff --git a/src/plugin/scorm/Installation/ClarolineScormInstaller.php b/src/plugin/scorm/Installation/ClarolineScormInstaller.php
index b1e9b8da96c..9cb40fcf65b 100644
--- a/src/plugin/scorm/Installation/ClarolineScormInstaller.php
+++ b/src/plugin/scorm/Installation/ClarolineScormInstaller.php
@@ -6,4 +6,8 @@
class ClarolineScormInstaller extends AdditionalInstaller
{
+ public function hasMigrations(): bool
+ {
+ return true;
+ }
}
diff --git a/src/plugin/slideshow/Installation/ClarolineSlideshowInstaller.php b/src/plugin/slideshow/Installation/ClarolineSlideshowInstaller.php
index 26c8ae26c00..5f1255402c8 100644
--- a/src/plugin/slideshow/Installation/ClarolineSlideshowInstaller.php
+++ b/src/plugin/slideshow/Installation/ClarolineSlideshowInstaller.php
@@ -6,4 +6,8 @@
class ClarolineSlideshowInstaller extends AdditionalInstaller
{
+ public function hasMigrations(): bool
+ {
+ return true;
+ }
}
diff --git a/src/plugin/tag/Installation/ClarolineTagInstaller.php b/src/plugin/tag/Installation/ClarolineTagInstaller.php
index 0070850fdb4..f2416af92b3 100644
--- a/src/plugin/tag/Installation/ClarolineTagInstaller.php
+++ b/src/plugin/tag/Installation/ClarolineTagInstaller.php
@@ -6,4 +6,8 @@
class ClarolineTagInstaller extends AdditionalInstaller
{
+ public function hasMigrations(): bool
+ {
+ return true;
+ }
}
diff --git a/src/plugin/url/Installation/HeVinciUrlInstaller.php b/src/plugin/url/Installation/HeVinciUrlInstaller.php
index ad1927081bf..0aa70d4457a 100644
--- a/src/plugin/url/Installation/HeVinciUrlInstaller.php
+++ b/src/plugin/url/Installation/HeVinciUrlInstaller.php
@@ -6,4 +6,8 @@
class HeVinciUrlInstaller extends AdditionalInstaller
{
+ public function hasMigrations(): bool
+ {
+ return true;
+ }
}
diff --git a/src/plugin/video-player/Installation/ClarolineVideoPlayerInstaller.php b/src/plugin/video-player/Installation/ClarolineVideoPlayerInstaller.php
index ed1804867af..827cbd90d19 100644
--- a/src/plugin/video-player/Installation/ClarolineVideoPlayerInstaller.php
+++ b/src/plugin/video-player/Installation/ClarolineVideoPlayerInstaller.php
@@ -6,8 +6,4 @@
class ClarolineVideoPlayerInstaller extends AdditionalInstaller
{
- public function hasMigrations(): bool
- {
- return false;
- }
}
diff --git a/src/plugin/wiki/Installation/IcapWikiInstaller.php b/src/plugin/wiki/Installation/IcapWikiInstaller.php
index fc973e32e97..37277ad25f4 100644
--- a/src/plugin/wiki/Installation/IcapWikiInstaller.php
+++ b/src/plugin/wiki/Installation/IcapWikiInstaller.php
@@ -6,4 +6,8 @@
class IcapWikiInstaller extends AdditionalInstaller
{
+ public function hasMigrations(): bool
+ {
+ return true;
+ }
}