2013-02-26 01:09:40 +00:00
< ? php /** @file */
2011-08-01 23:51:01 +00:00
require_once ( " include/template_processor.php " );
2014-07-14 06:00:03 +00:00
require_once ( " include/smarty.php " );
2011-08-01 23:51:01 +00:00
2013-05-08 07:51:38 +00:00
/**
* This is our template processor
*
* @ param string | FriendicaSmarty $s the string requiring macro substitution ,
* or an instance of FriendicaSmarty
* @ param array $r key value pairs ( search => replace )
* @ return string substituted string
*/
2011-08-01 23:51:01 +00:00
function replace_macros ( $s , $r ) {
2013-01-06 21:42:51 +00:00
$a = get_app ();
2013-11-29 03:17:20 +00:00
$arr = array ( 'template' => $s , 'params' => $r );
call_hooks ( 'replace_macros' , $arr );
2013-05-08 07:51:38 +00:00
$t = $a -> template_engine ();
2013-11-29 03:17:20 +00:00
$output = $t -> replace_macros ( $arr [ 'template' ], $arr [ 'params' ]);
2013-01-06 21:42:51 +00:00
return $output ;
2013-02-27 02:26:33 +00:00
}
2011-08-01 23:51:01 +00:00
2011-08-11 04:06:35 +00:00
// random string, there are 86 characters max in text mode, 128 for hex
// output is urlsafe
define ( 'RANDOM_STRING_HEX' , 0x00 );
define ( 'RANDOM_STRING_TEXT' , 0x01 );
2011-08-01 23:51:01 +00:00
2013-02-27 02:26:33 +00:00
2011-08-11 04:06:35 +00:00
function random_string ( $size = 64 , $type = RANDOM_STRING_HEX ) {
// generate a bit of entropy and run it through the whirlpool
$s = hash ( 'whirlpool' , ( string ) rand () . uniqid ( rand (), true ) . ( string ) rand (),(( $type == RANDOM_STRING_TEXT ) ? true : false ));
$s = (( $type == RANDOM_STRING_TEXT ) ? str_replace ( " \n " , " " , base64url_encode ( $s , true )) : $s );
return ( substr ( $s , 0 , $size ));
2013-02-27 02:26:33 +00:00
}
2011-08-01 23:51:01 +00:00
/**
* This is our primary input filter .
*
* The high bit hack only involved some old IE browser , forget which ( IE5 / Mac ? )
* that had an XSS attack vector due to stripping the high - bit on an 8 - bit character
* after cleansing , and angle chars with the high bit set could get through as markup .
*
* This is now disabled because it was interfering with some legitimate unicode sequences
* and hopefully there aren ' t a lot of those browsers left .
*
* Use this on any text input where angle chars are not valid or permitted
* They will be replaced with safer brackets . This may be filtered further
* if these are not allowed either .
*
2013-05-08 07:51:38 +00:00
* @ param string $string Input string
* @ return string Filtered string
2011-08-01 23:51:01 +00:00
*/
2013-02-27 02:26:33 +00:00
2011-08-01 23:51:01 +00:00
function notags ( $string ) {
return ( str_replace ( array ( " < " , " > " ), array ( '[' , ']' ), $string ));
// High-bit filter no longer used
// return(str_replace(array("<",">","\xBA","\xBC","\xBE"), array('[',']','','',''), $string));
2013-02-27 02:26:33 +00:00
}
2011-08-01 23:51:01 +00:00
// use this on "body" or "content" input where angle chars shouldn't be removed,
// and allow them to be safely displayed.
2013-02-27 02:26:33 +00:00
2013-05-08 07:51:38 +00:00
/**
* use this on " body " or " content " input where angle chars shouldn ' t be removed ,
* and allow them to be safely displayed .
* @ param string $string
* @ return string
*/
2011-08-01 23:51:01 +00:00
function escape_tags ( $string ) {
2012-12-07 00:12:45 +00:00
return ( htmlspecialchars ( $string , ENT_COMPAT , 'UTF-8' , false ));
2012-08-16 03:01:55 +00:00
2013-02-27 02:26:33 +00:00
}
2011-08-01 23:51:01 +00:00
2013-09-02 08:38:17 +00:00
function z_input_filter ( $channel_id , $s , $type = 'text/bbcode' ) {
if ( $type === 'text/bbcode' )
return escape_tags ( $s );
if ( $type === 'text/markdown' )
return escape_tags ( $s );
if ( $type == 'text/plain' )
return escape_tags ( $s );
$r = q ( " select account_id, account_roles from account left join channel on channel_account_id = account_id where channel_id = %d limit 1 " ,
intval ( $channel_id )
);
2013-09-02 23:01:29 +00:00
if ( $r && ( $r [ 0 ][ 'account_roles' ] & ACCOUNT_ROLE_ALLOWCODE )) {
2013-09-02 08:38:17 +00:00
if ( local_user () && ( get_account_id () == $r [ 0 ][ 'account_id' ])) {
return $s ;
}
}
if ( $type === 'text/html' )
return purify_html ( $s );
return escape_tags ( $s );
}
2013-05-28 08:40:27 +00:00
function purify_html ( $s ) {
require_once ( 'library/HTMLPurifier.auto.php' );
require_once ( 'include/html2bbcode.php' );
// FIXME this function has html output, not bbcode - so safely purify these
// $s = html2bb_video($s);
// $s = oembed_html2bbcode($s);
$config = HTMLPurifier_Config :: createDefault ();
$config -> set ( 'Cache.DefinitionImpl' , null );
2014-07-11 22:28:26 +00:00
$config -> set ( 'Attr.EnableID' , true );
2013-05-28 08:40:27 +00:00
$purifier = new HTMLPurifier ( $config );
return $purifier -> purify ( $s );
}
2013-12-05 05:10:03 +00:00
2011-08-01 23:51:01 +00:00
// generate a string that's random, but usually pronounceable.
// used to generate initial passwords
2013-02-27 02:26:33 +00:00
2013-05-08 07:51:38 +00:00
/**
* generate a string that ' s random , but usually pronounceable .
* used to generate initial passwords
* @ param int $len
* @ return string
*/
2011-08-01 23:51:01 +00:00
function autoname ( $len ) {
2012-04-07 08:04:45 +00:00
if ( $len <= 0 )
2012-04-06 01:44:36 +00:00
return '' ;
2011-08-01 23:51:01 +00:00
$vowels = array ( 'a' , 'a' , 'ai' , 'au' , 'e' , 'e' , 'e' , 'ee' , 'ea' , 'i' , 'ie' , 'o' , 'ou' , 'u' );
if ( mt_rand ( 0 , 5 ) == 4 )
$vowels [] = 'y' ;
$cons = array (
'b' , 'bl' , 'br' ,
'c' , 'ch' , 'cl' , 'cr' ,
'd' , 'dr' ,
'f' , 'fl' , 'fr' ,
'g' , 'gh' , 'gl' , 'gr' ,
'h' ,
'j' ,
'k' , 'kh' , 'kl' , 'kr' ,
'l' ,
'm' ,
'n' ,
'p' , 'ph' , 'pl' , 'pr' ,
'qu' ,
'r' , 'rh' ,
's' , 'sc' , 'sh' , 'sm' , 'sp' , 'st' ,
't' , 'th' , 'tr' ,
'v' ,
'w' , 'wh' ,
'x' ,
'z' , 'zh'
);
$midcons = array ( 'ck' , 'ct' , 'gn' , 'ld' , 'lf' , 'lm' , 'lt' , 'mb' , 'mm' , 'mn' , 'mp' ,
'nd' , 'ng' , 'nk' , 'nt' , 'rn' , 'rp' , 'rt' );
$noend = array ( 'bl' , 'br' , 'cl' , 'cr' , 'dr' , 'fl' , 'fr' , 'gl' , 'gr' ,
'kh' , 'kl' , 'kr' , 'mn' , 'pl' , 'pr' , 'rh' , 'tr' , 'qu' , 'wh' );
$start = mt_rand ( 0 , 2 );
if ( $start == 0 )
$table = $vowels ;
else
$table = $cons ;
$word = '' ;
for ( $x = 0 ; $x < $len ; $x ++ ) {
$r = mt_rand ( 0 , count ( $table ) - 1 );
$word .= $table [ $r ];
if ( $table == $vowels )
$table = array_merge ( $cons , $midcons );
else
$table = $vowels ;
}
$word = substr ( $word , 0 , $len );
foreach ( $noend as $noe ) {
if (( strlen ( $word ) > 2 ) && ( substr ( $word , - 2 ) == $noe )) {
$word = substr ( $word , 0 , - 1 );
break ;
}
}
if ( substr ( $word , - 1 ) == 'q' )
$word = substr ( $word , 0 , - 1 );
return $word ;
2013-02-27 02:26:33 +00:00
}
2011-08-01 23:51:01 +00:00
// escape text ($str) for XML transport
// returns escaped text.
2013-02-27 02:26:33 +00:00
2013-05-08 07:51:38 +00:00
/**
* escape text ( $str ) for XML transport
* @ param string $str
* @ return string Escaped text .
*/
2011-08-01 23:51:01 +00:00
function xmlify ( $str ) {
$buffer = '' ;
2013-02-06 04:14:19 +00:00
$len = mb_strlen ( $str );
for ( $x = 0 ; $x < $len ; $x ++ ) {
$char = mb_substr ( $str , $x , 1 );
2011-08-01 23:51:01 +00:00
switch ( $char ) {
case " \r " :
break ;
case " & " :
$buffer .= '&' ;
break ;
case " ' " :
$buffer .= ''' ;
break ;
case " \" " :
$buffer .= '"' ;
break ;
case '<' :
$buffer .= '<' ;
break ;
case '>' :
$buffer .= '>' ;
break ;
case " \n " :
$buffer .= " \n " ;
break ;
default :
$buffer .= $char ;
break ;
}
}
$buffer = trim ( $buffer );
return ( $buffer );
2013-02-27 02:26:33 +00:00
}
2011-08-01 23:51:01 +00:00
// undo an xmlify
// pass xml escaped text ($s), returns unescaped text
2013-02-27 02:26:33 +00:00
2011-08-01 23:51:01 +00:00
function unxmlify ( $s ) {
$ret = str_replace ( '&' , '&' , $s );
$ret = str_replace ( array ( '<' , '>' , '"' , ''' ), array ( '<' , '>' , '"' , " ' " ), $ret );
return $ret ;
2013-02-27 02:26:33 +00:00
}
2011-08-01 23:51:01 +00:00
// convenience wrapper, reverse the operation "bin2hex"
2013-03-28 02:02:01 +00:00
// This is a built-in function in php >= 5.4
2013-02-27 02:26:33 +00:00
2013-02-27 08:59:41 +00:00
if ( ! function_exists ( 'hex2bin' )) {
2011-08-01 23:51:01 +00:00
function hex2bin ( $s ) {
2011-10-21 02:11:34 +00:00
if ( ! ( is_string ( $s ) && strlen ( $s )))
return '' ;
2014-03-17 03:34:21 +00:00
if ( strlen ( $s ) & 1 ) {
logger ( 'hex2bin: illegal hex string: ' . $s );
return $s ;
}
2011-08-01 23:51:01 +00:00
if ( ! ctype_xdigit ( $s )) {
return ( $s );
}
return ( pack ( " H* " , $s ));
2013-02-27 08:59:41 +00:00
}}
2011-08-01 23:51:01 +00:00
// Automatic pagination.
// To use, get the count of total items.
// Then call $a->set_pager_total($number_items);
// Optionally call $a->set_pager_itemspage($n) to the number of items to display on each page
// Then call paginate($a) after the end of the display loop to insert the pager block on the page
// (assuming there are enough items to paginate).
// When using with SQL, the setting LIMIT %d, %d => $a->pager['start'],$a->pager['itemspage']
// will limit the results to the correct items for the current page.
// The actual page handling is then accomplished at the application layer.
2013-02-27 02:26:33 +00:00
2011-08-01 23:51:01 +00:00
function paginate ( & $a ) {
$o = '' ;
$stripped = preg_replace ( '/(&page=[0-9]*)/' , '' , $a -> query_string );
2012-04-02 07:45:45 +00:00
2012-11-09 03:07:19 +00:00
// $stripped = preg_replace('/&zid=(.*?)([\?&]|$)/ism','',$stripped);
2012-04-02 07:45:45 +00:00
2011-08-01 23:51:01 +00:00
$stripped = str_replace ( 'q=' , '' , $stripped );
$stripped = trim ( $stripped , '/' );
$pagenum = $a -> pager [ 'page' ];
$url = $a -> get_baseurl () . '/' . $stripped ;
if ( $a -> pager [ 'total' ] > $a -> pager [ 'itemspage' ]) {
$o .= '<div class="pager">' ;
if ( $a -> pager [ 'page' ] != 1 )
$o .= '<span class="pager_prev">' . " <a href= \" $url " . '&page=' . ( $a -> pager [ 'page' ] - 1 ) . '">' . t ( 'prev' ) . '</a></span> ' ;
$o .= " <span class= \" pager_first \" ><a href= \" $url " . " &page=1 \" > " . t ( 'first' ) . " </a></span> " ;
$numpages = $a -> pager [ 'total' ] / $a -> pager [ 'itemspage' ];
$numstart = 1 ;
$numstop = $numpages ;
if ( $numpages > 14 ) {
$numstart = (( $pagenum > 7 ) ? ( $pagenum - 7 ) : 1 );
$numstop = (( $pagenum > ( $numpages - 7 )) ? $numpages : ( $numstart + 14 ));
}
for ( $i = $numstart ; $i <= $numstop ; $i ++ ){
if ( $i == $a -> pager [ 'page' ])
$o .= '<span class="pager_current">' . (( $i < 10 ) ? ' ' . $i : $i );
else
$o .= " <span class= \" pager_n \" ><a href= \" $url " . " &page= $i\ " > " .(( $i < 10) ? ' '. $i : $i ). " </ a > " ;
$o .= '</span> ' ;
}
if (( $a -> pager [ 'total' ] % $a -> pager [ 'itemspage' ]) != 0 ) {
if ( $i == $a -> pager [ 'page' ])
$o .= '<span class="pager_current">' . (( $i < 10 ) ? ' ' . $i : $i );
else
$o .= " <span class= \" pager_n \" ><a href= \" $url " . " &page= $i\ " > " .(( $i < 10) ? ' '. $i : $i ). " </ a > " ;
$o .= '</span> ' ;
}
$lastpage = (( $numpages > intval ( $numpages )) ? intval ( $numpages ) + 1 : $numpages );
$o .= " <span class= \" pager_last \" ><a href= \" $url " . " &page= $lastpage\ " > " . t('last') . " </ a ></ span > " ;
if (( $a -> pager [ 'total' ] - ( $a -> pager [ 'itemspage' ] * $a -> pager [ 'page' ])) > 0 )
$o .= '<span class="pager_next">' . " <a href= \" $url " . " &page= " . ( $a -> pager [ 'page' ] + 1 ) . '">' . t ( 'next' ) . '</a></span>' ;
$o .= '</div>' . " \r \n " ;
}
return $o ;
2013-02-27 02:26:33 +00:00
}
2011-08-01 23:51:01 +00:00
2013-01-19 08:43:05 +00:00
function alt_pager ( & $a , $i , $more = '' , $less = '' ) {
$o = '' ;
if ( ! $more )
$more = t ( 'older' );
if ( ! $less )
$less = t ( 'newer' );
2012-07-15 03:39:46 +00:00
$stripped = preg_replace ( '/(&page=[0-9]*)/' , '' , $a -> query_string );
$stripped = str_replace ( 'q=' , '' , $stripped );
$stripped = trim ( $stripped , '/' );
$pagenum = $a -> pager [ 'page' ];
2013-01-19 08:43:05 +00:00
$url = $a -> get_baseurl () . '/' . $stripped ;
2012-07-15 03:39:46 +00:00
2013-06-04 01:16:00 +00:00
return replace_macros ( get_markup_template ( 'alt_pager.tpl' ), array (
'$has_less' => (( $a -> pager [ 'page' ] > 1 ) ? true : false ),
2013-10-11 08:50:06 +00:00
'$has_more' => (( $i > 0 && $i >= $a -> pager [ 'itemspage' ]) ? true : false ),
2013-06-04 01:16:00 +00:00
'$less' => $less ,
'$more' => $more ,
'$url' => $url ,
'$prevpage' => $a -> pager [ 'page' ] - 1 ,
'$nextpage' => $a -> pager [ 'page' ] + 1 ,
));
2012-07-15 03:39:46 +00:00
2013-02-27 02:26:33 +00:00
}
2012-07-15 03:39:46 +00:00
2011-08-01 23:51:01 +00:00
// Turn user/group ACLs stored as angle bracketed text into arrays
2013-02-27 02:26:33 +00:00
2011-08-01 23:51:01 +00:00
function expand_acl ( $s ) {
2012-11-15 02:18:28 +00:00
// turn string array of angle-bracketed elements into string array
// e.g. "<123xyz><246qyo><sxo33e>" => array(123xyz,246qyo,sxo33e);
2011-08-01 23:51:01 +00:00
$ret = array ();
if ( strlen ( $s )) {
$t = str_replace ( '<' , '' , $s );
$a = explode ( '>' , $t );
foreach ( $a as $aa ) {
2012-11-15 02:18:28 +00:00
if ( $aa )
$ret [] = $aa ;
2011-08-01 23:51:01 +00:00
}
}
return $ret ;
2013-02-27 02:26:33 +00:00
}
2011-08-01 23:51:01 +00:00
// Used to wrap ACL elements in angle brackets for storage
2013-02-27 02:26:33 +00:00
2011-08-01 23:51:01 +00:00
function sanitise_acl ( & $item ) {
2012-12-07 22:18:10 +00:00
if ( strlen ( $item ))
2012-11-15 02:18:28 +00:00
$item = '<' . notags ( trim ( $item )) . '>' ;
2011-08-01 23:51:01 +00:00
else
unset ( $item );
2013-02-27 02:26:33 +00:00
}
2011-08-01 23:51:01 +00:00
// Convert an ACL array to a storable string
2013-02-27 02:26:33 +00:00
2011-08-01 23:51:01 +00:00
function perms2str ( $p ) {
$ret = '' ;
2012-11-12 03:12:20 +00:00
if ( is_array ( $p ))
$tmp = $p ;
else
$tmp = explode ( ',' , $p );
2011-08-01 23:51:01 +00:00
if ( is_array ( $tmp )) {
array_walk ( $tmp , 'sanitise_acl' );
$ret = implode ( '' , $tmp );
}
return $ret ;
2013-02-27 02:26:33 +00:00
}
2011-08-01 23:51:01 +00:00
// generate a guaranteed unique (for this domain) item ID for ATOM
// safe from birthday paradox
2013-02-27 02:26:33 +00:00
2012-10-04 05:28:19 +00:00
function item_message_id () {
2011-08-01 23:51:01 +00:00
do {
$dups = false ;
$hash = random_string ();
2013-03-22 01:25:41 +00:00
$mid = $hash . '@' . get_app () -> get_hostname ();
2011-08-01 23:51:01 +00:00
2014-02-04 03:54:32 +00:00
$r = q ( " SELECT id FROM item WHERE mid = '%s' LIMIT 1 " ,
2013-03-22 01:25:41 +00:00
dbesc ( $mid ));
2011-08-01 23:51:01 +00:00
if ( count ( $r ))
$dups = true ;
} while ( $dups == true );
2013-03-22 01:25:41 +00:00
return $mid ;
2013-02-27 02:26:33 +00:00
}
2011-08-01 23:51:01 +00:00
// Generate a guaranteed unique photo ID.
// safe from birthday paradox
2013-02-27 02:26:33 +00:00
2011-08-01 23:51:01 +00:00
function photo_new_resource () {
do {
$found = false ;
$resource = hash ( 'md5' , uniqid ( mt_rand (), true ));
2014-02-04 03:54:32 +00:00
$r = q ( " SELECT id FROM photo WHERE resource_id = '%s' LIMIT 1 " ,
2011-08-01 23:51:01 +00:00
dbesc ( $resource )
);
if ( count ( $r ))
$found = true ;
} while ( $found == true );
return $resource ;
2013-02-27 02:26:33 +00:00
}
2011-08-01 23:51:01 +00:00
// for html,xml parsing - let's say you've got
// an attribute foobar="class1 class2 class3"
// and you want to find out if it contains 'class3'.
// you can't use a normal sub string search because you
// might match 'notclass3' and a regex to do the job is
// possible but a bit complicated.
// pass the attribute string as $attr and the attribute you
// are looking for as $s - returns true if found, otherwise false
function attribute_contains ( $attr , $s ) {
$a = explode ( ' ' , $attr );
if ( count ( $a ) && in_array ( $s , $a ))
return true ;
return false ;
2013-02-27 02:26:33 +00:00
}
2011-08-01 23:51:01 +00:00
function logger ( $msg , $level = 0 ) {
2012-01-02 19:11:06 +00:00
// turn off logger in install mode
global $a ;
2012-02-12 22:18:32 +00:00
global $db ;
if (( $a -> module == 'install' ) || ( ! ( $db && $db -> connected ))) return ;
2011-08-01 23:51:01 +00:00
$debugging = get_config ( 'system' , 'debugging' );
$loglevel = intval ( get_config ( 'system' , 'loglevel' ));
$logfile = get_config ( 'system' , 'logfile' );
if (( ! $debugging ) || ( ! $logfile ) || ( $level > $loglevel ))
return ;
2014-09-05 06:13:46 +00:00
$where = '' ;
if ( version_compare ( PHP_VERSION , '5.4.0' ) >= 0 ) {
$stack = debug_backtrace ( DEBUG_BACKTRACE_IGNORE_ARGS , 2 );
$where = basename ( $stack [ 0 ][ 'file' ]) . ':' . $stack [ 0 ][ 'line' ] . ':' . $stack [ 1 ][ 'function' ] . ': ' ;
}
@ file_put_contents ( $logfile , datetime_convert () . ':' . session_id () . ' ' . $where . $msg . " \n " , FILE_APPEND );
2011-08-01 23:51:01 +00:00
return ;
2013-02-27 02:26:33 +00:00
}
2011-08-01 23:51:01 +00:00
2013-02-06 04:39:19 +00:00
// This is a special logging facility for developers. It allows one to target specific things to trace/debug
// and is identical to logger() with the exception of the log filename. This allows one to isolate specific
// calls while allowing logger() to paint a bigger picture of overall activity and capture more detail.
// If you find dlogger() calls in checked in code, you are free to remove them - so as to provide a noise-free
// development environment which responds to events you are targetting personally.
2013-02-27 02:26:33 +00:00
2013-02-06 04:39:19 +00:00
function dlogger ( $msg , $level = 0 ) {
// turn off logger in install mode
global $a ;
global $db ;
if (( $a -> module == 'install' ) || ( ! ( $db && $db -> connected ))) return ;
$debugging = get_config ( 'system' , 'debugging' );
$loglevel = intval ( get_config ( 'system' , 'loglevel' ));
$logfile = get_config ( 'system' , 'dlogfile' );
if (( ! $debugging ) || ( ! $logfile ) || ( $level > $loglevel ))
return ;
@ file_put_contents ( $logfile , datetime_convert () . ':' . session_id () . ' ' . $msg . " \n " , FILE_APPEND );
return ;
2013-02-27 02:26:33 +00:00
}
2013-02-06 04:39:19 +00:00
2013-02-09 10:46:50 +00:00
function profiler ( $t1 , $t2 , $label ) {
if ( file_exists ( 'profiler.out' ) && $t1 && t2 )
@ file_put_contents ( 'profiler.out' , sprintf ( '%01.4f %s' , $t2 - $t1 , $label ) . " \n " , FILE_APPEND );
}
2013-02-06 04:39:19 +00:00
2013-02-27 02:26:33 +00:00
2011-08-01 23:51:01 +00:00
function activity_match ( $haystack , $needle ) {
if (( $haystack === $needle ) || (( basename ( $needle ) === $haystack ) && strstr ( $needle , NAMESPACE_ACTIVITY_SCHEMA )))
return true ;
2013-05-24 01:50:27 +00:00
2011-08-01 23:51:01 +00:00
return false ;
2013-02-27 02:26:33 +00:00
}
2011-08-01 23:51:01 +00:00
// Pull out all #hashtags and @person tags from $s;
// We also get @person@domain.com - which would make
// the regex quite complicated as tags can also
// end a sentence. So we'll run through our results
// and strip the period from any tags which end with one.
// Returns array of tags found, or empty array.
2013-02-27 02:26:33 +00:00
2011-08-01 23:51:01 +00:00
function get_tags ( $s ) {
$ret = array ();
// ignore anything in a code block
$s = preg_replace ( '/\[code\](.*?)\[\/code\]/sm' , '' , $s );
2014-02-05 13:34:25 +00:00
// ignore anything in [style= ]
$s = preg_replace ( '/\[style=(.*?)\]/sm' , '' , $s );
2014-04-12 23:58:19 +00:00
// match any double quoted tags
if ( preg_match_all ( '/([@#]\"\;.*?\"\;)/' , $s , $match )) {
foreach ( $match [ 1 ] as $mtch ) {
$ret [] = $mtch ;
}
}
2011-08-01 23:51:01 +00:00
// Match full names against @tags including the space between first and last
// We will look these up afterward to see if they are full names or not recognisable.
2014-04-12 23:58:19 +00:00
2011-11-03 04:07:17 +00:00
if ( preg_match_all ( '/(@[^ \x0D\x0A,:?]+ [^ \x0D\x0A@,:?]+)([ \x0D\x0A@,:?]|$)/' , $s , $match )) {
2011-08-01 23:51:01 +00:00
foreach ( $match [ 1 ] as $mtch ) {
if ( strstr ( $mtch , " ] " )) {
// we might be inside a bbcode color tag - leave it alone
continue ;
}
if ( substr ( $mtch , - 1 , 1 ) === '.' )
$ret [] = substr ( $mtch , 0 , - 1 );
else
$ret [] = $mtch ;
}
}
// Otherwise pull out single word tags. These can be @nickname, @first_last
// and #hash tags.
2011-10-26 02:59:57 +00:00
if ( preg_match_all ( '/([@#][^ \x0D\x0A,;:?]+)([ \x0D\x0A,;:?]|$)/' , $s , $match )) {
2011-08-01 23:51:01 +00:00
foreach ( $match [ 1 ] as $mtch ) {
if ( strstr ( $mtch , " ] " )) {
// we might be inside a bbcode color tag - leave it alone
continue ;
}
2011-09-10 00:35:26 +00:00
if ( substr ( $mtch , - 1 , 1 ) === '.' )
$mtch = substr ( $mtch , 0 , - 1 );
2011-08-01 23:51:01 +00:00
// ignore strictly numeric tags like #1
2014-02-04 03:38:15 +00:00
if (( strpos ( $mtch , '#' ) === 0 ) && ( ctype_digit ( substr ( $mtch , 1 )) || substr ( $mtch , 1 , 1 ) === '^' ))
2011-08-01 23:51:01 +00:00
continue ;
2011-11-26 06:41:50 +00:00
// try not to catch url fragments
if ( strpos ( $s , $mtch ) && preg_match ( '/[a-zA-z0-9\/]/' , substr ( $s , strpos ( $s , $mtch ) - 1 , 1 )))
continue ;
2014-04-13 00:04:54 +00:00
// or quote remnants from the quoted strings we already picked out earlier
if ( strpos ( $mtch , '"' ))
continue ;
2011-09-10 00:35:26 +00:00
$ret [] = $mtch ;
2011-08-01 23:51:01 +00:00
}
}
2014-02-04 03:38:15 +00:00
// bookmarks
2014-02-05 03:39:56 +00:00
if ( preg_match_all ( '/#\^\[(url|zrl)(.*?)\](.*?)\[\/(url|zrl)\]/' , $s , $match , PREG_SET_ORDER )) {
2014-02-04 03:38:15 +00:00
foreach ( $match as $mtch ) {
$ret [] = $mtch [ 0 ];
}
}
2014-03-31 03:53:59 +00:00
// make sure the longer tags are returned first so that if two or more have common substrings
// we'll replace the longest ones first. Otherwise the common substring would be found in
// both strings and the string replacement would link both to the shorter strings and
// fail to link the longer string. RedMatrix github issue #378
usort ( $ret , 'tag_sort_length' );
2014-02-04 03:38:15 +00:00
2014-03-31 03:53:59 +00:00
2014-04-13 06:57:19 +00:00
// logger('get_tags: ' . print_r($ret,true));
2014-02-04 03:38:15 +00:00
2011-08-01 23:51:01 +00:00
return $ret ;
2013-02-27 02:26:33 +00:00
}
2011-08-01 23:51:01 +00:00
2014-03-31 03:53:59 +00:00
function tag_sort_length ( $a , $b ) {
if ( mb_strlen ( $a ) == mb_strlen ( $b ))
return 0 ;
return (( mb_strlen ( $b ) < mb_strlen ( $a )) ? ( - 1 ) : 1 );
}
2011-08-01 23:51:01 +00:00
2014-02-16 22:13:26 +00:00
function strip_zids ( $s ) {
return preg_replace ( '/[\?&]zid=(.*?)(&|$)/ism' , '$2' , $s );
}
2011-08-01 23:51:01 +00:00
// quick and dirty quoted_printable encoding
2013-02-27 02:26:33 +00:00
2011-08-01 23:51:01 +00:00
function qp ( $s ) {
return str_replace ( " % " , " = " , rawurlencode ( $s ));
2013-02-27 02:26:33 +00:00
}
2011-08-01 23:51:01 +00:00
2012-07-17 04:52:26 +00:00
function get_mentions ( $item , $tags ) {
2011-08-01 23:51:01 +00:00
$o = '' ;
2012-07-17 04:52:26 +00:00
if ( ! count ( $tags ))
2011-08-01 23:51:01 +00:00
return $o ;
2012-07-17 04:52:26 +00:00
foreach ( $tags as $x ) {
if ( $x [ 'type' ] == TERM_MENTION ) {
$o .= " \t \t " . '<link rel="mentioned" href="' . $x [ 'url' ] . '" />' . " \r \n " ;
$o .= " \t \t " . '<link rel="ostatus:attention" href="' . $x [ 'url' ] . '" />' . " \r \n " ;
2011-08-01 23:51:01 +00:00
}
}
return $o ;
2013-02-27 02:26:33 +00:00
}
2011-08-01 23:51:01 +00:00
function contact_block () {
$o = '' ;
$a = get_app ();
2014-03-14 00:13:36 +00:00
if ( ! $a -> profile [ 'uid' ])
return ;
if ( ! perm_is_allowed ( $a -> profile [ 'uid' ], get_observer_hash (), 'view_contacts' ))
return ;
2011-08-01 23:51:01 +00:00
$shown = get_pconfig ( $a -> profile [ 'uid' ], 'system' , 'display_friend_count' );
2012-11-14 03:32:59 +00:00
2012-02-12 07:49:05 +00:00
if ( $shown === false )
2011-08-01 23:51:01 +00:00
$shown = 24 ;
2012-02-12 07:49:05 +00:00
if ( $shown == 0 )
return ;
2011-08-01 23:51:01 +00:00
2014-05-09 00:08:34 +00:00
$is_owner = (( local_user () && local_user () == $a -> profile [ 'uid' ]) ? true : false );
$abook_flags = ABOOK_FLAG_PENDING | ABOOK_FLAG_SELF ;
$xchan_flags = XCHAN_FLAGS_ORPHAN | XCHAN_FLAGS_DELETED ;
if ( ! $is_owner ) {
2014-07-17 05:32:18 +00:00
$abook_flags = $abook_flags | ABOOK_FLAG_HIDDEN ;
2014-05-09 00:08:34 +00:00
$xchan_flags = $xchan_flags | XCHAN_FLAGS_HIDDEN ;
}
2012-08-31 01:17:38 +00:00
if (( ! is_array ( $a -> profile )) || ( $a -> profile [ 'hide_friends' ]))
2011-08-01 23:51:01 +00:00
return $o ;
2014-04-15 00:29:19 +00:00
$r = q ( " SELECT COUNT(abook_id) AS total FROM abook left join xchan on abook_xchan = xchan_hash WHERE abook_channel = %d and not ( abook_flags & %d ) and not (xchan_flags & %d) " ,
2014-03-03 03:40:59 +00:00
intval ( $a -> profile [ 'uid' ]),
2014-05-09 00:08:34 +00:00
intval ( $abook_flags ),
intval ( $xchan_flags )
2011-08-01 23:51:01 +00:00
);
if ( count ( $r )) {
$total = intval ( $r [ 0 ][ 'total' ]);
}
if ( ! $total ) {
2013-02-02 19:07:28 +00:00
$contacts = t ( 'No connections' );
2011-08-31 15:31:44 +00:00
$micropro = Null ;
2011-08-01 23:51:01 +00:00
2011-08-31 15:31:44 +00:00
} else {
2012-11-15 04:55:05 +00:00
2014-04-15 00:29:19 +00:00
$r = q ( " SELECT abook.*, xchan.* FROM abook left join xchan on abook.abook_xchan = xchan.xchan_hash WHERE abook_channel = %d AND not ( abook_flags & %d) and not (xchan_flags & %d ) ORDER BY RAND() LIMIT %d " ,
2011-08-31 15:31:44 +00:00
intval ( $a -> profile [ 'uid' ]),
2014-07-17 05:32:18 +00:00
intval ( $abook_flags | ABOOK_FLAG_ARCHIVED ),
2014-05-09 00:08:34 +00:00
intval ( $xchan_flags ),
2011-08-31 15:31:44 +00:00
intval ( $shown )
);
2012-11-15 04:55:05 +00:00
2011-08-31 15:31:44 +00:00
if ( count ( $r )) {
2012-12-07 02:17:43 +00:00
$contacts = sprintf ( tt ( '%d Connection' , '%d Connections' , $total ), $total );
2011-08-31 15:31:44 +00:00
$micropro = Array ();
foreach ( $r as $rr ) {
2014-07-17 05:32:18 +00:00
$rr [ 'archived' ] = (( $rr [ 'abook_flags' ] & ABOOK_FLAG_ARCHIVED ) ? true : false );
2011-08-31 15:31:44 +00:00
$micropro [] = micropro ( $rr , true , 'mpfriend' );
}
}
2011-08-01 23:51:01 +00:00
}
2011-08-31 15:31:44 +00:00
$tpl = get_markup_template ( 'contact_block.tpl' );
$o = replace_macros ( $tpl , array (
'$contacts' => $contacts ,
2013-02-19 08:20:47 +00:00
'$nickname' => $a -> profile [ 'channel_address' ],
2013-02-19 11:00:29 +00:00
'$viewconnections' => t ( 'View Connections' ),
2011-08-31 15:31:44 +00:00
'$micropro' => $micropro ,
));
2011-08-01 23:51:01 +00:00
$arr = array ( 'contacts' => $r , 'output' => $o );
call_hooks ( 'contact_block_end' , $arr );
return $o ;
2013-02-27 02:26:33 +00:00
}
2011-08-01 23:51:01 +00:00
2012-12-07 02:17:43 +00:00
function chanlink_hash ( $s ) {
return z_root () . '/chanview?f=&hash=' . urlencode ( $s );
}
function chanlink_url ( $s ) {
return z_root () . '/chanview?f=&url=' . urlencode ( $s );
}
function chanlink_cid ( $d ) {
return z_root () . '/chanview?f=&cid=' . intval ( $d );
}
2013-01-25 12:30:03 +00:00
function magiclink_url ( $observer , $myaddr , $url ) {
return (( $observer )
? z_root () . '/magic?f=&dest=' . $url . '&addr=' . $myaddr
: $url
);
}
2012-12-07 02:17:43 +00:00
2013-02-27 02:26:33 +00:00
2011-08-01 23:51:01 +00:00
function micropro ( $contact , $redirect = false , $class = '' , $textmode = false ) {
2012-12-30 23:28:13 +00:00
if ( $contact [ 'click' ])
$url = '#' ;
else
$url = chanlink_hash ( $contact [ 'xchan_hash' ]);
2011-08-01 23:51:01 +00:00
2012-12-07 02:17:43 +00:00
return replace_macros ( get_markup_template (( $textmode ) ? 'micropro_txt.tpl' : 'micropro_img.tpl' ), array (
2012-12-30 23:28:13 +00:00
'$click' => (( $contact [ 'click' ]) ? $contact [ 'click' ] : '' ),
2014-07-17 05:21:29 +00:00
'$class' => $class . (( $contact [ 'archived' ]) ? ' archived' : '' ),
2012-12-07 02:17:43 +00:00
'$url' => $url ,
'$photo' => $contact [ 'xchan_photo_s' ],
'$name' => $contact [ 'xchan_name' ],
'$title' => $contact [ 'xchan_name' ] . ' [' . $contact [ 'xchan_addr' ] . ']' ,
));
2013-02-27 02:26:33 +00:00
}
2011-08-01 23:51:01 +00:00
2011-09-05 00:35:06 +00:00
function search ( $s , $id = 'search-box' , $url = '/search' , $save = false ) {
2011-08-01 23:51:01 +00:00
$a = get_app ();
2014-10-08 10:36:26 +00:00
return replace_macros ( get_markup_template ( 'searchbox.tpl' ), array (
'$s' => $s ,
'$id' => $id ,
'$action_url' => $a -> get_baseurl (( stristr ( $url , 'network' )) ? true : false ) . $url ,
'$search_label' => t ( 'Search' ),
'$save_label' => t ( 'Save' ),
'$savedsearch' => feature_enabled ( local_user (), 'savedsearch' )
));
2013-02-27 02:26:33 +00:00
}
2011-08-01 23:51:01 +00:00
2013-12-10 05:20:55 +00:00
function searchbox ( $s , $id = 'search-box' , $url = '/search' , $save = false ) {
2014-10-08 10:36:26 +00:00
return replace_macros ( get_markup_template ( 'searchbox.tpl' ), array (
'$s' => $s ,
'$id' => $id ,
'$action_url' => z_root () . '/' . $url ,
'$search_label' => t ( 'Search' ),
'$save_label' => t ( 'Save' ),
'$savedsearch' => feature_enabled ( local_user (), 'savedsearch' )
));
2013-12-10 05:20:55 +00:00
}
2011-08-01 23:51:01 +00:00
function valid_email ( $x ){
2012-07-02 01:56:00 +00:00
if ( get_config ( 'system' , 'disable_email_validation' ))
return true ;
2011-12-16 22:31:39 +00:00
if ( preg_match ( '/^[_a-zA-Z0-9\-\+]+(\.[_a-zA-Z0-9\-\+]+)*@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)+$/' , $x ))
2011-08-01 23:51:01 +00:00
return true ;
return false ;
2013-02-27 02:26:33 +00:00
}
2011-08-01 23:51:01 +00:00
/**
*
* Function : linkify
*
* Replace naked text hyperlink with HTML formatted hyperlink
*
*/
2013-02-27 02:26:33 +00:00
2011-08-01 23:51:01 +00:00
function linkify ( $s ) {
2013-04-08 23:58:52 +00:00
$s = preg_replace ( " /(https? \ : \ / \ /[a-zA-Z0-9 \ : \ / \ - \ ? \ & \ ; \ . \ = \ _ \ @ \ ~ \ # \ ' \ % \$ \ ! \ +]*)/ " , ' <a href="$1" >$1</a>' , $s );
2011-09-15 03:47:49 +00:00
$s = preg_replace ( " / \ <(.*?)(src|href)=(.*?) \ & \ ;(.*?) \ >/ism " , '<$1$2=$3&$4>' , $s );
2011-08-01 23:51:01 +00:00
return ( $s );
2013-02-27 02:26:33 +00:00
}
2011-08-01 23:51:01 +00:00
2013-12-25 10:45:22 +00:00
/**
* @ function sslify ( $s )
* Replace media element using http url with https to a local redirector if using https locally
* @ param string $s
*
* Looks for HTML tags containing src elements that are http when we ' re viewing an https page
* Typically this throws an insecure content violation in the browser . So we redirect them
* to a local redirector which uses https and which redirects to the selected content
*
* @ returns string
*/
function sslify ( $s ) {
if ( strpos ( z_root (), 'https:' ) === false )
return $s ;
$matches = null ;
$cnt = preg_match_all ( " / \ <(.*?)src= \" (http \ :.*?) \" (.*?) \ >/ " , $s , $matches , PREG_SET_ORDER );
if ( $cnt ) {
foreach ( $matches as $match ) {
$s = str_replace ( $match [ 2 ], z_root () . '/sslify?f=&url=' . urlencode ( $match [ 2 ]), $s );
}
}
return $s ;
}
2012-07-20 01:53:26 +00:00
function get_poke_verbs () {
// index is present tense verb
// value is array containing past tense verb, translation of present, translation of past
$arr = array (
'poke' => array ( 'poked' , t ( 'poke' ), t ( 'poked' )),
2012-07-21 10:48:59 +00:00
'ping' => array ( 'pinged' , t ( 'ping' ), t ( 'pinged' )),
2012-07-20 01:53:26 +00:00
'prod' => array ( 'prodded' , t ( 'prod' ), t ( 'prodded' )),
'slap' => array ( 'slapped' , t ( 'slap' ), t ( 'slapped' )),
2012-07-21 10:48:59 +00:00
'finger' => array ( 'fingered' , t ( 'finger' ), t ( 'fingered' )),
'rebuff' => array ( 'rebuffed' , t ( 'rebuff' ), t ( 'rebuffed' )),
2012-07-20 01:53:26 +00:00
);
call_hooks ( 'poke_verbs' , $arr );
return $arr ;
}
2011-08-01 23:51:01 +00:00
2012-08-24 03:00:10 +00:00
function get_mood_verbs () {
$arr = array (
'happy' => t ( 'happy' ),
'sad' => t ( 'sad' ),
'mellow' => t ( 'mellow' ),
'tired' => t ( 'tired' ),
'perky' => t ( 'perky' ),
'angry' => t ( 'angry' ),
'stupefied' => t ( 'stupified' ),
'puzzled' => t ( 'puzzled' ),
'interested' => t ( 'interested' ),
'bitter' => t ( 'bitter' ),
'cheerful' => t ( 'cheerful' ),
'alive' => t ( 'alive' ),
'annoyed' => t ( 'annoyed' ),
'anxious' => t ( 'anxious' ),
'cranky' => t ( 'cranky' ),
'disturbed' => t ( 'disturbed' ),
'frustrated' => t ( 'frustrated' ),
2014-04-27 02:33:39 +00:00
'depressed' => t ( 'depressed' ),
2012-08-24 03:00:10 +00:00
'motivated' => t ( 'motivated' ),
'relaxed' => t ( 'relaxed' ),
'surprised' => t ( 'surprised' ),
);
call_hooks ( 'mood_verbs' , $arr );
return $arr ;
}
2011-08-01 23:51:01 +00:00
/**
*
* Function : smilies
*
* Description :
* Replaces text emoticons with graphical images
*
* @ Parameter : string $s
*
* Returns string
2012-02-22 09:50:06 +00:00
*
* It is expected that this function will be called using HTML text .
2014-01-29 22:56:05 +00:00
* We will escape text between HTML pre and code blocks , and HTML attributes
* ( such as urls ) from being processed .
2012-02-22 09:50:06 +00:00
*
* At a higher level , the bbcode [ nosmile ] tag can be used to prevent this
* function from being executed by the prepare_text () routine when preparing
* bbcode source for HTML display
*
2011-08-01 23:51:01 +00:00
*/
2013-02-27 02:26:33 +00:00
2012-02-14 23:31:08 +00:00
function smilies ( $s , $sample = false ) {
2012-03-19 10:18:39 +00:00
2011-08-01 23:51:01 +00:00
$a = get_app ();
2012-03-19 10:18:39 +00:00
if ( intval ( get_config ( 'system' , 'no_smilies' ))
|| ( local_user () && intval ( get_pconfig ( local_user (), 'system' , 'no_smilies' ))))
return $s ;
2014-09-09 04:36:33 +00:00
2014-02-02 13:52:00 +00:00
$s = preg_replace_callback ( '{<(pre|code)>.*?</\1>}ism' , 'smile_shield' , $s );
$s = preg_replace_callback ( '/<[a-z]+ .*?>/ism' , 'smile_shield' , $s );
2012-02-22 07:13:03 +00:00
2012-02-14 23:31:08 +00:00
$texts = array (
'<3' ,
'</3' ,
'<\\3' ,
':-)' ,
';-)' ,
':-(' ,
':-P' ,
2012-03-22 04:45:45 +00:00
':-p' ,
2012-02-14 23:31:08 +00:00
':-"' ,
':-"' ,
':-x' ,
':-X' ,
':-D' ,
'8-|' ,
'8-O' ,
':-O' ,
'\\o/' ,
'o.O' ,
'O.o' ,
2012-04-02 05:57:50 +00:00
'o_O' ,
'O_o' ,
2012-02-14 23:31:08 +00:00
" :'( " ,
" :-! " ,
" :-/ " ,
" :-[ " ,
" 8-) " ,
':beer' ,
':homebrew' ,
':coffee' ,
2012-02-16 23:15:28 +00:00
':facepalm' ,
2012-05-31 00:22:51 +00:00
':like' ,
':dislike' ,
2014-08-21 23:46:24 +00:00
'red#matrix' ,
2013-05-29 03:30:04 +00:00
'red#' ,
2014-08-21 23:46:24 +00:00
'r#'
2012-02-14 23:31:08 +00:00
);
$icons = array (
2012-06-28 23:42:40 +00:00
'<img class="smiley" src="' . $a -> get_baseurl () . '/images/smiley-heart.gif" alt="<3" />' ,
'<img class="smiley" src="' . $a -> get_baseurl () . '/images/smiley-brokenheart.gif" alt="</3" />' ,
'<img class="smiley" src="' . $a -> get_baseurl () . '/images/smiley-brokenheart.gif" alt="<\\3" />' ,
'<img class="smiley" src="' . $a -> get_baseurl () . '/images/smiley-smile.gif" alt=":-)" />' ,
'<img class="smiley" src="' . $a -> get_baseurl () . '/images/smiley-wink.gif" alt=";-)" />' ,
'<img class="smiley" src="' . $a -> get_baseurl () . '/images/smiley-frown.gif" alt=":-(" />' ,
'<img class="smiley" src="' . $a -> get_baseurl () . '/images/smiley-tongue-out.gif" alt=":-P" />' ,
'<img class="smiley" src="' . $a -> get_baseurl () . '/images/smiley-tongue-out.gif" alt=":-p" />' ,
'<img class="smiley" src="' . $a -> get_baseurl () . '/images/smiley-kiss.gif" alt=":-\"" />' ,
'<img class="smiley" src="' . $a -> get_baseurl () . '/images/smiley-kiss.gif" alt=":-\"" />' ,
'<img class="smiley" src="' . $a -> get_baseurl () . '/images/smiley-kiss.gif" alt=":-x" />' ,
'<img class="smiley" src="' . $a -> get_baseurl () . '/images/smiley-kiss.gif" alt=":-X" />' ,
'<img class="smiley" src="' . $a -> get_baseurl () . '/images/smiley-laughing.gif" alt=":-D" />' ,
'<img class="smiley" src="' . $a -> get_baseurl () . '/images/smiley-surprised.gif" alt="8-|" />' ,
'<img class="smiley" src="' . $a -> get_baseurl () . '/images/smiley-surprised.gif" alt="8-O" />' ,
'<img class="smiley" src="' . $a -> get_baseurl () . '/images/smiley-surprised.gif" alt=":-O" />' ,
'<img class="smiley" src="' . $a -> get_baseurl () . '/images/smiley-thumbsup.gif" alt="\\o/" />' ,
'<img class="smiley" src="' . $a -> get_baseurl () . '/images/smiley-Oo.gif" alt="o.O" />' ,
'<img class="smiley" src="' . $a -> get_baseurl () . '/images/smiley-Oo.gif" alt="O.o" />' ,
'<img class="smiley" src="' . $a -> get_baseurl () . '/images/smiley-Oo.gif" alt="o_O" />' ,
'<img class="smiley" src="' . $a -> get_baseurl () . '/images/smiley-Oo.gif" alt="O_o" />' ,
'<img class="smiley" src="' . $a -> get_baseurl () . '/images/smiley-cry.gif" alt=":\'(" />' ,
'<img class="smiley" src="' . $a -> get_baseurl () . '/images/smiley-foot-in-mouth.gif" alt=":-!" />' ,
'<img class="smiley" src="' . $a -> get_baseurl () . '/images/smiley-undecided.gif" alt=":-/" />' ,
'<img class="smiley" src="' . $a -> get_baseurl () . '/images/smiley-embarassed.gif" alt=":-[" />' ,
'<img class="smiley" src="' . $a -> get_baseurl () . '/images/smiley-cool.gif" alt="8-)" />' ,
'<img class="smiley" src="' . $a -> get_baseurl () . '/images/beer_mug.gif" alt=":beer" />' ,
'<img class="smiley" src="' . $a -> get_baseurl () . '/images/beer_mug.gif" alt=":homebrew" />' ,
'<img class="smiley" src="' . $a -> get_baseurl () . '/images/coffee.gif" alt=":coffee" />' ,
'<img class="smiley" src="' . $a -> get_baseurl () . '/images/smiley-facepalm.gif" alt=":facepalm" />' ,
'<img class="smiley" src="' . $a -> get_baseurl () . '/images/like.gif" alt=":like" />' ,
'<img class="smiley" src="' . $a -> get_baseurl () . '/images/dislike.gif" alt=":dislike" />' ,
2014-09-09 04:36:33 +00:00
'<a href="http://getzot.com"><strong>red<img class="smiley" src="' . $a -> get_baseurl () . '/images/rm-16.png" alt="' . urlencode ( 'red#matrix' ) . '" />matrix</strong></a>' ,
'<a href="http://getzot.com"><strong>red<img class="smiley" src="' . $a -> get_baseurl () . '/images/rm-16.png" alt="' . urlencode ( 'red#' ) . '" />matrix</strong></a>' ,
2014-08-21 23:46:24 +00:00
'<a href="http://getzot.com"><strong>red<img class="smiley" src="' . $a -> get_baseurl () . '/images/rm-16.png" alt="r#" />matrix</strong></a>'
2013-12-09 22:05:52 +00:00
2012-02-14 23:31:08 +00:00
);
$params = array ( 'texts' => $texts , 'icons' => $icons , 'string' => $s );
call_hooks ( 'smilie' , $params );
2011-09-12 10:21:39 +00:00
2012-02-14 23:31:08 +00:00
if ( $sample ) {
$s = '<div class="smiley-sample">' ;
for ( $x = 0 ; $x < count ( $params [ 'texts' ]); $x ++ ) {
$s .= '<dl><dt>' . $params [ 'texts' ][ $x ] . '</dt><dd>' . $params [ 'icons' ][ $x ] . '</dd></dl>' ;
}
}
else {
2012-03-06 20:50:38 +00:00
$params [ 'string' ] = preg_replace_callback ( '/<(3+)/' , 'preg_heart' , $params [ 'string' ]);
2012-02-14 23:31:08 +00:00
$s = str_replace ( $params [ 'texts' ], $params [ 'icons' ], $params [ 'string' ]);
}
2012-02-21 02:06:43 +00:00
2014-02-02 13:52:00 +00:00
$s = preg_replace_callback ( '/<!--base64:(.*?)-->/ism' , 'smile_unshield' , $s );
2012-02-22 07:13:03 +00:00
2011-09-12 10:21:39 +00:00
return $s ;
2013-02-27 02:26:33 +00:00
}
2011-08-01 23:51:01 +00:00
2014-02-02 13:52:00 +00:00
function smile_shield ( $m ) {
return '<!--base64:' . base64url_encode ( $m [ 0 ]) . '-->' ;
}
2012-02-22 07:13:03 +00:00
2014-02-02 13:52:00 +00:00
function smile_unshield ( $m ) {
return base64url_decode ( $m [ 1 ]);
2012-02-22 07:13:03 +00:00
}
2012-03-06 20:50:38 +00:00
// expand <3333 to the correct number of hearts
2012-02-22 07:13:03 +00:00
2012-03-06 20:50:38 +00:00
function preg_heart ( $x ) {
$a = get_app ();
if ( strlen ( $x [ 1 ]) == 1 )
return $x [ 0 ];
$t = '' ;
for ( $cnt = 0 ; $cnt < strlen ( $x [ 1 ]); $cnt ++ )
2012-06-28 23:42:40 +00:00
$t .= '<img class="smiley" src="' . $a -> get_baseurl () . '/images/smiley-heart.gif" alt="<3" />' ;
2012-03-06 20:50:38 +00:00
$r = str_replace ( $x [ 0 ], $t , $x [ 0 ]);
return $r ;
}
2012-02-22 07:13:03 +00:00
2013-02-27 02:26:33 +00:00
2011-08-01 23:51:01 +00:00
function day_translate ( $s ) {
$ret = str_replace ( array ( 'Monday' , 'Tuesday' , 'Wednesday' , 'Thursday' , 'Friday' , 'Saturday' , 'Sunday' ),
array ( t ( 'Monday' ), t ( 'Tuesday' ), t ( 'Wednesday' ), t ( 'Thursday' ), t ( 'Friday' ), t ( 'Saturday' ), t ( 'Sunday' )),
$s );
$ret = str_replace ( array ( 'January' , 'February' , 'March' , 'April' , 'May' , 'June' , 'July' , 'August' , 'September' , 'October' , 'November' , 'December' ),
array ( t ( 'January' ), t ( 'February' ), t ( 'March' ), t ( 'April' ), t ( 'May' ), t ( 'June' ), t ( 'July' ), t ( 'August' ), t ( 'September' ), t ( 'October' ), t ( 'November' ), t ( 'December' )),
$ret );
return $ret ;
2013-02-27 02:26:33 +00:00
}
2011-08-01 23:51:01 +00:00
function normalise_link ( $url ) {
$ret = str_replace ( array ( 'https:' , '//www.' ), array ( 'http:' , '//' ), $url );
return ( rtrim ( $ret , '/' ));
2013-02-27 02:26:33 +00:00
}
2011-08-01 23:51:01 +00:00
/**
*
* Compare two URLs to see if they are the same , but ignore
* slight but hopefully insignificant differences such as if one
* is https and the other isn ' t , or if one is www . something and
* the other isn ' t - and also ignore case differences .
*
* Return true if the URLs match , otherwise false .
*
*/
2013-02-27 02:26:33 +00:00
2011-08-01 23:51:01 +00:00
function link_compare ( $a , $b ) {
if ( strcasecmp ( normalise_link ( $a ), normalise_link ( $b )) === 0 )
return true ;
return false ;
2013-02-27 02:26:33 +00:00
}
2011-08-01 23:51:01 +00:00
2011-08-04 04:05:39 +00:00
// Given an item array, convert the body element from bbcode to html and add smilie icons.
// If attach is true, also add icons for item attachments
2011-08-01 23:51:01 +00:00
2013-09-17 05:51:39 +00:00
function unobscure ( & $item ) {
if ( array_key_exists ( 'item_flags' , $item ) && ( $item [ 'item_flags' ] & ITEM_OBSCURED )) {
$key = get_config ( 'system' , 'prvkey' );
if ( $item [ 'title' ])
2013-11-20 23:20:12 +00:00
$item [ 'title' ] = crypto_unencapsulate ( json_decode_plus ( $item [ 'title' ]), $key );
2013-09-17 05:51:39 +00:00
if ( $item [ 'body' ])
2013-11-20 23:20:12 +00:00
$item [ 'body' ] = crypto_unencapsulate ( json_decode_plus ( $item [ 'body' ]), $key );
2013-09-17 05:51:39 +00:00
}
}
2013-10-14 04:14:04 +00:00
function theme_attachments ( & $item ) {
2013-07-29 04:04:03 +00:00
2013-08-06 10:54:49 +00:00
$arr = json_decode_plus ( $item [ 'attach' ]);
2013-10-14 04:14:04 +00:00
if ( is_array ( $arr ) && count ( $arr )) {
$attaches = array ();
2011-08-01 23:51:01 +00:00
foreach ( $arr as $r ) {
$icon = '' ;
2013-02-01 08:49:07 +00:00
$icontype = substr ( $r [ 'type' ], 0 , strpos ( $r [ 'type' ], '/' ));
2013-10-14 22:34:47 +00:00
// FIXME This should probably be a giant "if" statement in the template so that we don't have icon names
// embedded in php code
2013-02-01 08:49:07 +00:00
switch ( $icontype ) {
case 'video' :
2013-10-14 04:14:04 +00:00
$icon = 'icon-facetime-video' ;
break ;
2013-02-01 08:49:07 +00:00
case 'audio' :
2013-10-14 04:14:04 +00:00
$icon = 'icon-volume-up' ;
break ;
2013-02-01 08:49:07 +00:00
case 'image' :
2013-10-14 11:49:28 +00:00
$icon = 'icon-picture' ;
2013-10-14 04:14:04 +00:00
break ;
2013-02-01 08:49:07 +00:00
case 'text' :
2013-10-14 04:14:04 +00:00
$icon = 'icon-align-justify' ;
2013-02-01 08:49:07 +00:00
break ;
default :
2013-10-14 04:14:04 +00:00
$icon = 'icon-question' ;
2013-02-01 08:49:07 +00:00
break ;
2011-08-01 23:51:01 +00:00
}
2013-02-01 08:49:07 +00:00
2013-12-12 07:13:36 +00:00
$title = htmlspecialchars ( $r [ 'title' ], ENT_COMPAT , 'UTF-8' );
2013-02-01 08:49:07 +00:00
if ( ! $title )
$title = t ( 'unknown.???' );
$title .= ' ' . $r [ 'length' ] . ' ' . t ( 'bytes' );
2014-09-23 06:49:12 +00:00
require_once ( 'include/identity.php' );
if ( is_foreigner ( $item [ 'author_xchan' ]))
$url = $r [ 'href' ];
else
$url = z_root () . '/magic?f=&hash=' . $item [ 'author_xchan' ] . '&dest=' . $r [ 'href' ] . '/' . $r [ 'revision' ];
2013-02-01 08:49:07 +00:00
$s .= '<a href="' . $url . '" title="' . $title . '" class="attachlink" >' . $icon . '</a>' ;
2013-10-14 04:14:04 +00:00
$attaches [] = array ( 'title' => $title , 'url' => $url , 'icon' => $icon );
2011-08-01 23:51:01 +00:00
}
2013-10-14 04:14:04 +00:00
}
$s = replace_macros ( get_markup_template ( 'item_attach.tpl' ), array (
'$attaches' => $attaches
));
return $s ;
}
2013-10-14 11:49:28 +00:00
function format_categories ( & $item , $writeable ) {
$s = '' ;
$terms = get_terms_oftype ( $item [ 'term' ], TERM_CATEGORY );
if ( $terms ) {
$categories = array ();
foreach ( $terms as $t ) {
2013-12-13 20:30:44 +00:00
$term = htmlspecialchars ( $t [ 'term' ], ENT_COMPAT , 'UTF-8' , false ) ;
2013-10-14 22:34:47 +00:00
if ( ! trim ( $term ))
continue ;
2013-10-14 11:49:28 +00:00
$removelink = (( $writeable ) ? z_root () . '/filerm/' . $item [ 'id' ] . '?f=&cat=' . urlencode ( $t [ 'term' ]) : '' );
2013-12-02 23:15:02 +00:00
$categories [] = array ( 'term' => $term , 'writeable' => $writeable , 'removelink' => $removelink , 'url' => zid ( $t [ 'url' ]));
2013-10-14 11:49:28 +00:00
}
}
$s = replace_macros ( get_markup_template ( 'item_categories.tpl' ), array (
'$remove' => t ( 'remove category' ),
'$categories' => $categories
));
return $s ;
}
2014-04-01 00:03:07 +00:00
// Add any hashtags which weren't mentioned in the message body, e.g. community tags
function format_hashtags ( & $item ) {
$s = '' ;
$terms = get_terms_oftype ( $item [ 'term' ], TERM_HASHTAG );
if ( $terms ) {
$categories = array ();
foreach ( $terms as $t ) {
$term = htmlspecialchars ( $t [ 'term' ], ENT_COMPAT , 'UTF-8' , false ) ;
if ( ! trim ( $term ))
continue ;
if ( strpos ( $item [ 'body' ], $t [ 'url' ]))
continue ;
if ( $s )
$s .= ' ' ;
$s .= '#<a href="' . zid ( $t [ 'url' ]) . '" >' . $term . '</a>' ;
}
}
return $s ;
}
2014-07-01 05:46:17 +00:00
function format_mentions ( & $item ) {
$s = '' ;
$terms = get_terms_oftype ( $item [ 'term' ], TERM_MENTION );
if ( $terms ) {
$categories = array ();
foreach ( $terms as $t ) {
$term = htmlspecialchars ( $t [ 'term' ], ENT_COMPAT , 'UTF-8' , false ) ;
if ( ! trim ( $term ))
continue ;
if ( strpos ( $item [ 'body' ], $t [ 'url' ]))
continue ;
if ( $s )
$s .= ' ' ;
$s .= '@<a href="' . zid ( $t [ 'url' ]) . '" >' . $term . '</a>' ;
}
}
return $s ;
}
2014-04-01 00:03:07 +00:00
2013-10-14 11:49:28 +00:00
function format_filer ( & $item ) {
$s = '' ;
$terms = get_terms_oftype ( $item [ 'term' ], TERM_FILE );
if ( $terms ) {
$categories = array ();
foreach ( $terms as $t ) {
2013-12-13 20:30:44 +00:00
$term = htmlspecialchars ( $t [ 'term' ], ENT_COMPAT , 'UTF-8' , false ) ;
2013-10-14 22:34:47 +00:00
if ( ! trim ( $term ))
continue ;
2013-10-14 11:49:28 +00:00
$removelink = z_root () . '/filerm/' . $item [ 'id' ] . '?f=&term=' . urlencode ( $t [ 'term' ]);
$categories [] = array ( 'term' => $term , 'removelink' => $removelink );
}
}
$s = replace_macros ( get_markup_template ( 'item_filer.tpl' ), array (
'$remove' => t ( 'remove from file' ),
'$categories' => $categories
));
return $s ;
}
2013-10-14 04:14:04 +00:00
function prepare_body ( & $item , $attach = false ) {
$a = get_app ();
call_hooks ( 'prepare_body_init' , $item );
unobscure ( $item );
$s = prepare_text ( $item [ 'body' ], $item [ 'mimetype' ]);
$prep_arr = array ( 'item' => $item , 'html' => $s );
call_hooks ( 'prepare_body' , $prep_arr );
$s = $prep_arr [ 'html' ];
if ( ! $attach ) {
return $s ;
2011-08-01 23:51:01 +00:00
}
2012-07-10 05:08:25 +00:00
2013-10-14 04:14:04 +00:00
$s .= theme_attachments ( $item );
2013-03-04 07:38:08 +00:00
$writeable = (( get_observer_hash () == $item [ 'owner_xchan' ]) ? true : false );
2014-04-01 00:03:07 +00:00
$s .= format_hashtags ( $item );
2014-07-01 05:46:17 +00:00
if ( $item [ 'resource_type' ])
$s .= format_mentions ( $item );
2013-10-14 11:49:28 +00:00
$s .= format_categories ( $item , $writeable );
2012-03-13 11:04:26 +00:00
2013-10-14 11:49:28 +00:00
if ( local_user () == $item [ 'uid' ])
$s .= format_filer ( $item );
2011-10-24 22:47:17 +00:00
2013-12-25 10:45:22 +00:00
2013-12-25 12:06:26 +00:00
$s = sslify ( $s );
2013-12-25 10:45:22 +00:00
2012-03-17 10:07:49 +00:00
// Look for spoiler
$spoilersearch = '<blockquote class="spoiler">' ;
// Remove line breaks before the spoiler
while (( strpos ( $s , " \n " . $spoilersearch ) !== false ))
$s = str_replace ( " \n " . $spoilersearch , $spoilersearch , $s );
while (( strpos ( $s , " <br /> " . $spoilersearch ) !== false ))
$s = str_replace ( " <br /> " . $spoilersearch , $spoilersearch , $s );
while (( strpos ( $s , $spoilersearch ) !== false )) {
$pos = strpos ( $s , $spoilersearch );
$rnd = random_string ( 8 );
2012-03-17 11:15:59 +00:00
$spoilerreplace = '<br /> <span id="spoiler-wrap-' . $rnd . '" style="white-space:nowrap;" class="fakelink" onclick="openClose(\'spoiler-' . $rnd . '\');">' . sprintf ( t ( 'Click to open/close' )) . '</span>' .
2012-03-17 10:07:49 +00:00
'<blockquote class="spoiler" id="spoiler-' . $rnd . '" style="display: none;">' ;
$s = substr ( $s , 0 , $pos ) . $spoilerreplace . substr ( $s , $pos + strlen ( $spoilersearch ));
}
2012-03-17 11:15:59 +00:00
// Look for quote with author
$authorsearch = '<blockquote class="author">' ;
while (( strpos ( $s , $authorsearch ) !== false )) {
$pos = strpos ( $s , $authorsearch );
$rnd = random_string ( 8 );
$authorreplace = '<br /> <span id="author-wrap-' . $rnd . '" style="white-space:nowrap;" class="fakelink" onclick="openClose(\'author-' . $rnd . '\');">' . sprintf ( t ( 'Click to open/close' )) . '</span>' .
'<blockquote class="author" id="author-' . $rnd . '" style="display: block;">' ;
$s = substr ( $s , 0 , $pos ) . $authorreplace . substr ( $s , $pos + strlen ( $authorsearch ));
}
2011-10-24 22:47:17 +00:00
$prep_arr = array ( 'item' => $item , 'html' => $s );
call_hooks ( 'prepare_body_final' , $prep_arr );
2012-03-10 14:50:35 +00:00
2011-10-24 22:47:17 +00:00
return $prep_arr [ 'html' ];
2013-02-27 02:26:33 +00:00
}
2011-08-01 23:51:01 +00:00
2011-08-04 04:05:39 +00:00
// Given a text string, convert from bbcode to html and add smilie icons.
2013-02-27 02:26:33 +00:00
2013-03-21 23:14:08 +00:00
function prepare_text ( $text , $content_type = 'text/bbcode' ) {
2011-08-01 23:51:01 +00:00
2013-09-02 08:38:17 +00:00
2013-03-21 23:14:08 +00:00
switch ( $content_type ) {
case 'text/plain' :
$s = escape_tags ( $text );
break ;
case 'text/html' :
$s = $text ;
break ;
case 'text/markdown' :
require_once ( 'library/markdown.php' );
$s = Markdown ( $text );
break ;
2013-08-11 23:56:06 +00:00
// No security checking is done here at display time - so we need to verify
// that the author is allowed to use PHP before storing. We also cannot allow
// importation of PHP text bodies from other sites. Therefore this content
// type is only valid for web pages (and profile details).
// It may be possible to provide a PHP message body which is evaluated on the
// sender's site before sending it elsewhere. In that case we will have a
// different content-type here.
case 'application/x-php' :
ob_start ();
eval ( $text );
$s = ob_get_contents ();
ob_end_clean ();
break ;
2013-03-21 23:14:08 +00:00
case 'text/bbcode' :
case '' :
default :
require_once ( 'include/bbcode.php' );
if ( stristr ( $text , '[nosmile]' ))
$s = bbcode ( $text );
else
$s = smilies ( bbcode ( $text ));
2013-04-15 03:41:58 +00:00
$s = zidify_links ( $s );
2013-03-21 23:14:08 +00:00
break ;
}
2013-09-02 23:37:54 +00:00
//logger('prepare_text: ' . $s);
2011-08-01 23:51:01 +00:00
return $s ;
2013-02-27 02:26:33 +00:00
}
2011-08-01 23:51:01 +00:00
2013-04-15 03:41:58 +00:00
/**
* zidify_callback () and zidify_links () work together to turn any HTML a tags with class = " zrl " into zid links
* These will typically be generated by a bbcode '[zrl]' tag . This is done inside prepare_text () rather than bbcode ()
* because the latter is used for general purpose conversions and the former is used only when preparing text for
* immediate display .
*
* Issues : Currently the order of HTML parameters in the text is somewhat rigid and inflexible .
* We assume it looks like < a class = " zrl " href = " xxxxxxxxxx " > and will not work if zrl and href appear in a different order .
*/
function zidify_callback ( $match ) {
2014-02-19 03:47:13 +00:00
$is_zid = (( feature_enabled ( local_user (), 'sendzid' )) || ( strpos ( $match [ 1 ], 'zrl' )) ? true : false );
$replace = '<a' . $match [ 1 ] . ' href="' . (( $is_zid ) ? zid ( $match [ 2 ]) : $match [ 2 ]) . '"' ;
2013-04-15 03:41:58 +00:00
$x = str_replace ( $match [ 0 ], $replace , $match [ 0 ]);
return $x ;
}
2013-05-27 12:27:35 +00:00
function zidify_img_callback ( $match ) {
2014-02-19 03:47:13 +00:00
$is_zid = (( feature_enabled ( local_user (), 'sendzid' )) || ( strpos ( $match [ 1 ], 'zrl' )) ? true : false );
$replace = '<img' . $match [ 1 ] . ' src="' . (( $is_zid ) ? zid ( $match [ 2 ]) : $match [ 2 ]) . '"' ;
2013-05-27 12:27:35 +00:00
$x = str_replace ( $match [ 0 ], $replace , $match [ 0 ]);
return $x ;
}
2013-04-15 03:41:58 +00:00
function zidify_links ( $s ) {
2014-02-19 03:47:13 +00:00
$s = preg_replace_callback ( '/\<a(.*?)href\=\"(.*?)\"/ism' , 'zidify_callback' , $s );
$s = preg_replace_callback ( '/\<img(.*?)src\=\"(.*?)\"/ism' , 'zidify_img_callback' , $s );
2013-04-15 03:41:58 +00:00
return $s ;
}
2011-08-01 23:51:01 +00:00
/**
* return atom link elements for all of our hubs
*/
2013-02-27 02:26:33 +00:00
2011-08-01 23:51:01 +00:00
function feed_hublinks () {
$hub = get_config ( 'system' , 'huburl' );
$hubxml = '' ;
if ( strlen ( $hub )) {
$hubs = explode ( ',' , $hub );
if ( count ( $hubs )) {
foreach ( $hubs as $h ) {
$h = trim ( $h );
if ( ! strlen ( $h ))
continue ;
$hubxml .= '<link rel="hub" href="' . xmlify ( $h ) . '" />' . " \n " ;
}
}
}
return $hubxml ;
2013-02-27 02:26:33 +00:00
}
2011-08-01 23:51:01 +00:00
/* return atom link elements for salmon endpoints */
2013-02-27 02:26:33 +00:00
2011-08-01 23:51:01 +00:00
function feed_salmonlinks ( $nick ) {
$a = get_app ();
$salmon = '<link rel="salmon" href="' . xmlify ( $a -> get_baseurl () . '/salmon/' . $nick ) . '" />' . " \n " ;
// old style links that status.net still needed as of 12/2010
$salmon .= ' <link rel="http://salmon-protocol.org/ns/salmon-replies" href="' . xmlify ( $a -> get_baseurl () . '/salmon/' . $nick ) . '" />' . " \n " ;
$salmon .= ' <link rel="http://salmon-protocol.org/ns/salmon-mention" href="' . xmlify ( $a -> get_baseurl () . '/salmon/' . $nick ) . '" />' . " \n " ;
return $salmon ;
2013-02-27 02:26:33 +00:00
}
2011-08-01 23:51:01 +00:00
2014-01-10 00:23:58 +00:00
function get_plink ( $item , $conversation_mode = true ) {
2013-10-21 03:29:52 +00:00
$a = get_app ();
2014-01-10 00:23:58 +00:00
if ( $conversation_mode )
2013-10-21 03:29:52 +00:00
$key = 'plink' ;
else
$key = 'llink' ;
2013-11-10 22:15:57 +00:00
if ( x ( $item , $key )) {
2011-09-16 10:51:14 +00:00
return array (
2013-10-21 03:29:52 +00:00
'href' => zid ( $item [ $key ]),
2014-05-30 04:34:08 +00:00
'title' => t ( 'Link to Source' ),
2011-09-16 10:51:14 +00:00
);
2012-06-29 00:43:29 +00:00
}
else {
2011-09-16 10:51:14 +00:00
return false ;
}
2013-02-27 02:26:33 +00:00
}
2011-08-01 23:51:01 +00:00
function unamp ( $s ) {
return str_replace ( '&' , '&' , $s );
2013-02-27 02:26:33 +00:00
}
2013-09-03 03:25:33 +00:00
function layout_select ( $channel_id , $current = '' ) {
$r = q ( " select mid,sid from item left join item_id on iid = item.id where service = 'PDL' and item.uid = item_id.uid and item_id.uid = %d and (item_restrict & %d) " ,
intval ( $channel_id ),
intval ( ITEM_PDL )
);
if ( $r ) {
$o = t ( 'Select a page layout: ' );
$o .= '<select name="layout_mid" id="select-layout_mid" >' ;
$empty_selected = (( $current === '' ) ? ' selected="selected" ' : '' );
$o .= '<option value="" ' . $empty_selected . '>' . t ( 'default' ) . '</option>' ;
foreach ( $r as $rr ) {
$selected = (( $rr [ 'mid' ] == $current ) ? ' selected="selected" ' : '' );
$o .= '<option value="' . $rr [ 'mid' ] . '"' . $selected . '>' . $rr [ 'sid' ] . '</option>' ;
}
$o .= '</select>' ;
}
return $o ;
}
2011-08-01 23:51:01 +00:00
2013-09-02 08:38:17 +00:00
function mimetype_select ( $channel_id , $current = 'text/bbcode' ) {
$x = array (
'text/bbcode' ,
2014-08-26 19:13:27 +00:00
'text/html' ,
2013-09-02 08:38:17 +00:00
'text/markdown' ,
'text/plain'
);
2013-09-02 20:31:59 +00:00
$r = q ( " select account_id, account_roles from account left join channel on account_id = channel_account_id where
2013-09-02 08:38:17 +00:00
channel_id = % d limit 1 " ,
intval ( $channel_id )
);
if ( $r ) {
if ( $r [ 0 ][ 'account_roles' ] & ACCOUNT_ROLE_ALLOWCODE ) {
2014-08-26 19:13:27 +00:00
if ( local_user () && get_account_id () == $r [ 0 ][ 'account_id' ])
2013-09-02 20:31:59 +00:00
$x [] = 'application/x-php' ;
2013-09-02 08:38:17 +00:00
}
}
$o = t ( 'Page content type: ' );
$o .= '<select name="mimetype" id="mimetype-select">' ;
foreach ( $x as $y ) {
$select = (( $y == $current ) ? ' selected="selected" ' : '' );
$o .= '<option name="' . $y . '"' . $select . '>' . $y . '</option>' ;
}
$o .= '</select>' ;
return $o ;
}
2011-08-01 23:51:01 +00:00
function lang_selector () {
2012-08-13 03:56:23 +00:00
global $a ;
2012-04-13 09:56:21 +00:00
2011-08-01 23:51:01 +00:00
$langs = glob ( 'view/*/strings.php' );
2012-04-13 09:56:21 +00:00
$lang_options = array ();
$selected = " " ;
2011-08-01 23:51:01 +00:00
if ( is_array ( $langs ) && count ( $langs )) {
2011-09-21 23:00:17 +00:00
$langs [] = '' ;
2011-08-01 23:51:01 +00:00
if ( ! in_array ( 'view/en/strings.php' , $langs ))
$langs [] = 'view/en/' ;
asort ( $langs );
foreach ( $langs as $l ) {
2011-09-21 23:00:17 +00:00
if ( $l == '' ) {
2012-04-13 09:56:21 +00:00
$lang_options [ " " ] = t ( 'default' );
2011-09-21 23:00:17 +00:00
continue ;
}
2011-08-01 23:51:01 +00:00
$ll = substr ( $l , 5 );
$ll = substr ( $ll , 0 , strrpos ( $ll , '/' ));
2012-08-13 03:56:23 +00:00
$selected = (( $ll === $a -> language && ( x ( $_SESSION , 'language' ))) ? $ll : $selected );
2012-04-13 09:56:21 +00:00
$lang_options [ $ll ] = $ll ;
2011-08-01 23:51:01 +00:00
}
}
2012-04-13 09:56:21 +00:00
$tpl = get_markup_template ( " lang_selector.tpl " );
$o = replace_macros ( $tpl , array (
'$title' => t ( 'Select an alternate language' ),
'$langs' => array ( $lang_options , $selected ),
));
2011-08-01 23:51:01 +00:00
return $o ;
2013-02-27 02:26:33 +00:00
}
2011-08-01 23:51:01 +00:00
function return_bytes ( $size_str ) {
switch ( substr ( $size_str , - 1 ))
{
case 'M' : case 'm' : return ( int ) $size_str * 1048576 ;
case 'K' : case 'k' : return ( int ) $size_str * 1024 ;
case 'G' : case 'g' : return ( int ) $size_str * 1073741824 ;
default : return $size_str ;
}
2013-02-27 02:26:33 +00:00
}
2011-08-01 23:51:01 +00:00
2012-08-27 06:05:00 +00:00
function base64url_encode ( $s , $strip_padding = true ) {
2011-08-01 23:51:01 +00:00
$s = strtr ( base64_encode ( $s ), '+/' , '-_' );
if ( $strip_padding )
$s = str_replace ( '=' , '' , $s );
return $s ;
}
function base64url_decode ( $s ) {
2012-01-25 00:45:58 +00:00
if ( is_array ( $s )) {
logger ( 'base64url_decode: illegal input: ' . print_r ( debug_backtrace (), true ));
return $s ;
}
2011-08-01 23:51:01 +00:00
return base64_decode ( strtr ( $s , '-_' , '+/' ));
}
2011-08-17 03:05:02 +00:00
2011-09-20 23:31:45 +00:00
2011-10-12 01:24:37 +00:00
function cleardiv () {
return '<div class="clear"></div>' ;
}
function bb_translate_video ( $s ) {
$matches = null ;
$r = preg_match_all ( " / \ [video \ ](.*?) \ [ \ /video \ ]/ism " , $s , $matches , PREG_SET_ORDER );
if ( $r ) {
foreach ( $matches as $mtch ) {
if (( stristr ( $mtch [ 1 ], 'youtube' )) || ( stristr ( $mtch [ 1 ], 'youtu.be' )))
$s = str_replace ( $mtch [ 0 ], '[youtube]' . $mtch [ 1 ] . '[/youtube]' , $s );
elseif ( stristr ( $mtch [ 1 ], 'vimeo' ))
$s = str_replace ( $mtch [ 0 ], '[vimeo]' . $mtch [ 1 ] . '[/vimeo]' , $s );
}
}
return $s ;
}
function html2bb_video ( $s ) {
2012-06-14 02:59:20 +00:00
$s = preg_replace ( '#<object[^>]+>(.*?)https?://www.youtube.com/((?:v|cp)/[A-Za-z0-9\-_=]+)(.*?)</object>#ism' ,
2011-10-12 01:24:37 +00:00
'[youtube]$2[/youtube]' , $s );
2012-06-14 02:59:20 +00:00
$s = preg_replace ( '#<iframe[^>](.*?)https?://www.youtube.com/embed/([A-Za-z0-9\-_=]+)(.*?)</iframe>#ism' ,
2011-10-12 01:24:37 +00:00
'[youtube]$2[/youtube]' , $s );
2012-06-14 02:59:20 +00:00
$s = preg_replace ( '#<iframe[^>](.*?)https?://player.vimeo.com/video/([0-9]+)(.*?)</iframe>#ism' ,
2011-10-12 01:24:37 +00:00
'[vimeo]$2[/vimeo]' , $s );
return $s ;
2011-10-27 08:54:52 +00:00
}
/**
* apply xmlify () to all values of array $val , recursively
*/
function array_xmlify ( $val ){
if ( is_bool ( $val )) return $val ? " true " : " false " ;
if ( is_array ( $val )) return array_map ( 'array_xmlify' , $val );
return xmlify (( string ) $val );
}
2012-01-18 00:30:32 +00:00
function reltoabs ( $text , $base )
{
if ( empty ( $base ))
2013-02-27 02:26:33 +00:00
return $text ;
2012-01-18 00:30:32 +00:00
$base = rtrim ( $base , '/' );
$base2 = $base . " / " ;
// Replace links
$pattern = " /<a([^>]*) href= \" (?!http|https| \ /)([^ \" ]*) \" / " ;
$replace = " <a \$ { 1} href= \" " . $base2 . " \$ { 2} \" " ;
$text = preg_replace ( $pattern , $replace , $text );
$pattern = " /<a([^>]*) href= \" (?!http|https)([^ \" ]*) \" / " ;
$replace = " <a \$ { 1} href= \" " . $base . " \$ { 2} \" " ;
$text = preg_replace ( $pattern , $replace , $text );
// Replace images
$pattern = " /<img([^>]*) src= \" (?!http|https| \ /)([^ \" ]*) \" / " ;
$replace = " <img \$ { 1} src= \" " . $base2 . " \$ { 2} \" " ;
$text = preg_replace ( $pattern , $replace , $text );
$pattern = " /<img([^>]*) src= \" (?!http|https)([^ \" ]*) \" / " ;
$replace = " <img \$ { 1} src= \" " . $base . " \$ { 2} \" " ;
$text = preg_replace ( $pattern , $replace , $text );
// Done
return $text ;
}
2012-03-06 20:50:38 +00:00
function item_post_type ( $item ) {
2012-07-10 05:08:25 +00:00
2013-06-20 04:50:14 +00:00
switch ( $item [ 'resource_type' ]) {
case 'photo' :
$post_type = t ( 'photo' );
break ;
case 'event' :
$post_type = t ( 'event' );
break ;
default :
$post_type = t ( 'status' );
if ( $item [ 'mid' ] != $item [ 'parent_mid' ])
$post_type = t ( 'comment' );
break ;
}
2012-07-10 05:08:25 +00:00
2013-06-20 22:55:20 +00:00
if ( strlen ( $item [ 'verb' ]) && ( ! activity_match ( $item [ 'verb' ], ACTIVITY_POST )))
2013-06-20 04:50:14 +00:00
$post_type = t ( 'activity' );
2012-07-10 05:08:25 +00:00
2013-06-20 04:50:14 +00:00
return $post_type ;
2012-03-12 04:32:11 +00:00
}
2012-03-06 20:50:38 +00:00
2012-03-22 23:17:10 +00:00
function undo_post_tagging ( $s ) {
$matches = null ;
2014-02-04 03:54:32 +00:00
$cnt = preg_match_all ( '/([@#])(\!*)\[zrl=(.*?)\](.*?)\[\/zrl\]/ism' , $s , $matches , PREG_SET_ORDER );
2012-03-22 23:17:10 +00:00
if ( $cnt ) {
foreach ( $matches as $mtch ) {
2014-02-04 03:54:32 +00:00
$s = str_replace ( $mtch [ 0 ], $mtch [ 1 ] . $mtch [ 2 ] . str_replace ( ' ' , '_' , $mtch [ 4 ]), $s );
2012-03-22 23:17:10 +00:00
}
}
return $s ;
}
2012-04-10 23:31:49 +00:00
function fix_mce_lf ( $s ) {
$s = str_replace ( " \r \n " , " \n " , $s );
2012-08-01 12:02:43 +00:00
// $s = str_replace("\n\n","\n",$s);
2012-04-10 23:31:49 +00:00
return $s ;
2012-04-13 09:56:21 +00:00
}
2012-05-09 05:46:40 +00:00
function protect_sprintf ( $s ) {
return ( str_replace ( '%' , '%%' , $s ));
}
2012-06-12 02:36:04 +00:00
function is_a_date_arg ( $s ) {
$i = intval ( $s );
if ( $i > 1900 ) {
$y = date ( 'Y' );
if ( $i <= $y + 1 && strpos ( $s , '-' ) == 4 ) {
$m = intval ( substr ( $s , 5 ));
if ( $m > 0 && $m <= 12 )
return true ;
}
}
return false ;
}
2012-07-31 04:51:25 +00:00
function legal_webbie ( $s ) {
if ( ! strlen ( $s ))
return '' ;
$x = $s ;
do {
$s = $x ;
$x = preg_replace ( '/^([^a-z])(.*?)/' , " $ 2 " , $s );
} while ( $x != $s );
return preg_replace ( '/([^a-z0-9\-\_])/' , '' , $x );
}
function check_webbie ( $arr ) {
$str = '' ;
$taken = array ();
if ( count ( $arr )) {
foreach ( $arr as $x ) {
$y = legal_webbie ( $x );
if ( strlen ( $y )) {
if ( $str )
$str .= ',' ;
$str .= " ' " . dbesc ( $y ) . " ' " ;
}
}
2014-04-07 02:59:00 +00:00
2012-07-31 04:51:25 +00:00
if ( strlen ( $str )) {
2012-09-26 00:57:20 +00:00
$r = q ( " select channel_address from channel where channel_address in ( $str ) " );
2012-07-31 04:51:25 +00:00
if ( count ( $r )) {
foreach ( $r as $rr ) {
2012-09-26 00:57:20 +00:00
$taken [] = $rr [ 'channel_address' ];
2012-07-31 04:51:25 +00:00
}
}
foreach ( $arr as $x ) {
2014-04-07 02:59:00 +00:00
$y = legal_webbie ( $x );
if ( ! in_array ( $y , $taken )) {
return $y ;
2012-07-31 04:51:25 +00:00
}
}
}
}
return '' ;
}
2012-08-09 23:26:44 +00:00
2012-08-30 06:03:03 +00:00
function ids_to_querystr ( $arr , $idx = 'id' ) {
$t = array ();
foreach ( $arr as $x )
$t [] = $x [ $idx ];
return ( implode ( ',' , $t ));
2012-10-08 04:44:11 +00:00
}
2013-01-20 06:21:00 +00:00
// Fetches xchan and hubloc data for an array of items with only an
// author_xchan and owner_xchan. If $abook is true also include the abook info.
// This is needed in the API to save extra per item lookups there.
2014-09-23 05:03:19 +00:00
function xchan_query ( & $items , $abook = true , $effective_uid = 0 ) {
2012-10-08 04:44:11 +00:00
$arr = array ();
if ( $items && count ( $items )) {
2014-09-23 05:03:19 +00:00
if ( $effective_uid ) {
for ( $x = 0 ; $x < count ( $items ); $x ++ ) {
$items [ $x ][ 'real_uid' ] = $items [ $x ][ 'uid' ];
$items [ $x ][ 'uid' ] = $effective_uid ;
}
}
2012-10-08 04:44:11 +00:00
foreach ( $items as $item ) {
if ( $item [ 'owner_xchan' ] && ( ! in_array ( $item [ 'owner_xchan' ], $arr )))
$arr [] = " ' " . dbesc ( $item [ 'owner_xchan' ]) . " ' " ;
if ( $item [ 'author_xchan' ] && ( ! in_array ( $item [ 'author_xchan' ], $arr )))
$arr [] = " ' " . dbesc ( $item [ 'author_xchan' ]) . " ' " ;
}
}
if ( count ( $arr )) {
2013-01-20 06:21:00 +00:00
if ( $abook ) {
2013-06-20 22:55:20 +00:00
$chans = q ( " select * from xchan left join hubloc on hubloc_hash = xchan_hash left join abook on abook_xchan = xchan_hash and abook_channel = %d
where xchan_hash in ( " . implode(',', $arr ) . " ) and ( hubloc_flags & " . intval(HUBLOC_FLAGS_PRIMARY) . " ) " ,
2013-06-20 09:03:14 +00:00
intval ( $item [ 'uid' ])
);
2013-01-20 06:21:00 +00:00
}
else {
$chans = q ( " select xchan.*,hubloc.* from xchan left join hubloc on hubloc_hash = xchan_hash
where xchan_hash in ( " . implode(',', $arr ) . " ) and ( hubloc_flags & " . intval(HUBLOC_FLAGS_PRIMARY) . " ) " );
}
2014-09-01 03:51:05 +00:00
$xchans = q ( " select * from xchan where xchan_hash in ( " . implode ( ',' , $arr ) . " ) and xchan_network in ('rss','unknown') " );
if ( ! $chans )
$chans = $xchans ;
else
$chans = array_merge ( $xchans , $chans );
2012-10-08 04:44:11 +00:00
}
if ( $items && count ( $items ) && $chans && count ( $chans )) {
for ( $x = 0 ; $x < count ( $items ); $x ++ ) {
$items [ $x ][ 'owner' ] = find_xchan_in_array ( $items [ $x ][ 'owner_xchan' ], $chans );
$items [ $x ][ 'author' ] = find_xchan_in_array ( $items [ $x ][ 'author_xchan' ], $chans );
}
}
}
2012-12-06 00:44:07 +00:00
function xchan_mail_query ( & $item ) {
$arr = array ();
$chans = null ;
if ( $item ) {
if ( $item [ 'from_xchan' ] && ( ! in_array ( $item [ 'from_xchan' ], $arr )))
$arr [] = " ' " . dbesc ( $item [ 'from_xchan' ]) . " ' " ;
if ( $item [ 'to_xchan' ] && ( ! in_array ( $item [ 'to_xchan' ], $arr )))
$arr [] = " ' " . dbesc ( $item [ 'to_xchan' ]) . " ' " ;
}
if ( count ( $arr )) {
$chans = q ( " select xchan.*,hubloc.* from xchan left join hubloc on hubloc_hash = xchan_hash
where xchan_hash in ( " . implode(',', $arr ) . " ) and ( hubloc_flags & " . intval(HUBLOC_FLAGS_PRIMARY) . " ) " );
}
if ( $chans ) {
$item [ 'from' ] = find_xchan_in_array ( $item [ 'from_xchan' ], $chans );
$item [ 'to' ] = find_xchan_in_array ( $item [ 'to_xchan' ], $chans );
}
}
2012-10-08 04:44:11 +00:00
function find_xchan_in_array ( $xchan , $arr ) {
if ( count ( $arr )) {
foreach ( $arr as $x ) {
if ( $x [ 'xchan_hash' ] === $xchan ) {
return $x ;
}
}
}
return array ();
2012-11-07 00:16:26 +00:00
}
2012-11-14 03:32:59 +00:00
function get_rel_link ( $j , $rel ) {
2012-11-07 00:16:26 +00:00
if ( count ( $j ))
foreach ( $j as $l )
2012-11-14 03:32:59 +00:00
if ( $l [ 'rel' ] === $rel )
return $l [ 'href' ];
2012-11-07 00:16:26 +00:00
return '' ;
}
// Lots of code to write here
function magic_link ( $s ) {
return $s ;
}
2012-11-15 01:02:30 +00:00
2013-01-21 02:05:29 +00:00
// if $escape is true, dbesc() each element before adding quotes
function stringify_array_elms ( & $arr , $escape = false ) {
2012-11-15 01:02:30 +00:00
for ( $x = 0 ; $x < count ( $arr ); $x ++ )
2013-01-21 02:05:29 +00:00
$arr [ $x ] = " ' " . (( $escape ) ? dbesc ( $arr [ $x ]) : $arr [ $x ]) . " ' " ;
2012-11-15 01:02:30 +00:00
}
2012-12-29 08:33:04 +00:00
/**
* Indents a flat JSON string to make it more human - readable .
*
* @ param string $json The original JSON string to process .
*
* @ return string Indented version of the original JSON string .
*/
function jindent ( $json ) {
2013-02-27 02:26:33 +00:00
$result = '' ;
$pos = 0 ;
$strLen = strlen ( $json );
$indentStr = ' ' ;
$newLine = " \n " ;
$prevChar = '' ;
$outOfQuotes = true ;
2012-12-29 08:33:04 +00:00
2013-02-27 02:26:33 +00:00
for ( $i = 0 ; $i <= $strLen ; $i ++ ) {
2012-12-29 08:33:04 +00:00
2013-02-27 02:26:33 +00:00
// Grab the next character in the string.
$char = substr ( $json , $i , 1 );
2012-12-29 08:33:04 +00:00
2013-02-27 02:26:33 +00:00
// Are we inside a quoted string?
if ( $char == '"' && $prevChar != '\\' ) {
$outOfQuotes = ! $outOfQuotes ;
// If this character is the end of an element,
// output a new line and indent the next line.
} else if (( $char == '}' || $char == ']' ) && $outOfQuotes ) {
$result .= $newLine ;
$pos -- ;
for ( $j = 0 ; $j < $pos ; $j ++ ) {
$result .= $indentStr ;
}
}
// Add the character to the result string.
$result .= $char ;
// If the last character was the beginning of an element,
// output a new line and indent the next line.
if (( $char == ',' || $char == '{' || $char == '[' ) && $outOfQuotes ) {
$result .= $newLine ;
if ( $char == '{' || $char == '[' ) {
$pos ++ ;
}
for ( $j = 0 ; $j < $pos ; $j ++ ) {
$result .= $indentStr ;
}
}
$prevChar = $char ;
}
2012-12-29 08:33:04 +00:00
2013-02-27 02:26:33 +00:00
return $result ;
2012-12-29 08:33:04 +00:00
}
2013-01-05 06:04:57 +00:00
2013-08-06 10:29:57 +00:00
function json_decode_plus ( $s ) {
$x = json_decode ( $s , true );
if ( ! $x )
$x = json_decode ( str_replace ( array ( '\\"' , '\\\\' ), array ( '"' , '\\' ), $s ), true );
return $x ;
2013-09-04 02:55:26 +00:00
}
function design_tools () {
2013-12-19 10:16:14 +00:00
$channel = get_app () -> get_channel ();
$who = $channel [ 'channel_address' ];
return replace_macros ( get_markup_template ( 'design_tools.tpl' ), array (
'$title' => t ( 'Design' ),
'$who' => $who ,
'$blocks' => t ( 'Blocks' ),
'$menus' => t ( 'Menus' ),
'$layout' => t ( 'Layouts' ),
'$pages' => t ( 'Pages' )
));
2013-09-04 02:55:26 +00:00
}
2013-09-20 02:50:13 +00:00
/* case insensitive in_array() */
function in_arrayi ( $needle , $haystack ) {
return in_array ( strtolower ( $needle ), array_map ( 'strtolower' , $haystack ));
}
2014-02-18 03:48:05 +00:00
function normalise_openid ( $s ) {
return trim ( str_replace ( array ( 'http://' , 'https://' ), array ( '' , '' ), $s ), '/' );
}
2014-09-06 10:11:07 +00:00
// used in ajax endless scroll request to find out all the args that the master page was viewing.
// This was using $_REQUEST, but $_REQUEST also contains all your cookies. So we're restricting it
// to $_GET. If this is used in a post handler, that decision may need to be considered.
2014-09-06 07:37:15 +00:00
function extra_query_args () {
$s = '' ;
2014-09-06 10:11:07 +00:00
if ( count ( $_GET )) {
foreach ( $_GET as $k => $v ) {
2014-09-06 07:37:15 +00:00
// these are request vars we don't want to duplicate
if ( ! in_array ( $k , array ( 'q' , 'f' , 'zid' , 'page' , 'PHPSESSID' ))) {
$s .= '&' . $k . '=' . $v ;
}
}
}
return $s ;
2014-10-08 10:36:26 +00:00
}