Fix documents migration + fix show/download files using resources

#2326
pull/2715/head
Julio Montoya 7 years ago
parent a5f2e2263e
commit f5d0592029
  1. 12
      config/routes.yaml
  2. 16
      config/services.yaml
  3. 8
      main/document/document.php
  4. 11
      main/document/show_content.php
  5. 5
      public/courses.php
  6. 80
      src/CoreBundle/Controller/ResourceController.php
  7. 2
      src/CoreBundle/Entity/Resource/AbstractResource.php
  8. 5
      src/CoreBundle/Entity/Resource/ResourceFile.php
  9. 5
      src/CoreBundle/Entity/Resource/ResourceLink.php
  10. 38
      src/CoreBundle/Security/Authorization/Voter/ResourceNodeVoter.php
  11. 2
      src/CourseBundle/Resources/config/routing.yml
  12. 201
      tests/scripts/migrate_item_property.php

@ -20,12 +20,12 @@ sonata_user_admin_security_logout:
# Resources # Resources
app_document: #app_document:
resource: | # resource: |
alias: app.document # alias: app.document
path: /resource/documents # path: /resource/documents
form: Chamilo\CoreBundle\Form\Type\DocumentType # form: Chamilo\CoreBundle\Form\Type\DocumentType
type: sylius.resource # type: sylius.resource
app_document_index: app_document_index:
path: /courses/{course}/resource/documents/ path: /courses/{course}/resource/documents/

@ -46,14 +46,14 @@ services:
sylius_settings: sylius_settings:
driver: doctrine/orm driver: doctrine/orm
sylius_resource: #sylius_resource:
resources: # resources:
app.document: # app.document:
templates: ChamiloCoreBundle:Document # templates: ChamiloCoreBundle:Document
classes: # classes:
controller: Chamilo\CoreBundle\Controller\ResourceController # controller: Chamilo\CoreBundle\Controller\ResourceController
model: Chamilo\CourseBundle\Entity\CDocument # model: Chamilo\CourseBundle\Entity\CDocument
repository: Chamilo\CoreBundle\Repository\ResourceRepository # repository: Chamilo\CoreBundle\Repository\ResourceRepository
# #
#sonata.media.provider.private: #sonata.media.provider.private:

