Browse Source

TLD-577 Récupération de la durée d'un module

www-data 3 years ago
parent
commit
3f5f4d00e5
3 changed files with 169 additions and 145 deletions
  1. 138
    139
      LearningModels/DOMSCORM2004.php
  2. 28
    6
      Package/PackageValidator.php
  3. 3
    0
      Services/ScormEngine.php

+ 138
- 139
LearningModels/DOMSCORM2004.php View File

@@ -16,7 +16,7 @@ class DOMSCORM2004 extends DOMSCORM
16 16
     }
17 17
 
18 18
 
19
-    protected function loadNamespaces() : void
19
+    protected function loadNamespaces(): void
20 20
     {
21 21
         SCORMTools::loadNamespacesSCORM2004($this->xpath);
22 22
     }
@@ -25,7 +25,7 @@ class DOMSCORM2004 extends DOMSCORM
25 25
      * durée estimé par l'auteur du cours
26 26
 
27 27
      * @return array
28
-     * * [datetime] => hh:ii:ss (ex. 01:45:00)
28
+     * * [duration] => P[yY][mM][dD][T[hH][nM][s[.s]S]] (ex. PT1H30M)
29 29
      * * [description] => Texte ecrit par l'auteur du module (ex.: Durée estimée de la formation)
30 30
      */
31 31
     public function getTypicalLearningTime()
@@ -36,7 +36,7 @@ class DOMSCORM2004 extends DOMSCORM
36 36
         $result = array();
