more refactor tags/mentions
This commit is contained in:
parent
356c7003f2
commit
d9759ba63c
@ -533,7 +533,7 @@ class Item extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
// Look for tags and linkify them
|
// Look for tags and linkify them
|
||||||
$results = linkify_tags($a, $body, ($uid) ? $uid : $profile_uid);
|
$results = linkify_tags($a, $body, ($uid) ? $uid : $profile_uid);
|
||||||
|
logger('linkify: ' . print_r($results,true));
|
||||||
if($results) {
|
if($results) {
|
||||||
|
|
||||||
// Set permissions based on tag replacements
|
// Set permissions based on tag replacements
|
||||||
|
113
include/text.php
113
include/text.php
@ -824,7 +824,7 @@ function get_tags($s) {
|
|||||||
|
|
||||||
// match bracket mentions
|
// match bracket mentions
|
||||||
|
|
||||||
if(preg_match_all('/([@!]\{.*?\})/',$s,$match)) {
|
if(preg_match_all('/([@!]\!?\{.*?\})/',$s,$match)) {
|
||||||
foreach($match[1] as $mtch) {
|
foreach($match[1] as $mtch) {
|
||||||
$ret[] = $mtch;
|
$ret[] = $mtch;
|
||||||
}
|
}
|
||||||
@ -833,12 +833,19 @@ function get_tags($s) {
|
|||||||
// Pull out single word tags. These can be @nickname, @first_last
|
// Pull out single word tags. These can be @nickname, @first_last
|
||||||
// and #hash tags.
|
// and #hash tags.
|
||||||
|
|
||||||
if(preg_match_all('/(?<![a-zA-Z0-9=\pL\/\?\;])([@#\!][^ \x0D\x0A,;:\?\[\{\&]+)/u',$s,$match)) {
|
if(preg_match_all('/(?<![a-zA-Z0-9=\pL\/\?\;])([@#\!]\!?[^ \x0D\x0A,;:\?\[\{\&]+)/u',$s,$match)) {
|
||||||
foreach($match[1] as $mtch) {
|
foreach($match[1] as $mtch) {
|
||||||
|
|
||||||
|
// Cleanup/ignore false positives
|
||||||
|
|
||||||
|
// Just ignore these rather than try and adjust the regex to deal with them
|
||||||
|
if(in_array($mtch,[ '@!', '!!' ]))
|
||||||
|
continue;
|
||||||
|
// likewise for trailing period. Strip it off rather than complicate the regex further.
|
||||||
if(substr($mtch,-1,1) === '.')
|
if(substr($mtch,-1,1) === '.')
|
||||||
$mtch = substr($mtch,0,-1);
|
$mtch = substr($mtch,0,-1);
|
||||||
// ignore strictly numeric tags like #1 or #^ bookmarks or ## double hash
|
// ignore strictly numeric tags like #1 or #^ bookmarks or ## double hash
|
||||||
if((strpos($mtch,'#') === 0) && ( ctype_digit(substr($mtch,1)) || substr($mtch,1,1) === '^') || substr($mtch,1,1) === '#')
|
if((strpos($mtch,'#') === 0) && ( ctype_digit(substr($mtch,1)) || in_array(substr($mtch,1,1), [ '^', '#' ])))
|
||||||
continue;
|
continue;
|
||||||
// or quote remnants from the quoted strings we already picked out earlier
|
// or quote remnants from the quoted strings we already picked out earlier
|
||||||
if(strpos($mtch,'"'))
|
if(strpos($mtch,'"'))
|
||||||
@ -863,7 +870,7 @@ function get_tags($s) {
|
|||||||
|
|
||||||
usort($ret,'tag_sort_length');
|
usort($ret,'tag_sort_length');
|
||||||
|
|
||||||
// logger('get_tags: ' . print_r($ret,true));
|
// logger('get_tags: ' . print_r($ret,true));
|
||||||
|
|
||||||
return $ret;
|
return $ret;
|
||||||
}
|
}
|
||||||
@ -2537,9 +2544,10 @@ function handle_tag($a, &$body, &$access_tag, &$str_tags, $profile_uid, $tag, $i
|
|||||||
$termtype = ((strpos($tag,'!') === 0) ? TERM_FORUM : $termtype);
|
$termtype = ((strpos($tag,'!') === 0) ? TERM_FORUM : $termtype);
|
||||||
$termtype = ((strpos($tag,'#^[') === 0) ? TERM_BOOKMARK : $termtype);
|
$termtype = ((strpos($tag,'#^[') === 0) ? TERM_BOOKMARK : $termtype);
|
||||||
|
|
||||||
//is it a hash tag?
|
// Is it a hashtag of some kind?
|
||||||
if(strpos($tag,'#') === 0) {
|
|
||||||
if(strpos($tag,'#^[') === 0) {
|
if ( in_array($termtype, [ TERM_HASHTAG, TERM_BOOKMARK ] )) {
|
||||||
|
if($termtype === TERM_BOOKMARK) {
|
||||||
if(preg_match('/#\^\[(url|zrl)(.*?)\](.*?)\[\/(url|zrl)\]/',$tag,$match)) {
|
if(preg_match('/#\^\[(url|zrl)(.*?)\](.*?)\[\/(url|zrl)\]/',$tag,$match)) {
|
||||||
$basetag = $match[3];
|
$basetag = $match[3];
|
||||||
$url = ((substr($match[2],0,1) === '=') ? substr($match[2],1) : $match[3]);
|
$url = ((substr($match[2],0,1) === '=') ? substr($match[2],1) : $match[3]);
|
||||||
@ -2548,12 +2556,13 @@ function handle_tag($a, &$body, &$access_tag, &$str_tags, $profile_uid, $tag, $i
|
|||||||
}
|
}
|
||||||
// if the tag is already replaced...
|
// if the tag is already replaced...
|
||||||
elseif((strpos($tag,'[zrl=')) || (strpos($tag,'[url='))) {
|
elseif((strpos($tag,'[zrl=')) || (strpos($tag,'[url='))) {
|
||||||
//...do nothing
|
// ...do nothing
|
||||||
return $replaced;
|
return $replaced;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(! $replaced) {
|
if(! $replaced) {
|
||||||
|
|
||||||
// base tag has the tags name only
|
// double-quoted hashtags: base tag has the htmlentity name only
|
||||||
|
|
||||||
if((substr($tag,0,7) === '#"') && (substr($tag,-6,6) === '"')) {
|
if((substr($tag,0,7) === '#"') && (substr($tag,-6,6) === '"')) {
|
||||||
$basetag = substr($tag,7);
|
$basetag = substr($tag,7);
|
||||||
@ -2562,21 +2571,20 @@ function handle_tag($a, &$body, &$access_tag, &$str_tags, $profile_uid, $tag, $i
|
|||||||
else
|
else
|
||||||
$basetag = substr($tag,1);
|
$basetag = substr($tag,1);
|
||||||
|
|
||||||
//create text for link
|
// create text for link
|
||||||
|
|
||||||
$url = z_root() . '/search?tag=' . rawurlencode($basetag);
|
$url = z_root() . '/search?tag=' . rawurlencode($basetag);
|
||||||
$newtag = '#[zrl=' . z_root() . '/search?tag=' . rawurlencode($basetag) . ']' . $basetag . '[/zrl]';
|
$newtag = '#[zrl=' . z_root() . '/search?tag=' . rawurlencode($basetag) . ']' . $basetag . '[/zrl]';
|
||||||
|
|
||||||
//replace tag by the link. Make sure to not replace something in the middle of a word
|
// replace tag by the link. Make sure to not replace something in the middle of a word
|
||||||
// The '=' is needed to not replace color codes if the code is also used as a tag
|
|
||||||
// Much better would be to somehow completely avoiding things in e.g. [color]-tags.
|
|
||||||
// This would allow writing things like "my favourite tag=#foobar".
|
|
||||||
$body = preg_replace('/(?<![a-zA-Z0-9=])'.preg_quote($tag,'/').'/', $newtag, $body);
|
$body = preg_replace('/(?<![a-zA-Z0-9=])'.preg_quote($tag,'/').'/', $newtag, $body);
|
||||||
$replaced = true;
|
$replaced = true;
|
||||||
}
|
}
|
||||||
//is the link already in str_tags?
|
|
||||||
|
// is the link already in str_tags?
|
||||||
if(! stristr($str_tags,$newtag)) {
|
if(! stristr($str_tags,$newtag)) {
|
||||||
//append or set str_tags
|
// append or set str_tags
|
||||||
if(strlen($str_tags))
|
if(strlen($str_tags))
|
||||||
$str_tags .= ',';
|
$str_tags .= ',';
|
||||||
|
|
||||||
@ -2587,43 +2595,38 @@ function handle_tag($a, &$body, &$access_tag, &$str_tags, $profile_uid, $tag, $i
|
|||||||
'termtype' => $termtype,
|
'termtype' => $termtype,
|
||||||
'term' => $basetag,
|
'term' => $basetag,
|
||||||
'url' => $url,
|
'url' => $url,
|
||||||
'contact' => $r[0]
|
'contact' => []
|
||||||
];
|
];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//is it a person tag?
|
// END hashtags
|
||||||
|
|
||||||
$grouptag = false;
|
// BEGIN mentions
|
||||||
|
|
||||||
if(strpos($tag,'!') === 0) {
|
if ( in_array($termtype, [ TERM_MENTION, TERM_FORUM ] )) {
|
||||||
$grouptag = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(strpos($tag,'@') === 0 || $grouptag) {
|
// The @! tag and !! tag will alter permissions
|
||||||
|
|
||||||
// The @! tag will alter permissions
|
// $in_network is set to false to avoid false positives on posts originating
|
||||||
$exclusive = (((! $grouptag) && (strpos($tag,'!') === 1) && $in_network) ? true : false);
|
// on a network which does not implement privacy tags or implements them differently.
|
||||||
if(($grouptag) && (strpos($tag,'!!') === 0)) {
|
|
||||||
$exclusive = true;
|
$exclusive = (((strpos($tag,'!') === 1) && $in_network) ? true : false);
|
||||||
}
|
|
||||||
|
|
||||||
//is it already replaced?
|
//is it already replaced?
|
||||||
if(strpos($tag,'[zrl=') || strpos($tag,'[url='))
|
if(strpos($tag,'[zrl=') || strpos($tag,'[url='))
|
||||||
return $replaced;
|
return $replaced;
|
||||||
|
|
||||||
//get the person's name
|
// get the channel name
|
||||||
|
// First extract the name or name fragment we are going to replace
|
||||||
|
|
||||||
$name = substr($tag,(($exclusive) ? 2 : 1)); // The name or name fragment we are going to replace
|
$name = substr($tag,(($exclusive) ? 2 : 1));
|
||||||
$newname = $name; // a copy that we can mess with
|
$newname = $name; // make a copy that we can mess with
|
||||||
$tagcid = 0;
|
$tagcid = 0;
|
||||||
|
|
||||||
$r = null;
|
$r = null;
|
||||||
|
|
||||||
// is it some generated name?
|
// is it some generated (autocompleted) name?
|
||||||
|
|
||||||
$forum = false;
|
|
||||||
$trailing_plus_name = false;
|
|
||||||
|
|
||||||
if(substr($name,0,1) === '{' && substr($name,-1,1) === '}') {
|
if(substr($name,0,1) === '{' && substr($name,-1,1) === '}') {
|
||||||
$newname = substr($name,1);
|
$newname = substr($name,1);
|
||||||
@ -2639,15 +2642,17 @@ function handle_tag($a, &$body, &$access_tag, &$str_tags, $profile_uid, $tag, $i
|
|||||||
|
|
||||||
// look for matching names in the address book
|
// look for matching names in the address book
|
||||||
|
|
||||||
// Two ways to deal with spaces - double quote the name or use underscores
|
// Double quote the entire mentioned term to include special characters
|
||||||
// we see this after input filtering so quotes have been html entity encoded
|
// such as spaces and some punctuation.
|
||||||
|
|
||||||
|
// We see this after input filtering so quotes have been html entity encoded
|
||||||
|
|
||||||
if((substr($name,0,6) === '"') && (substr($name,-6,6) === '"')) {
|
if((substr($name,0,6) === '"') && (substr($name,-6,6) === '"')) {
|
||||||
$newname = substr($name,6);
|
$newname = substr($name,6);
|
||||||
$newname = substr($newname,0,-6);
|
$newname = substr($newname,0,-6);
|
||||||
}
|
}
|
||||||
|
|
||||||
//select someone from this user's contacts by name
|
// select someone from this user's contacts by name
|
||||||
|
|
||||||
$r = q("SELECT * FROM abook left join xchan on abook_xchan = xchan_hash
|
$r = q("SELECT * FROM abook left join xchan on abook_xchan = xchan_hash
|
||||||
WHERE xchan_name = '%s' AND abook_channel = %d LIMIT 1",
|
WHERE xchan_name = '%s' AND abook_channel = %d LIMIT 1",
|
||||||
@ -2664,7 +2669,7 @@ function handle_tag($a, &$body, &$access_tag, &$str_tags, $profile_uid, $tag, $i
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
//select someone by attag or nick and the name passed in
|
// select someone by attag or nick and the name passed in
|
||||||
|
|
||||||
if(! $r) {
|
if(! $r) {
|
||||||
$r = q("SELECT * FROM abook left join xchan on abook_xchan = xchan_hash
|
$r = q("SELECT * FROM abook left join xchan on abook_xchan = xchan_hash
|
||||||
@ -2679,7 +2684,7 @@ function handle_tag($a, &$body, &$access_tag, &$str_tags, $profile_uid, $tag, $i
|
|||||||
// $r is set if we found something
|
// $r is set if we found something
|
||||||
|
|
||||||
$channel = App::get_channel();
|
$channel = App::get_channel();
|
||||||
|
|
||||||
if($r) {
|
if($r) {
|
||||||
$profile = $r[0]['xchan_url'];
|
$profile = $r[0]['xchan_url'];
|
||||||
$newname = $r[0]['xchan_name'];
|
$newname = $r[0]['xchan_name'];
|
||||||
@ -2717,23 +2722,24 @@ function handle_tag($a, &$body, &$access_tag, &$str_tags, $profile_uid, $tag, $i
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if there is an url for this channel
|
// if there is a url for this channel
|
||||||
|
|
||||||
if(isset($profile)) {
|
if(isset($profile)) {
|
||||||
$replaced = true;
|
$replaced = true;
|
||||||
//create profile link
|
//create profile link
|
||||||
$profile = str_replace(',','%2c',$profile);
|
$profile = str_replace(',','%2c',$profile);
|
||||||
$url = $profile;
|
$url = $profile;
|
||||||
if($grouptag) {
|
if($termtype === TERM_FORUM) {
|
||||||
$newtag = '!' . (($exclusive) ? '!' : '') . '[zrl=' . $profile . ']' . $newname . '[/zrl]';
|
$newtag = '!' . (($exclusive) ? '!' : '') . '[zrl=' . $profile . ']' . $newname . '[/zrl]';
|
||||||
$body = str_replace('!' . (($exclusive) ? '!' : '') . $name, $newtag, $body);
|
$body = str_replace('!' . (($exclusive) ? '!' : '') . $name, $newtag, $body);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
// ( $termtype === TERM_MENTION )
|
||||||
$newtag = '@' . (($exclusive) ? '!' : '') . '[zrl=' . $profile . ']' . $newname . '[/zrl]';
|
$newtag = '@' . (($exclusive) ? '!' : '') . '[zrl=' . $profile . ']' . $newname . '[/zrl]';
|
||||||
$body = str_replace('@' . (($exclusive) ? '!' : '') . $name, $newtag, $body);
|
$body = str_replace('@' . (($exclusive) ? '!' : '') . $name, $newtag, $body);
|
||||||
}
|
}
|
||||||
|
|
||||||
//append tag to str_tags
|
// append tag to str_tags
|
||||||
if(! stristr($str_tags,$newtag)) {
|
if(! stristr($str_tags,$newtag)) {
|
||||||
if(strlen($str_tags))
|
if(strlen($str_tags))
|
||||||
$str_tags .= ',';
|
$str_tags .= ',';
|
||||||
@ -2747,14 +2753,14 @@ function handle_tag($a, &$body, &$access_tag, &$str_tags, $profile_uid, $tag, $i
|
|||||||
'termtype' => $termtype,
|
'termtype' => $termtype,
|
||||||
'term' => $newname,
|
'term' => $newname,
|
||||||
'url' => $url,
|
'url' => $url,
|
||||||
'contact' => $r[0]
|
'contact' => (($r) ? $r[0] : [])
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
function linkify_tags($a, &$body, $uid, $in_network = true) {
|
function linkify_tags($a, &$body, $uid, $in_network = true) {
|
||||||
$str_tags = '';
|
$str_tags = EMPTY_STR;
|
||||||
$tagged = array();
|
$tagged = [];
|
||||||
$results = array();
|
$results = [];
|
||||||
|
|
||||||
$tags = get_tags($body);
|
$tags = get_tags($body);
|
||||||
|
|
||||||
@ -2762,19 +2768,6 @@ function linkify_tags($a, &$body, $uid, $in_network = true) {
|
|||||||
foreach($tags as $tag) {
|
foreach($tags as $tag) {
|
||||||
$access_tag = '';
|
$access_tag = '';
|
||||||
|
|
||||||
// If we already tagged 'Robert Johnson', don't try and tag 'Robert'.
|
|
||||||
// Robert Johnson should be first in the $tags array
|
|
||||||
|
|
||||||
$fullnametagged = false;
|
|
||||||
for($x = 0; $x < count($tagged); $x ++) {
|
|
||||||
if(stristr($tagged[$x],$tag . ' ')) {
|
|
||||||
$fullnametagged = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if($fullnametagged)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
$success = handle_tag($a, $body, $access_tag, $str_tags, ($uid) ? $uid : App::$profile_uid , $tag, $in_network);
|
$success = handle_tag($a, $body, $access_tag, $str_tags, ($uid) ? $uid : App::$profile_uid , $tag, $in_network);
|
||||||
|
|
||||||
$results[] = array('success' => $success, 'access_tag' => $access_tag);
|
$results[] = array('success' => $success, 'access_tag' => $access_tag);
|
||||||
|
Reference in New Issue
Block a user