plugin is entirely user centric
willnorris opened this issue · comments
Right now, the plugin assumes that all WebFinger queries are for users. This is probably fine for now, but it's worth noting that the WebFinger spec itself provides an example where the query is for a webpage: http://tools.ietf.org/html/rfc7033#section-3.2
I think it's actually fine to consider this out of scope for now (though it wouldn't take too much work to remedy this), but I wanted to at least track it here.
I love this idea! It is a nice way to return the short URL or the license of the article.
I think we should add some actions (for example before checking the user) to enable completely custom outputs
The more I think about this feature the more convinced I am that we should start with that even if it is only conceptual. The resource is the first call and everything else depends on it, so it could result in a complete refactoring process if we implement it at last.
I tried to implement this in a first draft and I am curious what you think about https://github.com/pfefferle/wordpress-webfinger/tree/resource-centric
- I added a pre_render action, so users can write there own resource specific outputs
- I postfixed (<- I hope this is a word) the new webfinger hooks with
webfinger_user_output
andwebfinger_post_output
becausewebfinger_user
should be used to filter the user (perhaps in theget_user_by_uri
function) - I added a generic hook
webfinger_generic_output
to enable an object independent (if the resource is no post or user) output
It would also be possible to only use one filter and pass the post or user-object or null (for custum/generic outputs)
if ($user = self::get_user_by_uri($wp->query_vars['resource'])) {
$object = $user;
} else if ($post = self::get_post_by_uri($wp->query_vars['resource'])) {
$object = $post;
} else {
$object = null;
}
$webfinger = apply_filters('webfinger_output', $webfinger, $object, $wp->query_vars['resource']);
...but that means that the implementor has to use something linke get_class
to get knowledge about the resource type. We have to do the check anyways (to get the post or user) so I thought it would be a more comfortable way to add several filters.
I think we have to rethink the use of the webfinger
filter nevertheless... the filter should be working if there is a user or not.
what do you think about
// find matching user
$user = self::get_user_by_uri($wp->query_vars['resource']);
// filter webfinger array
$webfinger = apply_filters('webfinger_output', array(), $user, $wp->query_vars['resource'], $wp->query_vars);
// check if there is a output
if (empty($webfinger)) {
status_header(404);
header('Content-Type: text/plain; charset=' . get_bloginfo('charset'), true);
echo 'no user found';
exit;
}
do_action('webfinger_render', $webfinger);
That would allow us to pass the user if there is one or null if not. That would allow extensions that focuses on post-urls etc. To be downwards compatible we have to rename the filter and have hook the old filter into the new one like I did here: https://github.com/pfefferle/wordpress-webfinger/blob/resource-centric/plugin.php#L334 because the old filter always expects a user.
the alternative would be to add a general filter without the user param in addition to the current filter like
// find matching user
$user = self::get_user_by_uri($wp->query_vars['resource']);
$webfinger = array();
if ($user) {
// filter webfinger array
$webfinger = apply_filters('webfinger', $webfinger, $user, $wp->query_vars['resource'], $wp->query_vars);
} else {
$webfinger = apply_filters('webfinger_general', $webfinger, $wp->query_vars['resource'], $wp->query_vars);
}
// check if there is a output
if (empty($webfinger)) {
status_header(404);
header('Content-Type: text/plain; charset=' . get_bloginfo('charset'), true);
echo 'no user found';
exit;
}
do_action('webfinger_render', $webfinger);
I am not sure if it is good to parse a param that could be null
as used in the first example
I implemented the mentioned in a branch: https://github.com/pfefferle/wordpress-webfinger/tree/generic-filter
The changes:
- the WP_User can be null
- the 404 check checks if the array is filled
Extensibility
- to add data for all users in the system you have to check if $user is not null
- to add user-specific entries you have to check the $user id
- to add for example post-specific entries you have to check if $user is null and check the url...
I experimented with another version. A generic filter and the user stuff hooks into this filter and provides a second, user specific filter. It's in the main branch right now. Not sure if it like it though...
changed it once again.
- parse request adds a generic "webfinger_data" filter
- the user stuff hooks into this filter and provides a separate "webfinger_user_data" filter
- the user is set via a "webfinger_user" filter to replace it with some custom code