Skip to content

Implied photo #100

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 8, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 48 additions & 16 deletions Mf2/Parser.php
Original file line number Diff line number Diff line change
Expand Up @@ -951,25 +951,13 @@ public function parseH(\DOMElement $e) {

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

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

// Look for double nested img @src
foreach ($this->xpath->query('./*[count(preceding-sibling::*)+count(following-sibling::*)=0]/img[count(preceding-sibling::*)+count(following-sibling::*)=0]', $e) as $em) {
if ($em->getAttribute('src') != '')
throw new Exception($em->getAttribute('src'));
}
} catch (Exception $exc) {
$return['photo'][] = $this->resolveUrl($exc->getMessage());
if ($photo !== false) {
$return['photo'][] = $this->resolveUrl($photo);
}

}

// Check for u-url
Expand Down Expand Up @@ -1023,6 +1011,50 @@ public function parseH(\DOMElement $e) {
return $parsed;
}

/**
* @see http://microformats.org/wiki/microformats2-parsing#parsing_for_implied_properties
*/
public function parseImpliedPhoto(\DOMElement $e) {

if ($e->tagName == 'img') {
return $e->getAttribute('src');
}

if ($e->tagName == 'object' && $e->hasAttribute('data')) {
return $e->getAttribute('data');
}

$xpaths = array(
'./img',
'./object',
'./*[count(preceding-sibling::*)+count(following-sibling::*)=0]/img',
'./*[count(preceding-sibling::*)+count(following-sibling::*)=0]/object',
);

foreach ($xpaths as $path) {
$els = $this->xpath->query($path, $e);

if ($els->length == 1) {
$el = $els->item(0);
$hClasses = mfNamesFromElement($el, 'h-');

// no nested h-
if (empty($hClasses)) {

if ($el->tagName == 'img') {
return $el->getAttribute('src');
} else if ($el->tagName == 'object' && $el->getAttribute('data') != '') {
return $el->getAttribute('data');
}

} // no nested h-
}
}

// no implied photo
return false;
}

/**
* Parse Rels and Alternatives
*
Expand Down
75 changes: 73 additions & 2 deletions tests/Mf2/ParseImpliedTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,22 +81,24 @@ public function testParsesImpliedUPhotoFromDoublyNestedImgSrc() {
$this->assertEquals('http://example.com/img.png', $output['items'][0]['properties']['photo'][0]);
}

/*
* see testImpliedPhotoFromNestedObject() and testImpliedPhotoFromNestedObject()
public function testIgnoresImgIfNotOnlyChild() {
$input = '<div class="h-card"><img src="http://example.com/img.png" /> <p>Moar text</p></div>';
$parser = new Parser($input);
$output = $parser->parse();

$this->assertArrayNotHasKey('photo', $output['items'][0]['properties']);
}

public function testIgnoresDoublyNestedImgIfNotOnlyDoublyNestedChild() {
$input = '<div class="h-card"><span><img src="http://example.com/img.png" /> <p>Moar text</p></span></div>';
$parser = new Parser($input);
$output = $parser->parse();

$this->assertArrayNotHasKey('photo', $output['items'][0]['properties']);
}

*/

public function testParsesImpliedUUrlFromAHref() {
$input = '<a class="h-card" href="http://example.com/">Some Name</a>';
Expand Down Expand Up @@ -182,4 +184,73 @@ public function testParsesImpliedNameFromAbbrTitle() {
$result = Mf2\parse($input);
$this->assertEquals('Barnaby Walters', $result['items'][0]['properties']['name'][0]);
}

public function testImpliedPhotoFromObject() {
$input = '<object class="h-card" data="http://example/photo1.jpg">John Doe</object>';
$result = Mf2\parse($input);

$this->assertArrayHasKey('photo', $result['items'][0]['properties']);
$this->assertEquals('http://example/photo1.jpg', $result['items'][0]['properties']['photo'][0]);
}

/**
* Correcting previous test testIgnoresImgIfNotOnlyChild()
* This *should* return the photo since h-x>img[src]:only-of-type:not[.h-*]
* @see https://indiewebcamp.com/User:Tantek.com
*/
public function testImpliedPhotoFromNestedImg() {
$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>';
$result = Mf2\parse($input);

$this->assertArrayHasKey('photo', $result['items'][0]['properties']);
$this->assertEquals('https://pbs.twimg.com/profile_images/423350922408767488/nlA_m2WH.jpeg', $result['items'][0]['properties']['photo'][0]);
}

public function testIgnoredPhotoIfMultipleImg() {
$input = '<div class="h-card"><img src="http://example/photo2.jpg" /> <img src="http://example/photo3.jpg" /> </div>';
$result = Mf2\parse($input);

$this->assertArrayNotHasKey('photo', $result['items'][0]['properties']);
}

/**
* Correcting previous test testIgnoresDoublyNestedImgIfNotOnlyDoublyNestedChild()
* This *should* return the photo since .h-x>object[data]:only-of-type:not[.h-*]
*/
public function testImpliedPhotoFromNestedObject() {
$input = '<div class="h-card"><object data="http://example/photo3.jpg">John Doe</object> <p>Moar text</p></div>';
$result = Mf2\parse($input);

$this->assertArrayHasKey('photo', $result['items'][0]['properties']);
$this->assertEquals('http://example/photo3.jpg', $result['items'][0]['properties']['photo'][0]);
}

public function testIgnoredPhotoIfMultipleObject() {
$input = '<div class="h-card"><object data="http://example/photo3.jpg">John Doe</object> <object data="http://example/photo4.jpg"></object> </div>';
$result = Mf2\parse($input);

$this->assertArrayNotHasKey('photo', $result['items'][0]['properties']);
}

public function testIgnoredPhotoIfNestedImgH() {
$input = '<div class="h-entry"> <img src="http://example/photo2.jpg" class="h-card" /> </div>';
$result = Mf2\parse($input);

$this->assertArrayNotHasKey('photo', $result['items'][0]['properties']);
}

public function testIgnoredPhotoIfNestedImgHasHClass() {
$input = '<div class="h-entry"> <img src="http://example/photo2.jpg" alt="John Doe" class="h-card" /> </div>';
$result = Mf2\parse($input);

$this->assertArrayNotHasKey('photo', $result['items'][0]['properties']);
}

public function testIgnoredPhotoIfNestedObjectHasHClass() {
$input = '<div class="h-entry"> <object data="http://example/photo3.jpg" class="h-card">John Doe</object> </div>';
$result = Mf2\parse($input);

$this->assertArrayNotHasKey('photo', $result['items'][0]['properties']);
}

}