diff --git a/Controller/ScormController.php b/Controller/ScormController.php index 3e11fa1..3784729 100644 --- a/Controller/ScormController.php +++ b/Controller/ScormController.php @@ -23,8 +23,10 @@ use Claroline\ScormBundle\Manager\ScormManager; use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Symfony\Component\EventDispatcher\EventDispatcherInterface; +use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\Routing\RouterInterface; use Symfony\Component\Security\Core\Exception\AccessDeniedException; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface; @@ -36,16 +38,18 @@ class ScormController extends Controller private $eventDispatcher; private $om; private $request; + private $router; private $scormManager; private $tokenStorage; private $authorization; /** * @DI\InjectParams({ - * "eventDispatcher" = @DI\Inject("event_dispatcher"), - * "om" = @DI\Inject("claroline.persistence.object_manager"), - * "requestStack" = @DI\Inject("request_stack"), - * "scormManager" = @DI\Inject("claroline.manager.scorm_manager"), + * "eventDispatcher" = @DI\Inject("event_dispatcher"), + * "om" = @DI\Inject("claroline.persistence.object_manager"), + * "requestStack" = @DI\Inject("request_stack"), + * "router" = @DI\Inject("router"), + * "scormManager" = @DI\Inject("claroline.manager.scorm_manager"), * "authorization" = @DI\Inject("security.authorization_checker"), * "tokenStorage" = @DI\Inject("security.token_storage") * }) @@ -54,6 +58,7 @@ public function __construct( EventDispatcherInterface $eventDispatcher, ObjectManager $om, RequestStack $requestStack, + RouterInterface $router, ScormManager $scormManager, TokenStorageInterface $tokenStorage, AuthorizationCheckerInterface $authorization @@ -62,6 +67,7 @@ public function __construct( $this->eventDispatcher = $eventDispatcher; $this->om = $om; $this->request = $requestStack; + $this->router = $router; $this->scormManager = $scormManager; $this->tokenStorage = $tokenStorage; $this->authorization = $authorization; @@ -69,8 +75,9 @@ public function __construct( /** * @EXT\Route( - * "/render/scorm/12/{scormId}", - * name = "claro_render_scorm_12_resource" + * "/render/scorm/12/{scormId}/mode/{mode}", + * name = "claro_render_scorm_12_resource", + * defaults={"mode"=0} * ) * @EXT\ParamConverter( * "scorm", @@ -83,7 +90,7 @@ public function __construct( * * @return Response */ - public function renderScorm12ResourceAction(Scorm12Resource $scorm) + public function renderScorm12ResourceAction(Scorm12Resource $scorm, $mode = 0) { $this->checkAccess('OPEN', $scorm); $user = $this->tokenStorage->getToken()->getUser(); @@ -91,6 +98,8 @@ public function renderScorm12ResourceAction(Scorm12Resource $scorm) $rootScos = array(); $trackings = array(); $scos = $scorm->getScos(); + $nbActiveScos = 0; + $lastActiveSco = null; if (!$isAnon) { $scosTracking = $this->scormManager @@ -111,16 +120,32 @@ public function renderScorm12ResourceAction(Scorm12Resource $scorm) $trackings[$sco->getId()] = $this->scormManager ->createScorm12ScoTracking($user, $sco); } + + if (!$sco->getIsBlock()) { + $nbActiveScos++; + $lastActiveSco = $sco; + } } + + if ($mode === 0 && $nbActiveScos === 1) { + + return new RedirectResponse( + $this->router->generate( + 'claro_render_scorm_12_sco', + array('scoId' => $lastActiveSco->getId()) + ) + ); + } else { - return array( - 'resource' => $scorm, - '_resource' => $scorm, - 'scos' => $rootScos, - 'workspace' => $scorm->getResourceNode()->getWorkspace(), - 'trackings' => $trackings, - 'isAnon' => $isAnon - ); + return array( + 'resource' => $scorm, + '_resource' => $scorm, + 'scos' => $rootScos, + 'workspace' => $scorm->getResourceNode()->getWorkspace(), + 'trackings' => $trackings, + 'isAnon' => $isAnon + ); + } } /** @@ -364,8 +389,9 @@ private function logScorm12ScoResult( /** * @EXT\Route( - * "/render/scorm/2004/{scormId}", - * name = "claro_render_scorm_2004_resource" + * "/render/scorm/2004/{scormId}/mode/{mode}", + * name = "claro_render_scorm_2004_resource", + * defaults={"mode"=0} * ) * @EXT\ParamConverter( * "scorm", @@ -378,7 +404,7 @@ private function logScorm12ScoResult( * * @return Response */ - public function renderScorm2004ResourceAction(Scorm2004Resource $scorm) + public function renderScorm2004ResourceAction(Scorm2004Resource $scorm, $mode = 0) { $this->checkScorm2004ResourceAccess('OPEN', $scorm); $user = $this->tokenStorage->getToken()->getUser(); @@ -386,6 +412,8 @@ public function renderScorm2004ResourceAction(Scorm2004Resource $scorm) $rootScos = array(); $trackings = array(); $scos = $scorm->getScos(); + $nbActiveScos = 0; + $lastActiveSco = null; if (!$isAnon) { $scosTracking = $this->scormManager @@ -406,16 +434,32 @@ public function renderScorm2004ResourceAction(Scorm2004Resource $scorm) $trackings[$sco->getId()] = $this->scormManager ->createScorm2004ScoTracking($user, $sco); } + + if (!$sco->getIsBlock()) { + $nbActiveScos++; + $lastActiveSco = $sco; + } } - return array( - 'resource' => $scorm, - '_resource' => $scorm, - 'scos' => $rootScos, - 'workspace' => $scorm->getResourceNode()->getWorkspace(), - 'trackings' => $trackings, - 'isAnon' => $isAnon - ); + if ($mode === 0 && $nbActiveScos === 1) { + + return new RedirectResponse( + $this->router->generate( + 'claro_render_scorm_2004_sco', + array('scoId' => $lastActiveSco->getId()) + ) + ); + } else { + + return array( + 'resource' => $scorm, + '_resource' => $scorm, + 'scos' => $rootScos, + 'workspace' => $scorm->getResourceNode()->getWorkspace(), + 'trackings' => $trackings, + 'isAnon' => $isAnon + ); + } } /** diff --git a/Entity/Scorm12Resource.php b/Entity/Scorm12Resource.php index cced6f5..3748853 100644 --- a/Entity/Scorm12Resource.php +++ b/Entity/Scorm12Resource.php @@ -21,7 +21,7 @@ class Scorm12Resource extends AbstractResource { /** - * @ORM\Column(name="hash_name", length=50) + * @ORM\Column(name="hash_name") */ protected $hashName; diff --git a/Entity/Scorm2004Resource.php b/Entity/Scorm2004Resource.php index 8624fc7..0ebe5c7 100644 --- a/Entity/Scorm2004Resource.php +++ b/Entity/Scorm2004Resource.php @@ -21,7 +21,7 @@ class Scorm2004Resource extends AbstractResource { /** - * @ORM\Column(name="hash_name", length=50) + * @ORM\Column(name="hash_name") */ protected $hashName; diff --git a/Listener/Scorm12Listener.php b/Listener/Scorm12Listener.php index b7ec64d..afbe115 100644 --- a/Listener/Scorm12Listener.php +++ b/Listener/Scorm12Listener.php @@ -22,7 +22,6 @@ use Claroline\ScormBundle\Entity\Scorm12Resource; use Claroline\ScormBundle\Entity\Scorm12Sco; use Claroline\ScormBundle\Form\ScormType; -use Claroline\ScormBundle\Manager\ScormManager; use Claroline\ScormBundle\Listener\Exception\InvalidScormArchiveException; use JMS\DiExtraBundle\Annotation as DI; use Symfony\Bundle\TwigBundle\TwigEngine; @@ -54,7 +53,6 @@ class Scorm12Listener private $scorm12ScoTrackingRepo; private $templating; private $translator; - private $scormManager; /** * @DI\InjectParams({ @@ -65,8 +63,7 @@ class Scorm12Listener * "requestStack" = @DI\Inject("request_stack"), * "router" = @DI\Inject("router"), * "templating" = @DI\Inject("templating"), - * "translator" = @DI\Inject("translator"), - * "scormManager" = @DI\Inject("claroline.manager.scorm_manager") + * "translator" = @DI\Inject("translator") * }) */ public function __construct( @@ -90,7 +87,7 @@ public function __construct( $this->router = $router; $this->scormResourceRepo = $om->getRepository('ClarolineScormBundle:Scorm12Resource'); $this->scormResourcesPath = $this->container - ->getParameter('kernel.root_dir') . '/../web/uploads/scormresources/'; + ->getParameter('claroline.param.uploads_directory') . '/scormresources/'; $this->scorm12ScoTrackingRepo = $om->getRepository('ClarolineScormBundle:Scorm12ScoTracking'); $this->templating = $templating; $this->translator = $translator; @@ -134,11 +131,12 @@ public function onCreate(CreateResourceEvent $event) try { if ($form->isValid()) { $tmpFile = $form->get('file')->getData(); + $workspace = $event->getParent()->getWorkspace(); if ($this->isScormArchive($tmpFile)) { $scormResource = $this->container ->get('claroline.manager.scorm_manager') - ->createScorm12($tmpFile, $form->get('name')->getData()); + ->createScorm12($tmpFile, $form->get('name')->getData(), $workspace); $event->setResources(array($scormResource)); $event->stopPropagation(); @@ -250,6 +248,7 @@ public function onCopy(CopyResourceEvent $event) public function onDownload(DownloadResourceEvent $event) { $event->setItem($this->filePath . $event->getResource()->getHashName()); + $event->setExtension('zip'); $event->stopPropagation(); } @@ -279,7 +278,7 @@ private function isScormArchive(UploadedFile $file) /** * Deletes recursively a directory and its content. * - * @param $dir The path to the directory to delete. + * @param $dirPath The path to the directory to delete. */ private function deleteFiles($dirPath) { diff --git a/Listener/Scorm2004Listener.php b/Listener/Scorm2004Listener.php index 43a69f8..2fdddb3 100644 --- a/Listener/Scorm2004Listener.php +++ b/Listener/Scorm2004Listener.php @@ -87,7 +87,7 @@ public function __construct( $this->router = $router; $this->scormResourceRepo = $om->getRepository('ClarolineScormBundle:Scorm2004Resource'); $this->scormResourcesPath = $this->container - ->getParameter('kernel.root_dir') . '/../web/uploads/scormresources/'; + ->getParameter('claroline.param.uploads_directory') . '/scormresources/'; $this->scorm2004ScoTrackingRepo = $om->getRepository('ClarolineScormBundle:Scorm2004ScoTracking'); $this->templating = $templating; $this->translator = $translator; @@ -131,6 +131,8 @@ public function onCreate(CreateResourceEvent $event) try { if ($form->isValid()) { $tmpFile = $form->get('file')->getData(); + $workspace = $event->getParent()->getWorkspace(); + $prefix = 'WORKSPACE_' . $workspace->getId(); if ($this->isScormArchive($tmpFile)) { $scormResource = new Scorm2004Resource(); @@ -139,7 +141,7 @@ public function onCreate(CreateResourceEvent $event) $extension = pathinfo($fileName, PATHINFO_EXTENSION); $hashName = $this->container->get('claroline.utilities.misc') ->generateGuid() . "." . $extension; - $scormResource->setHashName($hashName); + $scormResource->setHashName($prefix . DIRECTORY_SEPARATOR . $hashName); $scos = $this->generateScosFromScormArchive($tmpFile); if (count($scos) > 0) { @@ -148,9 +150,9 @@ public function onCreate(CreateResourceEvent $event) } else { throw new InvalidScormArchiveException('no_sco_in_scorm_archive_message'); } - $this->unzipScormArchive($tmpFile, $hashName); + $this->unzipScormArchive($tmpFile, $hashName, $prefix); // Move Scorm archive in the files directory - $tmpFile->move($this->filePath, $hashName); + $tmpFile->move($this->filePath . DIRECTORY_SEPARATOR . $prefix, $hashName); $event->setResources(array($scormResource)); $event->stopPropagation(); @@ -263,6 +265,7 @@ public function onCopy(CopyResourceEvent $event) public function onDownload(DownloadResourceEvent $event) { $event->setItem($this->filePath . $event->getResource()->getHashName()); + $event->setExtension('zip'); $event->stopPropagation(); } @@ -295,11 +298,11 @@ private function isScormArchive(UploadedFile $file) * @param UploadedFile $file * @param $hashName name of the destination directory */ - private function unzipScormArchive(UploadedFile $file, $hashName) + private function unzipScormArchive(UploadedFile $file, $hashName, $prefix) { $zip = new \ZipArchive(); $zip->open($file); - $destinationDir = $this->scormResourcesPath . $hashName; + $destinationDir = $this->scormResourcesPath . $prefix . DIRECTORY_SEPARATOR . $hashName; if (!file_exists($destinationDir)) { mkdir($destinationDir, 0777, true); diff --git a/Manager/ScormManager.php b/Manager/ScormManager.php index 0d50a0b..7b138c3 100644 --- a/Manager/ScormManager.php +++ b/Manager/ScormManager.php @@ -13,6 +13,7 @@ namespace Claroline\ScormBundle\Manager; use Claroline\CoreBundle\Entity\User; +use Claroline\CoreBundle\Entity\Workspace\Workspace; use Claroline\CoreBundle\Persistence\ObjectManager; use Claroline\ScormBundle\Entity\Scorm12Resource; use Claroline\ScormBundle\Entity\Scorm12Sco; @@ -58,18 +59,19 @@ public function __construct(ObjectManager $om, ContainerInterface $container) $this->scorm2004ScoTrackingRepo = $om->getRepository('ClarolineScormBundle:Scorm2004ScoTracking'); $this->scormResourcesPath = $this->container - ->getParameter('kernel.root_dir') . '/../web/uploads/scormresources/'; + ->getParameter('claroline.param.uploads_directory') . '/scormresources/'; $this->filePath = $this->container ->getParameter('claroline.param.files_directory') . DIRECTORY_SEPARATOR; } - public function createScorm12($tmpFile, $name) + public function createScorm12($tmpFile, $name, Workspace $workspace) { + $prefix = 'WORKSPACE_' . $workspace->getId(); $scormResource = new Scorm12Resource(); $scormResource->setName($name); $hashName = $this->container->get('claroline.utilities.misc') ->generateGuid() . '.zip'; - $scormResource->setHashName($hashName); + $scormResource->setHashName($prefix . DIRECTORY_SEPARATOR . $hashName); $scos = $this->generateScosFromScormArchive($tmpFile); if (count($scos) > 0) { @@ -78,9 +80,9 @@ public function createScorm12($tmpFile, $name) } else { throw new InvalidScormArchiveException('no_sco_in_scorm_archive_message'); } - $this->unzipScormArchive($tmpFile, $hashName); + $this->unzipScormArchive($tmpFile, $hashName, $prefix); // Move Scorm archive in the files directory - $tmpFile->move($this->filePath, $hashName); + $tmpFile->move($this->filePath . DIRECTORY_SEPARATOR . $prefix, $hashName); return $scormResource; } @@ -496,11 +498,11 @@ private function persistScos( * @param UploadedFile $file * @param $hashName name of the destination directory */ - private function unzipScormArchive(\SplFileInfo $file, $hashName) + private function unzipScormArchive(\SplFileInfo $file, $hashName, $prefix) { $zip = new \ZipArchive(); $zip->open($file); - $destinationDir = $this->scormResourcesPath . $hashName; + $destinationDir = $this->scormResourcesPath . $prefix . DIRECTORY_SEPARATOR . $hashName; if (!file_exists($destinationDir)) { mkdir($destinationDir, 0777, true); diff --git a/Migrations/pdo_mysql/Version20150827171038.php b/Migrations/pdo_mysql/Version20150827171038.php new file mode 100644 index 0000000..a6a0f1a --- /dev/null +++ b/Migrations/pdo_mysql/Version20150827171038.php @@ -0,0 +1,34 @@ +addSql(" + ALTER TABLE claro_scorm_2004_resource CHANGE hash_name hash_name VARCHAR(255) NOT NULL + "); + $this->addSql(" + ALTER TABLE claro_scorm_12_resource CHANGE hash_name hash_name VARCHAR(255) NOT NULL + "); + } + + public function down(Schema $schema) + { + $this->addSql(" + ALTER TABLE claro_scorm_12_resource CHANGE hash_name hash_name VARCHAR(50) NOT NULL COLLATE utf8_unicode_ci + "); + $this->addSql(" + ALTER TABLE claro_scorm_2004_resource CHANGE hash_name hash_name VARCHAR(50) NOT NULL COLLATE utf8_unicode_ci + "); + } +} \ No newline at end of file diff --git a/Resources/views/scorm12MenuSco.html.twig b/Resources/views/scorm12MenuSco.html.twig index d162330..56c7c08 100644 --- a/Resources/views/scorm12MenuSco.html.twig +++ b/Resources/views/scorm12MenuSco.html.twig @@ -75,6 +75,17 @@ } } + $('#menu-display-btn').on('click', function () { + if ($('#menu-box').hasClass('hidden')) { + $('#content-box').removeClass('col-md-12'); + $('#content-box').addClass('col-md-9'); + $('#menu-box').removeClass('hidden'); + } else { + $('#menu-box').addClass('hidden'); + $('#content-box').removeClass('col-md-9'); + $('#content-box').addClass('col-md-12'); + } + }); {% endblock %} @@ -83,18 +94,20 @@

{{ currentSco.getTitle() }}

+
+
-