Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Cursus] copy action #2850

Merged
merged 11 commits into from
Sep 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/main/core/Entity/Planning/PlannedObject.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@
use Doctrine\ORM\Mapping as ORM;

/**
* @ORM\Entity()
* @ORM\Entity(repositoryClass="Claroline\CoreBundle\Repository\Planning\PlannedObjectRepository")
*
* @ORM\Table(name="claro_planned_object")
*/
class PlannedObject
Expand Down Expand Up @@ -74,6 +75,7 @@ class PlannedObject

/**
* @ORM\ManyToOne(targetEntity="Claroline\CoreBundle\Entity\Location")
*
* @ORM\JoinColumn(name="location_id", nullable=true, onDelete="SET NULL")
*/
private ?Location $location = null;
Expand Down
20 changes: 20 additions & 0 deletions src/main/core/Repository/Planning/PlannedObjectRepository.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

/*
* This file is part of the Claroline Connect package.
*
* (c) Claroline Consortium <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Claroline\CoreBundle\Repository\Planning;

use Claroline\AppBundle\Repository\UniqueValueFinder;
use Doctrine\ORM\EntityRepository;

class PlannedObjectRepository extends EntityRepository
{
use UniqueValueFinder;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@

namespace Claroline\CoreBundle\Subscriber\Crud\Planning;

use Claroline\AppBundle\Event\Crud\CopyEvent;
use Claroline\AppBundle\Event\Crud\CreateEvent;
use Claroline\AppBundle\Event\Crud\DeleteEvent;
use Claroline\AppBundle\Event\Crud\UpdateEvent;
use Claroline\AppBundle\Event\CrudEvents;
use Claroline\AppBundle\Persistence\ObjectManager;
use Claroline\CoreBundle\Entity\Location;
use Claroline\CoreBundle\Entity\Planning\AbstractPlanned;
use Claroline\CoreBundle\Entity\Planning\PlannedObject;
use Claroline\CoreBundle\Entity\User;
use Claroline\AppBundle\Event\CrudEvents;
use Claroline\CoreBundle\Manager\FileManager;
use Claroline\CoreBundle\Manager\PlanningManager;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
Expand Down Expand Up @@ -55,6 +56,7 @@ public static function getSubscribedEvents(): array
CrudEvents::getEventName(CrudEvents::POST_CREATE, static::getPlannedClass()) => 'postCreate',
CrudEvents::getEventName(CrudEvents::PRE_UPDATE, static::getPlannedClass()) => 'preUpdate',
CrudEvents::getEventName(CrudEvents::POST_DELETE, static::getPlannedClass()) => 'postDelete',
CrudEvents::getEventName(CrudEvents::PRE_COPY, static::getPlannedClass()) => 'preCopy',
];
}

Expand Down Expand Up @@ -151,4 +153,21 @@ public function postDelete(DeleteEvent $event): void
$this->fileManager->unlinkFile(PlannedObject::class, $object->getUuid(), $object->getThumbnail());
}
}

public function preCopy(CopyEvent $event): void
{
/** @var AbstractPlanned $original */
$original = $event->getObject();

/** @var AbstractPlanned $copy */
$copy = $event->getCopy();

$copy->setCreatedAt(new \DateTime());
$copy->setUpdatedAt(new \DateTime());
WolfyWin marked this conversation as resolved.
Show resolved Hide resolved

$plannedObjectRepo = $this->om->getRepository(PlannedObject::class);

$copyName = $plannedObjectRepo->findNextUnique('name', $original->getPlannedObject()->getName());
$copy->getPlannedObject()->setName($copyName);
}
}
43 changes: 43 additions & 0 deletions src/plugin/cursus/Controller/CourseController.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@

use Claroline\AppBundle\API\Options;
use Claroline\AppBundle\Controller\AbstractCrudController;
use Claroline\AppBundle\Controller\RequestDecoderTrait;
use Claroline\AppBundle\Manager\PdfManager;
use Claroline\CoreBundle\Component\Context\DesktopContext;
use Claroline\CoreBundle\Entity\Organization\Organization;
use Claroline\CoreBundle\Entity\User;
use Claroline\CoreBundle\Entity\Workspace\Workspace;
use Claroline\CoreBundle\Library\Normalizer\TextNormalizer;
use Claroline\CoreBundle\Library\RoutingHelper;
use Claroline\CoreBundle\Manager\Tool\ToolManager;
Expand All @@ -42,6 +44,7 @@
class CourseController extends AbstractCrudController
{
use PermissionCheckerTrait;
use RequestDecoderTrait;

private TokenStorageInterface $tokenStorage;
private RoutingHelper $routing;
Expand Down Expand Up @@ -201,6 +204,46 @@ public function restoreAction(Request $request): JsonResponse
}, $processed));
}

