1 | <?php |
||
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) { |
|
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); |
|
|
|||
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) { |
|
104 | 7 | if(in_array($predicate->getValue(), self::$MEANINGLESS_PREDICATES)) { |
|
105 | 3 | $additionalNodes[] = $this->resourceListNodeParser->parse($node->getSubject(), 'wikibase-item'); |
|
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'); |
|
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) { |
|
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'; |
|
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.