|
@@ -1,4 +1,5 @@
|
1
|
1
|
<?php
|
|
2
|
+
|
2
|
3
|
namespace Logipro\Bundle\SCORMBundle\Services;
|
3
|
4
|
|
4
|
5
|
use Doctrine\ORM\EntityManagerInterface;
|
|
@@ -115,7 +116,7 @@ class ScormEngine
|
115
|
116
|
'duration' => ''
|
116
|
117
|
)
|
117
|
118
|
);
|
118
|
|
-
|
|
119
|
+
|
119
|
120
|
// Controle sur la clef fournie (elle doit etre non null et non existante en BD)
|
120
|
121
|
if (!empty($courseKey)) {
|
121
|
122
|
$course = $this->requireCourse($courseKey);
|
|
@@ -126,7 +127,7 @@ class ScormEngine
|
126
|
127
|
return $response;
|
127
|
128
|
}
|
128
|
129
|
|
129
|
|
- // ZIP
|
|
130
|
+ // ZIP
|
130
|
131
|
// Test de l'existence du fichier à uploader
|
131
|
132
|
if (!file_exists($zipPath)) {
|
132
|
133
|
$response['code'] = 400;
|
|
@@ -192,7 +193,7 @@ class ScormEngine
|
192
|
193
|
$zipFile->extractZipFile($this->packageFolder, $this->contentFolder);
|
193
|
194
|
}
|
194
|
195
|
|
195
|
|
- // COURS
|
|
196
|
+ // COURS
|
196
|
197
|
// Création du cours
|
197
|
198
|
$course = new Course();
|
198
|
199
|
$course->setCourseKey($courseKey);
|
|
@@ -203,7 +204,7 @@ class ScormEngine
|
203
|
204
|
$response['course']['courseKey'] = $course->getCourseKey();
|
204
|
205
|
$response['course']['maxVersion'] = $course->getMaxVersion();
|
205
|
206
|
|
206
|
|
- // Mapping Zip/Cours
|
|
207
|
+ // Mapping Zip/Cours
|
207
|
208
|
$mapping = new MapCourseZipfile();
|
208
|
209
|
$mapping->setCourse($course);
|
209
|
210
|
$mapping->setZipFile($zipFile);
|
|
@@ -248,7 +249,7 @@ class ScormEngine
|
248
|
249
|
'duration' => ''
|
249
|
250
|
)
|
250
|
251
|
);
|
251
|
|
-
|
|
252
|
+
|
252
|
253
|
// Controle sur la clef fournie (elle doit etre non null et non existante en BD)
|
253
|
254
|
if (!empty($courseKey)) {
|
254
|
255
|
$course = $this->requireCourse($courseKey);
|
|
@@ -259,7 +260,7 @@ class ScormEngine
|
259
|
260
|
return $response;
|
260
|
261
|
}
|
261
|
262
|
|
262
|
|
- // ZIP
|
|
263
|
+ // ZIP
|
263
|
264
|
// Test de l'existence du fichier à uploader
|
264
|
265
|
if (!file_exists($zipPath)) {
|
265
|
266
|
$response['code'] = 400;
|
|
@@ -321,7 +322,7 @@ class ScormEngine
|
321
|
322
|
$zipFile->extractZipFile($this->packageFolder, $this->contentFolder);
|
322
|
323
|
}
|
323
|
324
|
|
324
|
|
- // COURS
|
|
325
|
+ // COURS
|
325
|
326
|
// MaJ du cours
|
326
|
327
|
$course->setVersionRule($versioningRule);
|
327
|
328
|
$newMaxVersion = $course->getMaxVersion();
|
|
@@ -333,7 +334,7 @@ class ScormEngine
|
333
|
334
|
$response['course']['courseKey'] = $course->getCourseKey();
|
334
|
335
|
$response['course']['maxVersion'] = $newMaxVersion;
|
335
|
336
|
|
336
|
|
- // Mapping Zip/Cours
|
|
337
|
+ // Mapping Zip/Cours
|
337
|
338
|
$mapping = new MapCourseZipfile();
|
338
|
339
|
$mapping->setCourse($course);
|
339
|
340
|
$mapping->setZipFile($zipFile);
|
|
@@ -385,7 +386,7 @@ class ScormEngine
|
385
|
386
|
$response['error'] = 'La clef du nouveau cours dupliqué est requise.';
|
386
|
387
|
return $response;
|
387
|
388
|
}
|
388
|
|
-
|
|
389
|
+
|
389
|
390
|
// Contrôle de l'existence du cours à dupliquer
|
390
|
391
|
$originalCourse = $this->requireCourse($orginalCourseKey);
|
391
|
392
|
|
|
@@ -403,7 +404,7 @@ class ScormEngine
|
403
|
404
|
$response['error'] = 'La clef du nouveau cours existe déjà. Utilser \'updateCourse\' pour mettre à jour un cours existant.';
|
404
|
405
|
return $response;
|
405
|
406
|
}
|
406
|
|
-
|
|
407
|
+
|
407
|
408
|
// COURS
|
408
|
409
|
$newCourse = clone $originalCourse;
|
409
|
410
|
$newCourse->setCourseKey($newCourseKey);
|
|
@@ -420,7 +421,7 @@ class ScormEngine
|
420
|
421
|
$mapping->setCourse($newCourse);
|
421
|
422
|
$mapping->setZipFile($zipFile);
|
422
|
423
|
$mapping->setVersion($newCourse->getMaxVersion());
|
423
|
|
-
|
|
424
|
+
|
424
|
425
|
$this->em->persist($mapping);
|
425
|
426
|
$this->em->flush();
|
426
|
427
|
|
|
@@ -471,7 +472,7 @@ class ScormEngine
|
471
|
472
|
$this->em->flush();
|
472
|
473
|
return true;
|
473
|
474
|
}
|
474
|
|
-
|
|
475
|
+
|
475
|
476
|
return false;
|
476
|
477
|
}
|
477
|
478
|
|
|
@@ -503,11 +504,11 @@ class ScormEngine
|
503
|
504
|
return null;
|
504
|
505
|
}
|
505
|
506
|
|
506
|
|
- public function getCourses() : array
|
|
507
|
+ public function getCourses(): array
|
507
|
508
|
{
|
508
|
509
|
$repository = $this->em->getRepository(Course::class);
|
509
|
510
|
$courses = $repository->findAll();
|
510
|
|
-
|
|
511
|
+
|
511
|
512
|
return $courses;
|
512
|
513
|
}
|
513
|
514
|
|
|
@@ -560,7 +561,7 @@ class ScormEngine
|
560
|
561
|
} else {
|
561
|
562
|
$response['error'] = 'La clef d\'identification est necessaire';
|
562
|
563
|
}
|
563
|
|
-
|
|
564
|
+
|
564
|
565
|
return $response;
|
565
|
566
|
}
|
566
|
567
|
|
|
@@ -585,7 +586,7 @@ class ScormEngine
|
585
|
586
|
$this->em->flush();
|
586
|
587
|
}
|
587
|
588
|
}
|
588
|
|
- return $learner->getLearnerKey();
|
|
589
|
+ return $learner->getLearnerKey();
|
589
|
590
|
}
|
590
|
591
|
|
591
|
592
|
/**
|
|
@@ -626,7 +627,7 @@ class ScormEngine
|
626
|
627
|
$this->em->flush();
|
627
|
628
|
return true;
|
628
|
629
|
}
|
629
|
|
-
|
|
630
|
+
|
630
|
631
|
return false;
|
631
|
632
|
}
|
632
|
633
|
|
|
@@ -682,7 +683,7 @@ class ScormEngine
|
682
|
683
|
} else {
|
683
|
684
|
$response['error'] = 'La clef d\'identification est necessaire';
|
684
|
685
|
}
|
685
|
|
-
|
|
686
|
+
|
686
|
687
|
return $response;
|
687
|
688
|
}
|
688
|
689
|
|
|
@@ -695,7 +696,7 @@ class ScormEngine
|
695
|
696
|
*
|
696
|
697
|
* @return array
|
697
|
698
|
*/
|
698
|
|
- public function getPlayerVariables(string $registrationKey, string $data = null, Response $response = null) : array
|
|
699
|
+ public function getPlayerVariables(string $registrationKey, string $data = null, Response $response = null): array
|
699
|
700
|
{
|
700
|
701
|
$result = array();
|
701
|
702
|
// Vérification de l'existance de l'inscription
|
|
@@ -705,7 +706,7 @@ class ScormEngine
|
705
|
706
|
// Erreur : une inscription valide doit être passée
|
706
|
707
|
return null;
|
707
|
708
|
}
|
708
|
|
-
|
|
709
|
+
|
709
|
710
|
// Récupération du cours et des infos de version
|
710
|
711
|
$course = $registration->getCourse();
|
711
|
712
|
$maxVersion = $course->getMaxVersion();
|
|
@@ -732,11 +733,11 @@ class ScormEngine
|
732
|
733
|
$currentVersion = $maxVersion;
|
733
|
734
|
|
734
|
735
|
if (!$needCreation) {
|
735
|
|
-// TODO Indiquer dans la réponse que l'on a effectué une modification de version pour l'apprenant
|
|
736
|
+ // TODO Indiquer dans la réponse que l'on a effectué une modification de version pour l'apprenant
|
736
|
737
|
$data = null;
|
737
|
738
|
}
|
738
|
739
|
}
|
739
|
|
-
|
|
740
|
+
|
740
|
741
|
// Récupération du zip correspondant et ainsi de la version du standard utilisée
|
741
|
742
|
$mapCourseZipRepository = $this->em->getRepository(MapCourseZipfile::class);
|
742
|
743
|
$mapCourseZip = $mapCourseZipRepository->findOneBy(array('course' => $course, 'version' => $currentVersion));
|
|
@@ -792,13 +793,13 @@ class ScormEngine
|
792
|
793
|
if (empty($registration)) {
|
793
|
794
|
return 0;
|
794
|
795
|
}
|
795
|
|
-
|
|
796
|
+
|
796
|
797
|
// Récupération du dernier essai moteur pour cette inscription
|
797
|
798
|
$registrationAttemptRepository = $this->em->getRepository(RegistrationAttempt::class);
|
798
|
799
|
$lastAttempt = $registrationAttemptRepository->findOneBy(array('registration' => $registration), array('registrationAttemptId' => 'desc'));
|
799
|
800
|
|
800
|
|
-// DETECTER AVANT LE TYPE DE SCORM POUR SAVOIR QUEL STANDARD
|
801
|
|
-// CODE SCORM 2004
|
|
801
|
+ // DETECTER AVANT LE TYPE DE SCORM POUR SAVOIR QUEL STANDARD
|
|
802
|
+ // CODE SCORM 2004
|
802
|
803
|
// On récupère le track correspondant
|
803
|
804
|
$track2004Repository = $this->em->getRepository(Scorm2004Track::class);
|
804
|
805
|
$track2004 = $track2004Repository->findOneBy(array('registrationAttempt' => $lastAttempt));
|
|
@@ -810,7 +811,7 @@ class ScormEngine
|
810
|
811
|
// en se basant sur l'état de complétion de l'ensemble des items terminaux
|
811
|
812
|
$mapTrackItemRepository = $this->em->getRepository(Scorm2004MapTrackItem::class);
|
812
|
813
|
$attemptItemRepository = $this->em->getRepository(Scorm2004AttemptProgressInformation::class);
|
813
|
|
-
|
|
814
|
+
|
814
|
815
|
$mapTrackItems = $mapTrackItemRepository->findBy(array('scorm2004Track' => $track2004));
|
815
|
816
|
|
816
|
817
|
if (!empty($mapTrackItems)) {
|
|
@@ -819,14 +820,14 @@ class ScormEngine
|
819
|
820
|
foreach ($mapTrackItems as $item) {
|
820
|
821
|
// Si les items sont terminaux
|
821
|
822
|
if ($item->getAvailableOrder() > -1) {
|
822
|
|
- $numFinalItems ++;
|
|
823
|
+ $numFinalItems++;
|
823
|
824
|
$identifier = $item->getItemIdentifier();
|
824
|
|
- $attemptItem = $attemptItemRepository->findOneBy(array('scorm2004Track'=> $track2004, 'item_identifier' => $identifier), array('attempt_id' => 'desc'));
|
|
825
|
+ $attemptItem = $attemptItemRepository->findOneBy(array('scorm2004Track' => $track2004, 'item_identifier' => $identifier), array('attempt_id' => 'desc'));
|
825
|
826
|
if (!empty($attemptItem)) {
|
826
|
827
|
$progressStatus = $attemptItem->getProgressStatus();
|
827
|
828
|
$completionStatus = $attemptItem->getCompletionStatus();
|
828
|
829
|
if (true == $progressStatus && true == $completionStatus) {
|
829
|
|
- $numCompletedItems ++;
|
|
830
|
+ $numCompletedItems++;
|
830
|
831
|
}
|
831
|
832
|
}
|
832
|
833
|
}
|
|
@@ -850,7 +851,7 @@ class ScormEngine
|
850
|
851
|
}
|
851
|
852
|
|
852
|
853
|
//Récupération du dernier essai SCORM sur l'organisation
|
853
|
|
- $lastOrganizationAttempt = $attemptItemRepository->findOneBy(array('scorm2004Track'=> $track2004, 'item_identifier' => $organization), array('attempt_id' => 'desc'));
|
|
854
|
+ $lastOrganizationAttempt = $attemptItemRepository->findOneBy(array('scorm2004Track' => $track2004, 'item_identifier' => $organization), array('attempt_id' => 'desc'));
|
854
|
855
|
if (empty($lastOrganizationAttempt)) {
|
855
|
856
|
return 0;
|
856
|
857
|
}
|
|
@@ -884,22 +885,22 @@ class ScormEngine
|
884
|
885
|
if (empty($registration)) {
|
885
|
886
|
return null;
|
886
|
887
|
}
|
887
|
|
-
|
|
888
|
+
|
888
|
889
|
// Récupération du dernier essai pour cette inscription
|
889
|
890
|
$registrationAttemptRepository = $this->em->getRepository(RegistrationAttempt::class);
|
890
|
891
|
$lastAttempt = $registrationAttemptRepository->findOneBy(array('registration' => $registration), array('registrationAttemptId' => 'desc'));
|
891
|
892
|
|
892
|
|
-// DETECTER AVANT LE TYPE DE SCORM POUR SAVOIR QUEL STANDARD
|
893
|
|
-// CODE SCORM 2004
|
|
893
|
+ // DETECTER AVANT LE TYPE DE SCORM POUR SAVOIR QUEL STANDARD
|
|
894
|
+ // CODE SCORM 2004
|
894
|
895
|
// On récupère le track correspondant
|
895
|
896
|
$track2004Repository = $this->em->getRepository(Scorm2004Track::class);
|
896
|
897
|
$track2004 = $track2004Repository->findOneBy(array('registrationAttempt' => $lastAttempt));
|
897
|
898
|
if (empty($track2004)) {
|
898
|
899
|
return null;
|
899
|
900
|
}
|
900
|
|
-
|
|
901
|
+
|
901
|
902
|
$mapTrackItemRepository = $this->em->getRepository(Scorm2004MapTrackItem::class);
|
902
|
|
-
|
|
903
|
+
|
903
|
904
|
$mapTrackItems = $mapTrackItemRepository->findBy(array('scorm2004Track' => $track2004));
|
904
|
905
|
|
905
|
906
|
$averageScore = null;
|
|
@@ -916,7 +917,7 @@ class ScormEngine
|
916
|
917
|
$score = $score * 100 / $scoreMax;
|
917
|
918
|
$score = max(min($score, 100), 0);
|
918
|
919
|
|
919
|
|
- $scoreNum ++;
|
|
920
|
+ $scoreNum++;
|
920
|
921
|
$scoreSum += $score;
|
921
|
922
|
}
|
922
|
923
|
}
|
|
@@ -943,22 +944,22 @@ class ScormEngine
|
943
|
944
|
if (empty($registration)) {
|
944
|
945
|
return null;
|
945
|
946
|
}
|
946
|
|
-
|
|
947
|
+
|
947
|
948
|
// Récupération du dernier essai pour cette inscription
|
948
|
949
|
$registrationAttemptRepository = $this->em->getRepository(RegistrationAttempt::class);
|
949
|
950
|
$lastAttempt = $registrationAttemptRepository->findOneBy(array('registration' => $registration), array('registrationAttemptId' => 'desc'));
|
950
|
951
|
|
951
|
|
-// DETECTER AVANT LE TYPE DE SCORM POUR SAVOIR QUEL STANDARD
|
952
|
|
-// CODE SCORM 2004
|
|
952
|
+ // DETECTER AVANT LE TYPE DE SCORM POUR SAVOIR QUEL STANDARD
|
|
953
|
+ // CODE SCORM 2004
|
953
|
954
|
// On récupère le track correspondant
|
954
|
955
|
$track2004Repository = $this->em->getRepository(Scorm2004Track::class);
|
955
|
956
|
$track2004 = $track2004Repository->findOneBy(array('registrationAttempt' => $lastAttempt));
|
956
|
957
|
if (empty($track2004)) {
|
957
|
958
|
return null;
|
958
|
959
|
}
|
959
|
|
-
|
|
960
|
+
|
960
|
961
|
$mapTrackItemRepository = $this->em->getRepository(Scorm2004MapTrackItem::class);
|
961
|
|
-
|
|
962
|
+
|
962
|
963
|
// Récupération des données pour chaque items
|
963
|
964
|
$mapTrackItems = $mapTrackItemRepository->findBy(array('scorm2004Track' => $track2004));
|
964
|
965
|
|
|
@@ -977,7 +978,7 @@ class ScormEngine
|
977
|
978
|
$identifier = $item->getItemIdentifier();
|
978
|
979
|
|
979
|
980
|
// On récupère le dernier AttemptProgressInfo en cours
|
980
|
|
- $attemptItem = $attemptItemRepository->findOneBy(array('scorm2004Track'=> $track2004, 'item_identifier' => $identifier), array('attempt_id' => 'desc'));
|
|
981
|
+ $attemptItem = $attemptItemRepository->findOneBy(array('scorm2004Track' => $track2004, 'item_identifier' => $identifier), array('attempt_id' => 'desc'));
|
981
|
982
|
|
982
|
983
|
// On récupère les interactions pour cet item et cet Attempt
|
983
|
984
|
$itemInteractions = $interactionRepository->findBy(array('scorm2004Track' => $track2004, 'scorm2004AttemptProgressInformation' => $attemptItem, 'itemIdentifier' => $identifier), array('interaction_id' => 'asc'));
|
|
@@ -985,10 +986,10 @@ class ScormEngine
|
985
|
986
|
// Si il existe des interactions
|
986
|
987
|
if (!empty($itemInteractions)) {
|
987
|
988
|
$result = array();
|
988
|
|
-
|
|
989
|
+
|
989
|
990
|
// On récupère le nom de l'item
|
990
|
991
|
$result['title'] = $domScorm2004->getTitle($identifier);
|
991
|
|
-
|
|
992
|
+
|
992
|
993
|
// On Récupère le Score sur le mapTrackItem
|
993
|
994
|
$score = null;
|
994
|
995
|
$scoreMax = $item->getScoreMax();
|
|
@@ -1036,7 +1037,7 @@ class ScormEngine
|
1036
|
1037
|
$this->em->flush();
|
1037
|
1038
|
return true;
|
1038
|
1039
|
}
|
1039
|
|
-
|
|
1040
|
+
|
1040
|
1041
|
return false;
|
1041
|
1042
|
}
|
1042
|
1043
|
|
|
@@ -1074,7 +1075,7 @@ class ScormEngine
|
1074
|
1075
|
$this->em->flush();
|
1075
|
1076
|
return true;
|
1076
|
1077
|
}
|
1077
|
|
-
|
|
1078
|
+
|
1078
|
1079
|
return false;
|
1079
|
1080
|
}
|
1080
|
1081
|
|
|
@@ -1155,8 +1156,7 @@ class ScormEngine
|
1155
|
1156
|
* @return array
|
1156
|
1157
|
*/
|
1157
|
1158
|
public function getAttemptStats(int $attemptId)
|
1158
|
|
- {
|
1159
|
|
- }
|
|
1159
|
+ { }
|
1160
|
1160
|
|
1161
|
1161
|
// TOOLS
|
1162
|
1162
|
|
|
@@ -1167,7 +1167,7 @@ class ScormEngine
|
1167
|
1167
|
* @param Response $response
|
1168
|
1168
|
* @return void
|
1169
|
1169
|
*/
|
1170
|
|
- private function prepareContentAccess(string $courseKey, Response $response = null) : void
|
|
1170
|
+ private function prepareContentAccess(string $courseKey, Response $response = null): void
|
1171
|
1171
|
{
|
1172
|
1172
|
if (!$this->session->has('scormkey')) {
|
1173
|
1173
|
$scormkey = rand();
|
|
@@ -1182,7 +1182,7 @@ class ScormEngine
|
1182
|
1182
|
$this->response = $response;
|
1183
|
1183
|
}
|
1184
|
1184
|
|
1185
|
|
- $pathCookie = $this->contentUrlPrefix."/$scormkey/$courseKey/";
|
|
1185
|
+ $pathCookie = $this->contentUrlPrefix . "/$scormkey/$courseKey/";
|
1186
|
1186
|
|
1187
|
1187
|
$md5cookiekey = md5($scormkey);
|
1188
|
1188
|
$cookie = new Cookie('SCORMBundle', $md5cookiekey, 0, $pathCookie);
|
|
@@ -1195,7 +1195,7 @@ class ScormEngine
|
1195
|
1195
|
*
|
1196
|
1196
|
* @return Response
|
1197
|
1197
|
*/
|
1198
|
|
- public function getResponse() : Response
|
|
1198
|
+ public function getResponse(): Response
|
1199
|
1199
|
{
|
1200
|
1200
|
return $this->response;
|
1201
|
1201
|
}
|
|
@@ -1210,11 +1210,11 @@ class ScormEngine
|
1210
|
1210
|
*
|
1211
|
1211
|
* @return string
|
1212
|
1212
|
*/
|
1213
|
|
- public function getBaseUrl($courseKey) : string
|
|
1213
|
+ public function getBaseUrl($courseKey): string
|
1214
|
1214
|
{
|
1215
|
|
- return $this->contentUrlPrefix.'/'.$this->session->get('scormkey').'/'.$courseKey;
|
|
1215
|
+ return $this->contentUrlPrefix . '/' . $this->session->get('scormkey') . '/' . $courseKey;
|
1216
|
1216
|
}
|
1217
|
|
-
|
|
1217
|
+
|
1218
|
1218
|
/**
|
1219
|
1219
|
* Retourne l'activité
|
1220
|
1220
|
*
|
|
@@ -1224,12 +1224,12 @@ class ScormEngine
|
1224
|
1224
|
protected function requireCourse(string $courseKey)
|
1225
|
1225
|
{
|
1226
|
1226
|
$repository = $this->em->getRepository(Course::class);
|
1227
|
|
-
|
|
1227
|
+
|
1228
|
1228
|
$course = $repository->findOneBy(array('courseKey' => $courseKey));
|
1229
|
1229
|
|
1230
|
1230
|
return $course;
|
1231
|
1231
|
}
|
1232
|
|
-
|
|
1232
|
+
|
1233
|
1233
|
/**
|
1234
|
1234
|
* Retourne l'apprenant
|
1235
|
1235
|
*
|
|
@@ -1244,7 +1244,7 @@ class ScormEngine
|
1244
|
1244
|
|
1245
|
1245
|
return $learner;
|
1246
|
1246
|
}
|
1247
|
|
-
|
|
1247
|
+
|
1248
|
1248
|
/**
|
1249
|
1249
|
* Retourne l'inscription
|
1250
|
1250
|
*
|
|
@@ -1260,8 +1260,8 @@ class ScormEngine
|
1260
|
1260
|
|
1261
|
1261
|
return $registration;
|
1262
|
1262
|
}
|
1263
|
|
-
|
1264
|
|
- /**
|
|
1263
|
+
|
|
1264
|
+ /**
|
1265
|
1265
|
* Retourne un essais relatif à une inscription
|
1266
|
1266
|
*
|
1267
|
1267
|
* @param int $attemptId
|