/**
* @Route("/copy", name="copy", methods={"POST"})
*/
public function copyAction(Request $request): JsonResponse
{
$processed = [];

$this->om->startFlushSuite();

$data = $this->decodeRequest($request);

$workspaceData = $data['workspace'] ?? null;
$workspace = null;

if ($workspaceData) {
$workspace = $this->om->getRepository(Workspace::class)->findOneBy(['uuid' => $data['workspace']['id']]);
}

/** @var Course[] $courses */
$courses = $this->om->getRepository(Course::class)->findBy([
'uuid' => $data['ids'],
]);

foreach ($courses as $course) {
if ($this->authorization->isGranted('ADMINISTRATE', $course)) {
$copy = $this->crud->copy($course);
if (1 === count($courses) && $workspace) {
$copy->setWorkspace($workspace);
}
$processed[] = $copy;
}
}

$this->om->endFlushSuite();

return new JsonResponse(array_map(function (Course $course) {
return $this->serializer->serialize($course);
}, $processed));
}

/**
* @Route("/{slug}/open", name="open", methods={"GET"})
*
Expand Down
31 changes: 31 additions & 0 deletions src/plugin/cursus/Controller/EventController.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
namespace Claroline\CursusBundle\Controller;

use Claroline\AppBundle\Controller\AbstractCrudController;
use Claroline\AppBundle\Controller\RequestDecoderTrait;
use Claroline\AppBundle\Manager\PdfManager;
use Claroline\CoreBundle\Entity\Group;
use Claroline\CoreBundle\Entity\Organization\Organization;
Expand Down Expand Up @@ -41,6 +42,7 @@
class EventController extends AbstractCrudController
{
use PermissionCheckerTrait;
use RequestDecoderTrait;

public function __construct(
AuthorizationCheckerInterface $authorization,
Expand Down Expand Up @@ -87,6 +89,35 @@ protected function getDefaultHiddenFilters(): array
return [];
}

/**
* @Route("/copy", name="copy", methods={"POST"})
*/
public function copyAction(Request $request): JsonResponse
{
$processed = [];

$this->om->startFlushSuite();

$data = $this->decodeRequest($request);

/** @var Event[] $events */
$events = $this->om->getRepository(Event::class)->findBy([
'uuid' => $data['ids'],
]);

foreach ($events as $event) {
if ($this->authorization->isGranted('EDIT', $event)) {
$processed[] = $this->crud->copy($event, [], ['parent' => $event->getSession()]);
}
}

$this->om->endFlushSuite();

return new JsonResponse(array_map(function (Event $event) {
return $this->serializer->serialize($event);
}, $processed));
}

/**
* @Route("/{workspace}", name="list", methods={"GET"})
*
Expand Down
31 changes: 31 additions & 0 deletions src/plugin/cursus/Controller/SessionController.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
namespace Claroline\CursusBundle\Controller;

use Claroline\AppBundle\Controller\AbstractCrudController;
use Claroline\AppBundle\Controller\RequestDecoderTrait;
use Claroline\AppBundle\Manager\PdfManager;
use Claroline\CoreBundle\Component\Context\DesktopContext;
use Claroline\CoreBundle\Entity\Group;
Expand Down Expand Up @@ -45,6 +46,7 @@
class SessionController extends AbstractCrudController
{
use PermissionCheckerTrait;
use RequestDecoderTrait;

private TokenStorageInterface $tokenStorage;
private TranslatorInterface $translator;
Expand Down Expand Up @@ -129,6 +131,35 @@ public function listPublicAction(Request $request): JsonResponse
);
}

/**
* @Route("/copy", name="copy", methods={"POST"})
*/
public function copyAction(Request $request): JsonResponse
{
$processed = [];

$this->om->startFlushSuite();

$data = $this->decodeRequest($request);

/** @var Session[] $sessions */
$sessions = $this->om->getRepository(Session::class)->findBy([
'uuid' => $data['ids'],
]);

foreach ($sessions as $session) {
if ($this->authorization->isGranted('EDIT', $session)) {
$processed[] = $this->crud->copy($session, [], ['parent' => $session->getCourse()]);
}
}

$this->om->endFlushSuite();

return new JsonResponse(array_map(function (Session $session) {
return $this->serializer->serialize($session);
}, $processed));
}

