2015-08-23 22:38:18 +02:00
< ? php
/**
* @ file include / identity . php
*/
require_once ( 'include/zot.php' );
require_once ( 'include/crypto.php' );
2015-10-24 13:04:14 +02:00
require_once ( 'include/menu.php' );
2015-08-23 22:38:18 +02:00
/**
* @ brief Called when creating a new channel .
*
* Checks the account ' s service class and number of current channels to determine
* whether creating a new channel is within the current service class constraints .
*
* @ param int $account_id
* Account_id used for this request
*
* @ returns assoziative array with :
* * \e boolean \b success boolean true if creating a new channel is allowed for this account
* * \e string \b message ( optional ) if success is false , optional error text
* * \e int \b total_identities
*/
function identity_check_service_class ( $account_id ) {
$ret = array ( 'success' => false , 'message' => '' );
$r = q ( " select count(channel_id) as total from channel where channel_account_id = %d and channel_removed = 0 " ,
intval ( $account_id )
);
if ( ! ( $r && count ( $r ))) {
$ret [ 'total_identities' ] = 0 ;
$ret [ 'message' ] = t ( 'Unable to obtain identity information from database' );
return $ret ;
}
$ret [ 'total_identities' ] = intval ( $r [ 0 ][ 'total' ]);
if ( ! account_service_class_allows ( $account_id , 'total_identities' , $r [ 0 ][ 'total' ])) {
$ret [ 'message' ] .= upgrade_message ();
return $ret ;
}
$ret [ 'success' ] = true ;
return $ret ;
}
/**
* @ brief Determine if the channel name is allowed when creating a new channel .
*
* This action is pluggable .
* We ' re currently only checking for an empty name or one that exceeds our
* storage limit ( 255 chars ) . 255 chars is probably going to create a mess on
* some pages .
* Plugins can set additional policies such as full name requirements , character
* sets , multi - byte length , etc .
*
* @ param string $name
*
* @ returns nil return if name is valid , or string describing the error state .
*/
function validate_channelname ( $name ) {
if ( ! $name )
return t ( 'Empty name' );
if ( strlen ( $name ) > 255 )
return t ( 'Name too long' );
$arr = array ( 'name' => $name );
call_hooks ( 'validate_channelname' , $arr );
if ( x ( $arr , 'message' ))
return $arr [ 'message' ];
}
/**
* @ brief Create a system channel - which has no account attached .
*
*/
function create_sys_channel () {
if ( get_sys_channel ())
return ;
// Ensure that there is a host keypair.
if (( ! get_config ( 'system' , 'pubkey' )) && ( ! get_config ( 'system' , 'prvkey' ))) {
require_once ( 'include/crypto.php' );
$hostkey = new_keypair ( 4096 );
set_config ( 'system' , 'pubkey' , $hostkey [ 'pubkey' ]);
set_config ( 'system' , 'prvkey' , $hostkey [ 'prvkey' ]);
}
create_identity ( array (
'account_id' => 'xxx' , // This will create an identity with an (integer) account_id of 0, but account_id is required
'nickname' => 'sys' ,
'name' => 'System' ,
'pageflags' => 0 ,
'publish' => 0 ,
'system' => 1
));
}
/**
* @ brief Returns the sys channel .
*
* @ return array | boolean
*/
function get_sys_channel () {
$r = q ( " select * from channel left join xchan on channel_hash = xchan_hash where channel_system = 1 limit 1 " );
if ( $r )
return $r [ 0 ];
return false ;
}
/**
* @ brief Checks if $channel_id is sys channel .
*
* @ param int $channel_id
* @ return boolean
*/
function is_sys_channel ( $channel_id ) {
$r = q ( " select channel_system from channel where channel_id = %d and channel_system = 1 limit 1 " ,
intval ( $channel_id )
);
if ( $r )
return true ;
return false ;
}
/**
* @ brief Return the total number of channels on this site .
*
* No filtering is performed except to check PAGE_REMOVED .
*
* @ returns int | booleean
* on error returns boolean false
*/
function channel_total () {
$r = q ( " select channel_id from channel where channel_removed = 0 " );
if ( is_array ( $r ))
return count ( $r );
return false ;
}
/**
* @ brief Create a new channel .
*
* Also creates the related xchan , hubloc , profile , and " self " abook records ,
* and an empty " Friends " group / collection for the new channel .
*
* @ param array $arr assoziative array with :
* * \e string \b name full name of channel
* * \e string \b nickname " email/url-compliant " nickname
* * \e int \b account_id to attach with this channel
* * [ other identity fields as desired ]
*
* @ returns array
* 'success' => boolean true or false
* 'message' => optional error text if success is false
* 'channel' => if successful the created channel array
*/
function create_identity ( $arr ) {
$a = get_app ();
$ret = array ( 'success' => false );
if ( ! $arr [ 'account_id' ]) {
$ret [ 'message' ] = t ( 'No account identifier' );
return $ret ;
}
$ret = identity_check_service_class ( $arr [ 'account_id' ]);
if ( ! $ret [ 'success' ]) {
return $ret ;
}
// save this for auto_friending
$total_identities = $ret [ 'total_identities' ];
$nick = mb_strtolower ( trim ( $arr [ 'nickname' ]));
if ( ! $nick ) {
$ret [ 'message' ] = t ( 'Nickname is required.' );
return $ret ;
}
$name = escape_tags ( $arr [ 'name' ]);
$pageflags = (( x ( $arr , 'pageflags' )) ? intval ( $arr [ 'pageflags' ]) : PAGE_NORMAL );
$system = (( x ( $arr , 'system' )) ? intval ( $arr [ 'system' ]) : 0 );
$name_error = validate_channelname ( $arr [ 'name' ]);
if ( $name_error ) {
$ret [ 'message' ] = $name_error ;
return $ret ;
}
if ( $nick === 'sys' && ( ! $system )) {
$ret [ 'message' ] = t ( 'Reserved nickname. Please choose another.' );
return $ret ;
}
if ( check_webbie ( array ( $nick )) !== $nick ) {
$ret [ 'message' ] = t ( 'Nickname has unsupported characters or is already being used on this site.' );
return $ret ;
}
$guid = zot_new_uid ( $nick );
$key = new_keypair ( 4096 );
$sig = base64url_encode ( rsa_sign ( $guid , $key [ 'prvkey' ]));
$hash = make_xchan_hash ( $guid , $sig );
// Force a few things on the short term until we can provide a theme or app with choice
$publish = 1 ;
if ( array_key_exists ( 'publish' , $arr ))
$publish = intval ( $arr [ 'publish' ]);
$primary = true ;
if ( array_key_exists ( 'primary' , $arr ))
$primary = intval ( $arr [ 'primary' ]);
$role_permissions = null ;
$global_perms = get_perms ();
if ( array_key_exists ( 'permissions_role' , $arr ) && $arr [ 'permissions_role' ]) {
$role_permissions = get_role_perms ( $arr [ 'permissions_role' ]);
if ( $role_permissions ) {
foreach ( $role_permissions as $p => $v ) {
if ( strpos ( $p , 'channel_' ) !== false ) {
$perms_keys .= ', ' . $p ;
$perms_vals .= ', ' . intval ( $v );
}
if ( $p === 'directory_publish' )
$publish = intval ( $v );
}
}
}
else {
$defperms = site_default_perms ();
foreach ( $defperms as $p => $v ) {
$perms_keys .= ', ' . $global_perms [ $p ][ 0 ];
$perms_vals .= ', ' . intval ( $v );
}
}
$expire = 0 ;
$r = q ( " insert into channel ( channel_account_id, channel_primary,
channel_name , channel_address , channel_guid , channel_guid_sig ,
channel_hash , channel_prvkey , channel_pubkey , channel_pageflags , channel_system , channel_expire_days , channel_timezone $perms_keys )
values ( % d , % d , '%s' , '%s' , '%s' , '%s' , '%s' , '%s' , '%s' , % d , % d , % d , '%s' $perms_vals ) " ,
intval ( $arr [ 'account_id' ]),
intval ( $primary ),
dbesc ( $name ),
dbesc ( $nick ),
dbesc ( $guid ),
dbesc ( $sig ),
dbesc ( $hash ),
dbesc ( $key [ 'prvkey' ]),
dbesc ( $key [ 'pubkey' ]),
intval ( $pageflags ),
intval ( $system ),
intval ( $expire ),
dbesc ( $a -> timezone )
);
$r = q ( " select * from channel where channel_account_id = %d
and channel_guid = '%s' limit 1 " ,
intval ( $arr [ 'account_id' ]),
dbesc ( $guid )
);
if ( ! $r ) {
$ret [ 'message' ] = t ( 'Unable to retrieve created identity' );
return $ret ;
}
$ret [ 'channel' ] = $r [ 0 ];
if ( intval ( $arr [ 'account_id' ]))
set_default_login_identity ( $arr [ 'account_id' ], $ret [ 'channel' ][ 'channel_id' ], false );
// Create a verified hub location pointing to this site.
$r = q ( " insert into hubloc ( hubloc_guid, hubloc_guid_sig, hubloc_hash, hubloc_addr, hubloc_primary,
hubloc_url , hubloc_url_sig , hubloc_host , hubloc_callback , hubloc_sitekey , hubloc_network )
values ( '%s' , '%s' , '%s' , '%s' , % d , '%s' , '%s' , '%s' , '%s' , '%s' , '%s' ) " ,
dbesc ( $guid ),
dbesc ( $sig ),
dbesc ( $hash ),
dbesc ( $ret [ 'channel' ][ 'channel_address' ] . '@' . get_app () -> get_hostname ()),
intval ( $primary ),
dbesc ( z_root ()),
dbesc ( base64url_encode ( rsa_sign ( z_root (), $ret [ 'channel' ][ 'channel_prvkey' ]))),
dbesc ( get_app () -> get_hostname ()),
dbesc ( z_root () . '/post' ),
dbesc ( get_config ( 'system' , 'pubkey' )),
dbesc ( 'zot' )
);
if ( ! $r )
logger ( 'create_identity: Unable to store hub location' );
$newuid = $ret [ 'channel' ][ 'channel_id' ];
$r = q ( " insert into xchan ( xchan_hash, xchan_guid, xchan_guid_sig, xchan_pubkey, xchan_photo_l, xchan_photo_m, xchan_photo_s, xchan_addr, xchan_url, xchan_follow, xchan_connurl, xchan_name, xchan_network, xchan_photo_date, xchan_name_date, xchan_system ) values ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d) " ,
dbesc ( $hash ),
dbesc ( $guid ),
dbesc ( $sig ),
dbesc ( $key [ 'pubkey' ]),
dbesc ( $a -> get_baseurl () . " /photo/profile/l/ { $newuid } " ),
dbesc ( $a -> get_baseurl () . " /photo/profile/m/ { $newuid } " ),
dbesc ( $a -> get_baseurl () . " /photo/profile/s/ { $newuid } " ),
dbesc ( $ret [ 'channel' ][ 'channel_address' ] . '@' . get_app () -> get_hostname ()),
dbesc ( z_root () . '/channel/' . $ret [ 'channel' ][ 'channel_address' ]),
dbesc ( z_root () . '/follow?f=&url=%s' ),
dbesc ( z_root () . '/poco/' . $ret [ 'channel' ][ 'channel_address' ]),
dbesc ( $ret [ 'channel' ][ 'channel_name' ]),
dbesc ( 'zot' ),
dbesc ( datetime_convert ()),
dbesc ( datetime_convert ()),
intval ( $system )
);
// Not checking return value.
// It's ok for this to fail if it's an imported channel, and therefore the hash is a duplicate
$r = q ( " INSERT INTO profile ( aid, uid, profile_guid, profile_name, is_default, publish, name, photo, thumb)
VALUES ( % d , % d , '%s' , '%s' , % d , % d , '%s' , '%s' , '%s' ) " ,
intval ( $ret [ 'channel' ][ 'channel_account_id' ]),
intval ( $newuid ),
dbesc ( random_string ()),
t ( 'Default Profile' ),
1 ,
$publish ,
dbesc ( $ret [ 'channel' ][ 'channel_name' ]),
dbesc ( $a -> get_baseurl () . " /photo/profile/l/ { $newuid } " ),
dbesc ( $a -> get_baseurl () . " /photo/profile/m/ { $newuid } " )
);
if ( $role_permissions ) {
$myperms = (( array_key_exists ( 'perms_auto' , $role_permissions ) && $role_permissions [ 'perms_auto' ]) ? intval ( $role_permissions [ 'perms_accept' ]) : 0 );
}
else
$myperms = PERMS_R_STREAM | PERMS_R_PROFILE | PERMS_R_PHOTOS | PERMS_R_ABOOK
| PERMS_W_STREAM | PERMS_W_WALL | PERMS_W_COMMENT | PERMS_W_MAIL | PERMS_W_CHAT
| PERMS_R_STORAGE | PERMS_R_PAGES | PERMS_W_LIKE ;
$r = q ( " insert into abook ( abook_account, abook_channel, abook_xchan, abook_closeness, abook_created, abook_updated, abook_self, abook_my_perms )
values ( % d , % d , '%s' , % d , '%s' , '%s' , % d , % d ) " ,
intval ( $ret [ 'channel' ][ 'channel_account_id' ]),
intval ( $newuid ),
dbesc ( $hash ),
intval ( 0 ),
dbesc ( datetime_convert ()),
dbesc ( datetime_convert ()),
intval ( 1 ),
intval ( $myperms )
);
if ( intval ( $ret [ 'channel' ][ 'channel_account_id' ])) {
// Save our permissions role so we can perhaps call it up and modify it later.
if ( $role_permissions ) {
set_pconfig ( $newuid , 'system' , 'permissions_role' , $arr [ 'permissions_role' ]);
if ( array_key_exists ( 'online' , $role_permissions ))
set_pconfig ( $newuid , 'system' , 'hide_presence' , 1 - intval ( $role_permissions [ 'online' ]));
if ( array_key_exists ( 'perms_auto' , $role_permissions ))
set_pconfig ( $newuid , 'system' , 'autoperms' ,(( $role_permissions [ 'perms_auto' ]) ? $role_permissions [ 'perms_accept' ] : 0 ));
}
// Create a group with yourself as a member. This allows somebody to use it
// right away as a default group for new contacts.
require_once ( 'include/group.php' );
group_add ( $newuid , t ( 'Friends' ));
group_add_member ( $newuid , t ( 'Friends' ), $ret [ 'channel' ][ 'channel_hash' ]);
// if our role_permissions indicate that we're using a default collection ACL, add it.
if ( is_array ( $role_permissions ) && $role_permissions [ 'default_collection' ]) {
$r = q ( " select hash from groups where uid = %d and name = '%s' limit 1 " ,
intval ( $newuid ),
dbesc ( t ( 'Friends' ) )
);
if ( $r ) {
q ( " update channel set channel_default_group = '%s', channel_allow_gid = '%s' where channel_id = %d " ,
dbesc ( $r [ 0 ][ 'hash' ]),
dbesc ( '<' . $r [ 0 ][ 'hash' ] . '>' ),
intval ( $newuid )
);
}
}
if ( ! $system ) {
set_pconfig ( $ret [ 'channel' ][ 'channel_id' ], 'system' , 'photo_path' , '%Y-%m' );
set_pconfig ( $ret [ 'channel' ][ 'channel_id' ], 'system' , 'attach_path' , '%Y-%m' );
}
// auto-follow any of the hub's pre-configured channel choices.
// Only do this if it's the first channel for this account;
// otherwise it could get annoying. Don't make this list too big
// or it will impact registration time.
$accts = get_config ( 'system' , 'auto_follow' );
if (( $accts ) && ( ! $total_identities )) {
require_once ( 'include/follow.php' );
if ( ! is_array ( $accts ))
$accts = array ( $accts );
foreach ( $accts as $acct ) {
if ( trim ( $acct ))
new_contact ( $newuid , trim ( $acct ), $ret [ 'channel' ], false );
}
}
2015-10-24 13:04:14 +02:00
call_hooks ( 'create_identity' , $newuid );
2015-08-23 22:38:18 +02:00
proc_run ( 'php' , 'include/directory.php' , $ret [ 'channel' ][ 'channel_id' ]);
}
$ret [ 'success' ] = true ;
return $ret ;
}
/**
* @ brief Set default channel to be used on login .
*
* @ param int $account_id
* login account
* @ param int $channel_id
* channel id to set as default for this account
* @ param boolean $force
* if true , set this default unconditionally
* if $force is false only do this if there is no existing default
*/
function set_default_login_identity ( $account_id , $channel_id , $force = true ) {
$r = q ( " select account_default_channel from account where account_id = %d limit 1 " ,
intval ( $account_id )
);
if ( $r ) {
if (( intval ( $r [ 0 ][ 'account_default_channel' ]) == 0 ) || ( $force )) {
$r = q ( " update account set account_default_channel = %d where account_id = %d " ,
intval ( $channel_id ),
intval ( $account_id )
);
}
}
}
/**
* @ brief Create an array representing the important channel information
* which would be necessary to create a nomadic identity clone . This includes
* most channel resources and connection information with the exception of content .
*
* @ param int $channel_id
* Channel_id to export
* @ param boolean $items
* Include channel posts ( wall items ), default false
*
* @ returns array
* See function for details
*/
function identity_basic_export ( $channel_id , $items = false ) {
/*
* Red basic channel export
*/
$ret = array ();
$ret [ 'compatibility' ] = array ( 'project' => PLATFORM_NAME , 'version' => RED_VERSION , 'database' => DB_UPDATE_VERSION );
$r = q ( " select * from channel where channel_id = %d limit 1 " ,
intval ( $channel_id )
);
if ( $r )
$ret [ 'channel' ] = $r [ 0 ];
$r = q ( " select * from profile where uid = %d " ,
intval ( $channel_id )
);
if ( $r )
$ret [ 'profile' ] = $r ;
$xchans = array ();
$r = q ( " select * from abook where abook_channel = %d " ,
intval ( $channel_id )
);
if ( $r ) {
$ret [ 'abook' ] = $r ;
foreach ( $r as $rr )
$xchans [] = $rr [ 'abook_xchan' ];
stringify_array_elms ( $xchans );
}
if ( $xchans ) {
$r = q ( " select * from xchan where xchan_hash in ( " . implode ( ',' , $xchans ) . " ) " );
if ( $r )
$ret [ 'xchan' ] = $r ;
$r = q ( " select * from hubloc where hubloc_hash in ( " . implode ( ',' , $xchans ) . " ) " );
if ( $r )
$ret [ 'hubloc' ] = $r ;
}
$r = q ( " select * from `groups` where uid = %d " ,
intval ( $channel_id )
);
if ( $r )
$ret [ 'group' ] = $r ;
$r = q ( " select * from group_member where uid = %d " ,
intval ( $channel_id )
);
if ( $r )
$ret [ 'group_member' ] = $r ;
$r = q ( " select * from pconfig where uid = %d " ,
intval ( $channel_id )
);
if ( $r )
$ret [ 'config' ] = $r ;
$r = q ( " select type, data, os_storage from photo where scale = 4 and profile = 1 and uid = %d limit 1 " ,
intval ( $channel_id )
);
if ( $r ) {
$ret [ 'photo' ] = array ( 'type' => $r [ 0 ][ 'type' ], 'data' => (( $r [ 0 ][ 'os_storage' ]) ? base64url_encode ( file_get_contents ( $r [ 0 ][ 'data' ])) : base64url_encode ( $r [ 0 ][ 'data' ])));
}
// All other term types will be included in items, if requested.
$r = q ( " select * from term where type in (%d,%d) and uid = %d " ,
intval ( TERM_SAVEDSEARCH ),
intval ( TERM_THING ),
intval ( $channel_id )
);
if ( $r )
$ret [ 'term' ] = $r ;
2015-10-24 13:04:14 +02:00
// add psuedo-column obj_baseurl to aid in relocations
$r = q ( " select obj.*, '%s' as obj_baseurl from obj where obj_channel = %d " ,
dbesc ( z_root ()),
2015-08-23 22:38:18 +02:00
intval ( $channel_id )
);
if ( $r )
$ret [ 'obj' ] = $r ;
2015-10-24 13:04:14 +02:00
$r = q ( " select * from app where app_channel = %d " ,
intval ( $channel_id )
);
if ( $r )
$ret [ 'app' ] = $r ;
$r = q ( " select * from chatroom where cr_uid = %d " ,
intval ( $channel_id )
);
if ( $r )
$ret [ 'chatroom' ] = $r ;
$r = q ( " select * from event where uid = %d " ,
intval ( $channel_id )
);
if ( $r )
$ret [ 'event' ] = $r ;
$r = q ( " select * from item where resource_type = 'event' and uid = %d " ,
intval ( $channel_id )
);
if ( $r ) {
$ret [ 'event_item' ] = array ();
xchan_query ( $r );
$r = fetch_post_tags ( $r , true );
foreach ( $r as $rr )
$ret [ 'event_item' ][] = encode_item ( $rr , true );
}
$x = menu_list ( $channel_id );
if ( $x ) {
$ret [ 'menu' ] = array ();
for ( $y = 0 ; $y < count ( $x ); $y ++ ) {
$m = menu_fetch ( $x [ $y ][ 'menu_name' ], $channel_id , $ret [ 'channel' ][ 'channel_hash' ]);
if ( $m )
$ret [ 'menu' ][] = menu_element ( $m );
}
}
$x = menu_list ( $channel_id );
if ( $x ) {
$ret [ 'menu' ] = array ();
for ( $y = 0 ; $y < count ( $x ); $y ++ ) {
$m = menu_fetch ( $x [ $y ][ 'menu_name' ], $channel_id , $ret [ 'channel' ][ 'channel_hash' ]);
if ( $m )
$ret [ 'menu' ][] = menu_element ( $m );
}
}
$addon = array ( 'channel_id' => $channel_id , 'data' => $ret );
call_hooks ( 'identity_basic_export' , $addon );
$ret = $addon [ 'data' ];
2015-08-23 22:38:18 +02:00
if ( ! $items )
return $ret ;
2015-10-24 13:04:14 +02:00
$r = q ( " select * from likes where channel_id = %d " ,
2015-08-23 22:38:18 +02:00
intval ( $channel_id )
);
if ( $r )
$ret [ 'likes' ] = $r ;
2015-10-24 13:04:14 +02:00
$r = q ( " select * from conv where uid = %d " ,
intval ( $channel_id )
);
if ( $r ) {
for ( $x = 0 ; $x < count ( $r ); $x ++ ) {
$r [ $x ][ 'subject' ] = base64url_decode ( str_rot47 ( $r [ $x ][ 'subject' ]));
}
$ret [ 'conv' ] = $r ;
}
$r = q ( " select * from mail where mail.uid = %d " ,
intval ( $channel_id )
);
if ( $r ) {
$m = array ();
foreach ( $r as $rr ) {
xchan_mail_query ( $rr );
$m [] = mail_encode ( $rr , true );
}
$ret [ 'mail' ] = $m ;
}
2015-08-23 22:38:18 +02:00
$r = q ( " select item_id.*, item.mid from item_id left join item on item_id.iid = item.id where item_id.uid = %d " ,
intval ( $channel_id )
);
if ( $r )
$ret [ 'item_id' ] = $r ;
//$key = get_config('system','prvkey');
/** @warning this may run into memory limits on smaller systems */
2015-10-24 13:04:14 +02:00
/** export three months of posts . If you want to export and import all posts you have to start with
2015-08-23 22:38:18 +02:00
* the first year and export / import them in ascending order .
2015-10-24 13:04:14 +02:00
*
* Don 't export linked resource items. we' ll have to pull those out separately .
2015-08-23 22:38:18 +02:00
*/
2015-10-24 13:04:14 +02:00
$r = q ( " select * from item where item_wall = 1 and item_deleted = 0 and uid = %d and created > %s - INTERVAL %s and resource_type = '' order by created " ,
2015-08-23 22:38:18 +02:00
intval ( $channel_id ),
db_utcnow (),
2015-10-24 13:04:14 +02:00
db_quoteinterval ( '3 MONTH' )
2015-08-23 22:38:18 +02:00
);
if ( $r ) {
$ret [ 'item' ] = array ();
xchan_query ( $r );
$r = fetch_post_tags ( $r , true );
foreach ( $r as $rr )
$ret [ 'item' ][] = encode_item ( $rr , true );
}
return $ret ;
}
function identity_export_year ( $channel_id , $year , $month = 0 ) {
if ( ! $year )
return array ();
if ( $month && $month <= 12 ) {
$target_month = sprintf ( '%02d' , $month );
$target_month_plus = sprintf ( '%02d' , $month + 1 );
}
else
$target_month = '01' ;
$ret = array ();
$mindate = datetime_convert ( 'UTC' , 'UTC' , $year . '-' . $target_month . '-01 00:00:00' );
if ( $month && $month < 12 )
$maxdate = datetime_convert ( 'UTC' , 'UTC' , $year . '-' . $target_month_plus . '-01 00:00:00' );
else
$maxdate = datetime_convert ( 'UTC' , 'UTC' , $year + 1 . '-01-01 00:00:00' );
2015-10-24 13:04:14 +02:00
$r = q ( " select * from item where item_wall = 1 and item_deleted = 0 and uid = %d and created >= '%s' and created < '%s' and resource_type = '' order by created " ,
2015-08-23 22:38:18 +02:00
intval ( $channel_id ),
dbesc ( $mindate ),
dbesc ( $maxdate )
);
if ( $r ) {
$ret [ 'item' ] = array ();
xchan_query ( $r );
$r = fetch_post_tags ( $r , true );
foreach ( $r as $rr )
$ret [ 'item' ][] = encode_item ( $rr , true );
}
$r = q ( " select item_id.*, item.mid from item_id left join item on item_id.iid = item.id where item_id.uid = %d
and item . created >= '%s' and item . created < '%s' order by created " ,
intval ( $channel_id ),
dbesc ( $mindate ),
dbesc ( $maxdate )
);
if ( $r )
$ret [ 'item_id' ] = $r ;
return $ret ;
}
/**
* @ brief Loads a profile into the App structure .
*
* The function requires a writeable copy of the main App structure , and the
* nickname of a valid channel .
*
* Permissions of the current observer are checked . If a restricted profile is available
* to the current observer , that will be loaded instead of the channel default profile .
*
* The channel owner can set $profile to a valid profile_guid to preview that profile .
*
* The channel default theme is also selected for use , unless over - riden elsewhere .
*
* @ param [ in , out ] App & $a
* @ param string $nickname
* @ param string $profile
*/
function profile_load ( & $a , $nickname , $profile = '' ) {
2015-10-24 13:04:14 +02:00
// logger('profile_load: ' . $nickname . (($profile) ? ' profile: ' . $profile : ''));
2015-08-23 22:38:18 +02:00
$user = q ( " select channel_id from channel where channel_address = '%s' and channel_removed = 0 limit 1 " ,
dbesc ( $nickname )
);
if ( ! $user ) {
logger ( 'profile error: ' . $a -> query_string , LOGGER_DEBUG );
notice ( t ( 'Requested channel is not available.' ) . EOL );
$a -> error = 404 ;
return ;
}
// get the current observer
$observer = $a -> get_observer ();
$can_view_profile = true ;
// Can the observer see our profile?
require_once ( 'include/permissions.php' );
if ( ! perm_is_allowed ( $user [ 0 ][ 'channel_id' ], $observer [ 'xchan_hash' ], 'view_profile' )) {
$can_view_profile = false ;
}
if ( ! $profile ) {
$r = q ( " SELECT abook_profile FROM abook WHERE abook_xchan = '%s' and abook_channel = '%d' limit 1 " ,
dbesc ( $observer [ 'xchan_hash' ]),
intval ( $user [ 0 ][ 'channel_id' ])
);
if ( $r )
$profile = $r [ 0 ][ 'abook_profile' ];
}
$p = null ;
if ( $profile ) {
$p = q ( " SELECT profile.uid AS profile_uid, profile.*, channel.* FROM profile
LEFT JOIN channel ON profile . uid = channel . channel_id
WHERE channel . channel_address = '%s' AND profile . profile_guid = '%s' LIMIT 1 " ,
dbesc ( $nickname ),
dbesc ( $profile )
);
}
if ( ! $p ) {
$p = q ( " SELECT profile.uid AS profile_uid, profile.*, channel.* FROM profile
LEFT JOIN channel ON profile . uid = channel . channel_id
WHERE channel . channel_address = '%s' and channel_removed = 0
AND profile . is_default = 1 LIMIT 1 " ,
dbesc ( $nickname )
);
}
if ( ! $p ) {
logger ( 'profile error: ' . $a -> query_string , LOGGER_DEBUG );
notice ( t ( 'Requested profile is not available.' ) . EOL );
$a -> error = 404 ;
return ;
}
$q = q ( " select * from profext where hash = '%s' and channel_id = %d " ,
dbesc ( $p [ 0 ][ 'profile_guid' ]),
intval ( $p [ 0 ][ 'profile_uid' ])
);
if ( $q ) {
$extra_fields = array ();
require_once ( 'include/identity.php' );
$profile_fields_basic = get_profile_fields_basic ();
$profile_fields_advanced = get_profile_fields_advanced ();
$advanced = (( feature_enabled ( local_channel (), 'advanced_profiles' )) ? true : false );
if ( $advanced )
$fields = $profile_fields_advanced ;
else
$fields = $profile_fields_basic ;
foreach ( $q as $qq ) {
foreach ( $fields as $k => $f ) {
if ( $k == $qq [ 'k' ]) {
$p [ 0 ][ $k ] = $qq [ 'v' ];
$extra_fields [] = $k ;
break ;
}
}
}
}
$p [ 0 ][ 'extra_fields' ] = $extra_fields ;
$z = q ( " select xchan_photo_date, xchan_addr from xchan where xchan_hash = '%s' limit 1 " ,
dbesc ( $p [ 0 ][ 'channel_hash' ])
);
if ( $z ) {
$p [ 0 ][ 'picdate' ] = $z [ 0 ][ 'xchan_photo_date' ];
$p [ 0 ][ 'reddress' ] = str_replace ( '@' , '@' , $z [ 0 ][ 'xchan_addr' ]);
}
// fetch user tags if this isn't the default profile
if ( ! $p [ 0 ][ 'is_default' ]) {
/** @BUG $profile_uid is undefinded for this query, so should not work. */
$x = q ( " select `keywords` from `profile` where uid = %d and `is_default` = 1 limit 1 " ,
intval ( $profile_uid )
);
if ( $x && $can_view_profile )
$p [ 0 ][ 'keywords' ] = $x [ 0 ][ 'keywords' ];
}
if ( $p [ 0 ][ 'keywords' ]) {
$keywords = str_replace ( array ( '#' , ',' , ' ' , ',,' ), array ( '' , ' ' , ',' , ',' ), $p [ 0 ][ 'keywords' ]);
if ( strlen ( $keywords ) && $can_view_profile )
$a -> page [ 'htmlhead' ] .= '<meta name="keywords" content="' . htmlentities ( $keywords , ENT_COMPAT , 'UTF-8' ) . '" />' . " \r \n " ;
}
$a -> profile = $p [ 0 ];
$a -> profile_uid = $p [ 0 ][ 'profile_uid' ];
$a -> page [ 'title' ] = $a -> profile [ 'channel_name' ] . " - " . $a -> profile [ 'channel_address' ] . " @ " . $a -> get_hostname ();
$a -> profile [ 'permission_to_view' ] = $can_view_profile ;
if ( $can_view_profile ) {
$online = get_online_status ( $nickname );
$a -> profile [ 'online_status' ] = $online [ 'result' ];
}
if ( local_channel ()) {
$a -> profile [ 'channel_mobile_theme' ] = get_pconfig ( local_channel (), 'system' , 'mobile_theme' );
$_SESSION [ 'mobile_theme' ] = $a -> profile [ 'channel_mobile_theme' ];
}
/*
* load / reload current theme info
*/
$_SESSION [ 'theme' ] = $p [ 0 ][ 'channel_theme' ];
// $a->set_template_engine(); // reset the template engine to the default in case the user's theme doesn't specify one
// $theme_info_file = "view/theme/".current_theme()."/php/theme.php";
// if (file_exists($theme_info_file)){
// require_once($theme_info_file);
// }
}
/**
* @ brief
*
* @ param App & $a
* @ param boolean $connect
*/
function profile_create_sidebar ( & $a , $connect = true ) {
$block = ((( get_config ( 'system' , 'block_public' )) && ( ! local_channel ()) && ( ! remote_channel ())) ? true : false );
$a -> set_widget ( 'profile' , profile_sidebar ( $a -> profile , $block , $connect ));
}
/**
* @ brief Formats a profile for display in the sidebar .
*
* It is very difficult to templatise the HTML completely
* because of all the conditional logic .
*
* @ param array $profile
* @ param int $block
* @ param boolean $show_connect
*
* @ return HTML string suitable for sidebar inclusion
* Exceptions : Returns empty string if passed $profile is wrong type or not populated
*/
function profile_sidebar ( $profile , $block = 0 , $show_connect = true ) {
$a = get_app ();
$observer = $a -> get_observer ();
$o = '' ;
$location = false ;
$pdesc = true ;
$reddress = true ;
if (( ! is_array ( $profile )) && ( ! count ( $profile )))
return $o ;
head_set_icon ( $profile [ 'thumb' ]);
$is_owner = (( $profile [ 'uid' ] == local_channel ()) ? true : false );
if ( is_sys_channel ( $profile [ 'uid' ]))
$show_connect = false ;
$profile [ 'picdate' ] = urlencode ( $profile [ 'picdate' ]);
call_hooks ( 'profile_sidebar_enter' , $profile );
require_once ( 'include/Contact.php' );
if ( $show_connect ) {
// This will return an empty string if we're already connected.
$connect_url = rconnect_url ( $profile [ 'uid' ], get_observer_hash ());
$connect = (( $connect_url ) ? t ( 'Connect' ) : '' );
if ( $connect_url )
$connect_url = sprintf ( $connect_url , urlencode ( $profile [ 'channel_address' ] . '@' . $a -> get_hostname ()));
// premium channel - over-ride
if ( $profile [ 'channel_pageflags' ] & PAGE_PREMIUM )
$connect_url = z_root () . '/connect/' . $profile [ 'channel_address' ];
}
// show edit profile to yourself
if ( $is_owner ) {
$profile [ 'menu' ] = array (
'chg_photo' => t ( 'Change profile photo' ),
'entries' => array (),
);
$multi_profiles = feature_enabled ( local_channel (), 'multi_profiles' );
if ( $multi_profiles ) {
$profile [ 'edit' ] = array ( $a -> get_baseurl () . '/profiles' , t ( 'Profiles' ), " " , t ( 'Manage/edit profiles' ));
$profile [ 'menu' ][ 'cr_new' ] = t ( 'Create New Profile' );
}
else
$profile [ 'edit' ] = array ( $a -> get_baseurl () . '/profiles/' . $profile [ 'id' ], t ( 'Edit Profile' ), '' , t ( 'Edit Profile' ));
$r = q ( " SELECT * FROM `profile` WHERE `uid` = %d " ,
local_channel ());
if ( $r ) {
foreach ( $r as $rr ) {
if ( ! ( $multi_profiles || $rr [ 'is_default' ]))
continue ;
$profile [ 'menu' ][ 'entries' ][] = array (
'photo' => $rr [ 'thumb' ],
'id' => $rr [ 'id' ],
'alt' => t ( 'Profile Image' ),
'profile_name' => $rr [ 'profile_name' ],
'isdefault' => $rr [ 'is_default' ],
'visible_to_everybody' => t ( 'visible to everybody' ),
'edit_visibility' => t ( 'Edit visibility' ),
);
}
}
}
if (( x ( $profile , 'address' ) == 1 )
|| ( x ( $profile , 'locality' ) == 1 )
|| ( x ( $profile , 'region' ) == 1 )
|| ( x ( $profile , 'postal_code' ) == 1 )
|| ( x ( $profile , 'country_name' ) == 1 ))
$location = t ( 'Location:' );
$profile [ 'homepage' ] = linkify ( $profile [ 'homepage' ], true );
$gender = (( x ( $profile , 'gender' ) == 1 ) ? t ( 'Gender:' ) : False );
$marital = (( x ( $profile , 'marital' ) == 1 ) ? t ( 'Status:' ) : False );
$homepage = (( x ( $profile , 'homepage' ) == 1 ) ? t ( 'Homepage:' ) : False );
$profile [ 'online' ] = (( $profile [ 'online_status' ] === 'online' ) ? t ( 'Online Now' ) : False );
2015-10-24 13:04:14 +02:00
// logger('online: ' . $profile['online']);
2015-08-23 22:38:18 +02:00
if ( ! perm_is_allowed ( $profile [ 'uid' ],(( is_array ( $observer )) ? $observer [ 'xchan_hash' ] : '' ), 'view_profile' )) {
$block = true ;
}
if (( $profile [ 'hidewall' ] && ( ! local_channel ()) && ( ! remote_channel ())) || $block ) {
$location = $reddress = $pdesc = $gender = $marital = $homepage = False ;
}
$firstname = (( strpos ( $profile [ 'channel_name' ], ' ' ))
? trim ( substr ( $profile [ 'channel_name' ], 0 , strpos ( $profile [ 'channel_name' ], ' ' ))) : $profile [ 'channel_name' ]);
$lastname = (( $firstname === $profile [ 'channel_name' ]) ? '' : trim ( substr ( $profile [ 'channel_name' ], strlen ( $firstname ))));
$diaspora = array (
'podloc' => z_root (),
'searchable' => (( $block ) ? 'false' : 'true' ),
'nickname' => $profile [ 'channel_address' ],
'fullname' => $profile [ 'channel_name' ],
'firstname' => $firstname ,
'lastname' => $lastname ,
'photo300' => z_root () . '/photo/profile/300/' . $profile [ 'uid' ] . '.jpg' ,
'photo100' => z_root () . '/photo/profile/100/' . $profile [ 'uid' ] . '.jpg' ,
'photo50' => z_root () . '/photo/profile/50/' . $profile [ 'uid' ] . '.jpg' ,
);
$contact_block = contact_block ();
$channel_menu = false ;
$menu = get_pconfig ( $profile [ 'uid' ], 'system' , 'channel_menu' );
if ( $menu && ! $block ) {
require_once ( 'include/menu.php' );
$m = menu_fetch ( $menu , $profile [ 'uid' ], $observer [ 'xchan_hash' ]);
if ( $m )
$channel_menu = menu_render ( $m );
}
$menublock = get_pconfig ( $profile [ 'uid' ], 'system' , 'channel_menublock' );
if ( $menublock && ( ! $block )) {
require_once ( 'include/comanche.php' );
$channel_menu .= comanche_block ( $menublock );
}
$tpl = get_markup_template ( 'profile_vcard.tpl' );
require_once ( 'include/widgets.php' );
$z = widget_rating ( array ( 'target' => $profile [ 'channel_hash' ]));
$o .= replace_macros ( $tpl , array (
'$profile' => $profile ,
'$connect' => $connect ,
'$connect_url' => $connect_url ,
'$location' => $location ,
'$gender' => $gender ,
'$pdesc' => $pdesc ,
'$marital' => $marital ,
'$homepage' => $homepage ,
'$chanmenu' => $channel_menu ,
'$diaspora' => $diaspora ,
'$reddress' => $reddress ,
'$rating' => $z ,
'$contact_block' => $contact_block ,
));
$arr = array ( 'profile' => & $profile , 'entry' => & $o );
call_hooks ( 'profile_sidebar' , $arr );
return $o ;
}
/**
* @ FIXME or remove
*/
function get_birthdays () {
$a = get_app ();
$o = '' ;
if ( ! local_channel ())
return $o ;
$bd_format = t ( 'g A l F d' ) ; // 8 AM Friday January 18
$bd_short = t ( 'F d' );
$r = q ( " SELECT `event`.*, `event`.`id` AS `eid`, `contact`.* FROM `event`
LEFT JOIN `contact` ON `contact` . `id` = `event` . `cid`
WHERE `event` . `uid` = % d AND `type` = 'birthday' AND `start` < '%s' AND `finish` > '%s'
ORDER BY `start` ASC " ,
intval ( local_channel ()),
dbesc ( datetime_convert ( 'UTC' , 'UTC' , 'now + 6 days' )),
dbesc ( datetime_convert ( 'UTC' , 'UTC' , 'now' ))
);
if ( $r && count ( $r )) {
$total = 0 ;
$now = strtotime ( 'now' );
$cids = array ();
$istoday = false ;
foreach ( $r as $rr ) {
if ( strlen ( $rr [ 'name' ]))
$total ++ ;
if (( strtotime ( $rr [ 'start' ] . ' +00:00' ) < $now ) && ( strtotime ( $rr [ 'finish' ] . ' +00:00' ) > $now ))
$istoday = true ;
}
$classtoday = $istoday ? ' birthday-today ' : '' ;
if ( $total ) {
foreach ( $r as & $rr ) {
if ( ! strlen ( $rr [ 'name' ]))
continue ;
// avoid duplicates
if ( in_array ( $rr [ 'cid' ], $cids ))
continue ;
$cids [] = $rr [ 'cid' ];
$today = ((( strtotime ( $rr [ 'start' ] . ' +00:00' ) < $now ) && ( strtotime ( $rr [ 'finish' ] . ' +00:00' ) > $now )) ? true : false );
$sparkle = '' ;
$url = $rr [ 'url' ];
if ( $rr [ 'network' ] === NETWORK_DFRN ) {
$sparkle = " sparkle " ;
$url = $a -> get_baseurl () . '/redir/' . $rr [ 'cid' ];
}
$rr [ 'link' ] = $url ;
$rr [ 'title' ] = $rr [ 'name' ];
$rr [ 'date' ] = day_translate ( datetime_convert ( 'UTC' , $a -> timezone , $rr [ 'start' ], $rr [ 'adjust' ] ? $bd_format : $bd_short )) . (( $today ) ? ' ' . t ( '[today]' ) : '' );
$rr [ 'startime' ] = Null ;
$rr [ 'today' ] = $today ;
}
}
}
$tpl = get_markup_template ( " birthdays_reminder.tpl " );
return replace_macros ( $tpl , array (
'$baseurl' => $a -> get_baseurl (),
'$classtoday' => $classtoday ,
'$count' => $total ,
'$event_reminders' => t ( 'Birthday Reminders' ),
'$event_title' => t ( 'Birthdays this week:' ),
'$events' => $r ,
'$lbr' => '{' , // raw brackets mess up if/endif macro processing
'$rbr' => '}'
));
}
/**
* @ FIXME
*/
function get_events () {
require_once ( 'include/bbcode.php' );
$a = get_app ();
if ( ! local_channel ())
return $o ;
$bd_format = t ( 'g A l F d' ) ; // 8 AM Friday January 18
$bd_short = t ( 'F d' );
$r = q ( " SELECT `event`.* FROM `event`
WHERE `event` . `uid` = % d AND `type` != 'birthday' AND `start` < '%s' AND `start` > '%s'
ORDER BY `start` ASC " ,
intval ( local_channel ()),
dbesc ( datetime_convert ( 'UTC' , 'UTC' , 'now + 6 days' )),
dbesc ( datetime_convert ( 'UTC' , 'UTC' , 'now - 1 days' ))
);
if ( $r && count ( $r )) {
$now = strtotime ( 'now' );
$istoday = false ;
foreach ( $r as $rr ) {
if ( strlen ( $rr [ 'name' ]))
$total ++ ;
$strt = datetime_convert ( 'UTC' , $rr [ 'convert' ] ? $a -> timezone : 'UTC' , $rr [ 'start' ], 'Y-m-d' );
if ( $strt === datetime_convert ( 'UTC' , $a -> timezone , 'now' , 'Y-m-d' ))
$istoday = true ;
}
$classtoday = (( $istoday ) ? 'event-today' : '' );
foreach ( $r as & $rr ) {
if ( $rr [ 'adjust' ])
$md = datetime_convert ( 'UTC' , $a -> timezone , $rr [ 'start' ], 'Y/m' );
else
$md = datetime_convert ( 'UTC' , 'UTC' , $rr [ 'start' ], 'Y/m' );
$md .= " /#link- " . $rr [ 'id' ];
$title = substr ( strip_tags ( bbcode ( $rr [ 'desc' ])), 0 , 32 ) . '... ' ;
if ( ! $title )
$title = t ( '[No description]' );
$strt = datetime_convert ( 'UTC' , $rr [ 'convert' ] ? $a -> timezone : 'UTC' , $rr [ 'start' ]);
$today = (( substr ( $strt , 0 , 10 ) === datetime_convert ( 'UTC' , $a -> timezone , 'now' , 'Y-m-d' )) ? true : false );
$rr [ 'link' ] = $md ;
$rr [ 'title' ] = $title ;
$rr [ 'date' ] = day_translate ( datetime_convert ( 'UTC' , $rr [ 'adjust' ] ? $a -> timezone : 'UTC' , $rr [ 'start' ], $bd_format )) . (( $today ) ? ' ' . t ( '[today]' ) : '' );
$rr [ 'startime' ] = $strt ;
$rr [ 'today' ] = $today ;
}
}
$tpl = get_markup_template ( " events_reminder.tpl " );
return replace_macros ( $tpl , array (
'$baseurl' => $a -> get_baseurl (),
'$classtoday' => $classtoday ,
'$count' => count ( $r ),
'$event_reminders' => t ( 'Event Reminders' ),
'$event_title' => t ( 'Events this week:' ),
'$events' => $r ,
));
}
function advanced_profile ( & $a ) {
require_once ( 'include/text.php' );
if ( ! perm_is_allowed ( $a -> profile [ 'profile_uid' ], get_observer_hash (), 'view_profile' ))
return '' ;
$o = '' ;
$o .= '<h2>' . t ( 'Profile' ) . '</h2>' ;
if ( $a -> profile [ 'name' ]) {
$tpl = get_markup_template ( 'profile_advanced.tpl' );
$profile = array ();
$profile [ 'fullname' ] = array ( t ( 'Full Name:' ), $a -> profile [ 'name' ] ) ;
if ( $a -> profile [ 'gender' ]) $profile [ 'gender' ] = array ( t ( 'Gender:' ), $a -> profile [ 'gender' ] );
$ob_hash = get_observer_hash ();
if ( $ob_hash && perm_is_allowed ( $a -> profile [ 'profile_uid' ], $ob_hash , 'post_like' )) {
$profile [ 'canlike' ] = true ;
$profile [ 'likethis' ] = t ( 'Like this channel' );
$profile [ 'profile_guid' ] = $a -> profile [ 'profile_guid' ];
}
$likers = q ( " select liker, xchan.* from likes left join xchan on liker = xchan_hash where channel_id = %d and target_type = '%s' and verb = '%s' " ,
intval ( $a -> profile [ 'profile_uid' ]),
dbesc ( ACTIVITY_OBJ_PROFILE ),
dbesc ( ACTIVITY_LIKE )
);
$profile [ 'likers' ] = array ();
$profile [ 'like_count' ] = count ( $likers );
$profile [ 'like_button_label' ] = tt ( 'Like' , 'Likes' , $profile [ 'like_count' ], 'noun' );
if ( $likers ) {
foreach ( $likers as $l )
$profile [ 'likers' ][] = array ( 'name' => $l [ 'xchan_name' ], 'url' => zid ( $l [ 'xchan_url' ]));
}
if (( $a -> profile [ 'dob' ]) && ( $a -> profile [ 'dob' ] != '0000-00-00' )) {
$val = '' ;
if (( substr ( $a -> profile [ 'dob' ], 5 , 2 ) === '00' ) || ( substr ( $a -> profile [ 'dob' ], 8 , 2 ) === '00' ))
$val = substr ( $a -> profile [ 'dob' ], 0 , 4 );
$year_bd_format = t ( 'j F, Y' );
$short_bd_format = t ( 'j F' );
if ( ! $val ) {
$val = (( intval ( $a -> profile [ 'dob' ]))
? day_translate ( datetime_convert ( 'UTC' , 'UTC' , $a -> profile [ 'dob' ] . ' 00:00 +00:00' , $year_bd_format ))
: day_translate ( datetime_convert ( 'UTC' , 'UTC' , '2001-' . substr ( $a -> profile [ 'dob' ], 5 ) . ' 00:00 +00:00' , $short_bd_format )));
}
$profile [ 'birthday' ] = array ( t ( 'Birthday:' ), $val );
}
if ( $age = age ( $a -> profile [ 'dob' ], $a -> profile [ 'timezone' ], '' ))
$profile [ 'age' ] = array ( t ( 'Age:' ), $age );
if ( $a -> profile [ 'marital' ])
$profile [ 'marital' ] = array ( t ( 'Status:' ), $a -> profile [ 'marital' ]);
if ( $a -> profile [ 'with' ])
$profile [ 'marital' ][ 'with' ] = bbcode ( $a -> profile [ 'with' ]);
if ( strlen ( $a -> profile [ 'howlong' ]) && $a -> profile [ 'howlong' ] !== NULL_DATE ) {
$profile [ 'howlong' ] = relative_date ( $a -> profile [ 'howlong' ], t ( 'for %1$d %2$s' ));
}
if ( $a -> profile [ 'sexual' ]) $profile [ 'sexual' ] = array ( t ( 'Sexual Preference:' ), $a -> profile [ 'sexual' ] );
if ( $a -> profile [ 'homepage' ]) $profile [ 'homepage' ] = array ( t ( 'Homepage:' ), linkify ( $a -> profile [ 'homepage' ]) );
if ( $a -> profile [ 'hometown' ]) $profile [ 'hometown' ] = array ( t ( 'Hometown:' ), linkify ( $a -> profile [ 'hometown' ]) );
if ( $a -> profile [ 'keywords' ]) $profile [ 'keywords' ] = array ( t ( 'Tags:' ), $a -> profile [ 'keywords' ]);
if ( $a -> profile [ 'politic' ]) $profile [ 'politic' ] = array ( t ( 'Political Views:' ), $a -> profile [ 'politic' ]);
if ( $a -> profile [ 'religion' ]) $profile [ 'religion' ] = array ( t ( 'Religion:' ), $a -> profile [ 'religion' ]);
if ( $txt = prepare_text ( $a -> profile [ 'about' ])) $profile [ 'about' ] = array ( t ( 'About:' ), $txt );
if ( $txt = prepare_text ( $a -> profile [ 'interest' ])) $profile [ 'interest' ] = array ( t ( 'Hobbies/Interests:' ), $txt );
if ( $txt = prepare_text ( $a -> profile [ 'likes' ])) $profile [ 'likes' ] = array ( t ( 'Likes:' ), $txt );
if ( $txt = prepare_text ( $a -> profile [ 'dislikes' ])) $profile [ 'dislikes' ] = array ( t ( 'Dislikes:' ), $txt );
if ( $txt = prepare_text ( $a -> profile [ 'contact' ])) $profile [ 'contact' ] = array ( t ( 'Contact information and Social Networks:' ), $txt );
if ( $txt = prepare_text ( $a -> profile [ 'channels' ])) $profile [ 'channels' ] = array ( t ( 'My other channels:' ), $txt );
if ( $txt = prepare_text ( $a -> profile [ 'music' ])) $profile [ 'music' ] = array ( t ( 'Musical interests:' ), $txt );
if ( $txt = prepare_text ( $a -> profile [ 'book' ])) $profile [ 'book' ] = array ( t ( 'Books, literature:' ), $txt );
if ( $txt = prepare_text ( $a -> profile [ 'tv' ])) $profile [ 'tv' ] = array ( t ( 'Television:' ), $txt );
if ( $txt = prepare_text ( $a -> profile [ 'film' ])) $profile [ 'film' ] = array ( t ( 'Film/dance/culture/entertainment:' ), $txt );
if ( $txt = prepare_text ( $a -> profile [ 'romance' ])) $profile [ 'romance' ] = array ( t ( 'Love/Romance:' ), $txt );
if ( $txt = prepare_text ( $a -> profile [ 'work' ])) $profile [ 'work' ] = array ( t ( 'Work/employment:' ), $txt );
if ( $txt = prepare_text ( $a -> profile [ 'education' ])) $profile [ 'education' ] = array ( t ( 'School/education:' ), $txt );
if ( $a -> profile [ 'extra_fields' ]) {
foreach ( $a -> profile [ 'extra_fields' ] as $f ) {
$x = q ( " select * from profdef where field_name = '%s' limit 1 " ,
dbesc ( $f )
);
if ( $x && $txt = prepare_text ( $a -> profile [ $f ]))
$profile [ $f ] = array ( $x [ 0 ][ 'field_desc' ] . ':' , $txt );
}
$profile [ 'extra_fields' ] = $a -> profile [ 'extra_fields' ];
}
$things = get_things ( $a -> profile [ 'profile_guid' ], $a -> profile [ 'profile_uid' ]);
// logger('mod_profile: things: ' . print_r($things,true), LOGGER_DATA);
return replace_macros ( $tpl , array (
'$title' => t ( 'Profile' ),
'$canlike' => (( $profile [ 'canlike' ]) ? true : false ),
'$likethis' => t ( 'Like this thing' ),
'$profile' => $profile ,
'$things' => $things
));
}
return '' ;
}
function get_my_url () {
if ( x ( $_SESSION , 'zrl_override' ))
return $_SESSION [ 'zrl_override' ];
if ( x ( $_SESSION , 'my_url' ))
return $_SESSION [ 'my_url' ];
return false ;
}
function get_my_address () {
if ( x ( $_SESSION , 'zid_override' ))
return $_SESSION [ 'zid_override' ];
if ( x ( $_SESSION , 'my_address' ))
return $_SESSION [ 'my_address' ];
return false ;
}
/**
* @ brief
*
* If somebody arrives at our site using a zid , add their xchan to our DB if we don ' t have it already .
* And if they aren ' t already authenticated here , attempt reverse magic auth .
*
* @ param App & $a
*
* @ hooks 'zid_init'
* string 'zid' - their zid
* string 'url' - the destination url
*/
function zid_init ( & $a ) {
$tmp_str = get_my_address ();
if ( validate_email ( $tmp_str )) {
proc_run ( 'php' , 'include/gprobe.php' , bin2hex ( $tmp_str ));
$arr = array ( 'zid' => $tmp_str , 'url' => $a -> cmd );
call_hooks ( 'zid_init' , $arr );
if ( ! local_channel ()) {
$r = q ( " select * from hubloc where hubloc_addr = '%s' order by hubloc_connected desc limit 1 " ,
dbesc ( $tmp_str )
);
if ( $r && remote_channel () && remote_channel () === $r [ 0 ][ 'hubloc_hash' ])
return ;
logger ( 'zid_init: not authenticated. Invoking reverse magic-auth for ' . $tmp_str );
// try to avoid recursion - but send them home to do a proper magic auth
$query = $a -> query_string ;
$query = str_replace ( array ( '?zid=' , '&zid=' ), array ( '?rzid=' , '&rzid=' ), $query );
$dest = '/' . urlencode ( $query );
if ( $r && ( $r [ 0 ][ 'hubloc_url' ] != z_root ()) && ( ! strstr ( $dest , '/magic' )) && ( ! strstr ( $dest , '/rmagic' ))) {
goaway ( $r [ 0 ][ 'hubloc_url' ] . '/magic' . '?f=&rev=1&dest=' . z_root () . $dest );
}
else
logger ( 'zid_init: no hubloc found.' );
}
}
}
/**
* @ brief Adds a zid parameter to a url .
*
* @ param string $s
* The url to accept the zid
* @ param boolean $address
* $address to use instead of session environment
* @ return string
*
* @ hooks 'zid'
* string url - url to accept zid
* string zid - urlencoded zid
* string result - the return string we calculated , change it if you want to return something else
*/
function zid ( $s , $address = '' ) {
if ( ! strlen ( $s ) || strpos ( $s , 'zid=' ))
return $s ;
$has_params = (( strpos ( $s , '?' )) ? true : false );
$num_slashes = substr_count ( $s , '/' );
if ( ! $has_params )
$has_params = (( strpos ( $s , '&' )) ? true : false );
$achar = strpos ( $s , '?' ) ? '&' : '?' ;
$mine = get_my_url ();
$myaddr = (( $address ) ? $address : get_my_address ());
/** @ FIXME checking against our own channel url is no longer reliable . We may have a lot
* of urls attached to out channel . Should probably match against our site , since we
* will not need to remote authenticate on our own site anyway .
*/
if ( $mine && $myaddr && ( ! link_compare ( $mine , $s )))
$zurl = $s . (( $num_slashes >= 3 ) ? '' : '/' ) . $achar . 'zid=' . urlencode ( $myaddr );
else
$zurl = $s ;
$arr = array ( 'url' => $s , 'zid' => urlencode ( $myaddr ), 'result' => $zurl );
call_hooks ( 'zid' , $arr );
return $arr [ 'result' ];
}
// Used from within PCSS themes to set theme parameters. If there's a
// puid request variable, that is the "page owner" and normally their theme
// settings take precedence; unless a local user sets the "always_my_theme"
// system pconfig, which means they don't want to see anybody else's theme
// settings except their own while on this site.
function get_theme_uid () {
$uid = (( $_REQUEST [ 'puid' ]) ? intval ( $_REQUEST [ 'puid' ]) : 0 );
if ( local_channel ()) {
if (( get_pconfig ( local_channel (), 'system' , 'always_my_theme' )) || ( ! $uid ))
return local_channel ();
}
if ( ! $uid ) {
$x = get_sys_channel ();
if ( $x )
return $x [ 'channel_id' ];
}
return $uid ;
}
/**
* @ brief Retrieves the path of the default_profile_photo for this system
* with the specified size .
*
* @ param int $size
* one of ( 300 , 80 , 48 )
* @ returns string
*/
function get_default_profile_photo ( $size = 300 ) {
$scheme = get_config ( 'system' , 'default_profile_photo' );
if ( ! $scheme )
$scheme = 'rainbow_man' ;
return 'images/default_profile_photos/' . $scheme . '/' . $size . '.png' ;
}
/**
* @ brief Test whether a given identity is NOT a member of the Hubzilla .
*
* @ param string $s ;
* xchan_hash of the identity in question
* @ returns boolean true or false
*/
function is_foreigner ( $s ) {
return (( strpbrk ( $s , '.:@' )) ? true : false );
}
/**
* @ brief Test whether a given identity is a member of the Hubzilla .
*
* @ param string $s ;
* xchan_hash of the identity in question
* @ returns boolean true or false
*/
function is_member ( $s ) {
return (( is_foreigner ( $s )) ? false : true );
}
function get_online_status ( $nick ) {
$ret = array ( 'result' => false );
if ( get_config ( 'system' , 'block_public' ) && ! local_channel () && ! remote_channel ())
return $ret ;
$r = q ( " select channel_id, channel_hash from channel where channel_address = '%s' limit 1 " ,
dbesc ( argv ( 1 ))
);
if ( $r ) {
$hide = get_pconfig ( $r [ 0 ][ 'channel_id' ], 'system' , 'hide_online_status' );
if ( $hide )
return $ret ;
$x = q ( " select cp_status from chatpresence where cp_xchan = '%s' and cp_room = 0 limit 1 " ,
dbesc ( $r [ 0 ][ 'channel_hash' ])
);
if ( $x )
$ret [ 'result' ] = $x [ 0 ][ 'cp_status' ];
}
return $ret ;
}
function remote_online_status ( $webbie ) {
$result = false ;
$r = q ( " select * from hubloc where hubloc_addr = '%s' limit 1 " ,
dbesc ( $webbie )
);
if ( ! $r )
return $result ;
$url = $r [ 0 ][ 'hubloc_url' ] . '/online/' . substr ( $webbie , 0 , strpos ( $webbie , '@' ));
$x = z_fetch_url ( $url );
if ( $x [ 'success' ]) {
$j = json_decode ( $x [ 'body' ], true );
if ( $j )
$result = (( $j [ 'result' ]) ? $j [ 'result' ] : false );
}
return $result ;
}
function get_channel_by_nick ( $nick ) {
$r = q ( " select * from channel where channel_address = '%s' limit 1 " ,
dbesc ( $nick )
);
return (( $r ) ? $r [ 0 ] : false );
}
/**
* @ brief
*
* @ return string
*/
function identity_selector () {
if ( local_channel ()) {
$r = q ( " select channel.*, xchan.* from channel left join xchan on channel.channel_hash = xchan.xchan_hash where channel.channel_account_id = %d and channel_removed = 0 order by channel_name " ,
intval ( get_account_id ())
);
if ( count ( $r ) > 1 ) {
//$account = get_app()->get_account();
$o = replace_macros ( get_markup_template ( 'channel_id_select.tpl' ), array (
'$channels' => $r ,
'$selected' => local_channel ()
));
return $o ;
}
}
return '' ;
}
function is_public_profile () {
if ( ! local_channel ())
return false ;
if ( intval ( get_config ( 'system' , 'block_public' )))
return false ;
$channel = get_app () -> get_channel ();
if ( $channel && $channel [ 'channel_r_profile' ] == PERMS_PUBLIC )
return true ;
return false ;
}
function get_profile_fields_basic ( $filter = 0 ) {
$profile_fields_basic = (( $filter == 0 ) ? get_config ( 'system' , 'profile_fields_basic' ) : null );
if ( ! $profile_fields_basic )
$profile_fields_basic = array ( 'name' , 'pdesc' , 'chandesc' , 'gender' , 'dob' , 'dob_tz' , 'address' , 'locality' , 'region' , 'postal_code' , 'country_name' , 'marital' , 'sexual' , 'homepage' , 'hometown' , 'keywords' , 'about' , 'contact' );
$x = array ();
if ( $profile_fields_basic )
foreach ( $profile_fields_basic as $f )
$x [ $f ] = 1 ;
return $x ;
}
function get_profile_fields_advanced ( $filter = 0 ) {
$basic = get_profile_fields_basic ( $filter );
$profile_fields_advanced = (( $filter == 0 ) ? get_config ( 'system' , 'profile_fields_advanced' ) : null );
if ( ! $profile_fields_advanced )
$profile_fields_advanced = array ( 'with' , 'howlong' , 'politic' , 'religion' , 'likes' , 'dislikes' , 'interest' , 'channels' , 'music' , 'book' , 'film' , 'tv' , 'romance' , 'work' , 'education' );
$x = array ();
if ( $basic )
foreach ( $basic as $f => $v )
$x [ $f ] = $v ;
if ( $profile_fields_advanced )
foreach ( $profile_fields_advanced as $f )
$x [ $f ] = 1 ;
return $x ;
}
/**
* @ brief Clear notifyflags for a channel .
*
* Most likely during bulk import of content or other activity that is likely
* to generate huge amounts of undesired notifications .
*
* @ param int $channel_id
* The channel to disable notifications for
* @ returns int
* Current notification flag value . Send this to notifications_on () to restore the channel settings when finished
* with the activity requiring notifications_off ();
*/
function notifications_off ( $channel_id ) {
$r = q ( " select channel_notifyflags from channel where channel_id = %d limit 1 " ,
intval ( $channel_id )
);
q ( " update channel set channel_notifyflags = 0 where channel_id = %d " ,
intval ( $channel_id )
);
return intval ( $r [ 0 ][ 'channel_notifyflags' ]);
}
function notifications_on ( $channel_id , $value ) {
$x = q ( " update channel set channel_notifyflags = %d where channel_id = %d " ,
intval ( $value ),
intval ( $channel_id )
);
return $x ;
}
function get_channel_default_perms ( $uid ) {
$r = q ( " select abook_my_perms from abook where abook_channel = %d and abook_self = 1 limit 1 " ,
intval ( $uid )
);
if ( $r )
return $r [ 0 ][ 'abook_my_perms' ];
return 0 ;
}