@ -40,6 +40,7 @@ $actionsRight = '';
$action = isset($_REQUEST['action']) ? $_REQUEST['action'] : ''; $action = isset($_REQUEST['action']) ? $_REQUEST['action'] : '';
$allowUseTool = false; $allowUseTool = false;
if ($allowDownloadDocumentsByApiKey) { if ($allowDownloadDocumentsByApiKey) {
try { try {
if ($action != 'download') { if ($action != 'download') {
@ -329,6 +330,13 @@ switch ($action) {
// Launch event // Launch event
Event::event_download($document_data['url']); Event::event_download($document_data['url']);
$publicPath = api_get_path(WEB_PUBLIC_PATH);
$courseCode = api_get_course_id();
$path = $document_data['path'];
$url = $publicPath."courses/$courseCode/document$path";
header("Location: $url");
exit;
// Check visibility of document and paths // Check visibility of document and paths
if (!($isAllowedToEdit || $groupMemberWithUploadRights) && if (!($isAllowedToEdit || $groupMemberWithUploadRights) &&
!DocumentManager::is_visible_by_id($document_id, $courseInfo, $sessionId, api_get_user_id()) !DocumentManager::is_visible_by_id($document_id, $courseInfo, $sessionId, api_get_user_id())

@ -44,6 +44,17 @@ if (empty($document_data)) {
api_not_allowed(true); api_not_allowed(true);
} }
$publicPath = api_get_path(WEB_PUBLIC_PATH);
// http://localhost/chamilo2/courses/ABC/document/aa.html
$courseCode = api_get_course_id();
$path = $document_data['path'];
$type = 'show';
$url = $publicPath."courses/$courseCode/document$path?type=$type";
header("Location: $url");
exit;
$header_file = $document_data['path']; $header_file = $document_data['path'];
$name_to_show = cut($header_file, 80); $name_to_show = cut($header_file, 80);

@ -4,13 +4,14 @@
require_once '../main/inc/global.inc.php'; require_once '../main/inc/global.inc.php';
/** /**
* Redirects "courses/ABC/document/my_file.html" to the symfony Resourcecontroller see: * Redirects "courses/ABC/document/my_file.html" to the symfony ResourceController see:
* src/CoreBundle/Controller/ResourceController.php. * src/CoreBundle/Controller/ResourceController.php.
*/ */
$publicPath = api_get_path(WEB_PUBLIC_PATH); $publicPath = api_get_path(WEB_PUBLIC_PATH);
// http://localhost/chamilo2/courses/ABC/document/aa.html // http://localhost/chamilo2/courses/ABC/document/aa.html
$courseCode = Security::remove_XSS($_GET['courseCode']); $courseCode = Security::remove_XSS($_GET['courseCode']);
$path = Security::remove_XSS($_GET['url']); $path = Security::remove_XSS($_GET['url']);
$url = $publicPath."courses/$courseCode/document/$path"; $type = Security::remove_XSS($_GET['type']) ?? 'show';
$url = $publicPath."courses/$courseCode/document/$path?type=$type";
header("Location: $url"); header("Location: $url");
exit; exit;

@ -9,6 +9,7 @@ use APY\DataGridBundle\Grid\Export\CSVExport;
use APY\DataGridBundle\Grid\Export\ExcelExport; use APY\DataGridBundle\Grid\Export\ExcelExport;
use APY\DataGridBundle\Grid\Grid; use APY\DataGridBundle\Grid\Grid;
use APY\DataGridBundle\Grid\Source\Entity; use APY\DataGridBundle\Grid\Source\Entity;
use Chamilo\CoreBundle\Entity\Resource\ResourceNode;
use Chamilo\CoreBundle\Entity\Resource\ResourceRight; use Chamilo\CoreBundle\Entity\Resource\ResourceRight;
use Chamilo\CoreBundle\Repository\ResourceRepository; use Chamilo\CoreBundle\Repository\ResourceRepository;
use Chamilo\CoreBundle\Security\Authorization\Voter\ResourceNodeVoter; use Chamilo\CoreBundle\Security\Authorization\Voter\ResourceNodeVoter;
@ -17,13 +18,16 @@ use Chamilo\CourseBundle\Controller\CourseControllerTrait;
use Chamilo\CourseBundle\Entity\CDocument; use Chamilo\CourseBundle\Entity\CDocument;
use Chamilo\CourseBundle\Repository\CDocumentRepository; use Chamilo\CourseBundle\Repository\CDocumentRepository;
use FOS\RestBundle\View\View; use FOS\RestBundle\View\View;
use Sonata\MediaBundle\Provider\MediaProviderInterface;
use Sylius\Bundle\ResourceBundle\Controller\ResourceController as BaseResourceController; use Sylius\Bundle\ResourceBundle\Controller\ResourceController as BaseResourceController;
use Sylius\Bundle\ResourceBundle\Event\ResourceControllerEvent; use Sylius\Bundle\ResourceBundle\Event\ResourceControllerEvent;
use Sylius\Component\Resource\Exception\UpdateHandlingException; use Sylius\Component\Resource\Exception\UpdateHandlingException;
use Sylius\Component\Resource\ResourceActions; use Sylius\Component\Resource\ResourceActions;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\HttpException; use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/** /**
* Class ResourceController. * Class ResourceController.
@ -32,7 +36,8 @@ use Symfony\Component\HttpKernel\Exception\HttpException;
* *
* @package Chamilo\CoreBundle\Controller * @package Chamilo\CoreBundle\Controller
*/ */
class ResourceController extends BaseResourceController implements CourseControllerInterface //class ResourceController extends BaseResourceController implements CourseControllerInterface
class ResourceController extends BaseController implements CourseControllerInterface
{ {
use CourseControllerTrait; use CourseControllerTrait;
@ -400,6 +405,79 @@ class ResourceController extends BaseResourceController implements CourseControl
*/ */
public function showAction(Request $request): Response public function showAction(Request $request): Response
{ {
$file = $request->get('file');
$type = $request->get('type');
if (empty($type)) {
$type = 'show';
}
$documentRepo = $this->getDoctrine()->getRepository('ChamiloCourseBundle:CDocument');
$criteria = [
'path' => "/$file",
'course' => $this->getCourse(),
];
$document = $documentRepo->findOneBy($criteria);
if (empty($document)) {
throw new NotFoundHttpException();
}
/** @var ResourceNode $resourceNode */
$resourceNode = $document->getResourceNode();
$this->denyAccessUnlessGranted(
ResourceNodeVoter::VIEW,
$resourceNode,
'Unauthorised access to resource'
);
$resourceFile = $resourceNode->getResourceFile();
$media = $resourceFile->getMedia();
$format = MediaProviderInterface::FORMAT_REFERENCE;
if ($media) {
switch ($type) {
case 'show':
/** @var \Sonata\MediaBundle\Provider\ImageProvider $provider */
$provider = $this->get('sonata.media.pool')->getProvider($media->getProviderName());
$reference = $provider->getReferenceFile($media);
$filename = sprintf('%s/%s',
$provider->getFilesystem()->getAdapter()->getDirectory(),
$provider->generatePrivateUrl($media, $format)
);
//var_dump($provider->generatePublicUrl($media, $format));
//var_dump($filename);
return new BinaryFileResponse($filename);
exit;
return $this->render('@SonataMedia/Media/view.html.twig', [
'media' => $media,
'formats' => $this->get('sonata.media.pool')->getFormatNamesByContext($media->getContext()),
'format' => $format,
]);
break;
case 'download':
$provider = $this->get('sonata.media.pool')->getProvider($media->getProviderName());
$response = $provider->getDownloadResponse($media, $format, $this->get('sonata.media.pool')->getDownloadMode($media));
return $response;
break;
}
}
throw new NotFoundHttpException();
var_dump($resourceFile->getMedia()->getName());
$configuration = $this->requestConfigurationFactory->create($this->metadata, $request); $configuration = $this->requestConfigurationFactory->create($this->metadata, $request);
$this->isGrantedOr403($configuration, ResourceActions::SHOW); $this->isGrantedOr403($configuration, ResourceActions::SHOW);

@ -48,7 +48,7 @@ abstract class AbstractResource implements ResourceInterface
/** /**
* @return ResourceNode * @return ResourceNode
*/ */
public function getResourceNode() public function getResourceNode(): ResourceNode
{ {
return $this->resourceNode; return $this->resourceNode;
} }

@ -3,6 +3,7 @@
namespace Chamilo\CoreBundle\Entity\Resource; namespace Chamilo\CoreBundle\Entity\Resource;
use Chamilo\MediaBundle\Entity\Media;
use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo; use Gedmo\Mapping\Annotation as Gedmo;
@ -337,7 +338,7 @@ class ResourceFile
} }
/** /**
* @return mixed * @return Media
*/ */
public function getMedia() public function getMedia()
{ {
@ -345,7 +346,7 @@ class ResourceFile
} }
/** /**
* @param mixed $media * @param Media $media
* *
* @return ResourceFile * @return ResourceFile
*/ */

@ -173,6 +173,11 @@ class ResourceLink implements ResourceInterface
return $this; return $this;
} }
public function getResourceRight()
{
return $this->resourceRight;
}
/** /**
* @return int * @return int
*/ */

@ -6,6 +6,8 @@ namespace Chamilo\CoreBundle\Security\Authorization\Voter;
use Chamilo\CoreBundle\Entity\Course; use Chamilo\CoreBundle\Entity\Course;
use Chamilo\CoreBundle\Entity\Resource\ResourceLink; use Chamilo\CoreBundle\Entity\Resource\ResourceLink;
use Chamilo\CoreBundle\Entity\Resource\ResourceNode; use Chamilo\CoreBundle\Entity\Resource\ResourceNode;
use Chamilo\CoreBundle\Entity\Resource\ResourceRight;
use Zend\Permissions\Acl\Resource\GenericResource as SecurityResource;
use Chamilo\CoreBundle\Entity\Session; use Chamilo\CoreBundle\Entity\Session;
use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Security\Acl\Permission\MaskBuilder; use Symfony\Component\Security\Acl\Permission\MaskBuilder;
@ -100,7 +102,11 @@ class ResourceNodeVoter extends Voter
} }
/** /**
* {@inheritdoc} * @param string $attribute
* @param ResourceNode $resourceNode
* @param TokenInterface $token
*
* @return bool
*/ */
protected function voteOnAttribute($attribute, $resourceNode, TokenInterface $token): bool protected function voteOnAttribute($attribute, $resourceNode, TokenInterface $token): bool
{ {
@ -132,7 +138,7 @@ class ResourceNodeVoter extends Voter
$courseCode = $request->get('course'); $courseCode = $request->get('course');
$sessionId = $request->get('session'); $sessionId = $request->get('session');
$links = $resourceNode->getLinks(); $links = $resourceNode->getResourceLinks();
$linkFound = false; $linkFound = false;
/** @var ResourceLink $link */ /** @var ResourceLink $link */
@ -171,7 +177,7 @@ class ResourceNodeVoter extends Voter
// Check if resource was sent to a course // Check if resource was sent to a course
if ($linkCourse instanceof Course && !empty($courseCode)) { if ($linkCourse instanceof Course && !empty($courseCode)) {
$course = $this->container->get('chamilo_core.manager.course')->findOneByCode($courseCode); $course = $this->container->get('chamilo_core.entity.manager.course_manager')->findOneByCode($courseCode);
if ($course instanceof Course && if ($course instanceof Course &&
$linkCourse->getCode() === $course->getCode() $linkCourse->getCode() === $course->getCode()
) { ) {
@ -187,14 +193,34 @@ class ResourceNodeVoter extends Voter
} }
// Getting rights from the link // Getting rights from the link
$rightFromResourceLink = $link->getRights(); $rightFromResourceLink = $link->getResourceRight();
if ($rightFromResourceLink->count()) { if ($rightFromResourceLink->count()) {
// Taken rights from the link // Taken rights from the link
$rights = $rightFromResourceLink; $rights = $rightFromResourceLink;
} else { } else {
// Taken the rights from the default tool // Taken the rights from the default tool
$rights = $link->getResourceNode()->getTool()->getToolResourceRight(); //$rights = $link->getResourceNode()->getTool()->getToolResourceRight();
//$rights = $link->getResourceNode()->getResourceType()->getTool()->getToolResourceRight();
// By default the rights are:
// teacher: CRUD
// student: read
$readerMask = self::getReaderMask();
$editorMask = self::getEditorMask();
$resourceRight = new ResourceRight();
$resourceRight
->setMask($editorMask)
->setRole(self::ROLE_CURRENT_COURSE_TEACHER)
;
$rights[] = $resourceRight;
$resourceRight = new ResourceRight();
$resourceRight
->setMask($readerMask)
->setRole(self::ROLE_CURRENT_COURSE_STUDENT)
;
$rights[] = $resourceRight;
} }
// Asked mask // Asked mask
@ -230,7 +256,7 @@ class ResourceNodeVoter extends Voter
$acl->addRole($admin); $acl->addRole($admin);
// Adds a resource // Adds a resource
$resource = new Resource($link); $resource = new SecurityResource($link);
$acl->addResource($resource); $acl->addResource($resource);
// Role and permissions settings // Role and permissions settings

@ -10,7 +10,7 @@ core_tool:
core_tool_document: core_tool_document:
path: /courses/{course}/document/{file} path: /courses/{course}/document/{file}
defaults: defaults:
_controller: ChamiloCoreBundle:Resource:getDocument _controller: ChamiloCoreBundle:Resource:show
requirements: requirements:
file: .+ # allow "/" in {file} file: .+ # allow "/" in {file}

@ -13,7 +13,23 @@ use Chamilo\CoreBundle\Security\Authorization\Voter\ResourceNodeVoter;
require_once __DIR__.'/../../main/inc/global.inc.php'; require_once __DIR__.'/../../main/inc/global.inc.php';
$sql = "SELECT * FROM c_item_property WHERE tool = 'document' LIMIT 10"; $sql = "SELECT
d.id,
d.c_id,
d.session_id,
i.to_group_id,
i.to_user_id,
i.iid,
insert_user_id,
insert_date,
lastedit_date,
tool,
visibility
FROM c_item_property i
INNER JOIN c_document d
ON (d.iid = i.ref AND i.c_id = d.c_id)
WHERE i.tool = 'document' AND filetype <> 'folder' AND d.c_id = 4
ORDER BY d.path LIMIT 10";
$result = Database::query($sql); $result = Database::query($sql);
$fs = Container::$container->get('oneup_flysystem.courses_filesystem'); $fs = Container::$container->get('oneup_flysystem.courses_filesystem');
@ -22,6 +38,9 @@ $em = Database::getManager();
$resourceType = $em->getRepository('ChamiloCoreBundle:Resource\ResourceType')->findOneBy(['name' => 'document']); $resourceType = $em->getRepository('ChamiloCoreBundle:Resource\ResourceType')->findOneBy(['name' => 'document']);
$coursePath = api_get_path(SYS_PATH).'app/courses/'; $coursePath = api_get_path(SYS_PATH).'app/courses/';
$mediaManager = Container::$container->get('sonata.media.manager.media'); $mediaManager = Container::$container->get('sonata.media.manager.media');
$documentManager = $em->getRepository('ChamiloCourseBundle:CDocument');
$contextManager = Container::$container->get('sonata.classification.manager.context');
$defaultContext = $contextManager->findOneBy(['id' => 'default']);
while ($row = Database::fetch_array($result, 'ASSOC')) { while ($row = Database::fetch_array($result, 'ASSOC')) {
$itemIid = $row['iid']; $itemIid = $row['iid'];
@ -29,20 +48,31 @@ while ($row = Database::fetch_array($result, 'ASSOC')) {
$sessionId = $row['session_id']; $sessionId = $row['session_id'];
$groupId = $row['to_group_id']; $groupId = $row['to_group_id'];
$toUserId = $row['to_user_id']; $toUserId = $row['to_user_id'];
$documentId = $row['id'];
$toUser = api_get_user_entity($toUserId); $toUser = api_get_user_entity($toUserId);
$author = api_get_user_entity($row['insert_user_id']); $author = api_get_user_entity($row['insert_user_id']);
if (empty($author)) {
error_log("User does not exists in the DB ".$row['insert_user_id']);
continue;
}
$createdAt = api_get_utc_datetime($row['insert_date'], true, true); $createdAt = api_get_utc_datetime($row['insert_date'], true, true);
$lastUpdatedAt = api_get_utc_datetime($row['lastedit_date'], true, true); $lastUpdatedAt = api_get_utc_datetime($row['lastedit_date'], true, true);
$course = api_get_course_entity($courseId); $course = api_get_course_entity($courseId);
$session = api_get_course_entity($sessionId); if (empty($course)) {
error_log("Course does not exists in the DB $courseId");
continue;
}
$session = api_get_session_entity($sessionId);
$group = api_get_group_entity($groupId); $group = api_get_group_entity($groupId);
switch ($row['tool']) { switch ($row['tool']) {
case 'document': case 'document':
$documentData = DocumentManager::get_document_data_by_id($row['ref'], $course->getCode(), $sessionId); $documentData = DocumentManager::get_document_data_by_id($documentId, $course->getCode(), $sessionId);
var_dump($documentData); //var_dump($documentData);
if (!$documentData) { if (!$documentData) {
//$documentData = DocumentManager::get_document_data_by_id($row['ref'], $course->getCode(), $sessionId); //$documentData = DocumentManager::get_document_data_by_id($row['ref'], $course->getCode(), $sessionId);
error_log("Skipped item property iid #$itemIid"); error_log("Skipped item property iid #$itemIid");
@ -50,103 +80,114 @@ while ($row = Database::fetch_array($result, 'ASSOC')) {
} }
$folderPath = $course->getDirectory().'/document/'.$documentData['path']; $folderPath = $course->getDirectory().'/document/'.$documentData['path'];
$file = $coursePath.$folderPath; $file = $coursePath.$folderPath;
switch ($documentData['filetype']) { switch ($documentData['filetype']) {
case 'folder': case 'folder':
//$fs->createDir($folderPath); //$fs->createDir($folderPath);
/*$node = new ResourceNode();
$node
->setName($documentData['title'])
->setDescription('')
->setCreator($author)
->setResourceType($resourceType)
->setCreatedAt($createdAt)
->setUpdatedAt($lastUpdatedAt)
;
$em->persist($node);
$em->flush();*/
break; break;
case 'file': case 'file':
//$stream = fopen($file, 'r+'); $document = $documentManager->find($documentData['iid']);
//$fs->writeStream($folderPath, $stream); var_dump('Parsing document iid #'.$document->getIid());
//fclose($stream);
/** @var Media $media */ /** @var Media $media */
$media = $mediaManager->create(); $media = $mediaManager->create();
//$media = new Media();
$media->setName($documentData['title']); $media->setName($documentData['title']);
$fileName = basename($documentData['path']);
$extension = pathinfo($fileName, PATHINFO_EXTENSION);
$media->setSize($documentData['size']); $media->setSize($documentData['size']);
$media->setContext('default'); $media->setContext('default');
$media->setProviderName('sonata.media.provider.image');
var_dump($file); $provider = 'sonata.media.provider.image';
if (!in_array($extension, ['jpeg', 'jpg', 'gif', 'png'])) {
$provider = 'sonata.media.provider.file';
}
$media->setProviderName($provider);
$media->setEnabled(true); $media->setEnabled(true);
$stdFile = new Std $media->setBinaryContent($file);
$media->setBinaryContent(file_get_contents($file));
$mediaManager->save($media, true); $mediaManager->save($media, true);
$resourceFile = new ResourceFile();
$resourceFile->setMedia($media);
$resourceFile->setName($documentData['title']);
$em->persist($resourceFile);
$node = new ResourceNode();
$node
->setName($documentData['title'])
->setDescription($documentData['comment'] ?? '')
->setResourceFile($resourceFile)
->setCreator($author)
->setResourceType($resourceType)
->setCreatedAt($createdAt)
->setUpdatedAt($lastUpdatedAt)
;
$em->persist($node);
$document->setResourceNode($node);
$em->persist($document);
$em->flush();
$rights = [];
switch ($row['visibility']) {
case '0':
$newVisibility = ResourceLink::VISIBILITY_DRAFT;
$readerMask = ResourceNodeVoter::getReaderMask();
$editorMask = ResourceNodeVoter::getEditorMask();
$resourceRight = new ResourceRight();
$resourceRight
->setMask($editorMask)
->setRole(ResourceNodeVoter::ROLE_CURRENT_COURSE_TEACHER)
;
$rights[] = $resourceRight;
break;
case '1':
$newVisibility = ResourceLink::VISIBILITY_PUBLISHED;
break;
case '2':
$newVisibility = ResourceLink::VISIBILITY_DELETED;
break;
}
$link = new ResourceLink();
$link
->setCourse($course)
->setSession($session)
->setGroup($group)
->setUser($toUser)
->setResourceNode($node)
->setVisibility($newVisibility)
;
if (!empty($rights)) {
foreach ($rights as $right) {
$link->addResourceRight($right);
}
}
break; $em->persist($link);
} $em->flush();
continue;
$file = new ResourceFile();
$file
->setHash('')
->setName($documentData['title'])
->setOriginalFilename(basename($documentData['path']))
->setSize($documentData['size'])
;
$node = new ResourceNode();
$node
->setName($documentData['title'])
->setDescription($documentData['comment'])
->setResourceFile($file)
->setCreator($author)
->setResourceFile($file)
->setResourceType($resourceType)
->setCreatedAt($createdAt)
->setUpdatedAt($lastUpdatedAt)
;
$em->persist($node);
$em->flush();
$rights = [];
switch ($row['visibility']) {
case '0':
$newVisibility = ResourceLink::VISIBILITY_DRAFT;
$readerMask = ResourceNodeVoter::getReaderMask();
$editorMask = ResourceNodeVoter::getEditorMask();
$resourceRight = new ResourceRight();
$resourceRight
->setMask($editorMask)
->setRole(ResourceNodeVoter::ROLE_CURRENT_COURSE_TEACHER)
;
$rights[] = $resourceRight;
break;
case '1':
$newVisibility = ResourceLink::VISIBILITY_PUBLISHED;
break; break;
case '2':
$newVisibility = ResourceLink::VISIBILITY_DELETED;
break;
}
$link = new ResourceLink();
$link
->setCourse($course)
->setSession($session)
->setGroup($group)
->setUser($toUser)
->setResourceNode($node)
->setVisibility($newVisibility)
;
if (!empty($rights)) {
foreach ($rights as $right) {
$link->addResourceRight($right);
}
} }
$em->persist($link);
$em->flush();
break; break;
} }
} }

Loading…
Cancel
Save