/**
* @Route("/{id}/pdf", name="download_pdf", methods={"GET"})
*
Expand Down
3 changes: 3 additions & 0 deletions src/plugin/cursus/Repository/CourseRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

namespace Claroline\CursusBundle\Repository;

use Claroline\AppBundle\Repository\UniqueValueFinder;
use Claroline\CoreBundle\Entity\Facet\FieldFacet;
use Claroline\CoreBundle\Entity\User;
use Claroline\CoreBundle\Entity\Workspace\Workspace;
Expand All @@ -21,6 +22,8 @@

class CourseRepository extends EntityRepository
{
use UniqueValueFinder;

public function search(string $search, int $nbResults)
{
return $this->createQueryBuilder('c')
Expand Down
3 changes: 3 additions & 0 deletions src/plugin/cursus/Repository/EventRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,16 @@

namespace Claroline\CursusBundle\Repository;

use Claroline\AppBundle\Repository\UniqueValueFinder;
use Claroline\CoreBundle\Entity\User;
use Claroline\CursusBundle\Entity\Event;
use Claroline\CursusBundle\Entity\Registration\AbstractRegistration;
use Doctrine\ORM\EntityRepository;

class EventRepository extends EntityRepository
{
use UniqueValueFinder;

public function countParticipants(Event $event): array
{
return [
Expand Down
3 changes: 3 additions & 0 deletions src/plugin/cursus/Repository/SessionRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

namespace Claroline\CursusBundle\Repository;

use Claroline\AppBundle\Repository\UniqueValueFinder;
use Claroline\CoreBundle\Entity\User;
use Claroline\CoreBundle\Entity\Workspace\Workspace;
use Claroline\CursusBundle\Entity\Course;
Expand All @@ -20,6 +21,8 @@

class SessionRepository extends EntityRepository
{
use UniqueValueFinder;

public function findByWorkspace(Workspace $workspace)
{
return $this->getEntityManager()
Expand Down
3 changes: 3 additions & 0 deletions src/plugin/cursus/Resources/config/services/subscriber.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ services:
- '@security.token_storage'
- '@Claroline\AppBundle\Persistence\ObjectManager'
- '@Claroline\CoreBundle\Manager\FileManager'
- '@Claroline\AppBundle\API\Crud'
tags:
- { name: kernel.event_subscriber }

Expand All @@ -33,8 +34,10 @@ services:
Claroline\CursusBundle\Subscriber\Crud\SessionSubscriber:
arguments:
- '@security.token_storage'
- '@Claroline\AppBundle\Persistence\ObjectManager'
- '@Claroline\CoreBundle\Manager\FileManager'
- '@Claroline\CursusBundle\Manager\SessionManager'
- '@Claroline\AppBundle\API\Crud'
tags:
- { name: kernel.event_subscriber }

Expand Down
48 changes: 48 additions & 0 deletions src/plugin/cursus/Resources/modules/actions/course/copy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import {createElement} from 'react'

import {url} from '#/main/app/api'
import {ASYNC_BUTTON} from '#/main/app/buttons'
import {hasPermission} from '#/main/app/security'
import {trans, transChoice} from '#/main/app/intl/translation'

import {CourseCard} from '#/plugin/cursus/course/components/card'

export default (courses, refresher) => {
const processable = courses.filter(course => hasPermission('administrate', course))

return {
name: 'copy',
type: ASYNC_BUTTON,
icon: 'fa fa-fw fa-clone',
label: trans('copy', {}, 'actions'),
displayed: 0 !== processable.length,
confirm: {
title: transChoice('copy_course_confirm_title', processable.length, {}, 'actions'),
subtitle: 1 === processable.length ? processable[0].name : transChoice('count_elements', processable.length, {count: processable.length}),
message: transChoice('copy_course_confirm_message', processable.length, {count: processable.length}, 'actions'),
additional: [
createElement('div', {
key: 'additional',
className: 'modal-body'
}, processable.map(course => createElement(CourseCard, {
key: course.id,
orientation: 'row',
size: 'xs',
data: course
})))
]
},
request: {
url: url(['apiv2_cursus_course_copy']),
request: {
method: 'POST',
body: JSON.stringify({
ids: processable.map(course => course.id)
})
},
success: (response) => refresher.update(response)
},
group: trans('management'),
scope: ['object', 'collection']
}
}
Loading
Loading