Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
91.38% covered (success)
91.38%
53 / 58
66.67% covered (warning)
66.67%
6 / 9
CRAP
0.00% covered (danger)
0.00%
0 / 1
XMLFileUnit
91.38% covered (success)
91.38%
53 / 58
66.67% covered (warning)
66.67%
6 / 9
24.37
0.00% covered (danger)
0.00%
0 / 1
 crossValidate
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 getPlayerIfExists
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
3
 checkIfResourcesExist
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
5
 readPlayerId
71.43% covered (warning)
71.43%
5 / 7
0.00% covered (danger)
0.00%
0 / 1
4.37
 getDefinitionRef
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 getDefinition
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
6
 readPlayerDependencies
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
2
 checkRequestedAttachments
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 getRequestedAttachments
90.91% covered (success)
90.91%
10 / 11
0.00% covered (danger)
0.00%
0 / 1
3.01
1<?php
2/** @noinspection PhpUnhandledExceptionInspection */
3declare(strict_types=1);
4
5class XMLFileUnit extends XMLFile {
6  const type = 'Unit';
7  const canBeRelationSubject = true;
8  const canBeRelationObject = true;
9
10  const deprecatedElements = [
11    '/Unit/Definition/@type',
12    '/Unit/Metadata/Lastchange',
13    '/Unit/Dependencies/file'
14  ];
15
16  public function crossValidate(WorkspaceCache $workspaceCache): void {
17    parent::crossValidate($workspaceCache);
18
19    $this->checkRequestedAttachments();
20    $this->checkIfResourcesExist($workspaceCache);
21    $this->getPlayerIfExists($workspaceCache);
22  }
23
24  public function getPlayerIfExists(WorkspaceCache $validator): ?ResourceFile {
25    if (!$this->isValid()) {
26      return null;
27    }
28
29    $playerId = $this->readPlayerId();
30
31    $resource = $validator->getResource($playerId);
32
33    if ($resource != null) {
34      $this->addRelation(new FileRelation($resource->getType(), $playerId, FileRelationshipType::usesPlayer, $resource));
35    } else {
36      $this->report('error', "Player not found `$playerId`.");
37    }
38
39    return $resource;
40  }
41
42  private function checkIfResourcesExist(WorkspaceCache $validator): void {
43    $definitionRef = $this->getDefinitionRef();
44
45    $resources = $this->readPlayerDependencies();
46
47    if ($definitionRef) {
48      $resources['definition'] = $definitionRef;
49    }
50
51    foreach ($resources as $key => $resourceName) {
52      $resourceId = strtoupper($resourceName);
53      $resource = $validator->getResource($resourceId);
54
55      if ($resource != null) {
56        $relationshipType = ($key === 'definition') ? FileRelationshipType::isDefinedBy : FileRelationshipType::usesPlayerResource;
57        $this->addRelation(new FileRelation($resource->getType(), $resourceName, $relationshipType, $resource));
58
59      } else {
60        $this->report('error', "Resource `$resourceName` not found");
61      }
62    }
63  }
64
65  public function readPlayerId(): string {
66    if (!$this->isValid()) {
67      return '';
68    }
69
70    $definition = $this->getXml()->xpath('/Unit/Definition | /Unit/DefinitionRef');
71
72    $playerIdRaw = count($definition) ? (string) $definition[0]['player'] : null;
73
74    if (!$playerIdRaw) {
75      return '';
76    }
77
78    return FileID::normalize($playerIdRaw);
79  }
80
81  public function getDefinitionRef(): string {
82    $definitionRefNodes = $this->getXml()->xpath('/Unit/DefinitionRef');
83    return count($definitionRefNodes) ? (string) $definitionRefNodes[0] : '';
84  }
85
86  public function getDefinition(): string {
87    $definitionNodes = $this->getXml()->xpath('/Unit/Definition');
88    return count($definitionNodes) ? (string) $definitionNodes[0] : '';
89  }
90
91  private function readPlayerDependencies(): array {
92    if (!$this->isValid()) {
93      return [];
94    }
95
96    $dE = $this->getXml()->xpath('/Unit/Dependencies/file[not(@for) or @for="player"]|/Unit/Dependencies/File[not(@for) or @for="player"]');
97
98    return array_map(
99      function($e) {
100        return (string) $e;
101      },
102      $dE
103    );
104  }
105
106  private function checkRequestedAttachments(): void {
107    $requestedAttachments = $this->getRequestedAttachments();
108    $requestedAttachmentsCount = count($requestedAttachments);
109    if ($requestedAttachmentsCount) {
110      $this->report('info', "`$requestedAttachmentsCount` attachment(s) requested.");
111    }
112  }
113
114  public function getRequestedAttachments(): array {
115    $variables = $this->getXml()->xpath('/Unit/BaseVariables/Variable[@type="attachment"]');
116    $requestedAttachments = [];
117    foreach ($variables as $variable) {
118      if (!is_a($variable, SimpleXMLElement::class)) {
119        continue;
120      }
121
122      $requestedAttachments[] = new RequestedAttachment(
123        $this->getId(),
124        (string) $variable['format'],
125        (string) $variable['id']
126      );
127    }
128
129    return $requestedAttachments;
130  }
131}