Skip to content

Commit 8d86401

Browse files
committed
Added failing tests and fix for #88
1 parent 0ccc493 commit 8d86401

File tree

2 files changed

+121
-18
lines changed

2 files changed

+121
-18
lines changed

Mf2/Parser.php

Lines changed: 48 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -951,25 +951,13 @@ public function parseH(\DOMElement $e) {
951951

952952
// Check for u-photo
953953
if (!array_key_exists('photo', $return)) {
954-
// Look for img @src
955-
try {
956-
if ($e->tagName == 'img')
957-
throw new Exception($e->getAttribute('src'));
958954

959-
// Look for nested img @src
960-
foreach ($this->xpath->query('./img[count(preceding-sibling::*)+count(following-sibling::*)=0]', $e) as $em) {
961-
if ($em->getAttribute('src') != '')
962-
throw new Exception($em->getAttribute('src'));
963-
}
955+
$photo = $this->parseImpliedPhoto($e);
964956

965-
// Look for double nested img @src
966-
foreach ($this->xpath->query('./*[count(preceding-sibling::*)+count(following-sibling::*)=0]/img[count(preceding-sibling::*)+count(following-sibling::*)=0]', $e) as $em) {
967-
if ($em->getAttribute('src') != '')
968-
throw new Exception($em->getAttribute('src'));
969-
}
970-
} catch (Exception $exc) {
971-
$return['photo'][] = $this->resolveUrl($exc->getMessage());
957+
if ($photo !== false) {
958+
$return['photo'][] = $this->resolveUrl($photo);
972959
}
960+
973961
}
974962

975963
// Check for u-url
@@ -1023,6 +1011,50 @@ public function parseH(\DOMElement $e) {
10231011
return $parsed;
10241012
}
10251013

1014+
/**
1015+
* @see http://microformats.org/wiki/microformats2-parsing#parsing_for_implied_properties
1016+
*/
1017+
public function parseImpliedPhoto(\DOMElement $e) {
1018+
1019+
if ($e->tagName == 'img') {
1020+
return $e->getAttribute('src');
1021+
}
1022+
1023+
if ($e->tagName == 'object' && $e->hasAttribute('data')) {
1024+
return $e->getAttribute('data');
1025+
}
1026+
1027+
$xpaths = array(
1028+
'./img',
1029+
'./object',
1030+
'./*[count(preceding-sibling::*)+count(following-sibling::*)=0]/img',
1031+
'./*[count(preceding-sibling::*)+count(following-sibling::*)=0]/object',
1032+
);
1033+
1034+
foreach ($xpaths as $path) {
1035+
$els = $this->xpath->query($path, $e);
1036+
1037+
if ($els->length == 1) {
1038+
$el = $els->item(0);
1039+
$hClasses = mfNamesFromElement($el, 'h-');
1040+
1041+
// no nested h-
1042+
if (empty($hClasses)) {
1043+
1044+
if ($el->tagName == 'img') {
1045+
return $el->getAttribute('src');
1046+
} else if ($el->tagName == 'object' && $el->getAttribute('data') != '') {
1047+
return $el->getAttribute('data');
1048+
}
1049+
1050+
} // no nested h-
1051+
}
1052+
}
1053+
1054+
// no implied photo
1055+
return false;
1056+
}
1057+
10261058
/**
10271059
* Parse Rels and Alternatives
10281060
*

tests/Mf2/ParseImpliedTest.php

Lines changed: 73 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,22 +81,24 @@ public function testParsesImpliedUPhotoFromDoublyNestedImgSrc() {
8181
$this->assertEquals('http://example.com/img.png', $output['items'][0]['properties']['photo'][0]);
8282
}
8383

84+
/*
85+
* see testImpliedPhotoFromNestedObject() and testImpliedPhotoFromNestedObject()
8486
public function testIgnoresImgIfNotOnlyChild() {
8587
$input = '<div class="h-card"><img src="http://example.com/img.png" /> <p>Moar text</p></div>';
8688
$parser = new Parser($input);
8789
$output = $parser->parse();
8890
8991
$this->assertArrayNotHasKey('photo', $output['items'][0]['properties']);
9092
}
91-
93+
9294
public function testIgnoresDoublyNestedImgIfNotOnlyDoublyNestedChild() {
9395
$input = '<div class="h-card"><span><img src="http://example.com/img.png" /> <p>Moar text</p></span></div>';
9496
$parser = new Parser($input);
9597
$output = $parser->parse();
9698
9799
$this->assertArrayNotHasKey('photo', $output['items'][0]['properties']);
98100
}
99-
101+
*/
100102

101103
public function testParsesImpliedUUrlFromAHref() {
102104
$input = '<a class="h-card" href="http://example.com/">Some Name</a>';
@@ -182,4 +184,73 @@ public function testParsesImpliedNameFromAbbrTitle() {
182184
$result = Mf2\parse($input);
183185
$this->assertEquals('Barnaby Walters', $result['items'][0]['properties']['name'][0]);
184186
}
187+
188+
public function testImpliedPhotoFromObject() {
189+
$input = '<object class="h-card" data="http://example/photo1.jpg">John Doe</object>';
190+
$result = Mf2\parse($input);
191+
192+
$this->assertArrayHasKey('photo', $result['items'][0]['properties']);
193+
$this->assertEquals('http://example/photo1.jpg', $result['items'][0]['properties']['photo'][0]);
194+
}
195+
196+
/**
197+
* Correcting previous test testIgnoresImgIfNotOnlyChild()
198+
* This *should* return the photo since h-x>img[src]:only-of-type:not[.h-*]
199+
* @see https://indiewebcamp.com/User:Tantek.com
200+
*/
201+
public function testImpliedPhotoFromNestedImg() {
202+
$input = '<span class="h-card"><a href="http://tantek.com/" class="external text" style="border: 0px none;"><img src="https://pbs.twimg.com/profile_images/423350922408767488/nlA_m2WH.jpeg" style="width:128px;float:right;margin-left:1em"><b><span style="font-size:2em">Tantek Çelik</span></b></a></span>';
203+
$result = Mf2\parse($input);
204+
205+
$this->assertArrayHasKey('photo', $result['items'][0]['properties']);
206+
$this->assertEquals('https://pbs.twimg.com/profile_images/423350922408767488/nlA_m2WH.jpeg', $result['items'][0]['properties']['photo'][0]);
207+
}
208+
209+
public function testIgnoredPhotoIfMultipleImg() {
210+
$input = '<div class="h-card"><img src="http://example/photo2.jpg" /> <img src="http://example/photo3.jpg" /> </div>';
211+
$result = Mf2\parse($input);
212+
213+
$this->assertArrayNotHasKey('photo', $result['items'][0]['properties']);
214+
}
215+
216+
/**
217+
* Correcting previous test testIgnoresDoublyNestedImgIfNotOnlyDoublyNestedChild()
218+
* This *should* return the photo since .h-x>object[data]:only-of-type:not[.h-*]
219+
*/
220+
public function testImpliedPhotoFromNestedObject() {
221+
$input = '<div class="h-card"><object data="http://example/photo3.jpg">John Doe</object> <p>Moar text</p></div>';
222+
$result = Mf2\parse($input);
223+
224+
$this->assertArrayHasKey('photo', $result['items'][0]['properties']);
225+
$this->assertEquals('http://example/photo3.jpg', $result['items'][0]['properties']['photo'][0]);
226+
}
227+
228+
public function testIgnoredPhotoIfMultipleObject() {
229+
$input = '<div class="h-card"><object data="http://example/photo3.jpg">John Doe</object> <object data="http://example/photo4.jpg"></object> </div>';
230+
$result = Mf2\parse($input);
231+
232+
$this->assertArrayNotHasKey('photo', $result['items'][0]['properties']);
233+
}
234+
235+
public function testIgnoredPhotoIfNestedImgH() {
236+
$input = '<div class="h-entry"> <img src="http://example/photo2.jpg" class="h-card" /> </div>';
237+
$result = Mf2\parse($input);
238+
239+
$this->assertArrayNotHasKey('photo', $result['items'][0]['properties']);
240+
}
241+
242+
public function testIgnoredPhotoIfNestedImgHasHClass() {
243+
$input = '<div class="h-entry"> <img src="http://example/photo2.jpg" alt="John Doe" class="h-card" /> </div>';
244+
$result = Mf2\parse($input);
245+
246+
$this->assertArrayNotHasKey('photo', $result['items'][0]['properties']);
247+
}
248+
249+
public function testIgnoredPhotoIfNestedObjectHasHClass() {
250+
$input = '<div class="h-entry"> <object data="http://example/photo3.jpg" class="h-card">John Doe</object> </div>';
251+
$result = Mf2\parse($input);
252+
253+
$this->assertArrayNotHasKey('photo', $result['items'][0]['properties']);
254+
}
255+
185256
}

0 commit comments

Comments
 (0)