Skip to content

Commit 93b3a6f

Browse files
authored
Merge pull request #100 from gRegorLove/issue88
Implied photo
2 parents 3145087 + 8d86401 commit 93b3a6f

File tree

2 files changed

+121
-18
lines changed

2 files changed

+121
-18
lines changed

Mf2/Parser.php

+48-16
Original file line numberDiff line numberDiff line change
@@ -988,25 +988,13 @@ public function parseH(\DOMElement $e) {
988988

989989
// Check for u-photo
990990
if (!array_key_exists('photo', $return)) {
991-
// Look for img @src
992-
try {
993-
if ($e->tagName == 'img')
994-
throw new Exception($e->getAttribute('src'));
995991

996-
// Look for nested img @src
997-
foreach ($this->xpath->query('./img[count(preceding-sibling::*)+count(following-sibling::*)=0]', $e) as $em) {
998-
if ($em->getAttribute('src') != '')
999-
throw new Exception($em->getAttribute('src'));
1000-
}
992+
$photo = $this->parseImpliedPhoto($e);
1001993

1002-
// Look for double nested img @src
1003-
foreach ($this->xpath->query('./*[count(preceding-sibling::*)+count(following-sibling::*)=0]/img[count(preceding-sibling::*)+count(following-sibling::*)=0]', $e) as $em) {
1004-
if ($em->getAttribute('src') != '')
1005-
throw new Exception($em->getAttribute('src'));
1006-
}
1007-
} catch (Exception $exc) {
1008-
$return['photo'][] = $this->resolveUrl($exc->getMessage());
994+
if ($photo !== false) {
995+
$return['photo'][] = $this->resolveUrl($photo);
1009996
}
997+
1010998
}
1011999

10121000
// Check for u-url
@@ -1065,6 +1053,50 @@ public function parseH(\DOMElement $e) {
10651053
return $parsed;
10661054
}
10671055

1056+
/**
1057+
* @see http://microformats.org/wiki/microformats2-parsing#parsing_for_implied_properties
1058+
*/
1059+
public function parseImpliedPhoto(\DOMElement $e) {
1060+
1061+
if ($e->tagName == 'img') {
1062+
return $e->getAttribute('src');
1063+
}
1064+
1065+
if ($e->tagName == 'object' && $e->hasAttribute('data')) {
1066+
return $e->getAttribute('data');
1067+
}
1068+
1069+
$xpaths = array(
1070+
'./img',
1071+
'./object',
1072+
'./*[count(preceding-sibling::*)+count(following-sibling::*)=0]/img',
1073+
'./*[count(preceding-sibling::*)+count(following-sibling::*)=0]/object',
1074+
);
1075+
1076+
foreach ($xpaths as $path) {
1077+
$els = $this->xpath->query($path, $e);
1078+
1079+
if ($els->length == 1) {
1080+
$el = $els->item(0);
1081+
$hClasses = mfNamesFromElement($el, 'h-');
1082+
1083+
// no nested h-
1084+
if (empty($hClasses)) {
1085+
1086+
if ($el->tagName == 'img') {
1087+
return $el->getAttribute('src');
1088+
} else if ($el->tagName == 'object' && $el->getAttribute('data') != '') {
1089+
return $el->getAttribute('data');
1090+
}
1091+
1092+
} // no nested h-
1093+
}
1094+
}
1095+
1096+
// no implied photo
1097+
return false;
1098+
}
1099+
10681100
/**
10691101
* Parse Rels and Alternatives
10701102
*

tests/Mf2/ParseImpliedTest.php

+73-2
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)