*/
class DiscoveryHints {
-
- static function fromXRD($xrd)
+ static function fromXRD(XML_XRD $xrd)
{
$hints = array();
- foreach ($xrd->links as $link) {
- switch ($link['rel']) {
- case Discovery::PROFILEPAGE:
- $hints['profileurl'] = $link['href'];
- break;
- case Salmon::NS_MENTIONS:
- case Salmon::NS_REPLIES:
- $hints['salmon'] = $link['href'];
- break;
- case Discovery::UPDATESFROM:
- $hints['feedurl'] = $link['href'];
- break;
- case Discovery::HCARD:
- $hints['hcardurl'] = $link['href'];
- break;
- default:
- break;
+ if (Event::handle('StartDiscoveryHintsFromXRD', array($xrd, &$hints))) {
+ foreach ($xrd->links as $link) {
+ switch ($link->rel) {
+ case WebFingerResource_Profile::PROFILEPAGE:
+ $hints['profileurl'] = $link->href;
+ break;
+ case Salmon::REL_SALMON:
+ case Salmon::NS_MENTIONS: // XXX: deprecated, remove in the future
+ case Salmon::NS_REPLIES: // XXX: deprecated, remove in the future
+ $hints['salmon'] = $link->href;
+ break;
+ case Discovery::UPDATESFROM:
+ if (empty($link->type) || $link->type == 'application/atom+xml') {
+ $hints['feedurl'] = $link->href;
+ }
+ break;
+ case Discovery::HCARD:
+ case Discovery::MF2_HCARD:
+ $hints['hcard'] = $link->href;
+ break;
+ default:
+ break;
+ }
}
+ Event::handle('EndDiscoveryHintsFromXRD', array($xrd, &$hints));
}
return $hints;
// XXX: don't copy stuff into an array and then copy it again
- if (array_key_exists('nickname', $hcard)) {
- $hints['nickname'] = $hcard['nickname'];
+ if (array_key_exists('nickname', $hcard) && !empty($hcard['nickname'][0])) {
+ $hints['nickname'] = $hcard['nickname'][0];
}
- if (array_key_exists('fn', $hcard)) {
- $hints['fullname'] = $hcard['fn'];
- } else if (array_key_exists('n', $hcard)) {
- $hints['fullname'] = implode(' ', $hcard['n']);
+ if (array_key_exists('name', $hcard) && !empty($hcard['name'][0])) {
+ $hints['fullname'] = $hcard['name'][0];
}
if (array_key_exists('photo', $hcard) && count($hcard['photo'])) {
$hints['avatar'] = $hcard['photo'][0];
}
- if (array_key_exists('note', $hcard)) {
- $hints['bio'] = $hcard['note'];
+ if (array_key_exists('note', $hcard) && !empty($hcard['note'][0])) {
+ $hints['bio'] = $hcard['note'][0];
}
- if (array_key_exists('adr', $hcard)) {
- if (is_string($hcard['adr'])) {
- $hints['location'] = $hcard['adr'];
- } else if (is_array($hcard['adr'])) {
- $hints['location'] = implode(' ', $hcard['adr']);
- }
+ if (array_key_exists('adr', $hcard) && !empty($hcard['adr'][0])) {
+ $hints['location'] = $hcard['adr'][0]['value'];
}
- if (array_key_exists('url', $hcard)) {
- if (is_string($hcard['url'])) {
- $hints['homepage'] = $hcard['url'];
- } else if (is_array($hcard['url']) && !empty($hcard['url'])) {
- // HACK get the last one; that's how our hcards look
- $hints['homepage'] = $hcard['url'][count($hcard['url'])-1];
- }
+ if (array_key_exists('url', $hcard) && !empty($hcard['url'][0])) {
+ $hints['homepage'] = $hcard['url'][0];
}
return $hints;
static function _hcard($body, $url)
{
- // DOMDocument::loadHTML may throw warnings on unrecognized elements.
-
- $old = error_reporting(error_reporting() & ~E_WARNING);
-
- $doc = new DOMDocument();
- $doc->loadHTML($body);
-
- error_reporting($old);
-
- $xp = new DOMXPath($doc);
-
- $hcardNodes = self::_getChildrenByClass($doc->documentElement, 'vcard', $xp);
-
- $hcards = array();
-
- for ($i = 0; $i < $hcardNodes->length; $i++) {
-
- $hcardNode = $hcardNodes->item($i);
-
- $hcard = self::_hcardFromNode($hcardNode, $xp, $url);
-
- $hcards[] = $hcard;
- }
-
- $repr = null;
-
- foreach ($hcards as $hcard) {
- if (in_array($url, $hcard['url'])) {
- $repr = $hcard;
- break;
- }
- }
-
- if (!is_null($repr)) {
- return $repr;
- } else if (count($hcards) > 0) {
- return $hcards[0];
- } else {
+ $mf2 = new Mf2\Parser($body, $url);
+ $mf2 = $mf2->parse();
+
+ if (empty($mf2['items'])) {
return null;
}
- }
-
- function _getChildrenByClass($el, $cls, $xp)
- {
- // borrowed from hkit. Thanks dudes!
-
- $qry = ".//*[contains(concat(' ',normalize-space(@class),' '),' $cls ')]";
-
- $nodes = $xp->query($qry, $el);
-
- return $nodes;
- }
-
- function _hcardFromNode($hcardNode, $xp, $base)
- {
- $hcard = array();
-
- $hcard['url'] = array();
-
- $urlNodes = self::_getChildrenByClass($hcardNode, 'url', $xp);
-
- for ($j = 0; $j < $urlNodes->length; $j++) {
-
- $urlNode = $urlNodes->item($j);
-
- if ($urlNode->hasAttribute('href')) {
- $url = $urlNode->getAttribute('href');
- } else {
- $url = $urlNode->textContent;
- }
-
- $hcard['url'][] = self::_rel2abs($url, $base);
- }
-
- $hcard['photo'] = array();
- $photoNodes = self::_getChildrenByClass($hcardNode, 'photo', $xp);
+ $hcards = array();
- for ($j = 0; $j < $photoNodes->length; $j++) {
- $photoNode = $photoNodes->item($j);
- if ($photoNode->hasAttribute('src')) {
- $url = $photoNode->getAttribute('src');
- } else if ($photoNode->hasAttribute('href')) {
- $url = $photoNode->getAttribute('href');
- } else {
- $url = $photoNode->textContent;
+ foreach ($mf2['items'] as $item) {
+ if (!in_array('h-card', $item['type'])) {
+ continue;
}
- $hcard['photo'][] = self::_rel2abs($url, $base);
- }
-
- $singles = array('nickname', 'note', 'fn', 'n', 'adr');
-
- foreach ($singles as $single) {
-
- $nodes = self::_getChildrenByClass($hcardNode, $single, $xp);
- if ($nodes->length > 0) {
- $node = $nodes->item(0);
- $hcard[$single] = $node->textContent;
+ // We found a match, return it immediately
+ if (isset($item['properties']['url']) && in_array($url, $item['properties']['url'])) {
+ return $item['properties'];
}
- }
-
- return $hcard;
- }
-
- // XXX: this is a first pass; we probably need
- // to handle things like ../ and ./ and so on
-
- static function _rel2abs($rel, $wrt)
- {
- $parts = parse_url($rel);
-
- if ($parts === false) {
- return false;
- }
-
- // If it's got a scheme, use it
- if (!empty($parts['scheme'])) {
- return $rel;
+ // Let's keep all the hcards for later, to return one of them at least
+ $hcards[] = $item['properties'];
}
- $w = parse_url($wrt);
-
- $base = $w['scheme'].'://'.$w['host'];
-
- if ($rel[0] == '/') {
- return $base.$rel;
+ // No match immediately for the url we expected, but there were h-cards found
+ if (count($hcards) > 0) {
+ return $hcards[0];
}
- $wp = explode('/', $w['path']);
-
- array_pop($wp);
-
- return $base.implode('/', $wp).'/'.$rel;
+ return null;
}
}