2013-01-11 01:20:16 +01:00
< ? php
2017-04-30 06:07:00 +02:00
use Friendica\App ;
2017-08-26 08:04:21 +02:00
use Friendica\Core\System ;
2017-11-22 21:29:07 +01:00
use Friendica\Database\DBM ;
use Friendica\Object\Contact ;
2017-04-30 06:07:00 +02:00
2015-02-09 23:04:18 +01:00
function create_tags_from_item ( $itemid ) {
2017-08-26 09:32:10 +02:00
$profile_base = System :: baseUrl ();
2013-01-13 14:50:55 +01:00
$profile_data = parse_url ( $profile_base );
$profile_base_friendica = $profile_data [ 'host' ] . $profile_data [ 'path' ] . " /profile/ " ;
$profile_base_diaspora = $profile_data [ 'host' ] . $profile_data [ 'path' ] . " /u/ " ;
2015-03-07 21:24:39 +01:00
$messages = q ( " SELECT `guid`, `uid`, `id`, `edited`, `deleted`, `created`, `received`, `title`, `body`, `tag`, `parent` FROM `item` WHERE `id` = %d LIMIT 1 " , intval ( $itemid ));
2013-01-11 01:20:16 +01:00
if ( ! $messages )
return ;
$message = $messages [ 0 ];
// Clean up all tags
2013-01-13 14:50:55 +01:00
q ( " DELETE FROM `term` WHERE `otype` = %d AND `oid` = %d AND `type` IN (%d, %d) " ,
intval ( TERM_OBJ_POST ),
intval ( $itemid ),
intval ( TERM_HASHTAG ),
intval ( TERM_MENTION ));
2013-01-11 01:20:16 +01:00
if ( $message [ " deleted " ])
return ;
$taglist = explode ( " , " , $message [ " tag " ]);
$tags = " " ;
foreach ( $taglist as $tag )
2017-06-08 04:00:59 +02:00
if (( substr ( trim ( $tag ), 0 , 1 ) == " # " ) || ( substr ( trim ( $tag ), 0 , 1 ) == " @ " ))
2013-01-11 01:20:16 +01:00
$tags .= " " . trim ( $tag );
else
$tags .= " # " . trim ( $tag );
$data = " " . $message [ " title " ] . " " . $message [ " body " ] . " " . $tags . " " ;
2015-03-22 17:12:51 +01:00
// ignore anything in a code block
$data = preg_replace ( '/\[code\](.*?)\[\/code\]/sm' , '' , $data );
2013-01-11 01:20:16 +01:00
$tags = array ();
$pattern = " / \ W \ #([^ \ [].*?)[ \ s' \" .,:; \ ?! \ [ \ ] \ /]/ism " ;
if ( preg_match_all ( $pattern , $data , $matches ))
foreach ( $matches [ 1 ] as $match )
2017-08-19 00:12:40 +02:00
$tags [ " # " . strtolower ( $match )] = " " ;
2013-01-11 01:20:16 +01:00
$pattern = " / \ W([ \ #@]) \ [url \ =(.*?) \ ](.*?) \ [ \ /url \ ]/ism " ;
if ( preg_match_all ( $pattern , $data , $matches , PREG_SET_ORDER )) {
foreach ( $matches as $match )
$tags [ $match [ 1 ] . strtolower ( trim ( $match [ 3 ], ',.:;[]/\"?!' ))] = $match [ 2 ];
}
2013-01-13 14:50:55 +01:00
foreach ( $tags as $tag => $link ) {
if ( substr ( trim ( $tag ), 0 , 1 ) == " # " ) {
2013-06-26 13:58:54 +02:00
// try to ignore #039 or #1 or anything like that
2017-04-04 19:48:25 +02:00
if ( ctype_digit ( substr ( trim ( $tag ), 1 )))
2013-06-26 13:58:54 +02:00
continue ;
// try to ignore html hex escapes, e.g. #x2317
2017-04-04 19:48:25 +02:00
if (( substr ( trim ( $tag ), 1 , 1 ) == 'x' || substr ( trim ( $tag ), 1 , 1 ) == 'X' ) && ctype_digit ( substr ( trim ( $tag ), 2 )))
2013-06-21 14:00:30 +02:00
continue ;
2013-01-13 14:50:55 +01:00
$type = TERM_HASHTAG ;
$term = substr ( $tag , 1 );
} elseif ( substr ( trim ( $tag ), 0 , 1 ) == " @ " ) {
$type = TERM_MENTION ;
$term = substr ( $tag , 1 );
} else { // This shouldn't happen
$type = TERM_HASHTAG ;
2013-08-03 21:18:41 +02:00
$term = $tag ;
2013-01-13 14:50:55 +01:00
}
2015-03-08 03:27:14 +01:00
if ( $message [ " uid " ] == 0 ) {
$global = true ;
q ( " UPDATE `term` SET `global` = 1 WHERE `otype` = %d AND `guid` = '%s' " ,
intval ( TERM_OBJ_POST ), dbesc ( $message [ " guid " ]));
} else {
$isglobal = q ( " SELECT `global` FROM `term` WHERE `uid` = 0 AND `otype` = %d AND `guid` = '%s' " ,
intval ( TERM_OBJ_POST ), dbesc ( $message [ " guid " ]));
$global = ( count ( $isglobal ) > 0 );
}
$r = q ( " INSERT INTO `term` (`uid`, `oid`, `otype`, `type`, `term`, `url`, `guid`, `created`, `received`, `global`)
VALUES ( % d , % d , % d , % d , '%s' , '%s' , '%s' , '%s' , '%s' , % d ) " ,
intval ( $message [ " uid " ]), intval ( $itemid ), intval ( TERM_OBJ_POST ), intval ( $type ), dbesc ( $term ),
dbesc ( $link ), dbesc ( $message [ " guid " ]), dbesc ( $message [ " created " ]), dbesc ( $message [ " received " ]), intval ( $global ));
2013-01-13 14:50:55 +01:00
// Search for mentions
2017-06-08 04:00:59 +02:00
if (( substr ( $tag , 0 , 1 ) == '@' ) && ( strpos ( $link , $profile_base_friendica ) || strpos ( $link , $profile_base_diaspora ))) {
2013-01-13 14:50:55 +01:00
$users = q ( " SELECT `uid` FROM `contact` WHERE self AND (`url` = '%s' OR `nurl` = '%s') " , $link , $link );
foreach ( $users AS $user ) {
2014-03-09 09:19:14 +01:00
if ( $user [ " uid " ] == $message [ " uid " ]) {
2013-01-13 14:50:55 +01:00
q ( " UPDATE `item` SET `mention` = 1 WHERE `id` = %d " , intval ( $itemid ));
2014-03-09 09:19:14 +01:00
q ( " UPDATE `thread` SET `mention` = 1 WHERE `iid` = %d " , intval ( $message [ " parent " ]));
}
2013-01-13 14:50:55 +01:00
}
}
}
2013-01-11 01:20:16 +01:00
}
function create_tags_from_itemuri ( $itemuri , $uid ) {
$messages = q ( " SELECT `id` FROM `item` WHERE uri ='%s' AND uid=%d " , dbesc ( $itemuri ), intval ( $uid ));
2017-04-04 19:48:25 +02:00
if ( count ( $messages )) {
foreach ( $messages as $message ) {
2013-04-17 17:32:31 +02:00
create_tags_from_item ( $message [ " id " ]);
2017-04-04 19:48:25 +02:00
}
2013-04-17 17:32:31 +02:00
}
2013-01-11 01:20:16 +01:00
}
function update_items () {
2017-04-24 23:02:51 +02:00
$messages = dba :: p ( " SELECT `oid`,`item`.`guid`, `item`.`created`, `item`.`received` FROM `term` INNER JOIN `item` ON `item`.`id`=`term`.`oid` WHERE `term`.`otype` = 1 AND `term`.`guid` = '' " );
2015-03-07 21:24:39 +01:00
2017-04-24 23:02:51 +02:00
logger ( " fetched messages: " . dba :: num_rows ( $messages ));
while ( $message = dba :: fetch ( $messages )) {
2015-03-08 03:27:14 +01:00
if ( $message [ " uid " ] == 0 ) {
$global = true ;
q ( " UPDATE `term` SET `global` = 1 WHERE `otype` = %d AND `guid` = '%s' " ,
intval ( TERM_OBJ_POST ), dbesc ( $message [ " guid " ]));
} else {
$isglobal = q ( " SELECT `global` FROM `term` WHERE `uid` = 0 AND `otype` = %d AND `guid` = '%s' " ,
intval ( TERM_OBJ_POST ), dbesc ( $message [ " guid " ]));
$global = ( count ( $isglobal ) > 0 );
}
2015-03-09 00:45:53 +01:00
2015-03-08 03:27:14 +01:00
q ( " UPDATE `term` SET `guid` = '%s', `created` = '%s', `received` = '%s', `global` = %d WHERE `otype` = %d AND `oid` = %d " ,
2015-03-07 21:24:39 +01:00
dbesc ( $message [ " guid " ]), dbesc ( $message [ " created " ]), dbesc ( $message [ " received " ]),
2015-03-08 03:27:14 +01:00
intval ( $global ), intval ( TERM_OBJ_POST ), intval ( $message [ " oid " ]));
2015-03-07 21:24:39 +01:00
}
2017-04-24 23:02:51 +02:00
dba :: close ( $messages );
2015-03-09 00:45:53 +01:00
2017-04-24 23:02:51 +02:00
$messages = dba :: p ( " SELECT `guid` FROM `item` WHERE `uid` = 0 " );
2015-03-09 00:45:53 +01:00
2017-04-24 23:02:51 +02:00
logger ( " fetched messages: " . dba :: num_rows ( $messages ));
while ( $message = dba :: fetch ( messages )) {
2015-03-09 00:45:53 +01:00
q ( " UPDATE `item` SET `global` = 1 WHERE `guid` = '%s' " , dbesc ( $message [ " guid " ]));
}
2017-04-24 23:02:51 +02:00
dba :: close ( $messages );
2013-01-11 01:20:16 +01:00
}
2017-11-22 21:29:07 +01:00
2017-11-26 04:33:21 +01:00
/**
* @ brief Get alphabetical sorted array of used tags / terms of an user including
* a weighting by frequency of use .
*
* @ param int $uid The user ID .
* @ param int $count Max number of displayed tags / terms .
* @ param int $owner_id The contact id of the owner of the tagged items .
* @ param string $flags Special item flags .
* @ param int $type The tag / term type .
*
* @ return arr Alphabetical sorted array of used tags of an user .
*/
function tagadelic ( $uid , $count = 0 , $owner_id = 0 , $flags = '' , $type = TERM_HASHTAG ) {
2017-11-22 21:29:07 +01:00
require_once ( 'include/security.php' );
$item_condition = item_condition ();
$sql_options = item_permissions_sql ( $uid );
2017-11-26 16:14:16 +01:00
$limit = $count ? sprintf ( " LIMIT %d " , intval ( $count )) : " " ;
2017-11-22 21:29:07 +01:00
if ( $flags ) {
if ( $flags === 'wall' ) {
$sql_options .= " AND `item`.`wall` " ;
}
}
2017-11-22 23:18:01 +01:00
2017-11-23 00:59:20 +01:00
if ( $owner_id ) {
$sql_options .= " AND `item`.`owner-id` = " . intval ( $owner_id ) . " " ;
2017-11-22 21:29:07 +01:00
}
// Fetch tags
2017-11-26 16:14:16 +01:00
$r = dba :: p ( " SELECT `term`, COUNT(`term`) AS `total` FROM `term`
2017-11-22 21:29:07 +01:00
LEFT JOIN `item` ON `term` . `oid` = `item` . `id`
2017-11-26 16:14:16 +01:00
WHERE `term` . `uid` = ? AND `term` . `type` = ?
AND `term` . `otype` = ?
2017-11-23 03:43:39 +01:00
AND $item_condition $sql_options
2017-11-26 16:24:26 +01:00
GROUP BY `term` ORDER BY `total` DESC $limit " ,
2017-11-26 16:14:16 +01:00
$uid ,
$type ,
TERM_OBJ_POST
2017-11-22 21:29:07 +01:00
);
if ( ! DBM :: is_result ( $r )) {
return array ();
}
return tag_calc ( $r );
}
2017-11-26 04:33:21 +01:00
/**
* @ brief Construct a tag / term cloud block for an user .
*
* @ param int $uid The user ID .
* @ param int $count Max number of displayed tags / terms .
* @ param int $owner_id The contact ID of the owner of the tagged items .
* @ param string $flags Special item flags .
* @ param int $type The tag / term type .
*
* @ return string HTML formatted output .
*/
function wtagblock ( $uid , $count = 0 , $owner_id = 0 , $flags = '' , $type = TERM_HASHTAG ) {
2017-11-22 21:29:07 +01:00
$o = '' ;
2017-11-23 00:59:20 +01:00
$r = tagadelic ( $uid , $count , $owner_id , $flags , $type );
2017-11-26 04:33:21 +01:00
if ( count ( $r )) {
2017-11-23 00:59:20 +01:00
$contact = dba :: select (
" contact " ,
array ( " url " ),
2017-11-26 04:33:21 +01:00
array ( " id " => $uid ),
2017-11-23 00:59:20 +01:00
array ( " limit " => 1 )
);
$url = System :: removedBaseUrl ( $contact [ 'url' ]);
2017-11-22 21:29:07 +01:00
foreach ( $r as $rr ) {
$tag [ 'level' ] = $rr [ 2 ];
2017-11-23 00:59:20 +01:00
$tag [ 'url' ] = $url . " ?tag= " . urlencode ( $rr [ 0 ]);
2017-11-22 21:29:07 +01:00
$tag [ 'name' ] = $rr [ 0 ];
$tags [] = $tag ;
}
$tpl = get_markup_template ( " tagblock_widget.tpl " );
$o = replace_macros ( $tpl , array (
'$title' => t ( 'Tags' ),
'$tags' => $tags
));
}
return $o ;
}
2017-11-26 04:33:21 +01:00
/**
* @ brief Calculate weighting of tags according to the frequency of use .
*
* @ param array $arr Array of tags / terms with tag / term name and total count of use .
* @ return array Alphabetical sorted array of used tags / terms of an user .
*/
2017-11-22 21:29:07 +01:00
function tag_calc ( $arr ) {
$tags = array ();
$min = 1e9 ;
$max = - 1e9 ;
$x = 0 ;
if ( ! $arr ) {
return array ();
}
foreach ( $arr as $rr ) {
$tags [ $x ][ 0 ] = $rr [ 'term' ];
$tags [ $x ][ 1 ] = log ( $rr [ 'total' ]);
$tags [ $x ][ 2 ] = 0 ;
$min = min ( $min , $tags [ $x ][ 1 ]);
$max = max ( $max , $tags [ $x ][ 1 ]);
$x ++ ;
}
2017-11-22 23:18:01 +01:00
usort ( $tags , 'tags_sort' );
2017-11-22 21:29:07 +01:00
$range = max ( . 01 , $max - $min ) * 1.0001 ;
for ( $x = 0 ; $x < count ( $tags ); $x ++ ) {
$tags [ $x ][ 2 ] = 1 + floor ( 9 * ( $tags [ $x ][ 1 ] - $min ) / $range );
}
return $tags ;
}
2017-11-26 04:33:21 +01:00
/**
* @ brief Compare function to sort tags / terms alphabetically .
*
* @ param type $a
* @ param type $b
*
* @ return int
*/
function tags_sort ( $a , $b ) {
2017-11-22 21:29:07 +01:00
if ( strtolower ( $a [ 0 ]) == strtolower ( $b [ 0 ])) {
return 0 ;
}
2017-11-26 04:33:21 +01:00
return (( strtolower ( $a [ 0 ]) < strtolower ( $b [ 0 ])) ? - 1 : 1 );
2017-11-22 21:29:07 +01:00
}
2017-11-26 04:33:21 +01:00
/**
* @ brief Insert a tag cloud widget for the present profile .
*
* @ param int $limit Max number of displayed tags .
* @ return string HTML formattat output .
*/
function tagcloud_wall_widget ( $limit = 50 ) {
2017-11-22 21:29:07 +01:00
$a = get_app ();
if ( ! $a -> profile [ 'profile_uid' ] || ! $a -> profile [ 'url' ]) {
return " " ;
}
if ( feature_enabled ( $a -> profile [ 'profile_uid' ], 'tagadelic' )) {
$owner_id = Contact :: getIdForURL ( $a -> profile [ 'url' ]);
2017-11-22 23:18:01 +01:00
2017-11-22 21:29:07 +01:00
if ( ! $owner_id ) {
return " " ;
}
2017-11-22 23:18:01 +01:00
return wtagblock ( $a -> profile [ 'profile_uid' ], $limit , $owner_id , 'wall' );
2017-11-22 21:29:07 +01:00
}
return " " ;
}