37 37
         foreach ($children as $node) {
38 38
             switch ($node->nodeName) {
39
-                case 'datetime':
39
+                case 'duration':
40 40
                 case 'description': // IMPORTANT TODO: ce champ peut etre multilangue dans le manifest
41 41
                     $result[$node->nodeName] = $node->nodeValue;
42 42
                     break;
@@ -64,7 +64,7 @@ class DOMSCORM2004 extends DOMSCORM
64 64
         foreach ($organizations->childNodes as $organization) {
65 65
             if ($organization->nodeName == 'organization') { // on ne veut pas d'autre chose qu'une organization
66 66
                 $identifier = $organization->attributes->getNamedItem("identifier")->nodeValue;
67
-                if (($default == $identifier)||('mm-'.$default == $identifier)) { // ici expliquer pourquoi il faut ajouter 'mm-'
67
+                if (($default == $identifier) || ('mm-' . $default == $identifier)) { // ici expliquer pourquoi il faut ajouter 'mm-'
68 68
                     // on parcours les items de l'organization
69 69
                     $result = $this->organization2array($organization->childNodes);
70 70
                 }
@@ -90,10 +90,10 @@ class DOMSCORM2004 extends DOMSCORM
90 90
         }
91 91
         foreach ($itemList as $itemNode) {
92 92
             if ($itemNode->nodeName == 'title') {
93
-                $organization['title']=$itemNode->nodeValue;
93
+                $organization['title'] = $itemNode->nodeValue;
94 94
             }
95 95
             if ($itemNode->nodeName == 'adlcp:prerequisites') {
96
-                $organization['adlcp:prerequisites']=$itemNode->nodeValue;
96
+                $organization['adlcp:prerequisites'] = $itemNode->nodeValue;
97 97
             }
98 98
             if ($itemNode->nodeName == 'item') { // et voila la partie récursive
99 99
                 $itemId = $itemNode->attributes->getNamedItem("identifier")->nodeValue;
@@ -118,7 +118,7 @@ class DOMSCORM2004 extends DOMSCORM
118 118
      *
119 119
      * @return string identifiant de l'organization par default
120 120
      */
121
-    public function getDefaultOrganization() : string
121
+    public function getDefaultOrganization(): string
122 122
     {
123 123
         $tlt = $this->manifest->getElementsByTagName("organizations");
124 124
         $organizations = $tlt->item(0);
@@ -133,7 +133,7 @@ class DOMSCORM2004 extends DOMSCORM
133 133
      * @param string $item2 2eme item descendant commun
134 134
      * @return string ancetre commun ou null si pas trouvé
135 135
      */
136
-    public function findCommonAncestor(string $item1, string $item2) : ?string
136
+    public function findCommonAncestor(string $item1, string $item2): ?string
137 137
     {
138 138
         // algo : on remonte un noeud-item jusqu'à la racine pour former une branche, puis on fait pareil pour le second
139 139
         // et on stoppe lorsque le noeud observé est egal à un noeud de la branche.
@@ -147,7 +147,7 @@ class DOMSCORM2004 extends DOMSCORM
147 147
             $current = $currentNode->attributes->getNamedItem("identifier")->nodeValue;
148 148
             $branche[$current] = true;
149 149
             $currentNode = $currentNode->parentNode;
150
-        } while (($currentNode->nodeName == 'item')||($currentNode->nodeName == 'organization'));
150
+        } while (($currentNode->nodeName == 'item') || ($currentNode->nodeName == 'organization'));
151 151
 
152 152
         //remontee de la branche de l'item2 jusqu'à trouver
153 153
         $currentNode = $this->getItemByIdentifier($item2);
@@ -159,17 +159,17 @@ class DOMSCORM2004 extends DOMSCORM
159 159
             }
160 160
             $branche[$current] = 1;
161 161
             $currentNode = $currentNode->parentNode;
162
-        } while (($result == null)&&(($currentNode->nodeName == 'item')||($currentNode->nodeName == 'organization')));
162
+        } while (($result == null) && (($currentNode->nodeName == 'item') || ($currentNode->nodeName == 'organization')));
163 163
 
164 164
         return $result;
165 165
     }
166
-/**
167
- * trouve la Node par son "identifier" dans l'ensemble des "item" et "organization"
168
- *
169
- * @param string $id
170
- * @return \DOMNode
171
- */
172
-    private function getElementById(string $id) : ?\DOMNode
166
+    /**
167
+     * trouve la Node par son "identifier" dans l'ensemble des "item" et "organization"
168
+     *
169
+     * @param string $id
170
+     * @return \DOMNode
171
+     */
172
+    private function getElementById(string $id): ?\DOMNode
173 173
     {
174 174
         return $this->xpath->query("//*[name()='item' or name()='organization'][@identifier='$id']")->item(0);
175 175
     }
@@ -188,7 +188,7 @@ class DOMSCORM2004 extends DOMSCORM
188 188
         string $itemEnd,
189 189
         bool $withItemStart = true,
190 190
         bool $withItemEnd = true
191
-    ) : ?array {
191
+    ): ?array {
192 192
         // algo: on remonte les 2 branches jusqu'a la racine ou jusqu'a trouvé l'autre
193 193
         $findEnd = false; // indicateur du fait que l'on est trouvé la fin
194 194
         $branche = array();
@@ -238,14 +238,19 @@ class DOMSCORM2004 extends DOMSCORM
238 238
      * @param string $item
239 239
      * @return string|null item parent (null si c'est le parent de l'organization qui est demandé)
240 240
      */
241
-    public function getParent(string $item) : ?string
241
+    public function getParent(string $item): ?string
242 242
     {
243 243
         $itemNode = $this->getElementById($item);
244
-        $parent = $itemNode->parentNode;
245
-        if (($parent == null)||($itemNode->nodeName =='organization')) {
246
-            return null;
244
+
245
+        if ($itemNode) {
246
+            $parent = $itemNode->parentNode;
247
+            if (($parent == null) || ($itemNode->nodeName == 'organization')) {
248
+                return null;
249
+            }
250
+            return $parent->attributes->getNamedItem("identifier")->nodeValue;
247 251
         }
248
-        return $parent->attributes->getNamedItem("identifier")->nodeValue;
252
+
253
+        return null;
249 254
     }
250 255
 
251 256
     /**
@@ -255,22 +260,22 @@ class DOMSCORM2004 extends DOMSCORM
255 260
      * @param string $item item/organization racine de l'arbre (ou sous arbre)
256 261
      * @return array itemroot =>0, itemfirstchild => 1, itemfirstchildofchild => 2, ...
257 262
      */
258
-    public function getFlatTree(string $item) : array
263
+    public function getFlatTree(string $item): array
259 264
     {
260 265
         return $this->getFlatTreeRecursive($item); // cela pour bloquer toutes tentative de bricoler le 2eme parametre
261 266
     }
262 267
 
263
-    private function getFlatTreeRecursive(string $item, array &$output = null) : array
268
+    private function getFlatTreeRecursive(string $item, array &$output = null): array
264 269
     {
265 270
         $itemNode = $this->getElementById($item);
266 271
         $current = $itemNode->attributes->getNamedItem("identifier")->nodeValue;
267 272
         if ($output == null) {
268
-            $output=array();
273
+            $output = array();
269 274
         }
270
-        
275
+
271 276
         $output[$current] = sizeof($output);
272 277
         $enfantsNodeList = $itemNode->childNodes;
273
-        for ($i=0; $i<$enfantsNodeList->count(); $i++) {
278
+        for ($i = 0; $i < $enfantsNodeList->count(); $i++) {
274 279
             $enfant = $enfantsNodeList->item($i);
275 280
             if ($enfant->nodeName == 'item') { // on fait bien attentino de ne traiter que les items...
276 281
                 $enfantIdentifier = $enfant->attributes->getNamedItem("identifier")->nodeValue;
@@ -287,12 +292,12 @@ class DOMSCORM2004 extends DOMSCORM
287 292
      * @param string $item
288 293
      * @return array tableau des items enfants
289 294
      */
290
-    public function getChildren(string $item) : array
295
+    public function getChildren(string $item): array
291 296
     {
292 297
         $children = array();
293 298
         $itemNode = $this->getElementById($item);
294 299
         $childNodeList = $itemNode->childNodes;
295
-        for ($i=0; $i<$childNodeList->length; $i++) {
300
+        for ($i = 0; $i < $childNodeList->length; $i++) {
296 301
             $childNode = $childNodeList->item($i);
297 302
             if ($childNode->nodeName == "item") {
298 303
                 $child = $childNode->attributes->getNamedItem("identifier")->nodeValue;
@@ -319,14 +324,14 @@ class DOMSCORM2004 extends DOMSCORM
319 324
      * @return string valeur de l'attribut sous format chaine de caracteres => un cast sera necessaire
320 325
      * pour les attributs numérique
321 326
      */
322
-    protected function getAttributeByPath(string $path, string $attribute) : ?string
327
+    protected function getAttributeByPath(string $path, string $attribute): ?string
323 328
     {
324 329
         $value = null; // valeur de l'attribut
325 330
         $nodeList = $this->xpath->query($path);
326 331
         if ($nodeList->length == 1) {
327 332
             $node = $nodeList->item(0);
328 333
             $node = $node->attributes->getNamedItem($attribute);
329
-            if ($node !=null) {
334
+            if ($node != null) {
330 335
                 $value = $node->nodeValue;
331 336
             }
332 337
         }
@@ -351,7 +356,7 @@ class DOMSCORM2004 extends DOMSCORM
351 356
      * @param string $item pour lequel on examine le sequencing
352 357
      * @return string|null meme une valeur numérique sera une chaine (Ex. "true" (et pas (bool)1 ))
353 358
      */
354
-    public function getSequencingAttribute(string $tagPath, string $attributeName, string $item = null) : ?string
359
+    public function getSequencingAttribute(string $tagPath, string $attributeName, string $item = null): ?string
355 360
     {
356 361
         $value = null;
357 362
         if ($item != null) {
@@ -363,7 +368,7 @@ class DOMSCORM2004 extends DOMSCORM
363 368
                 $attributeNode = $sequencingNode->getAttributeNode('IDRef');
364 369
                 if ($attributeNode != null) {
365 370
                     $value = $this->getSequencingAttribute(
366
-                        'imsss:sequencing[@ID="'.$attributeNode->nodeValue.'"]/'.$tagPath,
371
+                        'imsss:sequencing[@ID="' . $attributeNode->nodeValue . '"]/' . $tagPath,
367 372
                         $attributeName
368 373
                     );
369 374
                     if ($value != null) { //on tient la valeur
@@ -375,16 +380,16 @@ class DOMSCORM2004 extends DOMSCORM
375 380
                 $value = SCORMTools::getAttributeDefaultValue($attributeName);
376 381
             }
377 382
             // sinon on récupère dans la sequence de l'item
378
-            $query = '//*[name()="item" or name()="organization"][@identifier="'.$item.'"]/imsss:sequencing/'.$tagPath;
383
+            $query = '//*[name()="item" or name()="organization"][@identifier="' . $item . '"]/imsss:sequencing/' . $tagPath;
379 384
         } else {
380
-            $query = '//imsss:sequencingCollection/'.$tagPath;
385
+            $query = '//imsss:sequencingCollection/' . $tagPath;
381 386
             $nodeList = $this->xpath->query($query);
382 387
         }
383 388
         $nodeList = $this->xpath->query($query);
384 389
         if ($nodeList->length == 1) {
385 390
             $node = $nodeList->item(0);
386 391
             $attributeNode = $node->attributes->getNamedItem($attributeName);
387
-            if ($attributeNode !=null) {
392
+            if ($attributeNode != null) {
388 393
                 $value = $attributeNode->nodeValue;
389 394
             }
390 395
         }
@@ -419,12 +424,12 @@ class DOMSCORM2004 extends DOMSCORM
419 424
      * @param string $attributeName
420 425
      * @return string|null
421 426
      */
422
-    public function getItemElementContent(string $item, string $path, string $attributeName = null) : ?string
427
+    public function getItemElementContent(string $item, string $path, string $attributeName = null): ?string
423 428
     {
424 429
 
425 430
         $content = null;
426
-        $query = '//*[name()="item" or name()="organization"][@identifier="'.$item.'"]/'.$path;
427
-   
431
+        $query = '//*[name()="item" or name()="organization"][@identifier="' . $item . '"]/' . $path;
432
+
428 433
         $nodeList = $this->xpath->query($query);
429 434
 
430 435
         if ($nodeList->length == 1) {
@@ -432,11 +437,10 @@ class DOMSCORM2004 extends DOMSCORM
432 437
             if ($attributeName == null) {
433 438
                 $content = $node->nodeValue;
434 439
             } else {
435
-                $content = $node->hasAttribute($attributeName) ? $node->getAttribute($attributeName) :
436
-                    SCORMTools::getAttributeDefaultValue($attributeName);
440
+                $content = $node->hasAttribute($attributeName) ? $node->getAttribute($attributeName) : SCORMTools::getAttributeDefaultValue($attributeName);
437 441
             }
438
-        } elseif ($nodeList->length>1) {
439
-            throw new \Exception("Element $path should have only 1 (or none) value, not ".$nodeList->length);
442
+        } elseif ($nodeList->length > 1) {
443
+            throw new \Exception("Element $path should have only 1 (or none) value, not " . $nodeList->length);
440 444
         } else {
441 445
             if ($attributeName != null) {
442 446
                 $content = SCORMTools::getAttributeDefaultValue($attributeName);
@@ -445,12 +449,12 @@ class DOMSCORM2004 extends DOMSCORM
445 449
         return $content;
446 450
     }
447 451
 
448
-    public function getDataMap(string $item) : ?array
452
+    public function getDataMap(string $item): ?array
449 453
     {
450 454
         $maps = array();
451
-        $query = '//*[name()="item" or name()="organization"][@identifier="'.$item.'"]/adlcp:data/adlcp:map';
455
+        $query = '//*[name()="item" or name()="organization"][@identifier="' . $item . '"]/adlcp:data/adlcp:map';
452 456
         $nodeList = $this->xpath->query($query);
453
-        for ($i=0; $i<$nodeList->length; $i++) {
457
+        for ($i = 0; $i < $nodeList->length; $i++) {
454 458
             $node = $nodeList->item($i);
455 459
             $targetID = $node->attributes->getNamedItem('targetID')->nodeValue;
456 460
             $maps[] = array();
@@ -458,7 +462,7 @@ class DOMSCORM2004 extends DOMSCORM
458 462
             $maps[$i]['readSharedData'] = $node->attributes->getNamedItem('readSharedData')->nodeValue ??
459 463
                 SCORMTools::getAttributeDefaultValue('readSharedData');
460 464
             $maps[$i]['writeSharedData'] = $node->attributes->getNamedItem('writeSharedData')->nodeValue ??
461
-            SCORMTools::getAttributeDefaultValue('writeSharedData');
465
+                SCORMTools::getAttributeDefaultValue('writeSharedData');
462 466
         }
463 467
         return $maps;
464 468
     }
@@ -482,22 +486,22 @@ class DOMSCORM2004 extends DOMSCORM
482 486
      * @param string $item
483 487
      * @return array
484 488
      */
485
-    public function getRollupRules(string $item) : array
489
+    public function getRollupRules(string $item): array
486 490
     {
487
-        
491
+
488 492
         $rules = array();
489 493
         // on commence par recuperer (si elles existent) les valeurs sur le sequencing collection
490 494
 
491 495
         $refSeqCol = $this->getAttributeByName($item, 'IDRef');
492 496
         if ($refSeqCol != null) {
493
-            $query = 'imsss:sequencingCollection/imsss:sequencing[@ID="'.$refSeqCol.'"]/imsss:rollupRules/descendant::*';
497
+            $query = 'imsss:sequencingCollection/imsss:sequencing[@ID="' . $refSeqCol . '"]/imsss:rollupRules/descendant::*';
494 498
             $listNodes = $this->xpath->query($query);
495 499
             $this->rollupNodesToArray($listNodes, $rules);
496 500
         }
497 501
 
498 502
         // recuperation des rules de la sequence de l'item
499
-        $query = '//*[name()="item" or name()="organization"][@identifier="'.
500
-        $item.'"]/imsss:sequencing/imsss:rollupRules/descendant::*';
503
+        $query = '//*[name()="item" or name()="organization"][@identifier="' .
504
+            $item . '"]/imsss:sequencing/imsss:rollupRules/descendant::*';
501 505
 
502 506
         $listNodes = $this->xpath->query($query);
503 507
 
@@ -506,35 +510,31 @@ class DOMSCORM2004 extends DOMSCORM
506 510
         return $rules;
507 511
     }
508 512
 
509
-    private function rollupNodesToArray(\DOMNodeList $listNodes, array &$rules) : void
513
+    private function rollupNodesToArray(\DOMNodeList $listNodes, array &$rules): void
510 514
     {
511 515
         $indice = -1; // indices du plus haut niveau du tableau de rule...
512 516
         // dans cette boucle on joue sur le fait que les tag sont ordonnés hiérarcchiquement (mere avant fille)
513
-        for ($i=0; $i<$listNodes->length; $i++) {
517
+        for ($i = 0; $i < $listNodes->length; $i++) {
514 518
             $node = $listNodes->item($i);
515 519
             switch ($node->nodeName) {
516 520
                 case 'imsss:rollupRule':
517 521
                     $indice++;
518 522
                     $rules[$indice] = array();
519 523
                     // si pas de valeur trouvée, il faut donner la valeur par défaut
520
-                    $rules[$indice]['childActivitySet'] = $node->hasAttribute('childActivitySet') ? $node->getAttribute('childActivitySet') :
521
-                        SCORMTools::getAttributeDefaultValue('childActivitySet');
522
-                    $rules[$indice]['minimumCount'] = $node->hasAttribute('minimumCount') ? $node->getAttribute('minimumCount') :
523
-                        SCORMTools::getAttributeDefaultValue('minimumCount');
524
-                    $rules[$indice]['minimumPercent'] = $node->hasAttribute('minimumPercent') ? $node->getAttribute('minimumPercent') :
525
-                        SCORMTools::getAttributeDefaultValue('minimumPercent');
524
+                    $rules[$indice]['childActivitySet'] = $node->hasAttribute('childActivitySet') ? $node->getAttribute('childActivitySet') : SCORMTools::getAttributeDefaultValue('childActivitySet');
525
+                    $rules[$indice]['minimumCount'] = $node->hasAttribute('minimumCount') ? $node->getAttribute('minimumCount') : SCORMTools::getAttributeDefaultValue('minimumCount');
526
+                    $rules[$indice]['minimumPercent'] = $node->hasAttribute('minimumPercent') ? $node->getAttribute('minimumPercent') : SCORMTools::getAttributeDefaultValue('minimumPercent');
526 527
                     break;
527 528
 
528 529
                 case 'imsss:rollupConditions':
529
-                    $rules[$indice]['conditionCombination'] = $node->hasAttribute('conditionCombination') ? $node->getAttribute('conditionCombination') :
530
-                        SCORMTools::getAttributeDefaultValue('imsss:rollupConditions@conditionCombination');
530
+                    $rules[$indice]['conditionCombination'] = $node->hasAttribute('conditionCombination') ? $node->getAttribute('conditionCombination') : SCORMTools::getAttributeDefaultValue('imsss:rollupConditions@conditionCombination');
531 531
                     break;
532 532
 
533 533
                 case 'imsss:rollupCondition':
534 534
                     $theAttributes = array();
535 535
                     // il faut initialiser certains attributs avec la valeur par défaut
536 536
                     $theAttributes['operator'] = SCORMTools::getAttributeDefaultValue('imsss:rollupCondition@operator');
537
-                    for ($j=0; $j<$node->attributes->length; $j++) {
537
+                    for ($j = 0; $j < $node->attributes->length; $j++) {
538 538
                         $nodeAttribute = $node->attributes->item($j);
539 539
                         $theAttributes[$nodeAttribute->nodeName] = $nodeAttribute->nodeValue;
540 540
                     }
@@ -542,7 +542,7 @@ class DOMSCORM2004 extends DOMSCORM
542 542
                     break;
543 543
 
544 544
                 case 'imsss:rollupAction':
545
-                    $rules[$indice]['action']= $node->getAttribute('action');
545
+                    $rules[$indice]['action'] = $node->getAttribute('action');
546 546
                     break;
547 547
             }
548 548
         }
@@ -572,7 +572,7 @@ class DOMSCORM2004 extends DOMSCORM
572 572
      * @param string $item
573 573
      * @return array
574 574
      */
575
-    public function getSequencingRules(string $item) : array
575
+    public function getSequencingRules(string $item): array
576 576
     {
577 577
         $rules1 = array();
578 578
         $rules2 = array();
@@ -580,14 +580,14 @@ class DOMSCORM2004 extends DOMSCORM
580 580
         // on commence par recuperer (si elles existent) les valeurs sur le sequencing collection
581 581
         $refSeqCol = $this->getAttributeByName($item, 'IDRef');
582 582
         if ($refSeqCol != null) {
583
-            $query = 'imsss:sequencingCollection/imsss:sequencing[@ID="'.$refSeqCol.'"]/imsss:sequencingRules/descendant::*';
583
+            $query = 'imsss:sequencingCollection/imsss:sequencing[@ID="' . $refSeqCol . '"]/imsss:sequencingRules/descendant::*';
584 584
             $listNodes = $this->xpath->query($query);
585 585
             $this->nodesToArray($listNodes, $rules1, $defaultObjectif);
586 586
         }
587 587
 
588 588
         // recuperation des rules de la sequence de l'item
589
-        $query = '//*[name()="item" or name()="organization"][@identifier="'.
590
-            $item.'"]/imsss:sequencing/imsss:sequencingRules/descendant::*';
589
+        $query = '//*[name()="item" or name()="organization"][@identifier="' .
590
+            $item . '"]/imsss:sequencing/imsss:sequencingRules/descendant::*';
591 591
 
592 592
         $listNodes = $this->xpath->query($query);
593 593
 
@@ -611,11 +611,11 @@ class DOMSCORM2004 extends DOMSCORM
611 611
      * @param string $defaultObjectif (default : null) si presente ajoute la clef referencedObjective avec cette valeur
612 612
      * @return void
613 613
      */
614
-    private function nodesToArray(\DOMNodeList $listNodes, array &$rules, string $defaultObjectif = null) : void
614
+    private function nodesToArray(\DOMNodeList $listNodes, array &$rules, string $defaultObjectif = null): void
615 615
     {
616 616
         $indice = -1; // indices du plus haut niveau du tableau de rule...
617 617
         // dans cette boucle on joue sur le fait que les tag sont ordonnés hiérarcchiquement (mere avant fille)
618
-        for ($i=0; $i<$listNodes->length; $i++) {
618
+        for ($i = 0; $i < $listNodes->length; $i++) {
619 619
             $node = $listNodes->item($i);
620 620
             switch ($node->nodeName) {
621 621
                 case 'imsss:preConditionRule':
@@ -628,7 +628,7 @@ class DOMSCORM2004 extends DOMSCORM
628 628
                     $theAttributes = array();
629 629
                     // il faut initialiser certains attributs avec la valeur par défaut
630 630
                     $theAttributes['operator'] = SCORMTools::getAttributeDefaultValue('imsss:ruleCondition@operator');
631
-                    for ($j=0; $j<$node->attributes->length; $j++) {
631
+                    for ($j = 0; $j < $node->attributes->length; $j++) {
632 632
                         $nodeAttribute = $node->attributes->item($j);
633 633
                         $theAttributes[$nodeAttribute->nodeName] = $nodeAttribute->nodeValue;
634 634
                     }
@@ -638,11 +638,10 @@ class DOMSCORM2004 extends DOMSCORM
638 638
                     $rules[$indice]['conditions'][] = $theAttributes;
639 639
                     break;
640 640
                 case 'imsss:ruleConditions':
641
-                    $rules[$indice]['conditionCombination']= $node->hasAttribute('conditionCombination') ? $node->getAttribute('conditionCombination') :
642
-                        SCORMTools::getAttributeDefaultValue('imsss:ruleConditions@conditionCombination');
641
+                    $rules[$indice]['conditionCombination'] = $node->hasAttribute('conditionCombination') ? $node->getAttribute('conditionCombination') : SCORMTools::getAttributeDefaultValue('imsss:ruleConditions@conditionCombination');
643 642
                     break;
644 643
                 case 'imsss:ruleAction':
645
-                    $rules[$indice]['action']= $node->getAttribute('action');
644
+                    $rules[$indice]['action'] = $node->getAttribute('action');
646 645
                     break;
647 646
             }
648 647
         }
@@ -683,11 +682,11 @@ class DOMSCORM2004 extends DOMSCORM
683 682
         $itemNode = $this->getItemByIdentifier($item); // la recherche sse fait au niveau de l'item
684 683
 
685 684
         // on recherche la presence de l'attribut dans tous les tags descendant sauf les items enfants
686
-        $query = 'descendant::*[name() != "item" and name() != "organization" and @'.$attributeName.'] | self::*[@'.$attributeName.']';
687
-        
685
+        $query = 'descendant::*[name() != "item" and name() != "organization" and @' . $attributeName . '] | self::*[@' . $attributeName . ']';
686
+
688 687
         $nodeList = $this->xpath->query($query, $itemNode);
689 688
 
690
-        for ($i=0; $i<$nodeList->length; $i++) {
689
+        for ($i = 0; $i < $nodeList->length; $i++) {
691 690
             $node = $nodeList->item($i);
692 691
             $value = $node->getAttribute($attributeName);
693 692
             $values[] = $value;
@@ -708,12 +707,12 @@ class DOMSCORM2004 extends DOMSCORM
708 707
      * @param string $objectiveID (facultatif) l'identifiant d'un objectif
709 708
      * @return array de tableaux d'"objective"s
710 709
      */
711
-    public function getObjectives(string $item, string $objectiveID = null) : array
710
+    public function getObjectives(string $item, string $objectiveID = null): array
712 711
     {
713 712
         $ids = array();
714 713
 
715
-        $equalObjective ='';
716
-        if ($objectiveID!=null) {
714
+        $equalObjective = '';
715
+        if ($objectiveID != null) {
717 716
             $equalObjective = "[@objectiveID='$objectiveID']";
718 717
         }
719 718
         $refSeqCol = $this->getAttributeByName($item, 'IDRef');
@@ -723,12 +722,12 @@ class DOMSCORM2004 extends DOMSCORM
723 722
         }
724 723
 
725 724
         // recuperation des rules de la sequence de l'item
726
-        $query = '//*[name()="item" or name()="organization"][@identifier="'.
727
-        $item."\"]/imsss:sequencing/imsss:objectives/child::*$equalObjective". $query2;
725
+        $query = '//*[name()="item" or name()="organization"][@identifier="' .
726
+            $item . "\"]/imsss:sequencing/imsss:objectives/child::*$equalObjective" . $query2;
728 727
 
729 728
         $listNodes = $this->xpath->query($query);
730
-        for ($i=0; $i<$listNodes->length; $i++) {
731
-            $minNormalizedMeasure=$this->xpath->query('imsss:minNormalizedMeasure', $listNodes->item($i))->item(0)->nodeValue ??
729
+        for ($i = 0; $i < $listNodes->length; $i++) {
730
+            $minNormalizedMeasure = $this->xpath->query('imsss:minNormalizedMeasure', $listNodes->item($i))->item(0)->nodeValue ??
732 731
                 SCORMTools::getAttributeDefaultValue('minNormalizedMeasure');
733 732
             $ids[] = $this->constructObjective(
734 733
                 $item,
@@ -747,24 +746,24 @@ class DOMSCORM2004 extends DOMSCORM
747 746
      * @param string $item
748 747
      * @return array|null
749 748
      */
750
-    public function getPrimaryObjective(string $item) : ?array
749
+    public function getPrimaryObjective(string $item): ?array
751 750
     {
752 751
         $o = null;
753
-        $query = '//*[name()="item" or name()="organization"][@identifier="'.
754
-            $item.'"]/imsss:sequencing/imsss:objectives/imsss:primaryObjective';
752
+        $query = '//*[name()="item" or name()="organization"][@identifier="' .
753
+            $item . '"]/imsss:sequencing/imsss:objectives/imsss:primaryObjective';
755 754
         $listNodes = $this->xpath->query($query);
756 755
 
757 756
         if ($listNodes->length == 0) { // tentative de recherche l'objectif primaire dans la sequencingcollection
758 757
             $refSeqCol = $this->getAttributeByName($item, 'IDRef');
759 758
             if ($refSeqCol != null) {
760
-                $query = '//imsss:sequencingCollection/imsss:sequencing[@ID="'.$refSeqCol.
759
+                $query = '//imsss:sequencingCollection/imsss:sequencing[@ID="' . $refSeqCol .
761 760
                     '"]/imsss:objectives/descendant::*[@objectiveID]';
762 761
                 $listNodes = $this->xpath->query($query);
763 762
             }
764 763
         }
765 764
 
766 765
         if ($listNodes->length == 1) {
767
-            $minNormalizedMeasure=$this->xpath->query('imsss:minNormalizedMeasure', $listNodes->item(0))->item(0)->nodeValue ??
766
+            $minNormalizedMeasure = $this->xpath->query('imsss:minNormalizedMeasure', $listNodes->item(0))->item(0)->nodeValue ??
768 767
                 SCORMTools::getAttributeDefaultValue('minNormalizedMeasure');
769 768
             $o = $this->constructObjective(
770 769
                 $item,
@@ -801,11 +800,11 @@ class DOMSCORM2004 extends DOMSCORM
801 800
      * @param string $objectiveID identifiant de l'ojectif contenant le tag
802 801
      * @return string|null
803 802
      */
804
-    public function getMinNormalizeMeasure(string $item, string $objectiveID) : ?string
803
+    public function getMinNormalizeMeasure(string $item, string $objectiveID): ?string
805 804
     {
806 805
         // recupere l'objectif
807 806
         $objectives = $this->getObjectives($item, $objectiveID); // il ne peut y avoir qu'un seul objectif
808
-        if (sizeof($objectives)!=1) {
807
+        if (sizeof($objectives) != 1) {
809 808
             return null;
810 809
         }
811 810
         return $objectives[0]['minNormalizedMeasure'];
@@ -825,71 +824,71 @@ class DOMSCORM2004 extends DOMSCORM
825 824
      * @param boolean $isPrimary
826 825
      * @return array|null
827 826
      */
828
-    
829
-    public function getMapInfos(string $item, string $objectiveID, bool $isPrimary) : ?array
827
+
828
+    public function getMapInfos(string $item, string $objectiveID, bool $isPrimary): ?array
830 829
     {
831 830
         $mapInfos = array(); // initialisation du tableau de retour
832
-        if (($objectiveID=='') && ($isPrimary==false)) {
833
-            throw new \Exception('SCORM 2004: objectiveID cannot be void for a non primary mapInfo tag. Item :'.$item);
831
+        if (($objectiveID == '') && ($isPrimary == false)) {
832
+            throw new \Exception('SCORM 2004: objectiveID cannot be void for a non primary mapInfo tag. Item :' . $item);
834 833
         }
835 834
         $mapInfo = $this->initNullMapinfo();
836 835
         $targetObjectiveIDs = array(); // tableau local pour mémoriser ces IDs, utile ppour l'algo
837 836
         // 1) récupération des nodes mapinfo ims
838 837
         if ($isPrimary == false) {
839
-            $query = '//*[name()="item" or name()="organization"][@identifier="'.
840
-            $item.'"]/imsss:sequencing/imsss:objectives/imsss:objective[@objectiveID="'.$objectiveID.'"]/imsss:mapInfo | '.
841
-            '//imsss:sequencingCollection/imsss:sequencing/imsss:objectives/imsss:objective[@objectiveID="'.$objectiveID.'"]/imsss:mapInfo';
838
+            $query = '//*[name()="item" or name()="organization"][@identifier="' .
839
+                $item . '"]/imsss:sequencing/imsss:objectives/imsss:objective[@objectiveID="' . $objectiveID . '"]/imsss:mapInfo | ' .
840
+                '//imsss:sequencingCollection/imsss:sequencing/imsss:objectives/imsss:objective[@objectiveID="' . $objectiveID . '"]/imsss:mapInfo';
842 841
         } else { // quand c'est un primaire, il n'y a pas d'objectiveID
843 842
             $refSeqCol = $this->getAttributeByName($item, 'IDRef');
844
-            $query2='';
843
+            $query2 = '';
845 844
             if ($refSeqCol != null) {
846 845
                 $query2 = " | //imsss:sequencingCollection/imsss:sequencing[@ID='$refSeqCol']/imsss:objectives/imsss:primaryObjective/imsss:mapInfo";
847 846
             }
848
-            $query = '//*[name()="item" or name()="organization"][@identifier="'.
849
-            $item.'"]/imsss:sequencing/imsss:objectives/imsss:primaryObjective/imsss:mapInfo'.$query2;
847
+            $query = '//*[name()="item" or name()="organization"][@identifier="' .
848
+                $item . '"]/imsss:sequencing/imsss:objectives/imsss:primaryObjective/imsss:mapInfo' . $query2;
850 849
         }
851 850
         $imsNodes = $this->xpath->query($query); // recupération des nodes map infos
852 851
 
853 852
         // 2) recuperation des complements de l'adl
854
-        for ($i=0; $i < $imsNodes->length; $i++) {
853
+        for ($i = 0; $i < $imsNodes->length; $i++) {
855 854
             $mapInfo = $this->initNullMapinfo();
856 855
             $attributes = $imsNodes->item($i)->attributes;
857
-            for ($j=0; $j<$attributes->length; $j++) {
856
+            for ($j = 0; $j < $attributes->length; $j++) {
858 857
                 $a = $attributes->item($j);
859 858
                 $mapInfo[$a->nodeName] = $a->nodeValue;
860 859
             }
861 860
             // recuperation complement
862
-            $query = '//*[name()="item" or name()="organization"][@identifier="'.
863
-            $item.'"]/imsss:sequencing/adlseq:objectives/child::*/adlseq:mapInfo[@targetObjectiveID="'.$mapInfo['targetObjectiveID'].'"] | '.
864
-            '//imsss:sequencingCollection/adlseq:objectives/child::*/adlseq:mapInfo[@targetObjectiveID="'.$mapInfo['targetObjectiveID'].'"]';
861
+            $query = '//*[name()="item" or name()="organization"][@identifier="' .
862
+                $item . '"]/imsss:sequencing/adlseq:objectives/child::*/adlseq:mapInfo[@targetObjectiveID="' . $mapInfo['targetObjectiveID'] . '"] | ' .
863
+                '//imsss:sequencingCollection/adlseq:objectives/child::*/adlseq:mapInfo[@targetObjectiveID="' . $mapInfo['targetObjectiveID'] . '"]';
865 864
             $adlNodes =  $this->xpath->query($query); // il ne devrait y avoir qu'un seul complement max
866 865
             if ($adlNodes->length > 1) { // on ne sait pas gérer le cas de plusieurs mapinfo pour 1 objectif
867
-                throw new \Exception('SCORM 2004: Several complement mapInfos adlseq tags found for item '.$item);
866
+                throw new \Exception('SCORM 2004: Several complement mapInfos adlseq tags found for item ' . $item);
868 867
             }
869 868
             if ($adlNodes->length == 1) {
870 869
                 $attributes = $adlNodes->item(0)->attributes;
871
-                for ($j=0; $j<$attributes->length; $j++) {
870
+                for ($j = 0; $j < $attributes->length; $j++) {
872 871
                     $a = $attributes->item($j);
873 872
                     $mapInfo[$a->nodeName] = $a->nodeValue;
874 873
                 }
875 874
             }
876 875
             $mapInfo = $this->completeMapinfoWithDefaults($mapInfo);
877 876
             $mapInfos[] = $mapInfo;
878
-            $targetObjectiveIDs[$mapInfo['targetObjectiveID']]= true; // on cree une entrée dans le tableau
877
+            $targetObjectiveIDs[$mapInfo['targetObjectiveID']] = true; // on cree une entrée dans le tableau
879 878
         }
880 879
 
881 880
         //3) recupération des mapinfo de l'adl qui sont isolés (pas de lien via targetObjectiveID)
882
-        $query = '//*[name()="item" or name()="organization"][@identifier="'.
883
-        $item.'"]/imsss:sequencing/adlseq:objectives/*[@objectiveID="'.$objectiveID.'"]/adlseq:mapInfo | '.
884
-        '//imsss:sequencingCollection/imsss:sequencing/adlseq:objectives/*[@objectiveID="'.$objectiveID.'"]/adlseq:mapInfo';
881
+        $query = '//*[name()="item" or name()="organization"][@identifier="' .
882
+            $item . '"]/imsss:sequencing/adlseq:objectives/*[@objectiveID="' . $objectiveID . '"]/adlseq:mapInfo | ' .
883
+            '//imsss:sequencingCollection/imsss:sequencing/adlseq:objectives/*[@objectiveID="' . $objectiveID . '"]/adlseq:mapInfo';
885 884
         $adlNodes =  $this->xpath->query($query);
886 885
         // on parcours la liste en creant un nouveau mapinfo lorsque targetObjectiveID n'est pas une clef
887
-        for ($i=0; $i < $adlNodes->length; $i++) {
886
+        for ($i = 0; $i < $adlNodes->length; $i++) {
888 887
             $attributes = $adlNodes->item($i)->attributes;
889 888
             $targetObjectiveID = $attributes->getNamedItem('targetObjectiveID')->nodeValue;
890 889
             if (!isset($targetObjectiveIDs[$targetObjectiveID])) { // creation d'un nouveau mapinfo, si iniexsitance
891 890
                 $mapInfo = $this->initNullMapinfo();
892
-                for ($j=0; $j<$attributes->length; $j++) {
891
+                for ($j = 0; $j < $attributes->length; $j++) {
893 892
                     $a = $attributes->item($j);
894 893
                     $mapInfo[$a->nodeName] = $a->nodeValue;
895 894
                 }
@@ -908,7 +907,7 @@ class DOMSCORM2004 extends DOMSCORM
908 907
      * @param array $mapInfo
909 908
      * @return array
910 909
      */
911
-    private function completeMapinfoWithDefaults(array $mapInfo) : array
910
+    private function completeMapinfoWithDefaults(array $mapInfo): array
912 911
     {
913 912
         foreach ($mapInfo as $key => $value) {
914 913
             if ($value == null) {
@@ -924,7 +923,7 @@ class DOMSCORM2004 extends DOMSCORM
924 923
      *
925 924
      * @return array
926 925
      */
927
-    private function initNullMapinfo() : array
926
+    private function initNullMapinfo(): array
928 927
     {
929 928
         return array( // tous les attributs que nous souhaitons retourner obligatoirement...
930 929
             'targetObjectiveID' => null, // ims
@@ -953,21 +952,21 @@ class DOMSCORM2004 extends DOMSCORM
953 952
      * @param boolean $isPrimary
954 953
      * @return string
955 954
      */
956
-    public function getSatisfiedByMeasure(string $item, string $objectiveID, bool $isPrimary) : string
955
+    public function getSatisfiedByMeasure(string $item, string $objectiveID, bool $isPrimary): string
957 956
     {
958 957
         $value = null;
959 958
         if ($isPrimary == false) {
960
-            $query = '//*[name()="item" or name()="organization"][@identifier="'.
961
-            $item.'"]/imsss:sequencing/imsss:objectives/imsss:objective[@objectiveID="'.$objectiveID.'"] | '.
962
-            '//imsss:sequencingCollection/imsss:sequencing/imsss:objectives/imsss:objective[@objectiveID="'.$objectiveID.'"]';
959
+            $query = '//*[name()="item" or name()="organization"][@identifier="' .
960
+                $item . '"]/imsss:sequencing/imsss:objectives/imsss:objective[@objectiveID="' . $objectiveID . '"] | ' .
961
+                '//imsss:sequencingCollection/imsss:sequencing/imsss:objectives/imsss:objective[@objectiveID="' . $objectiveID . '"]';
963 962
         } else { // en cas de primary on ne s'occupe pas de la valeur de l'objectiveID (qui pourrait etre "")
964 963
             $refSeqCol = $this->getAttributeByName($item, 'IDRef');
965 964
             $query2 = '';
966 965
             if ($refSeqCol != null) {
967
-                $query2 = ' | imsss:sequencingCollection/imsss:sequencing[@ID="'.$refSeqCol.'"]/imsss:objectives/imsss:primaryObjective';
966
+                $query2 = ' | imsss:sequencingCollection/imsss:sequencing[@ID="' . $refSeqCol . '"]/imsss:objectives/imsss:primaryObjective';
968 967
             }
969
-            $query = '//*[name()="item" or name()="organization"][@identifier="'.
970
-            $item.'"]/imsss:sequencing/imsss:objectives/imsss:primaryObjective'.$query2;
968
+            $query = '//*[name()="item" or name()="organization"][@identifier="' .
969
+                $item . '"]/imsss:sequencing/imsss:objectives/imsss:primaryObjective' . $query2;
971 970
         }
972 971
 
973 972
         $listNodes = $this->xpath->query($query);
@@ -987,11 +986,11 @@ class DOMSCORM2004 extends DOMSCORM
987 986
      * @param string $identifier identifient eventuelle de l'organization (si absent organisation par defaut)
988 987
      * @return string
989 988
      */
990
-    public function getIsGlobalToSystem(string $identifier = null) : string
989
+    public function getIsGlobalToSystem(string $identifier = null): string
991 990
     {
992 991
         $value = null;
993 992
         if ($identifier != null) {
994
-            $query = '//*[name()="organization"][@identifier="'.$identifier.'"]';
993
+            $query = '//*[name()="organization"][@identifier="' . $identifier . '"]';
995 994
         } else {
996 995
             $query = '//*[name()="organization"][1]'; //selection du &er element
997 996
         }
@@ -1020,7 +1019,7 @@ class DOMSCORM2004 extends DOMSCORM
1020 1019
      * @param string $item
1021 1020
      * @return string
1022 1021
      */
1023
-    public function getHref(string $item) : string
1022
+    public function getHref(string $item): string
1024 1023
     {
1025 1024
         $idhref = $this->getAttributeByName($item, 'identifierref');
1026 1025
         // y a t'il une base (cad un repertoire avant la reference)
@@ -1042,20 +1041,20 @@ class DOMSCORM2004 extends DOMSCORM
1042 1041
         }
1043 1042
         return $href;
1044 1043
     }
1045
-    
1044
+
1046 1045
     /**
1047 1046
      * le titre d'un item (ou d'une organization)
1048 1047
      *
1049 1048
      * @param string $item
1050 1049
      * @return string le titre
1051 1050
      */
1052
-    public function getTitle(string $item = null) : string
1051
+    public function getTitle(string $item = null): string
1053 1052
     {
1054 1053
         if ($item == null) {
1055 1054
             return parent::getTitle();
1056 1055
         }
1057 1056
 
1058
-        $query = '//*[name()="item" or name()="organization"][@identifier="'.$item.'"]/*[name()="title"]';
1057
+        $query = '//*[name()="item" or name()="organization"][@identifier="' . $item . '"]/*[name()="title"]';
1059 1058
 
1060 1059
         $listNodes = $this->xpath->query($query);
1061 1060
 
@@ -1066,20 +1065,20 @@ class DOMSCORM2004 extends DOMSCORM
1066 1065
 
1067 1066
         return $result;
1068 1067
     }
1069
-/**
1070
- * tableau des valeurs HideLMSUI d'un item
1071
- *
1072
- * @param string $item
1073
- * @return array
1074
- */
1075
-    public function getHideLMSUI(string $item) : array
1068
+    /**
1069
+     * tableau des valeurs HideLMSUI d'un item
1070
+     *
1071
+     * @param string $item
1072
+     * @return array
1073
+     */
1074
+    public function getHideLMSUI(string $item): array
1076 1075
     {
1077 1076
         $hideLMSUI = array();
1078
-        $query = '//*[name()="item" or name()="organization"][@identifier="'.$item.'"]/adlnav:presentation/adlnav:navigationInterface/adlnav:hideLMSUI';
1077
+        $query = '//*[name()="item" or name()="organization"][@identifier="' . $item . '"]/adlnav:presentation/adlnav:navigationInterface/adlnav:hideLMSUI';
1079 1078
 
1080 1079
         $listNodes = $this->xpath->query($query);
1081 1080
 
1082
-        for ($i=0; $i<$listNodes->length; $i++) {
1081
+        for ($i = 0; $i < $listNodes->length; $i++) {
1083 1082
             $hideLMSUI[] = $listNodes->item($i)->textContent;
1084 1083
         }
1085 1084
         return $hideLMSUI;

+ 28
- 6
Package/PackageValidator.php View File

@@ -3,9 +3,8 @@
3 3
 namespace Logipro\Bundle\SCORMBundle\Package;
4 4
 
5 5
 use Logipro\Bundle\SCORMBundle\LearningModels\DOMSCORM;
6
-use Logipro\Bundle\SCORMBundle\LearningModels\DOMSCORM12;
7
-use Logipro\Bundle\SCORMBundle\LearningModels\DOMSCORM2004;
8 6
 use Logipro\Bundle\SCORMBundle\LearningModels\DOMLearningModel;
7
+use Logipro\Bundle\SCORMBundle\Tools\TimeTools;
9 8
 
10 9
 class PackageValidator
11 10
 {
@@ -22,6 +21,7 @@ class PackageValidator
22 21
         $response = array(
23 22
             'standard' => null,
24 23
             'title' => null,
24
+            'duration' => null,
25 25
             'validation' => null
26 26
         );
27 27
 
@@ -31,7 +31,11 @@ class PackageValidator
31 31
         $result = $zip->open($zipPath);
32 32
 
33 33
         if ($result !== true) {
34
-            return sprintf("L'ouverture du ZIP a échoué avec le code : %d", $result);
34
+            $response['validation'] = array(
35
+                'status' => false,
36
+                'error' => sprintf("L'ouverture du ZIP a échoué avec le code : %d", $result)
37
+            );
38
+            return $response;
35 39
         }
36 40
 
37 41
         // Dans un premier temps on ne considère que SCORM
@@ -43,18 +47,32 @@ class PackageValidator
43 47
         $zipName = pathinfo($zipPath)['filename'];
44 48
 
45 49
         if ($manifest !== false) {
46
-            // SCORM
50
+            // SCORM - Définition du standard et création du parser (objet DOM)
47 51
             $standard = DOMSCORM::defineStandard($manifest);
48 52
             $dom = DOMLearningModel::getInstance($zipName, $manifest, $standard);
49 53
         } else {
50 54
             // Si pas de imsmanifest.xml --> possible autre standard
51
-            return null;
55
+            $response['validation'] = array(
56
+                'status' => false,
57
+                'error' => 'Standard non géré ou manifest absent'
58
+            );
59
+            return $response;
52 60
         }
53 61
 
54 62
         // Si standard identifié, on peut passé à la validation du xml
55 63
         if ($dom) {
56 64
             $response['standard'] = $standard;
57 65
             $response['title'] = $dom->getTitle();
66
+            $response['duration'] = '';
67
+            // Récupération de la balise durée (métadonnée)
68
+            $typicalLearningTime = $dom->getTypicalLearningTime();
69
+            if (!empty($typicalLearningTime)) {
70
+                if (array_key_exists('duration', $typicalLearningTime)) {
71
+                    $isoDuration = $typicalLearningTime['duration'];
72
+                    $duration = TimeTools::convertIso8601DurationToSeconds($isoDuration);
73
+                    $response['duration'] = $duration;
74
+                }
75
+            }
58 76
 
59 77
 // @TODO Validation XML reportée
60 78
             // $response['validation'] = $dom->validate();
@@ -62,7 +80,11 @@ class PackageValidator
62 80
                 'status' => true
63 81
             );
64 82
         } else {
65
-            return null;
83
+            $response['validation'] = array(
84
+                'status' => false,
85
+                'error' => 'Standard non géré'
86
+            );
87
+            return $response;
66 88
         }
67 89
 
68 90
         return $response;

+ 3
- 0
Services/ScormEngine.php View File

@@ -138,11 +138,14 @@ class ScormEngine
138 138
             $validation = PackageValidator::validatePackage($zipPath);
139 139
 
140 140
             if (!$validation['validation']['status']) {
141
+                $response['code'] = 400;
142
+                $response['error'] = $validation['validation']['error'];
141 143
                 return $response;
142 144
             }
143 145
 
144 146
             $response['metadata']['standard'] = $validation['standard'];
145 147
             $response['metadata']['title'] = $validation['title'];
148
+            $response['metadata']['duration'] = $validation['duration'];
146 149
 
147 150
             // Récupération de la signature du zip
148 151
             $hash = md5_file($zipPath);

Loading…
Cancel
Save