This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | namespace PPP\Wikidata\TreeSimplifier; |
||
4 | |||
5 | use DataValues\TimeValue; |
||
6 | use DateInterval; |
||
7 | use DateTime; |
||
8 | use InvalidArgumentException; |
||
9 | use PPP\DataModel\AbstractNode; |
||
10 | use PPP\DataModel\IntersectionNode; |
||
11 | use PPP\DataModel\JsonLdResourceNode; |
||
12 | use PPP\DataModel\MissingNode; |
||
13 | use PPP\DataModel\ResourceListNode; |
||
14 | use PPP\DataModel\ResourceNode; |
||
15 | use PPP\DataModel\StringResourceNode; |
||
16 | use PPP\DataModel\TripleNode; |
||
17 | use PPP\DataModel\UnionNode; |
||
18 | use PPP\Module\TreeSimplifier\NodeSimplifier; |
||
19 | use PPP\Wikidata\ValueParsers\ResourceListNodeParser; |
||
20 | use PPP\Wikidata\WikibaseResourceNode; |
||
21 | use stdClass; |
||
22 | use Wikibase\DataModel\Entity\EntityIdValue; |
||
23 | use Wikibase\DataModel\Entity\ItemId; |
||
24 | use Wikibase\DataModel\Entity\PropertyId; |
||
25 | |||
26 | /** |
||
27 | * Do some actions for specific use case: |
||
28 | * - if a predicate is not useful like "name" or "identity" cast subjects to wikibase items |
||
29 | * - if the predicte is son or daughter use "child" with an intersection with the relevant sex |
||
30 | * |
||
31 | * @licence AGPLv3+ |
||
32 | * @author Thomas Pellissier Tanon |
||
33 | * |
||
34 | * |
||
35 | * TODO: remove hardcoded values? |
||
36 | */ |
||
37 | class SpecificTripleNodeSimplifier implements NodeSimplifier { |
||
38 | |||
39 | private static $MEANINGLESS_PREDICATES = array( |
||
40 | 'name', |
||
41 | 'identity', |
||
42 | 'definition' |
||
43 | ); |
||
44 | |||
45 | const PROPERTY_CHILD = 'P40'; |
||
46 | const PROPERTY_SEX = 'P21'; |
||
47 | const PROPERTY_BIRTH_DATE = 'P569'; |
||
48 | const ITEM_MALE = 'Q6581097'; |
||
49 | const ITEM_FEMALE = 'Q6581072'; |
||
50 | |||
51 | /** |
||
52 | * @var ResourceListNodeParser |
||
53 | */ |
||
54 | private $resourceListNodeParser; |
||
55 | |||
56 | /** |
||
57 | * @var ResourceListForEntityProperty |
||
58 | */ |
||
59 | private $resourceListForEntityProperty; |
||
60 | |||
61 | /** |
||
62 | * @var DateTime |
||
63 | */ |
||
64 | private $now; |
||
65 | |||
66 | /** |
||
67 | * @param ResourceListNodeParser $resourceListNodeParser |
||
68 | * @param ResourceListForEntityProperty $resourceListForEntityProperty |
||
69 | * @param DateTime $now |
||
70 | */ |
||
71 | 11 | public function __construct(ResourceListNodeParser $resourceListNodeParser, ResourceListForEntityProperty $resourceListForEntityProperty, DateTime $now) { |
|
72 | 11 | $this->resourceListNodeParser = $resourceListNodeParser; |
|
73 | 11 | $this->resourceListForEntityProperty = $resourceListForEntityProperty; |
|
74 | 11 | $this->now = $now; |
|
75 | 11 | } |
|
76 | |||
77 | /** |
||
78 | * @see NodeSimplifier::isSimplifierFor |
||
79 | */ |
||
80 | 10 | public function isSimplifierFor(AbstractNode $node) { |
|
81 | 10 | return $node instanceof TripleNode && |
|
82 | 10 | $node->getSubject() instanceof ResourceListNode && |
|
83 | 10 | $node->getPredicate() instanceof ResourceListNode && |
|
84 | 10 | $node->getObject() instanceof MissingNode; |
|
85 | } |
||
86 | |||
87 | /** |
||
88 | * @see NodeSimplifier::doSimplification |
||
89 | */ |
||
90 | 8 | public function simplify(AbstractNode $node) { |
|
91 | 8 | if(!$this->isSimplifierFor($node)) { |
|
92 | 1 | throw new InvalidArgumentException('SpecificTripleNodeSimplifier can only clean TripleNode objects'); |
|
93 | } |
||
94 | |||
95 | 7 | return $this->doSimplification($node); |
|
0 ignored issues
–
show
|
|||
96 | } |
||
97 | |||
98 | 7 | public function doSimplification(TripleNode $node) { |
|
99 | 7 | $additionalNodes = array(); |
|
100 | 7 | $otherPredicates = array(); |
|
101 | |||
102 | /** @var ResourceNode $predicate */ |
||
103 | 7 | foreach($node->getPredicate() as $predicate) { |
|
0 ignored issues
–
show
|
|||
104 | 7 | if(in_array($predicate->getValue(), self::$MEANINGLESS_PREDICATES)) { |
|
105 | 3 | $additionalNodes[] = $this->resourceListNodeParser->parse($node->getSubject(), 'wikibase-item'); |
|
0 ignored issues
–
show
$node->getSubject() of type object<PPP\DataModel\AbstractNode> is not a sub-type of object<PPP\DataModel\ResourceListNode> . It seems like you assume a child class of the class PPP\DataModel\AbstractNode to be always present.
This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass. Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type. ![]() |
|||
106 | 7 | } else if($predicate->equals(new StringResourceNode('son'))) { |
|
107 | 1 | $additionalNodes[] = $this->buildSonNode($node); |
|
108 | 5 | } else if($predicate->equals(new StringResourceNode('daughter'))) { |
|
109 | 1 | $additionalNodes[] = $this->buildDaughterNode($node); |
|
110 | 4 | } else if($predicate->equals(new StringResourceNode('age'))) { |
|
111 | 1 | $additionalNodes[] = $this->buildAgeNode($node); |
|
112 | 1 | } else { |
|
113 | 2 | $otherPredicates[] = $predicate; |
|
114 | } |
||
115 | 7 | } |
|
116 | |||
117 | 7 | if(!empty($otherPredicates)) { |
|
118 | 2 | $additionalNodes[] = new TripleNode($node->getSubject(), new ResourceListNode($otherPredicates), $node->getObject()); |
|
119 | 2 | } |
|
120 | |||
121 | 7 | if(count($additionalNodes) === 1) { |
|
122 | 6 | return $additionalNodes[0]; |
|
123 | } |
||
124 | |||
125 | 1 | return new UnionNode($additionalNodes); |
|
126 | } |
||
127 | |||
128 | 1 | private function buildSonNode(TripleNode $node) { |
|
129 | 1 | return new IntersectionNode(array( |
|
130 | 1 | new TripleNode( |
|
131 | 1 | $node->getSubject(), |
|
132 | 1 | new ResourceListNode(array(new WikibaseResourceNode('', new EntityIdValue(new PropertyId(self::PROPERTY_CHILD))))), |
|
133 | 1 | $node->getObject() |
|
134 | 1 | ), |
|
135 | 1 | new TripleNode( |
|
136 | 1 | $node->getObject(), |
|
137 | 1 | new ResourceListNode(array(new WikibaseResourceNode('', new EntityIdValue(new PropertyId(self::PROPERTY_SEX))))), |
|
138 | 1 | new ResourceListNode(array(new WikibaseResourceNode('', new EntityIdValue(new ItemId(self::ITEM_MALE))))) |
|
139 | 1 | ), |
|
140 | 1 | )); |
|
141 | } |
||
142 | |||
143 | 1 | private function buildDaughterNode(TripleNode $node) { |
|
144 | 1 | return new IntersectionNode(array( |
|
145 | 1 | new TripleNode( |
|
146 | 1 | $node->getSubject(), |
|
147 | 1 | new ResourceListNode(array(new WikibaseResourceNode('', new EntityIdValue(new PropertyId(self::PROPERTY_CHILD))))), |
|
148 | 1 | $node->getObject() |
|
149 | 1 | ), |
|
150 | 1 | new TripleNode( |
|
151 | 1 | $node->getObject(), |
|
152 | 1 | new ResourceListNode(array(new WikibaseResourceNode('', new EntityIdValue(new PropertyId(self::PROPERTY_SEX))))), |
|
153 | 1 | new ResourceListNode(array(new WikibaseResourceNode('', new EntityIdValue(new ItemId(self::ITEM_FEMALE))))) |
|
154 | 1 | ), |
|
155 | 1 | )); |
|
156 | } |
||
157 | |||
158 | 1 | private function buildAgeNode(TripleNode $node) { |
|
159 | 1 | $subjectNodes = $this->resourceListNodeParser->parse($node->getSubject(), 'wikibase-item'); |
|
0 ignored issues
–
show
$node->getSubject() of type object<PPP\DataModel\AbstractNode> is not a sub-type of object<PPP\DataModel\ResourceListNode> . It seems like you assume a child class of the class PPP\DataModel\AbstractNode to be always present.
This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass. Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type. ![]() |
|||
160 | 1 | $ageValues = array(); |
|
161 | |||
162 | /** @var WikibaseResourceNode $subjectNode */ |
||
163 | 1 | foreach($subjectNodes as $subjectNode) { |
|
164 | 1 | $birthDateObjects = $this->resourceListForEntityProperty->getForEntityProperty( |
|
165 | 1 | $subjectNode->getDataValue()->getEntityId(), |
|
166 | 1 | new PropertyId(self::PROPERTY_BIRTH_DATE) |
|
167 | 1 | ); |
|
168 | |||
169 | /** @var WikibaseResourceNode $birthDateObject */ |
||
170 | 1 | foreach($birthDateObjects as $birthDateObject) { |
|
171 | 1 | $ageValues[] = $this->formatAgeValue($this->computeAge($birthDateObject->getDataValue())); |
|
172 | 1 | } |
|
173 | 1 | } |
|
174 | |||
175 | 1 | return new ResourceListNode($ageValues); |
|
176 | } |
||
177 | |||
178 | 1 | private function computeAge(TimeValue $birthDateValue) { |
|
179 | 1 | $birthDate = new DateTime(preg_replace('/^\+0*/', '', $birthDateValue->getTime())); |
|
180 | 1 | return $this->now->diff($birthDate); |
|
181 | } |
||
182 | |||
183 | //TODO: implement a DurationValue? |
||
184 | 1 | private function formatAgeValue(DateInterval $age) { |
|
185 | 1 | $formattedAge = $age->format('%y'); |
|
186 | |||
187 | 1 | $literal = new stdClass(); |
|
188 | 1 | $literal->{'@type'} = 'Duration'; |
|
189 | 1 | $literal->{'@value'} = $age->format('P%yY%mM%dD'); |
|
190 | |||
191 | 1 | $resource = new stdClass(); |
|
192 | 1 | $resource->{'@context'} = 'http://schema.org'; |
|
193 | 1 | $resource->{'@type'} = 'Duration'; |
|
194 | 1 | $resource->{'name'} = $formattedAge; |
|
195 | 1 | $resource->{'http://www.w3.org/1999/02/22-rdf-syntax-ns#value'} = $literal; |
|
196 | |||
197 | 1 | return new JsonLdResourceNode($formattedAge, $resource); |
|
198 | } |
||
199 | } |
||
200 |
This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.
Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.