Skip to content
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

Linked and formatted user names #527

Merged
merged 26 commits into from Mar 16, 2014
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
60a396c
wrap userlink building with event.
Klap-in Feb 3, 2014
8a7e0ee
update $username as well, when read from _SERVER
Klap-in Feb 3, 2014
62c8004
change default arg value of userinfo in null instead false
Klap-in Feb 14, 2014
7c2f8ee
handle interwiki without slashes as pageids. Added user interwiki
Klap-in Feb 14, 2014
b3d353e
wikilink needs wiki target as well
Klap-in Feb 14, 2014
7f08182
Extend showuseras config with username_link
Klap-in Feb 14, 2014
2d6df79
added tests for Doku_Renderer::_resolveInterWiki
Klap-in Feb 14, 2014
2345e87
wikilink creating refactored to _resolveinterwiki().
Klap-in Feb 15, 2014
5a9ce44
code reformatting
Klap-in Feb 15, 2014
4485a89
Fix double slash in coral interwikilink
Klap-in Feb 15, 2014
ddb55c7
Use DOKU_BASE in resolveinterwiki unittest
Klap-in Feb 15, 2014
6496c33
interwiki : prefixed configurls handled as wikilinks
Klap-in Feb 15, 2014
f379edc
fix comment in _resolveInterWiki
Klap-in Feb 15, 2014
6198904
generalised link colour in header, making interwiki links blue as wel…
selfthinker Feb 16, 2014
2a2a43c
change default userspace to :user:<username> and add interwiki class
Klap-in Feb 16, 2014
118e005
update unittest with interwiki.conf change as well
Klap-in Feb 16, 2014
6384941
added user.png for interwiki links
Klap-in Mar 10, 2014
f97db66
Merge remote-tracking branch 'origin/master' into userlink
Klap-in Mar 10, 2014
30f6ec4
update usage in userlink
Klap-in Mar 10, 2014
533772e
declare more clear, before used as ref
Klap-in Mar 10, 2014
15f3bc4
enable editorinfo and userinfo to return plain text names
Klap-in Mar 14, 2014
c18baa7
override user link icon in header
splitbrain Mar 15, 2014
c095302
improve phpdocs editorinfo()
Klap-in Mar 16, 2014
898f93a
Merge remote-tracking branch 'origin/userlink' into userlink
Klap-in Mar 16, 2014
cd4635e
Rename userinfo() to userlink()
Klap-in Mar 16, 2014
4d5fc92
use more consistent names
Klap-in Mar 16, 2014
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
53 changes: 53 additions & 0 deletions _test/tests/inc/parser/renderer_resolveinterwiki.test.php
@@ -0,0 +1,53 @@
<?php

require_once DOKU_INC . 'inc/parser/renderer.php';

/**
* Tests for Doku_Renderer::_resolveInterWiki()
*/
class Test_resolveInterwiki extends PHPUnit_Framework_TestCase {

function testDefaults() {
$Renderer = new Doku_Renderer();
$Renderer->interwiki = getInterwiki();
$Renderer->interwiki['scheme'] = '{SCHEME}://example.com';
$Renderer->interwiki['withslash'] = '/test';
$Renderer->interwiki['onlytext'] = ':onlytext{NAME}'; //with {URL} double urlencoded
$Renderer->interwiki['withquery'] = ':anyns:{NAME}?do=edit';

$tests = array(
// shortcut, reference and expected
array('wp', 'foo @+%/#txt', 'http://en.wikipedia.org/wiki/foo @+%/#txt'),
array('amazon', 'foo @+%/#txt', 'http://www.amazon.com/exec/obidos/ASIN/foo%20%40%2B%25%2F/splitbrain-20/#txt'),
array('doku', 'foo @+%/#txt', 'http://www.dokuwiki.org/foo%20%40%2B%25%2F#txt'),
array('coral', 'http://example.com:83/path/naar/?query=foo%20%40%2B%25%2F', 'http://example.com.83.nyud.net:8090/path/naar/?query=foo%20%40%2B%25%2F'),
array('scheme', 'ftp://foo @+%/#txt', 'ftp://example.com#txt'),
//relative url
array('withslash', 'foo @+%/#txt', '/testfoo%20%40%2B%25%2F#txt'),
array('skype', 'foo @+%/#txt', 'skype:foo @+%/#txt'),
//dokuwiki id's
array('onlytext', 'foo @+%#txt', DOKU_BASE.'doku.php?id=onlytextfoo#txt'),
array('user', 'foo @+%#txt', DOKU_BASE.'doku.php?id=wiki:users:foo#txt'),
array('withquery', 'foo @+%#txt', DOKU_BASE.'doku.php?id=anyns:foo&amp;do=edit#txt')
);

foreach($tests as $test) {
$url = $Renderer->_resolveInterWiki($test[0], $test[1]);

$this->assertEquals($test[2], $url);
}
}

function testNonexisting() {
$Renderer = new Doku_Renderer();
$Renderer->interwiki = getInterwiki();

$shortcut = 'nonexisting';
$reference = 'foo @+%/';
$url = $Renderer->_resolveInterWiki($shortcut, $reference);
$expected = 'http://www.google.com/search?q=foo%20%40%2B%25%2F&amp;btnI=lucky';

$this->assertEquals($expected, $url);
}

}
3 changes: 2 additions & 1 deletion conf/interwiki.conf
Expand Up @@ -24,12 +24,13 @@ amazon.de http://www.amazon.de/exec/obidos/ASIN/{URL}/splitbrain-21/
amazon.uk http://www.amazon.co.uk/exec/obidos/ASIN/
paypal https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&amp;business=
phpfn http://www.php.net/{NAME}
coral http://{HOST}.{PORT}.nyud.net:8090/{PATH}?{QUERY}
coral http://{HOST}.{PORT}.nyud.net:8090{PATH}?{QUERY}
freecache http://freecache.org/{NAME}
sb http://www.splitbrain.org/go/
skype skype:{NAME}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Damn. I forgot about this usecase. this will break with your change. You no longer can create a shortcut to have special protocol links like skype:, mailto: or javascript:

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we could use a (pseudo) full link syntax instead?

