'index.php?well-known=webfinger'
);
$wp_rewrite->rules = $webfinger_rules + $wp_rewrite->rules;
}
/**
* renders the output-file
*
* @param array
*/
public function parse_request($wp) {
// check if "resource" param exists
if (!array_key_exists('resource', $wp->query_vars)) {
return;
}
// find matching user
$user = WebfingerPlugin::get_user_by_uri($wp->query_vars['resource']);
if (!$user) {
return;
}
$format = 'json';
if (array_key_exists('format', $wp->query_vars)) {
$format = $wp->query_vars['format'];
}
$webfinger = apply_filters('webfinger', array(), $user, $wp->query_vars['resource'], $wp->query_vars);
do_action("webfinger_render", $format, $webfinger, $user, $wp->query_vars);
do_action("webfinger_render_{$format}", $webfinger, $user, $wp->query_vars);
}
/**
* renders the webfinger file in json
*/
public function render_jrd($webfinger) {
header("Access-Control-Allow-Origin: *");
header('Content-Type: application/jrd+json; charset=' . get_bloginfo('charset'), true);
echo json_encode($webfinger);
exit();
}
/**
* renders the webfinger file in xml
*/
public function render_xrd($webfinger, $user) {
header("Access-Control-Allow-Origin: *");
header('Content-Type: application/xrd+xml; charset=' . get_bloginfo('charset'), true);
echo "\n";
echo "\n";
echo WebfingerPlugin::jrd_to_xrd($webfinger);
// add xml-only content
do_action('webfinger_xrd', $user);
echo "\n";
exit;
}
/**
* generates the webfinger base array
*/
public function generate_default_content($webfinger, $user, $resource) {
$url = get_author_posts_url($user->ID, $user->user_nicename);
$photo = get_user_meta($user->ID, 'photo', true);
if(!$photo) $photo = 'http://www.gravatar.com/avatar/'.md5($user->user_email);
$webfinger = array('subject' => $resource,
'aliases' => WebfingerPlugin::get_resources($user->ID),
'links' => array(
array('rel' => 'http://webfinger.net/rel/profile-page', 'type' => 'text/html', 'href' => $url),
array('rel' => 'http://webfinger.net/rel/avatar', 'href' => $photo)
));
if ($user->user_url) {
$webfinger['links'][] = array('rel' => 'http://webfinger.net/rel/profile-page', 'type' => 'text/html', 'href' => $user->user_url);
}
return $webfinger;
}
/**
* filters the webfinger array by request params like "rel"
*
* @link tools.ietf.org/html/draft-jones-appsawg-webfinger#section-4.3
* @param array $array
* @param stdClass $user
* @param array $queries
* @return array
*/
public function filter_by_rel($webfinger, $user, $resource, $queries) {
// check if "rel" is set
if (!array_key_exists('rel', $queries)) {
return $webfinger;
}
remove_all_actions('webfinger_xrd');
// filter webfinger-array
$links = array();
foreach ($webfinger['links'] as $link) {
if ($link["rel"] == $queries["rel"]) {
$links[] = $link;
}
}
$webfinger['links'] = $links;
// return only "links" with the matching
return $webfinger;
}
/**
* add the host meta information
*/
public function add_host_meta_links($array) {
$array["links"][] = array("rel" => "lrdd", "template" => site_url("/?well-known=webfinger&resource={uri}&format=xrd"), "type" => "application/xrd+xml");
return $array;
}
/**
* returns a Userobject
*
* @param string $uri
* @return stdClass
*/
private function get_user_by_uri($uri) {
global $wpdb;
$uri = urldecode($uri);
if (preg_match("~^https?://~i", $uri)) {
// check if url matches with a
// users profile url
foreach (get_users_of_blog() as $user) {
if (rtrim(str_replace("www.", "", get_author_posts_url($user->ID, $user->user_nicename)), "/") ==
rtrim(str_replace("www.", "", $uri), "/")) {
return $user;
}
}
} elseif (preg_match('/^([a-zA-Z]+:)?([^@]+)@([a-zA-Z0-9._-]+)$/i', $uri, $array)) {
$username = $array[2];
$host = $array[3];
$email = $username."@".$host;
if ($host == parse_url(get_bloginfo('url'), PHP_URL_HOST)) {
$sql = "SELECT * FROM $wpdb->users u INNER JOIN $wpdb->usermeta um ON u.id=um.user_id WHERE u.user_email = '%s' OR
(um.meta_key = 'jabber' AND um.meta_value = '%s') OR
u.user_login = '%s' LIMIT 1;";
$user = $wpdb->get_results($wpdb->prepare($sql, $email, $email, $username));
if (!empty($user)) {
return $user[0];
}
}
}
return false;
}
/**
* recursive helper to generade the xrd-xml from the jrd array
*
* @param string $host_meta
* @return string
*/
public function jrd_to_xrd($webfinger) {
$xrd = null;
foreach ($webfinger as $type => $content) {
// print subject
if ($type == "subject") {
$xrd .= "$content";
continue;
}
// print aliases
if ($type == "aliases") {
foreach ($content as $uri) {
$xrd .= "".htmlentities($uri)."";
}
continue;
}
// print properties
if ($type == "properties") {
foreach ($content as $type => $uri) {
$xrd .= "".htmlentities($uri)."";
}
continue;
}
// print titles
if ($type == "titles") {
foreach ($content as $key => $value) {
if ($key == "default") {
$xrd .= "
".htmlentities($value)."";
} else {
$xrd .= "".htmlentities($value)."";
}
}
continue;
}
// print links
if ($type == "links") {
foreach ($content as $links) {
$temp = array();
$cascaded = false;
$xrd .= " $value) {
if (is_array($value)) {
$temp[$key] = $value;
$cascaded = true;
} else {
$xrd .= htmlentities($key)."='".htmlentities($value)."' ";
}
}
if ($cascaded) {
$xrd .= ">";
$xrd .= WebfingerPlugin::jrd_to_xrd($temp);
$xrd .= "";
} else {
$xrd .= " />";
}
}
continue;
}
}
return $xrd;
}
/**
* returns a users default webfinger
*
* @param mixed $id_or_name_or_object
* @param boolean $protocol
* @return string
*/
function get_resource($id_or_name_or_object, $protocol = false) {
$user = WebfingerPlugin::get_user_by_various($id_or_name_or_object);
if ($user) {
$resource = $user->user_login."@".parse_url(home_url(), PHP_URL_HOST);
if ($protocol) {
$resource = "acct:".$resource;
}
return $resource;
} else {
return null;
}
}
/**
* returns all webfinger "resources"
*
* @param mixed $id_or_name_or_object
*
* @return array
*/
public function get_resources($id_or_name_or_object) {
$user = WebfingerPlugin::get_user_by_various($id_or_name_or_object);
if ($user) {
$resources[] = WebfingerPlugin::get_resource($user, true);
$resources[] = get_author_posts_url($user->ID, $user->user_nicename);
if ($user->user_email && WebfingerPlugin::check_mail_domain($user->user_email)) {
$resources[] = "mailto:".$user->user_email;
}
if (get_user_meta($user->ID, "jabber", true) && $webfinger->check_mail_domain(get_user_meta($user->ID, "jabber", true))) {
$resources[] = "xmpp:".get_user_meta($user->ID, "jabber", true);
}
$resources = apply_filters('resources', $resources);
return array_unique($resources);
} else {
return array();
}
}
/**
* Convenience method to get user data by ID, username, object or from current user.
*
* @param mixed $id_or_name_or_object the username, ID or object. If not provided, the current user will be used.
* @return bool|object False on failure, User DB row object
*
* @author Will Norris
* @see get_userdata_by_various() # DiSo OpenID-Plugin
*/
public function get_user_by_various($id_or_name_or_object = null) {
if ( $id_or_name_or_object === null ) {
$user = wp_get_current_user();
if ($user == null) return false;
return $user->data;
} else if ( is_object($id_or_name_or_object) ) {
return $id_or_name_or_object;
} else if ( is_numeric($id_or_name_or_object) ) {
return get_userdata($id_or_name_or_object);
} else {
return get_userdatabylogin($id_or_name_or_object);
}
}
/**
* check if the email address has the same domain as the blog
*
* @param string $email
* @return boolean
*/
public function check_mail_domain($email) {
if (preg_match('/^([a-zA-Z]+:)?([^@]+)@([a-zA-Z0-9._-]+)$/i', $email, $email_parts) &&
($email_parts[3] == parse_url(home_url(), PHP_URL_HOST))) {
return true;
}
return false;
}
public function host_meta_draft($format, $host_meta, $query_vars) {
if (!array_key_exists('resource', $query_vars)) {
return;
}
// find matching user
$user = WebfingerPlugin::get_user_by_uri($query_vars['resource']);
if (!$user) {
return;
}
$webfinger = apply_filters('webfinger', array(), $user, $query_vars['resource'], $query_vars);
do_action("webfinger_render", $format, $webfinger, $user, $query_vars);
do_action("webfinger_render_{$format}", $webfinger, $user, $query_vars);
}
}
add_action('query_vars', array('WebfingerPlugin', 'query_vars'));
add_action('parse_request', array('WebfingerPlugin', 'parse_request'));
add_action('generate_rewrite_rules', array('WebfingerPlugin', 'rewrite_rules'));
add_action('host_meta_render', array('WebfingerPlugin', 'host_meta_draft'), 1, 3);
add_action('webfinger_render_json', array('WebfingerPlugin', 'render_jrd'), 1, 1);
add_action('webfinger_render_jrd', array('WebfingerPlugin', 'render_jrd'), 1, 1);
add_action('webfinger_render_xml', array('WebfingerPlugin', 'render_xrd'), 1, 2);
add_action('webfinger_render_xrd', array('WebfingerPlugin', 'render_xrd'), 1, 2);
add_filter('webfinger', array('WebfingerPlugin', 'generate_default_content'), 0, 3);
add_filter('webfinger', array('WebfingerPlugin', 'filter_by_rel'), 99, 4);
add_filter('host_meta', array('WebfingerPlugin', 'add_host_meta_links'));
register_activation_hook(__FILE__, 'flush_rewrite_rules');
register_deactivation_hook(__FILE__, 'flush_rewrite_rules');