user   [[wiki:user:{NAME}]]

But users would expect these to work too then:

user   [[wiki:user:{NAME}|Profile for {name}]]
user   [[wiki:user:{NAME}|{{some:img.png|Profile}}]]
user   [[wiki:user:{NAME}|{{http://example.com|some:img.png|Profile}}]]

which doesn't really make sense. Maybe we can do something like in mime.conf and prefix things that should be resolved as page name with a !

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FS#2713 suggests using _shortcut or .shortcut for internal links, you added !shortcut as well.

Which variant do we like?

google.de http://www.google.de/search?q=
go http://www.google.com/search?q={URL}&amp;btnI=lucky
user :wiki:users:{NAME}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would use singular here, so :wiki:user:{NAME}.
Also not sure if the wiki namespace is a good and/or essential place for it. :user:{NAME} would be easiest and is more universal.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agreed. :user:{NAME} seems to be a good default.


# To support VoIP/SIP links
callto callto://{NAME}
Expand Down
132 changes: 108 additions & 24 deletions inc/common.php
Expand Up @@ -1418,34 +1418,118 @@ function shorten($keep, $short, $max, $min = 9, $char = '…') {
* @author Andy Webber <dokuwiki AT andywebber DOT com>
*/
function editorinfo($username) {
global $conf;
return userinfo($username);
}

/**
* Returns users realname w/o link
*
* @param string|bool $username or false when currently logged-in user should be used
* @return string html of formatted user name
*
* @triggers COMMON_USER_LINK
*/
function userinfo($username = null) {
global $conf, $INFO;
/** @var DokuWiki_Auth_Plugin $auth */
global $auth;

switch($conf['showuseras']) {
case 'username':
case 'email':
case 'email_link':
if($auth) $info = $auth->getUserData($username);
break;
default:
return hsc($username);
}

if(isset($info) && $info) {
switch($conf['showuseras']) {
case 'username':
return hsc($info['name']);
case 'email':
return obfuscate($info['mail']);
case 'email_link':
$mail = obfuscate($info['mail']);
return '<a href="mailto:'.$mail.'">'.$mail.'</a>';
default:
return hsc($username);
// prepare initial event data
$data = array(
'username' => $username, // the unique user name
'name' => '',
'link' => array( //setting 'link' to false disables linking
'target' => '',
'pre' => '',
'suf' => '',
'style' => '',
'more' => '',
'url' => '',
'title' => '',
'class' => ''
),
'userinfo' => ''
);
if($username === null) {
$data['username'] = $username = $_SERVER['REMOTE_USER'];
$data['name'] = '<bdi>' . hsc($INFO['userinfo']['name']) . '</bdi> (<bdi>' . hsc($_SERVER['REMOTE_USER']) . '</bdi>)';
}

$evt = new Doku_Event('COMMON_USER_LINK', $data);
if($evt->advise_before(true)) {
if(empty($data['name'])) {
if($conf['showuseras'] == 'loginname') {
$data['name'] = hsc($data['username']);
} else {
if($auth) $info = $auth->getUserData($username);
if(isset($info) && $info) {
switch($conf['showuseras']) {
case 'username':
case 'username_link':
$data['name'] = hsc($info['name']);
break;
case 'email':
case 'email_link':
$data['name'] = obfuscate($info['mail']);
break;
}
}
}
}

/** @var Doku_Renderer_xhtml $xhtml_renderer */
static $xhtml_renderer = null;

if($data['link'] !== false && empty($data['link']['url'])) {

if(in_array($conf['showuseras'], array('email_link', 'username_link'))) {
if(!isset($info)) {
if($auth) $info = $auth->getUserData($username);
}
if(isset($info) && $info) {
if($conf['showuseras'] == 'email_link') {
$data['link']['url'] = 'mailto:' . obfuscate($info['mail']);
} else {
if(is_null($xhtml_renderer)) {
$xhtml_renderer = p_get_renderer('xhtml');
}
if(empty($xhtml_renderer->interwiki)) {
$xhtml_renderer->interwiki = getInterwiki();
}
$shortcut = 'user';
$data['link']['url'] = $xhtml_renderer->_resolveInterWiki($shortcut, $username, $exists);
if($exists !== null) {
if($exists) {
$data['link']['class'] .= ' wikilink1';
} else {
$data['link']['class'] .= ' wikilink2';
$data['link']['rel'] = 'nofollow';
}
}
}
} else {
$data['link'] = false;
}

} else {
$data['link'] = false;
}
}

if($data['link'] === false) {
$data['userinfo'] = $data['name'];
} else {
$data['link']['name'] = $data['name'];
if(is_null($xhtml_renderer)) {
$xhtml_renderer = p_get_renderer('xhtml');
}
$data['userinfo'] = $xhtml_renderer->_formatLink($data['link']);
}
} else {
return hsc($username);
}
$evt->advise_after();
unset($evt);

return $data['userinfo'];
}

/**
Expand Down
46 changes: 26 additions & 20 deletions inc/parser/renderer.php
Expand Up @@ -273,17 +273,17 @@ function tablecell_close(){}
*
* @author Andreas Gohr <andi@splitbrain.org>
*/
function _simpleTitle($name){
function _simpleTitle($name) {
global $conf;

//if there is a hash we use the ancor name only
list($name,$hash) = explode('#',$name,2);
list($name, $hash) = explode('#', $name, 2);
if($hash) return $hash;

if($conf['useslash']){
$name = strtr($name,';/',';:');
}else{
$name = strtr($name,';',':');
if($conf['useslash']) {
$name = strtr($name, ';/', ';:');
} else {
$name = strtr($name, ';', ':');
}

return noNSorNS($name);
Expand All @@ -292,9 +292,9 @@ function _simpleTitle($name){
/**
* Resolve an interwikilink
*/
function _resolveInterWiki(&$shortcut,$reference){
function _resolveInterWiki(&$shortcut, $reference, &$exists=null) {
//get interwiki URL
if ( isset($this->interwiki[$shortcut]) ) {
if(isset($this->interwiki[$shortcut])) {
$url = $this->interwiki[$shortcut];
} else {
// Default to Google I'm feeling lucky
Expand All @@ -303,25 +303,31 @@ function _resolveInterWiki(&$shortcut,$reference){
}

//split into hash and url part
list($reference,$hash) = explode('#',$reference,2);
list($reference, $hash) = explode('#', $reference, 2);

//replace placeholder
if(preg_match('#\{(URL|NAME|SCHEME|HOST|PORT|PATH|QUERY)\}#',$url)){
if(preg_match('#\{(URL|NAME|SCHEME|HOST|PORT|PATH|QUERY)\}#', $url)) {
//use placeholders
$url = str_replace('{URL}',rawurlencode($reference),$url);
$url = str_replace('{NAME}',$reference,$url);
$url = str_replace('{URL}', rawurlencode($reference), $url);
$url = str_replace('{NAME}', $reference, $url);
$parsed = parse_url($reference);
if(!$parsed['port']) $parsed['port'] = 80;
$url = str_replace('{SCHEME}',$parsed['scheme'],$url);
$url = str_replace('{HOST}',$parsed['host'],$url);
$url = str_replace('{PORT}',$parsed['port'],$url);
$url = str_replace('{PATH}',$parsed['path'],$url);
$url = str_replace('{QUERY}',$parsed['query'],$url);
}else{
$url = str_replace('{SCHEME}', $parsed['scheme'], $url);
$url = str_replace('{HOST}', $parsed['host'], $url);
$url = str_replace('{PORT}', $parsed['port'], $url);
$url = str_replace('{PATH}', $parsed['path'], $url);
$url = str_replace('{QUERY}', $parsed['query'], $url);
} else {
//default
$url = $url.rawurlencode($reference);
$url = $url . rawurlencode($reference);
}
//handle as wiki links
if($url{0} === ':') {
list($id, $urlparam) = explode('?', $url, 2);
$url = wl(cleanID($id), $urlparam);
$exists = page_exists($id);
}
if($hash) $url .= '#'.rawurlencode($hash);
if($hash) $url .= '#' . rawurlencode($hash);

return $url;
}
Expand Down
19 changes: 14 additions & 5 deletions inc/parser/xhtml.php
Expand Up @@ -685,7 +685,7 @@ function externallink($url, $name = null) {
}

/**
*/
*/
function interwikilink($match, $name = null, $wikiName, $wikiUri) {
global $conf;

Expand All @@ -697,19 +697,28 @@ function interwikilink($match, $name = null, $wikiName, $wikiUri) {
$link['name'] = $this->_getLinkTitle($name, $wikiUri, $isImage);

//get interwiki URL
$url = $this->_resolveInterWiki($wikiName,$wikiUri);
$exists = null;
$url = $this->_resolveInterWiki($wikiName, $wikiUri, $exists);

if ( !$isImage ) {
$class = preg_replace('/[^_\-a-z0-9]+/i','_',$wikiName);
if(!$isImage) {
$class = preg_replace('/[^_\-a-z0-9]+/i', '_', $wikiName);
$link['class'] = "interwiki iw_$class";
} else {
$link['class'] = 'media';
}

//do we stay at the same server? Use local target
if( strpos($url,DOKU_URL) === 0 ){
if(strpos($url, DOKU_URL) === 0 OR strpos($url, DOKU_BASE) === 0) {
$link['target'] = $conf['target']['wiki'];
}
if($exists !== null && !$isImage) {
if($exists) {
$link['class'] .= ' wikilink1';
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It makes sense to add the same interwiki iw_$class classes here, so we can add some styling. In this case a little user icon makes sense.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a icon. This user.png is of famfamfam image set.
In the header this colored image is used as well, while other icons in the header are gray...
How to handle this? Reuse the profile image of the 'edit profile' link (via css, only for user interwikilinks in the header)?

} else {
$link['class'] .= ' wikilink2';
$link['rel'] = 'nofollow';
}
}

$link['url'] = $url;
$link['title'] = htmlspecialchars($link['url']);
Expand Down
3 changes: 1 addition & 2 deletions inc/template.php
Expand Up @@ -885,9 +885,8 @@ function tpl_youarehere($sep = ' » ') {
*/
function tpl_userinfo() {
global $lang;
global $INFO;
if(isset($_SERVER['REMOTE_USER'])) {
print $lang['loggedinas'].': <bdi>'.hsc($INFO['userinfo']['name']).'</bdi> (<bdi>'.hsc($_SERVER['REMOTE_USER']).'</bdi>)';
print $lang['loggedinas'].': '.userinfo();
return true;
}
return false;
Expand Down
9 changes: 5 additions & 4 deletions lib/plugins/config/lang/en/lang.php
Expand Up @@ -245,10 +245,11 @@
$lang['xsendfile_o_3'] = 'Proprietary Nginx X-Accel-Redirect header';

/* Display user info */
$lang['showuseras_o_loginname'] = 'Login name';
$lang['showuseras_o_username'] = "User's full name";
$lang['showuseras_o_email'] = "User's e-mail addresss (obfuscated according to mailguard setting)";
$lang['showuseras_o_email_link'] = "User's e-mail addresss as a mailto: link";
$lang['showuseras_o_loginname'] = 'Login name';
$lang['showuseras_o_username'] = "User's full name";
$lang['showuseras_o_username_link'] = "User's full name as interwiki user link";
$lang['showuseras_o_email'] = "User's e-mail addresss (obfuscated according to mailguard setting)";
$lang['showuseras_o_email_link'] = "User's e-mail addresss as a mailto: link";

/* useheading options */
$lang['useheading_o_0'] = 'Never';
Expand Down
2 changes: 1 addition & 1 deletion lib/plugins/config/settings/config.metadata.php
Expand Up @@ -116,7 +116,7 @@
$meta['typography'] = array('multichoice','_choices' => array(0,1,2));
$meta['dformat'] = array('string');
$meta['signature'] = array('string');
$meta['showuseras'] = array('multichoice','_choices' => array('loginname','username','email','email_link'));
$meta['showuseras'] = array('multichoice','_choices' => array('loginname','username','username_link','email','email_link'));
$meta['toptoclevel'] = array('multichoice','_choices' => array(1,2,3,4,5)); // 5 toc levels
$meta['tocminheads'] = array('multichoice','_choices' => array(0,1,2,3,4,5,10,15,20));
$meta['maxtoclevel'] = array('multichoice','_choices' => array(0,1,2,3,4,5));
Expand Down