2013-02-26 01:09:40 +00:00
< ? php /** @file */
2012-07-29 00:21:42 +00:00
2012-11-13 04:59:18 +00:00
require_once ( 'include/crypto.php' );
2012-11-27 05:20:16 +00:00
require_once ( 'include/items.php' );
2012-07-29 00:21:42 +00:00
/**
*
2012-09-26 00:57:20 +00:00
* @ function zot_new_uid ( $channel_nick )
* @ channel_id = unique nickname of controlling entity
2012-07-29 00:21:42 +00:00
* @ returns string
*
*/
2012-09-26 00:57:20 +00:00
function zot_new_uid ( $channel_nick ) {
$rawstr = z_root () . '/' . $channel_nick . '.' . mt_rand ();
2012-08-27 06:05:00 +00:00
return ( base64url_encode ( hash ( 'whirlpool' , $rawstr , true ), true ));
2012-07-29 00:21:42 +00:00
}
/**
*
2013-02-20 01:13:23 +00:00
* Given an array of zot hashes , return all distinct hubs
2012-07-29 00:21:42 +00:00
* If primary is true , return only primary hubs
* Result is ordered by url to assist in batching .
2012-08-22 06:11:27 +00:00
* Return only the first primary hub as there should only be one .
2012-07-29 00:21:42 +00:00
*
*/
2012-08-10 03:31:06 +00:00
function zot_get_hubloc ( $arr , $primary = false ) {
2012-07-29 00:21:42 +00:00
$tmp = '' ;
if ( is_array ( $arr )) {
foreach ( $arr as $e ) {
if ( strlen ( $tmp ))
$tmp .= ',' ;
$tmp .= " ' " . dbesc ( $e ) . " ' " ;
}
}
if ( ! strlen ( $tmp ))
return array ();
2012-08-22 06:11:27 +00:00
$sql_extra = (( $primary ) ? " and hubloc_flags & " . intval ( HUBLOC_FLAGS_PRIMARY ) : " " );
$limit = (( $primary ) ? " limit 1 " : " " );
2012-11-01 00:38:22 +00:00
return q ( " select * from hubloc where hubloc_hash in ( $tmp ) $sql_extra order by hubloc_url $limit " );
2012-07-29 00:21:42 +00:00
}
2012-11-15 03:27:16 +00:00
/*
*
* zot_build_packet builds a notification packet that you can either
* store in the queue with a message array or call zot_zot to immediately
* zot it to the other side
*
*/
2012-11-19 03:19:16 +00:00
function zot_build_packet ( $channel , $type = 'notify' , $recipients = null , $remote_key = null , $secret = null ) {
2012-11-15 03:27:16 +00:00
$data = array (
'type' => $type ,
'sender' => array (
'guid' => $channel [ 'channel_guid' ],
'guid_sig' => base64url_encode ( rsa_sign ( $channel [ 'channel_guid' ], $channel [ 'channel_prvkey' ])),
'url' => z_root (),
'url_sig' => base64url_encode ( rsa_sign ( z_root (), $channel [ 'channel_prvkey' ]))
),
'callback' => '/post' ,
'version' => ZOT_REVISION
);
if ( $recipients )
$data [ 'recipients' ] = $recipients ;
2013-01-22 03:16:21 +00:00
if ( $secret ) {
2012-11-19 03:19:16 +00:00
$data [ 'secret' ] = $secret ;
2013-01-22 03:16:21 +00:00
$data [ 'secret_sig' ] = base64url_encode ( rsa_sign ( $secret , $channel [ 'channel_prvkey' ]));
}
2012-11-19 03:19:16 +00:00
2013-01-25 03:45:08 +00:00
logger ( 'zot_build_packet: ' . print_r ( $data , true ), LOGGER_DATA );
2012-11-27 11:08:26 +00:00
2012-11-15 03:27:16 +00:00
// Hush-hush ultra top-secret mode
if ( $remote_key ) {
2012-11-27 11:08:26 +00:00
$data = aes_encapsulate ( json_encode ( $data ), $remote_key );
2012-11-15 03:27:16 +00:00
}
return json_encode ( $data );
}
2013-03-26 04:32:12 +00:00
/**
* @ function : zot_zot
* @ param : string $url
* @ param : array $data
*
* @ returns : array => see z_post_url for returned data format
*/
2012-11-15 03:27:16 +00:00
function zot_zot ( $url , $data ) {
return z_post_url ( $url , array ( 'data' => $data ));
}
2013-03-26 04:32:12 +00:00
/**
* @ function : zot_finger
*
* Look up information about channel
* @ param : string $webbie
* does not have to be host qualified e . g . 'foo' is treated as 'foo@thishub'
* @ param : array $channel
* ( optional ), if supplied permissions will be enumerated specifically for $channel
2013-10-03 05:59:58 +00:00
* @ param : boolean $autofallback
* fallback / failover to http if https connection cannot be established . Default is true .
2013-03-26 04:32:12 +00:00
*
* @ returns : array => see z_post_url and mod / zfinger . php
*/
2013-10-02 05:20:09 +00:00
function zot_finger ( $webbie , $channel , $autofallback = true ) {
2012-11-01 03:53:02 +00:00
2012-11-01 04:42:20 +00:00
2012-11-01 03:53:02 +00:00
if ( strpos ( $webbie , '@' ) === false ) {
$address = $webbie ;
$host = get_app () -> get_hostname ();
}
else {
$address = substr ( $webbie , 0 , strpos ( $webbie , '@' ));
$host = substr ( $webbie , strpos ( $webbie , '@' ) + 1 );
}
$xchan_addr = $address . '@' . $host ;
2013-07-22 05:39:21 +00:00
if (( ! $address ) || ( ! $xchan_addr )) {
logger ( 'zot_finger: no address :' . $webbie );
return array ( 'success' => false );
}
2012-11-01 03:53:02 +00:00
$r = q ( " select xchan.*, hubloc.* from xchan
left join hubloc on xchan_hash = hubloc_hash
where xchan_addr = '%s' and ( hubloc_flags & % d ) limit 1 " ,
2013-08-26 03:11:49 +00:00
dbesc ( $xchan_addr ),
2012-11-01 03:53:02 +00:00
intval ( HUBLOC_FLAGS_PRIMARY )
);
if ( $r ) {
$url = $r [ 0 ][ 'hubloc_url' ];
}
else {
$url = 'https://' . $host ;
}
2012-11-11 07:26:12 +00:00
$rhs = '/.well-known/zot-info' ;
2013-02-14 04:09:30 +00:00
$https = (( strpos ( $url , 'https://' ) === 0 ) ? true : false );
2012-11-01 03:53:02 +00:00
2013-07-22 04:54:20 +00:00
logger ( 'zot_finger: ' . $address . ' at ' . $url , LOGGER_DEBUG );
2013-01-12 23:55:37 +00:00
2012-11-01 03:53:02 +00:00
if ( $channel ) {
$postvars = array (
2012-11-02 22:34:35 +00:00
'address' => $address ,
'target' => $channel [ 'channel_guid' ],
'target_sig' => $channel [ 'channel_guid_sig' ],
'key' => $channel [ 'channel_pubkey' ]
2012-11-01 03:53:02 +00:00
);
2013-01-12 23:55:37 +00:00
2012-11-01 03:53:02 +00:00
$result = z_post_url ( $url . $rhs , $postvars );
2013-02-14 04:09:30 +00:00
2013-10-02 05:20:09 +00:00
if (( ! $result [ 'success' ]) && ( $autofallback )) {
2013-02-14 04:09:30 +00:00
if ( $https ) {
logger ( 'zot_finger: https failed. falling back to http' );
$result = z_post_url ( 'http://' . $host . $rhs , $postvars );
}
}
2012-11-01 03:53:02 +00:00
}
else {
2013-01-12 23:55:37 +00:00
$rhs .= '?f=&address=' . urlencode ( $address );
2012-11-01 03:53:02 +00:00
$result = z_fetch_url ( $url . $rhs );
2013-10-02 05:20:09 +00:00
if (( ! $result [ 'success' ]) && ( $autofallback )) {
2013-02-14 04:09:30 +00:00
if ( $https ) {
logger ( 'zot_finger: https failed. falling back to http' );
$result = z_fetch_url ( 'http://' . $host . $rhs );
}
}
2012-11-01 03:53:02 +00:00
}
2013-02-14 04:09:30 +00:00
if ( ! $result [ 'success' ])
logger ( 'zot_finger: no results' );
2012-11-01 03:53:02 +00:00
return $result ;
}
2013-03-26 04:32:12 +00:00
/**
* @ function : zot_refresh
*
* zot_refresh is typically invoked when somebody has changed permissions of a channel and they are notified
* to fetch new permissions via a finger operation . This may result in a new connection ( abook entry ) being added to a local channel
* and it may result in auto - permissions being granted .
*
*/
2012-11-13 00:16:37 +00:00
function zot_refresh ( $them , $channel = null ) {
2012-11-11 04:08:07 +00:00
2012-12-30 23:28:13 +00:00
logger ( 'zot_refresh: them: ' . print_r ( $them , true ), LOGGER_DATA );
2013-01-03 09:53:22 +00:00
if ( $channel )
logger ( 'zot_refresh: channel: ' . print_r ( $channel , true ), LOGGER_DATA );
2012-12-30 23:28:13 +00:00
2012-11-11 04:08:07 +00:00
if ( $them [ 'hubloc_url' ])
$url = $them [ 'hubloc_url' ];
else {
2013-01-04 00:30:35 +00:00
$r = q ( " select hubloc_url from hubloc where hubloc_hash = '%s' and ( hubloc_flags & %d ) limit 1 " ,
2012-11-11 04:08:07 +00:00
dbesc ( $them [ 'xchan_hash' ]),
intval ( HUBLOC_FLAGS_PRIMARY )
);
if ( $r )
$url = $r [ 0 ][ 'hubloc_url' ];
}
2012-12-30 23:28:13 +00:00
if ( ! $url ) {
logger ( 'zot_refresh: no url' );
2012-12-31 06:41:53 +00:00
return false ;
2012-12-30 23:28:13 +00:00
}
2012-11-11 04:08:07 +00:00
2012-11-13 00:16:37 +00:00
$postvars = array ();
if ( $channel ) {
$postvars [ 'target' ] = $channel [ 'channel_guid' ];
$postvars [ 'target_sig' ] = $channel [ 'channel_guid_sig' ];
$postvars [ 'key' ] = $channel [ 'channel_pubkey' ];
}
if ( array_key_exists ( 'xchan_addr' , $them ) && $them [ 'xchan_addr' ])
$postvars [ 'address' ] = $them [ 'xchan_addr' ];
if ( array_key_exists ( 'xchan_hash' , $them ) && $them [ 'xchan_hash' ])
$postvars [ 'guid_hash' ] = $them [ 'xchan_hash' ];
if ( array_key_exists ( 'xchan_guid' , $them ) && $them [ 'xchan_guid' ]
&& array_key_exists ( 'xchan_guid_sig' , $them ) && $them [ 'xchan_guid_sig' ]) {
$postvars [ 'guid' ] = $them [ 'xchan_guid' ];
$postvars [ 'guid_sig' ] = $them [ 'xchan_guid_sig' ];
}
2012-11-11 07:26:12 +00:00
$rhs = '/.well-known/zot-info' ;
2012-11-11 04:08:07 +00:00
$result = z_post_url ( $url . $rhs , $postvars );
2013-01-25 03:45:08 +00:00
logger ( 'zot_refresh: zot-info: ' . print_r ( $result , true ), LOGGER_DATA );
2013-01-04 00:39:22 +00:00
2012-11-11 04:08:07 +00:00
if ( $result [ 'success' ]) {
2012-11-20 00:51:15 +00:00
$j = json_decode ( $result [ 'body' ], true );
2012-11-11 04:08:07 +00:00
2013-02-02 11:11:23 +00:00
if ( ! (( $j ) && ( $j [ 'success' ]))) {
logger ( 'zot_refresh: result not decodable' );
2013-01-26 23:50:31 +00:00
return false ;
2013-02-02 11:11:23 +00:00
}
2013-01-26 23:50:31 +00:00
2012-11-20 00:51:15 +00:00
$x = import_xchan ( $j );
2012-11-11 04:08:07 +00:00
2013-01-26 23:50:31 +00:00
if ( ! $x [ 'success' ])
return false ;
2012-11-11 04:08:07 +00:00
$xchan_hash = $x [ 'hash' ];
$their_perms = 0 ;
2012-11-13 00:16:37 +00:00
if ( $channel ) {
$global_perms = get_perms ();
2012-11-20 00:51:15 +00:00
if ( $j [ 'permissions' ][ 'data' ]) {
2012-11-13 00:16:37 +00:00
$permissions = aes_unencapsulate ( array (
2012-11-20 00:51:15 +00:00
'data' => $j [ 'permissions' ][ 'data' ],
'key' => $j [ 'permissions' ][ 'key' ],
'iv' => $j [ 'permissions' ][ 'iv' ]),
2012-11-13 00:16:37 +00:00
$channel [ 'channel_prvkey' ]);
if ( $permissions )
2012-11-20 00:51:15 +00:00
$permissions = json_decode ( $permissions , true );
2012-11-13 00:16:37 +00:00
logger ( 'decrypted permissions: ' . print_r ( $permissions , true ), LOGGER_DATA );
}
else
2012-11-20 00:51:15 +00:00
$permissions = $j [ 'permissions' ];
2012-11-13 00:16:37 +00:00
2013-01-02 09:44:50 +00:00
if ( $permissions && is_array ( $permissions )) {
foreach ( $permissions as $k => $v ) {
if ( $v ) {
$their_perms = $their_perms | intval ( $global_perms [ $k ][ 1 ]);
}
2012-11-13 00:16:37 +00:00
}
2012-11-11 04:08:07 +00:00
}
2012-11-30 07:06:03 +00:00
2012-12-02 06:37:41 +00:00
$r = q ( " select * from abook where abook_xchan = '%s' and abook_channel = %d and not (abook_flags & %d) limit 1 " ,
2012-11-13 09:42:08 +00:00
dbesc ( $x [ 'hash' ]),
intval ( $channel [ 'channel_id' ]),
2012-12-02 06:37:41 +00:00
intval ( ABOOK_FLAG_SELF )
2012-11-13 00:16:37 +00:00
);
2013-02-07 22:49:09 +00:00
2012-11-30 02:15:13 +00:00
if ( $r ) {
2013-02-07 22:49:09 +00:00
$y = q ( " update abook set abook_their_perms = %d
2012-11-30 02:15:13 +00:00
where abook_xchan = '%s' and abook_channel = % d
2012-12-02 06:37:41 +00:00
and not ( abook_flags & % d ) limit 1 " ,
2012-11-30 02:15:13 +00:00
intval ( $their_perms ),
dbesc ( $x [ 'hash' ]),
intval ( $channel [ 'channel_id' ]),
2012-12-02 06:37:41 +00:00
intval ( ABOOK_FLAG_SELF )
2012-11-30 02:15:13 +00:00
);
if ( ! $y )
logger ( 'abook update failed' );
}
else {
2012-12-02 06:37:41 +00:00
$default_perms = 0 ;
// look for default permissions to apply in return - e.g. auto-friend
$z = q ( " select * from abook where abook_channel = %d and (abook_flags & %d) limit 1 " ,
intval ( $channel [ 'channel_id' ]),
intval ( ABOOK_FLAG_SELF )
);
2013-02-07 22:49:09 +00:00
2012-12-02 06:37:41 +00:00
if ( $z )
2013-02-07 22:49:09 +00:00
$default_perms = intval ( $z [ 0 ][ 'abook_my_perms' ]);
2012-12-02 06:37:41 +00:00
2013-01-03 09:53:22 +00:00
$y = q ( " insert into abook ( abook_account, abook_channel, abook_xchan, abook_their_perms, abook_my_perms, abook_created, abook_updated, abook_flags ) values ( %d, %d, '%s', %d, %d, '%s', '%s', %d ) " ,
2012-11-30 02:15:13 +00:00
intval ( $channel [ 'channel_account_id' ]),
intval ( $channel [ 'channel_id' ]),
dbesc ( $x [ 'hash' ]),
intval ( $their_perms ),
2012-12-02 06:37:41 +00:00
intval ( $default_perms ),
2012-11-30 02:15:13 +00:00
dbesc ( datetime_convert ()),
dbesc ( datetime_convert ()),
2012-12-20 00:48:17 +00:00
intval (( $default_perms ) ? 0 : ABOOK_FLAG_PENDING )
2012-11-30 02:15:13 +00:00
);
2013-02-07 22:49:09 +00:00
2012-12-02 06:37:41 +00:00
if ( $y ) {
2013-02-07 22:49:09 +00:00
2012-11-30 02:15:13 +00:00
logger ( " New introduction received for { $channel [ 'channel_name' ] } " );
2012-12-02 06:37:41 +00:00
if ( $default_perms ) {
// send back a permissions update for auto-friend/auto-permissions
$z = q ( " select * from abook where abook_xchan = '%s' and abook_channel = %d and not (abook_flags & %d) limit 1 " ,
dbesc ( $x [ 'hash' ]),
intval ( $channel [ 'channel_id' ]),
intval ( ABOOK_FLAG_SELF )
);
if ( $z )
2013-05-20 03:16:05 +00:00
proc_run ( 'php' , 'include/notifier.php' , 'permission_update' , $z [ 0 ][ 'abook_id' ]);
2012-12-02 06:37:41 +00:00
}
}
2012-11-30 02:15:13 +00:00
}
2012-11-11 04:08:07 +00:00
}
return true ;
}
return false ;
}
2013-03-26 04:32:12 +00:00
/**
* @ function : zot_gethub
*
* A guid and a url , both signed by the sender , distinguish a known sender at a known location
* This function looks these up to see if the channel is known . If not , we will need to verify it .
* @ returns : array => hubloc record
*/
2012-08-01 00:55:27 +00:00
2012-11-20 00:51:15 +00:00
function zot_gethub ( $arr ) {
2012-11-13 04:59:18 +00:00
2012-11-20 00:51:15 +00:00
if ( $arr [ 'guid' ] && $arr [ 'guid_sig' ] && $arr [ 'url' ] && $arr [ 'url_sig' ]) {
2012-08-10 03:31:06 +00:00
$r = q ( " select * from hubloc
2012-08-27 06:05:00 +00:00
where hubloc_guid = '%s' and hubloc_guid_sig = '%s'
and hubloc_url = '%s' and hubloc_url_sig = '%s'
2012-08-10 03:31:06 +00:00
limit 1 " ,
2012-11-20 00:51:15 +00:00
dbesc ( $arr [ 'guid' ]),
dbesc ( $arr [ 'guid_sig' ]),
dbesc ( $arr [ 'url' ]),
dbesc ( $arr [ 'url_sig' ])
2012-08-10 03:31:06 +00:00
);
2013-01-05 03:24:17 +00:00
if ( $r && count ( $r )) {
logger ( 'zot_gethub: found' , LOGGER_DEBUG );
2012-08-10 03:31:06 +00:00
return $r [ 0 ];
2013-01-05 03:24:17 +00:00
}
2012-08-10 03:31:06 +00:00
}
2013-07-15 03:42:06 +00:00
logger ( 'zot_gethub: not found: ' . print_r ( $arr , true ), LOGGER_DEBUG );
2012-08-10 03:31:06 +00:00
return null ;
}
function zot_register_hub ( $arr ) {
2012-11-11 07:26:12 +00:00
$result = array ( 'success' => false );
2012-12-30 07:45:06 +00:00
if ( $arr [ 'url' ] && $arr [ 'url_sig' ] && $arr [ 'guid' ] && $arr [ 'guid_sig' ]) {
2012-11-11 07:26:12 +00:00
2012-11-20 00:51:15 +00:00
$guid_hash = base64url_encode ( hash ( 'whirlpool' , $arr [ 'guid' ] . $arr [ 'guid_sig' ], true ));
2012-11-11 07:26:12 +00:00
2013-01-03 00:28:47 +00:00
$url = $arr [ 'url' ] . '/.well-known/zot-info/?f=&guid_hash=' . $guid_hash ;
2013-01-25 03:45:08 +00:00
logger ( 'zot_register_hub: ' . $url , LOGGER_DEBUG );
2013-01-03 00:28:47 +00:00
$x = z_fetch_url ( $url );
2013-01-25 03:45:08 +00:00
logger ( 'zot_register_hub: ' . print_r ( $x , true ), LOGGER_DATA );
2012-11-11 07:26:12 +00:00
2012-08-10 03:31:06 +00:00
if ( $x [ 'success' ]) {
2012-11-20 00:51:15 +00:00
$record = json_decode ( $x [ 'body' ], true );
$c = import_xchan ( $record );
2012-11-11 07:26:12 +00:00
if ( $c [ 'success' ])
$result [ 'success' ] = true ;
2012-08-10 03:31:06 +00:00
}
}
2012-11-11 07:26:12 +00:00
return $result ;
2012-08-22 06:11:27 +00:00
}
2012-11-02 05:23:13 +00:00
2012-11-15 03:27:16 +00:00
// Takes a json associative array from zot_finger and imports the xchan and hublocs
// If the xchan already exists, update the name and photo if these have changed.
//
2013-09-25 03:13:53 +00:00
function import_xchan ( $arr , $ud_flags = 1 ) {
2012-11-15 03:27:16 +00:00
$ret = array ( 'success' => false );
2013-07-24 05:33:56 +00:00
$dirmode = intval ( get_config ( 'system' , 'directory_mode' ));
2013-03-21 09:21:44 +00:00
$changed = false ;
2013-09-15 10:48:43 +00:00
$what = '' ;
2012-11-15 03:27:16 +00:00
2013-07-19 01:22:08 +00:00
if ( ! ( is_array ( $arr ) && array_key_exists ( 'success' , $arr ) && $arr [ 'success' ])) {
logger ( 'import_xchan: invalid data packet: ' . print_r ( $arr , true ));
$ret [ 'message' ] = t ( 'Invalid data packet' );
return $ret ;
}
2012-11-20 00:51:15 +00:00
$xchan_hash = base64url_encode ( hash ( 'whirlpool' , $arr [ 'guid' ] . $arr [ 'guid_sig' ], true ));
2012-11-15 03:27:16 +00:00
$import_photos = false ;
2012-11-20 00:51:15 +00:00
if ( ! rsa_verify ( $arr [ 'guid' ], base64url_decode ( $arr [ 'guid_sig' ]), $arr [ 'key' ])) {
2012-12-30 23:28:13 +00:00
logger ( 'import_xchan: Unable to verify channel signature for ' . $arr [ 'address' ]);
2012-11-15 03:27:16 +00:00
$ret [ 'message' ] = t ( 'Unable to verify channel signature' );
return $ret ;
}
2013-04-30 01:21:23 +00:00
logger ( 'import_xchan: ' . $xchan_hash , LOGGER_DEBUG );
2012-11-15 03:27:16 +00:00
$r = q ( " select * from xchan where xchan_hash = '%s' limit 1 " ,
dbesc ( $xchan_hash )
);
2013-08-22 00:34:04 +00:00
if ( ! array_key_exists ( 'connect_url' , $arr ))
$arr [ 'connect_url' ] = '' ;
2013-08-26 03:17:45 +00:00
if ( strpos ( $arr [ 'address' ], '/' ) !== false )
$arr [ 'address' ] = substr ( $arr [ 'address' ], 0 , strpos ( $arr [ 'address' ], '/' ));
2013-01-22 08:20:25 +00:00
2012-11-15 03:27:16 +00:00
if ( $r ) {
2012-11-20 00:51:15 +00:00
if ( $r [ 0 ][ 'xchan_photo_date' ] != $arr [ 'photo_updated' ])
2013-01-22 08:20:25 +00:00
$import_photos = true ;
2013-01-22 10:56:32 +00:00
// if we import an entry from a site that's not ours and either or both of us is off the grid - hide the entry.
// TODO: check if we're the same directory realm, which would mean we are allowed to see it
$dirmode = get_config ( 'system' , 'directory_mode' );
if ((( $arr [ 'site' ][ 'directory_mode' ] === 'standalone' ) || ( $dirmode & DIRECTORY_MODE_STANDALONE ))
&& ( $arr [ 'site' ][ 'url' ] != z_root ()))
$arr [ 'searchable' ] = false ;
2013-02-02 11:11:23 +00:00
$hidden = ( 1 - intval ( $arr [ 'searchable' ]));
2013-01-22 10:56:32 +00:00
// Be careful - XCHAN_FLAGS_HIDDEN should evaluate to 1
2013-02-02 11:11:23 +00:00
if (( $r [ 0 ][ 'xchan_flags' ] & XCHAN_FLAGS_HIDDEN ) != $hidden )
2013-01-22 08:20:25 +00:00
$new_flags = $r [ 0 ][ 'xchan_flags' ] ^ XCHAN_FLAGS_HIDDEN ;
else
$new_flags = $r [ 0 ][ 'xchan_flags' ];
2013-08-22 00:34:04 +00:00
2013-09-23 03:38:24 +00:00
$adult = (( $r [ 0 ][ 'xchan_flags' ] & XCHAN_FLAGS_SELFCENSORED ) ? true : false );
$adult_changed = (( intval ( $adult ) != intval ( $arr [ 'adult_content' ])) ? true : false );
if ( $adult_changed )
$new_flags = $new_flags ^ XCHAN_FLAGS_SELFCENSORED ;
2013-08-26 03:17:45 +00:00
2013-03-13 00:39:35 +00:00
if (( $r [ 0 ][ 'xchan_name_date' ] != $arr [ 'name_updated' ])
|| ( $r [ 0 ][ 'xchan_connurl' ] != $arr [ 'connections_url' ])
|| ( $r [ 0 ][ 'xchan_flags' ] != $new_flags )
|| ( $r [ 0 ][ 'xchan_addr' ] != $arr [ 'address' ])
2013-08-22 00:34:04 +00:00
|| ( $r [ 0 ][ 'xchan_follow' ] != $arr [ 'follow_url' ])
|| ( $r [ 0 ][ 'xchan_connpage' ] != $arr [ 'connect_url' ])
2013-03-13 00:39:35 +00:00
|| ( $r [ 0 ][ 'xchan_url' ] != $arr [ 'url' ])) {
2013-08-22 00:34:04 +00:00
$r = q ( " update xchan set xchan_name = '%s', xchan_name_date = '%s', xchan_connurl = '%s', xchan_follow = '%s',
xchan_connpage = '%s' , xchan_flags = % d ,
2013-03-13 00:39:35 +00:00
xchan_addr = '%s' , xchan_url = '%s' where xchan_hash = '%s' limit 1 " ,
2012-11-20 00:51:15 +00:00
dbesc ( $arr [ 'name' ]),
dbesc ( $arr [ 'name_updated' ]),
2013-01-01 10:06:41 +00:00
dbesc ( $arr [ 'connections_url' ]),
2013-08-22 00:34:04 +00:00
dbesc ( $arr [ 'follow_url' ]),
dbesc ( $arr [ 'connect_url' ]),
2013-01-22 08:20:25 +00:00
intval ( $new_flags ),
2013-03-13 00:39:35 +00:00
dbesc ( $arr [ 'address' ]),
dbesc ( $arr [ 'url' ]),
2012-11-15 03:27:16 +00:00
dbesc ( $xchan_hash )
);
2013-04-30 01:21:23 +00:00
logger ( 'import_xchan: existing: ' . print_r ( $r [ 0 ], true ), LOGGER_DATA );
logger ( 'import_xchan: new: ' . print_r ( $arr , true ), LOGGER_DATA );
2013-09-15 10:48:43 +00:00
$what .= 'xchan ' ;
2013-03-21 09:21:44 +00:00
$changed = true ;
2012-11-15 03:27:16 +00:00
}
}
else {
$import_photos = true ;
2013-03-27 02:37:33 +00:00
if ((( $arr [ 'site' ][ 'directory_mode' ] === 'standalone' ) || ( $dirmode & DIRECTORY_MODE_STANDALONE ))
&& ( $arr [ 'site' ][ 'url' ] != z_root ()))
$arr [ 'searchable' ] = false ;
$hidden = ( 1 - intval ( $arr [ 'searchable' ]));
if ( $hidden )
$new_flags = XCHAN_FLAGS_HIDDEN ;
else
$new_flags = 0 ;
2013-09-23 03:38:24 +00:00
if ( $arr [ 'adult_content' ])
$new_flags |= XCHAN_FLAGS_SELFCENSORED ;
2013-03-27 02:37:33 +00:00
2012-11-15 03:27:16 +00:00
$x = q ( " insert into xchan ( xchan_hash, xchan_guid, xchan_guid_sig, xchan_pubkey, xchan_photo_mimetype,
2013-08-22 00:34:04 +00:00
xchan_photo_l , xchan_addr , xchan_url , xchan_connurl , xchan_follow , xchan_connpage , xchan_name , xchan_network , xchan_photo_date , xchan_name_date , xchan_flags )
values ( '%s' , '%s' , '%s' , '%s' , '%s' , '%s' , '%s' , '%s' , '%s' , '%s' , '%s' , '%s' , '%s' , '%s' , '%s' , % d ) " ,
2012-11-15 03:27:16 +00:00
dbesc ( $xchan_hash ),
2012-11-20 00:51:15 +00:00
dbesc ( $arr [ 'guid' ]),
dbesc ( $arr [ 'guid_sig' ]),
dbesc ( $arr [ 'key' ]),
dbesc ( $arr [ 'photo_mimetype' ]),
dbesc ( $arr [ 'photo' ]),
dbesc ( $arr [ 'address' ]),
dbesc ( $arr [ 'url' ]),
2013-01-01 10:06:41 +00:00
dbesc ( $arr [ 'connections_url' ]),
2013-08-22 00:34:04 +00:00
dbesc ( $arr [ 'follow_url' ]),
dbesc ( $arr [ 'connect_url' ]),
2012-11-20 00:51:15 +00:00
dbesc ( $arr [ 'name' ]),
2012-11-15 03:27:16 +00:00
dbesc ( 'zot' ),
2012-11-20 00:51:15 +00:00
dbesc ( $arr [ 'photo_updated' ]),
2013-03-27 02:37:33 +00:00
dbesc ( $arr [ 'name_updated' ]),
intval ( $new_flags )
2012-11-15 03:27:16 +00:00
);
2013-09-09 08:05:29 +00:00
2013-09-15 10:48:43 +00:00
$what .= 'new_xchan' ;
2013-03-21 09:21:44 +00:00
$changed = true ;
2012-11-15 03:27:16 +00:00
}
if ( $import_photos ) {
2013-04-26 03:01:24 +00:00
require_once ( 'include/photo/photo_driver.php' );
2012-11-15 03:27:16 +00:00
2012-12-06 23:52:37 +00:00
$photos = import_profile_photo ( $arr [ 'photo' ], $xchan_hash );
2012-11-15 03:27:16 +00:00
$r = q ( " update xchan set xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s'
where xchan_hash = '%s' limit 1 " ,
2012-11-20 00:51:15 +00:00
dbesc ( $arr [ 'photo_updated' ]),
2012-11-15 03:27:16 +00:00
dbesc ( $photos [ 0 ]),
dbesc ( $photos [ 1 ]),
dbesc ( $photos [ 2 ]),
dbesc ( $photos [ 3 ]),
dbesc ( $xchan_hash )
);
2013-03-21 09:21:44 +00:00
2013-09-15 10:48:43 +00:00
$what .= 'photo ' ;
2013-03-21 09:21:44 +00:00
$changed = true ;
2012-11-15 03:27:16 +00:00
}
2013-03-11 01:45:58 +00:00
// what we are missing for true hub independence is for any changes in the primary hub to
// get reflected not only in the hublocs, but also to update the URLs and addr in the appropriate xchan
2012-11-20 00:51:15 +00:00
if ( $arr [ 'locations' ]) {
2013-03-11 01:45:58 +00:00
$xisting = q ( " select hubloc_id, hubloc_url from hubloc where hubloc_hash = '%s' " ,
dbesc ( $xchan_hash )
);
2012-11-20 00:51:15 +00:00
foreach ( $arr [ 'locations' ] as $location ) {
if ( ! rsa_verify ( $location [ 'url' ], base64url_decode ( $location [ 'url_sig' ]), $arr [ 'key' ])) {
2012-12-30 23:28:13 +00:00
logger ( 'import_xchan: Unable to verify site signature for ' . $location [ 'url' ]);
2012-11-15 03:27:16 +00:00
$ret [ 'message' ] .= sprintf ( t ( 'Unable to verify site signature for %s' ), $location [ 'url' ]) . EOL ;
continue ;
}
2013-03-11 01:45:58 +00:00
for ( $x = 0 ; $x < count ( $xisting ); $x ++ ) {
2013-03-11 23:13:09 +00:00
if ( $xisting [ $x ][ 'hubloc_url' ] == $location [ 'url' ]) {
2013-03-11 01:45:58 +00:00
$xisting [ $x ][ 'updated' ] = true ;
}
}
2013-09-14 08:56:25 +00:00
// match as many fields as possible in case anything at all changed.
$r = q ( " select * from hubloc where hubloc_hash = '%s' and hubloc_guid = '%s' and hubloc_guid_sig = '%s' and hubloc_url = '%s' and hubloc_url_sig = '%s' and hubloc_host = '%s' and hubloc_addr = '%s' and hubloc_callback = '%s' and hubloc_sitekey = '%s' limit 1 " ,
2012-11-15 03:27:16 +00:00
dbesc ( $xchan_hash ),
2013-07-15 03:42:06 +00:00
dbesc ( $arr [ 'guid' ]),
dbesc ( $arr [ 'guid_sig' ]),
dbesc ( $location [ 'url' ]),
2013-09-14 08:56:25 +00:00
dbesc ( $location [ 'url_sig' ]),
dbesc ( $location [ 'host' ]),
dbesc ( $location [ 'address' ]),
dbesc ( $location [ 'callback' ]),
dbesc ( $location [ 'sitekey' ])
2012-11-15 03:27:16 +00:00
);
if ( $r ) {
2013-07-15 01:32:20 +00:00
logger ( 'import_xchan: hub exists: ' . $location [ 'url' ]);
2013-08-28 00:08:59 +00:00
// update connection timestamp
q ( " update hubloc set hubloc_connected = '%s' where hubloc_id = %d limit 1 " ,
dbesc ( datetime_convert ()),
intval ( $r [ 0 ][ 'hubloc_id' ])
);
2013-03-11 01:45:58 +00:00
if ((( $r [ 0 ][ 'hubloc_flags' ] & HUBLOC_FLAGS_PRIMARY ) && ( ! $location [ 'primary' ]))
|| (( ! ( $r [ 0 ][ 'hubloc_flags' ] & HUBLOC_FLAGS_PRIMARY )) && ( $location [ 'primary' ]))) {
2013-08-28 00:08:59 +00:00
$r = q ( " update hubloc set hubloc_flags = (hubloc_flags ^ %d), hubloc_updated = '%s' where hubloc_id = %d limit 1 " ,
2012-11-15 03:27:16 +00:00
intval ( HUBLOC_FLAGS_PRIMARY ),
2013-08-28 00:08:59 +00:00
dbesc ( datetime_convert ()),
2012-11-15 03:27:16 +00:00
intval ( $r [ 0 ][ 'hubloc_id' ])
);
2013-09-15 10:48:43 +00:00
$what = 'primary_hub ' ;
2013-08-11 23:12:40 +00:00
$changed = true ;
2012-11-15 03:27:16 +00:00
}
2013-09-18 03:50:09 +00:00
if ((( $r [ 0 ][ 'hubloc_flags' ] & HUBLOC_FLAGS_DELETED ) && ( ! $location [ 'deleted' ]))
|| (( ! ( $r [ 0 ][ 'hubloc_flags' ] & HUBLOC_FLAGS_DELETED )) && ( $location [ 'deleted' ]))) {
$r = q ( " update hubloc set hubloc_flags = (hubloc_flags ^ %d), hubloc_updated = '%s' where hubloc_id = %d limit 1 " ,
intval ( HUBLOC_FLAGS_DELETED ),
dbesc ( datetime_convert ()),
intval ( $r [ 0 ][ 'hubloc_id' ])
);
$what = 'delete_hub ' ;
$changed = true ;
}
2013-08-11 23:12:40 +00:00
continue ;
}
if ( ! $location [ 'sitekey' ]) {
logger ( 'import_xchan: empty hubloc sitekey. ' . print_r ( $location , true ));
2012-11-15 03:27:16 +00:00
continue ;
}
2013-08-27 00:06:19 +00:00
if ( strpos ( $location [ 'address' ], '/' ) !== false )
$location [ 'address' ] = substr ( $location [ 'address' ], 0 , strpos ( $location [ 'address' ], '/' ));
2013-03-11 01:45:58 +00:00
// new hub claiming to be primary. Make it so.
if ( intval ( $location [ 'primary' ])) {
2013-08-28 00:08:59 +00:00
$r = q ( " update hubloc set hubloc_flags = (hubloc_flags ^ %d), hubloc_updated = '%s' where hubloc_hash = '%s' and (hubloc_flags & %d ) " ,
2013-03-11 01:45:58 +00:00
intval ( HUBLOC_FLAGS_PRIMARY ),
2013-08-28 00:08:59 +00:00
dbesc ( datetime_convert ()),
2013-03-11 01:45:58 +00:00
dbesc ( $xchan_hash ),
intval ( HUBLOC_FLAGS_PRIMARY )
);
}
2013-07-15 01:32:20 +00:00
logger ( 'import_xchan: new hub: ' . $location [ 'url' ]);
2013-08-28 00:08:59 +00:00
$r = q ( " insert into hubloc ( hubloc_guid, hubloc_guid_sig, hubloc_hash, hubloc_addr, hubloc_flags, hubloc_url, hubloc_url_sig, hubloc_host, hubloc_callback, hubloc_sitekey, hubloc_updated, hubloc_connected)
values ( '%s' , '%s' , '%s' , '%s' , % d , '%s' , '%s' , '%s' , '%s' , '%s' , '%s' , '%s' ) " ,
2012-11-20 00:51:15 +00:00
dbesc ( $arr [ 'guid' ]),
dbesc ( $arr [ 'guid_sig' ]),
2012-11-15 03:27:16 +00:00
dbesc ( $xchan_hash ),
dbesc ( $location [ 'address' ]),
intval (( intval ( $location [ 'primary' ])) ? HUBLOC_FLAGS_PRIMARY : 0 ),
dbesc ( $location [ 'url' ]),
dbesc ( $location [ 'url_sig' ]),
dbesc ( $location [ 'host' ]),
dbesc ( $location [ 'callback' ]),
2013-08-28 00:08:59 +00:00
dbesc ( $location [ 'sitekey' ]),
dbesc ( datetime_convert ()),
dbesc ( datetime_convert ())
2012-11-15 03:27:16 +00:00
);
2013-09-15 10:48:43 +00:00
$what .= 'newhub ' ;
2013-03-21 09:21:44 +00:00
$changed = true ;
2012-11-15 03:27:16 +00:00
}
2013-03-11 01:45:58 +00:00
// get rid of any hubs we have for this channel which weren't reported.
if ( $xisting ) {
foreach ( $xisting as $x ) {
if ( ! array_key_exists ( 'updated' , $x )) {
2013-03-12 01:22:40 +00:00
logger ( 'import_xchan: removing unreferenced hub location ' . $x [ 'hubloc_url' ]);
2013-03-11 01:45:58 +00:00
$r = q ( " delete from hubloc where hubloc_id = %d limit 1 " ,
intval ( $x [ 'hubloc_id' ])
);
2013-09-15 10:48:43 +00:00
$what .= 'removed_hub' ;
2013-03-21 09:21:44 +00:00
$changed = true ;
2013-03-11 01:45:58 +00:00
}
}
}
2012-11-15 03:27:16 +00:00
}
2013-05-01 01:16:51 +00:00
// Are we a directory server of some kind?
2013-07-24 05:33:56 +00:00
2013-05-01 01:16:51 +00:00
if ( $dirmode != DIRECTORY_MODE_NORMAL ) {
if ( array_key_exists ( 'profile' , $arr ) && is_array ( $arr [ 'profile' ])) {
2013-09-26 04:22:36 +00:00
$profile_changed = import_directory_profile ( $xchan_hash , $arr [ 'profile' ], $arr [ 'address' ], $ud_flags , 1 );
2013-05-01 01:16:51 +00:00
if ( $profile_changed ) {
2013-09-15 10:48:43 +00:00
$what .= 'profile ' ;
2013-05-01 01:16:51 +00:00
$changed = true ;
}
}
else {
logger ( 'import_xchan: profile not available - hiding' );
// they may have made it private
$r = q ( " delete from xprof where xprof_hash = '%s' limit 1 " ,
dbesc ( $xchan_hash )
);
$r = q ( " delete from xtag where xtag_hash = '%s' limit 1 " ,
dbesc ( $xchan_hash )
);
}
}
2013-07-24 05:33:56 +00:00
if ( array_key_exists ( 'site' , $arr ) && is_array ( $arr [ 'site' ])) {
$profile_changed = import_site ( $arr [ 'site' ], $arr [ 'key' ]);
if ( $profile_changed ) {
2013-09-15 10:48:43 +00:00
$what .= 'site ' ;
2013-07-24 05:33:56 +00:00
$changed = true ;
}
}
2013-05-01 01:16:51 +00:00
2013-03-21 09:21:44 +00:00
if ( $changed ) {
2013-09-09 08:05:29 +00:00
$guid = random_string () . '@' . get_app () -> get_hostname ();
2013-09-25 03:13:53 +00:00
update_modtime ( $xchan_hash , $guid , $arr [ 'address' ], $ud_flags );
2013-09-15 10:48:43 +00:00
logger ( 'import_xchan: changed: ' . $what , LOGGER_DEBUG );
2013-03-21 09:21:44 +00:00
}
2012-11-15 03:27:16 +00:00
if ( ! x ( $ret , 'message' )) {
$ret [ 'success' ] = true ;
$ret [ 'hash' ] = $xchan_hash ;
}
2012-12-30 23:28:13 +00:00
logger ( 'import_xchan: result: ' . print_r ( $ret , true ), LOGGER_DATA );
2012-11-15 03:27:16 +00:00
return $ret ;
}
2012-12-31 22:45:26 +00:00
function zot_process_response ( $hub , $arr , $outq ) {
if ( ! $arr [ 'success' ]) {
logger ( 'zot_process_response: failed: ' . $hub );
2012-11-20 00:51:15 +00:00
return ;
2012-12-31 22:45:26 +00:00
}
2012-11-20 00:51:15 +00:00
$x = json_decode ( $arr [ 'body' ], true );
2012-12-31 22:45:26 +00:00
if ( ! $x ) {
logger ( 'zot_process_response: No json from ' . $hub );
logger ( 'zot_process_response: headers: ' . print_r ( $arr [ 'header' ], true ), LOGGER_DATA );
}
2012-11-20 00:51:15 +00:00
// synchronous message types are handled immediately
// async messages remain in the queue until processed.
if ( intval ( $outq [ 'outq_async' ])) {
$r = q ( " update outq set outq_delivered = 1, outq_updated = '%s' where outq_hash = '%s' and outq_channel = %d limit 1 " ,
dbesc ( datetime_convert ()),
dbesc ( $outq [ 'outq_hash' ]),
intval ( $outq [ 'outq_channel' ])
);
}
else {
$r = q ( " delete from outq where outq_hash = '%s' and outq_channel = %d limit 1 " ,
dbesc ( $outq [ 'outq_hash' ]),
intval ( $outq [ 'outq_channel' ])
);
}
logger ( 'zot_process_response: ' . print_r ( $x , true ), LOGGER_DATA );
2012-11-20 04:45:12 +00:00
}
2013-03-26 04:32:12 +00:00
/**
* @ function : zot_fetch
*
* We received a notification packet ( in mod / post . php ) that a message is waiting for us , and we ' ve verified the sender .
* Now send back a pickup message , using our message tracking ID ( $arr [ 'secret' ]), which we will sign .
* The entire pickup message is encrypted with the remote site ' s public key .
* If everything checks out on the remote end , we will receive back a packet containing one or more messages ,
* which will be processed before returning .
*
*/
2012-11-20 04:45:12 +00:00
function zot_fetch ( $arr ) {
logger ( 'zot_fetch: ' . print_r ( $arr , true ), LOGGER_DATA );
$url = $arr [ 'sender' ][ 'url' ] . $arr [ 'callback' ];
$ret_hub = zot_gethub ( $arr [ 'sender' ]);
if ( ! $ret_hub ) {
2013-03-26 04:32:12 +00:00
logger ( 'zot_fetch: no hub: ' . print_r ( $arr [ 'sender' ], true ));
2012-11-20 04:45:12 +00:00
return ;
}
$data = array (
'type' => 'pickup' ,
'url' => z_root (),
'callback_sig' => base64url_encode ( rsa_sign ( z_root () . '/post' , get_config ( 'system' , 'prvkey' ))),
'callback' => z_root () . '/post' ,
'secret' => $arr [ 'secret' ],
'secret_sig' => base64url_encode ( rsa_sign ( $arr [ 'secret' ], get_config ( 'system' , 'prvkey' )))
);
$datatosend = json_encode ( aes_encapsulate ( json_encode ( $data ), $ret_hub [ 'hubloc_sitekey' ]));
$fetch = zot_zot ( $url , $datatosend );
2013-10-02 09:50:02 +00:00
$result = zot_import ( $fetch , $arr [ 'sender' ][ 'url' ]);
2013-01-01 05:33:11 +00:00
return $result ;
2012-11-20 04:45:12 +00:00
}
2013-03-27 02:53:04 +00:00
/**
* @ function zot_import
*
* Process an incoming array of messages which were obtained via pickup , and
* import , update , delete as directed .
*
* The message types handled here are 'activity' ( e . g . posts ), 'mail' and 'profile'
*/
2012-11-20 04:45:12 +00:00
2013-10-02 09:50:02 +00:00
function zot_import ( $arr , $sender_url ) {
2012-11-20 04:45:12 +00:00
$data = json_decode ( $arr [ 'body' ], true );
2012-11-28 01:09:01 +00:00
2013-01-29 04:51:37 +00:00
if ( ! $data ) {
logger ( 'zot_import: empty body' );
return array ();
}
2012-11-20 04:45:12 +00:00
if ( array_key_exists ( 'iv' , $data )) {
$data = json_decode ( aes_unencapsulate ( $data , get_config ( 'system' , 'prvkey' )), true );
}
$incoming = $data [ 'pickup' ];
2013-01-01 08:45:44 +00:00
$return = array ();
2012-11-20 04:45:12 +00:00
if ( is_array ( $incoming )) {
foreach ( $incoming as $i ) {
2013-01-01 08:45:44 +00:00
$result = null ;
2012-11-27 05:20:16 +00:00
2012-11-28 01:09:01 +00:00
if ( array_key_exists ( 'iv' , $i [ 'notify' ])) {
$i [ 'notify' ] = json_decode ( aes_unencapsulate ( $i [ 'notify' ], get_config ( 'system' , 'prvkey' )), true );
}
2013-01-25 03:45:08 +00:00
logger ( 'zot_import: notify: ' . print_r ( $i [ 'notify' ], true ), LOGGER_DATA );
2012-12-06 00:44:07 +00:00
2013-10-02 09:50:02 +00:00
$hub = zot_gethub ( $i [ 'notify' ][ 'sender' ]);
if (( ! $hub ) || ( $hub [ 'hubloc_url' ] != $sender_url )) {
logger ( 'zot_import: potential forgery: wrong site for sender: ' . $sender_url . ' != ' . print_r ( $i [ 'notify' ], true ));
continue ;
}
2012-11-27 05:20:16 +00:00
$i [ 'notify' ][ 'sender' ][ 'hash' ] = base64url_encode ( hash ( 'whirlpool' , $i [ 'notify' ][ 'sender' ][ 'guid' ] . $i [ 'notify' ][ 'sender' ][ 'guid_sig' ], true ));
2012-11-26 07:18:11 +00:00
$deliveries = null ;
2012-11-27 05:20:16 +00:00
if ( array_key_exists ( 'recipients' , $i [ 'notify' ]) && count ( $i [ 'notify' ][ 'recipients' ])) {
2012-11-27 00:48:04 +00:00
logger ( 'specific recipients' );
2012-11-26 07:18:11 +00:00
$recip_arr = array ();
foreach ( $i [ 'notify' ][ 'recipients' ] as $recip ) {
2012-12-06 00:44:07 +00:00
$recip_arr [] = base64url_encode ( hash ( 'whirlpool' , $recip [ 'guid' ] . $recip [ 'guid_sig' ], true ));
2012-11-26 07:18:11 +00:00
}
stringify_array_elms ( $recip_arr );
2012-12-06 00:44:07 +00:00
$recips = implode ( ',' , $recip_arr );
2012-11-27 00:48:04 +00:00
$r = q ( " select channel_hash as hash from channel where channel_hash in ( " . $recips . " ) " );
2013-01-01 08:45:44 +00:00
if ( ! $r ) {
logger ( 'recips: no recipients on this site' );
2012-11-26 07:18:11 +00:00
continue ;
2013-01-01 08:45:44 +00:00
}
2012-11-26 07:18:11 +00:00
$deliveries = $r ;
// We found somebody on this site that's in the recipient list.
2012-11-20 04:45:12 +00:00
}
else {
2013-09-13 05:50:41 +00:00
if (( array_key_exists ( 'flags' , $i [ 'message' ])) && ( in_array ( 'private' , $i [ 'message' ][ 'flags' ]))) {
// This should not happen but until we can stop it...
logger ( 'private message was delivered with no recipients.' );
continue ;
}
2012-11-27 00:48:04 +00:00
logger ( 'public post' );
2012-11-20 04:45:12 +00:00
2013-01-25 04:43:33 +00:00
// Public post. look for any site members who are or may be accepting posts from this sender
2013-02-15 22:13:58 +00:00
// and who are allowed to see them based on the sender's permissions
$deliveries = allowed_public_recips ( $i );
2013-08-22 12:50:15 +00:00
2012-11-26 07:18:11 +00:00
}
2013-01-01 08:45:44 +00:00
if ( ! $deliveries ) {
logger ( 'zot_import: no deliveries on this site' );
2012-11-27 00:48:04 +00:00
continue ;
2013-01-01 08:45:44 +00:00
}
2012-11-27 00:48:04 +00:00
2012-11-26 07:18:11 +00:00
if ( $i [ 'message' ]) {
if ( $i [ 'message' ][ 'type' ] === 'activity' ) {
2012-11-27 05:20:16 +00:00
$arr = get_item_elements ( $i [ 'message' ]);
2013-07-29 04:04:03 +00:00
2013-01-26 23:50:31 +00:00
if ( ! array_key_exists ( 'created' , $arr )) {
logger ( 'Activity rejected: probable failure to lookup author/owner. ' . print_r ( $i [ 'message' ], true ));
continue ;
}
2013-08-01 21:27:40 +00:00
2013-01-25 03:45:08 +00:00
logger ( 'Activity received: ' . print_r ( $arr , true ), LOGGER_DATA );
logger ( 'Activity recipients: ' . print_r ( $deliveries , true ), LOGGER_DATA );
2012-12-03 04:54:20 +00:00
2012-11-28 01:09:01 +00:00
$relay = (( array_key_exists ( 'flags' , $i [ 'message' ]) && in_array ( 'relay' , $i [ 'message' ][ 'flags' ])) ? true : false );
2013-01-01 05:33:11 +00:00
$result = process_delivery ( $i [ 'notify' ][ 'sender' ], $arr , $deliveries , $relay );
2012-12-03 04:54:20 +00:00
2012-11-26 07:18:11 +00:00
}
elseif ( $i [ 'message' ][ 'type' ] === 'mail' ) {
2012-12-06 00:44:07 +00:00
$arr = get_mail_elements ( $i [ 'message' ]);
2013-01-25 03:45:08 +00:00
logger ( 'Mail received: ' . print_r ( $arr , true ), LOGGER_DATA );
logger ( 'Mail recipients: ' . print_r ( $deliveries , true ), LOGGER_DATA );
2012-12-06 00:44:07 +00:00
2013-01-01 05:33:11 +00:00
$result = process_mail_delivery ( $i [ 'notify' ][ 'sender' ], $arr , $deliveries );
2012-11-20 04:45:12 +00:00
2012-11-26 07:18:11 +00:00
}
2012-12-22 12:33:32 +00:00
elseif ( $i [ 'message' ][ 'type' ] === 'profile' ) {
$arr = get_profile_elements ( $i [ 'message' ]);
2013-01-25 03:45:08 +00:00
logger ( 'Profile received: ' . print_r ( $arr , true ), LOGGER_DATA );
logger ( 'Profile recipients: ' . print_r ( $deliveries , true ), LOGGER_DATA );
2012-12-22 12:33:32 +00:00
2013-01-01 05:33:11 +00:00
$result = process_profile_delivery ( $i [ 'notify' ][ 'sender' ], $arr , $deliveries );
2012-12-03 04:54:20 +00:00
2012-12-22 12:33:32 +00:00
}
2013-06-27 00:31:02 +00:00
elseif ( $i [ 'message' ][ 'type' ] === 'channel_sync' ) {
// $arr = get_channelsync_elements($i['message']);
2013-04-22 05:12:18 +00:00
2013-06-27 00:31:02 +00:00
$arr = $i [ 'message' ];
2013-04-22 05:12:18 +00:00
2013-06-27 00:31:02 +00:00
logger ( 'Channel sync received: ' . print_r ( $arr , true ), LOGGER_DATA );
logger ( 'Channel sync recipients: ' . print_r ( $deliveries , true ), LOGGER_DATA );
2013-07-26 05:57:06 +00:00
$result = process_channel_sync_delivery ( $i [ 'notify' ][ 'sender' ], $arr , $deliveries );
2013-06-27 00:31:02 +00:00
}
2012-12-22 12:33:32 +00:00
}
2013-09-11 11:59:45 +00:00
if ( $result ){
2013-01-01 08:45:44 +00:00
$return = array_merge ( $return , $result );
2013-09-11 11:59:45 +00:00
}
2012-11-20 04:45:12 +00:00
}
}
2013-01-01 05:33:11 +00:00
2013-01-01 08:45:44 +00:00
return $return ;
2013-01-01 05:33:11 +00:00
2012-11-20 04:45:12 +00:00
}
2012-11-27 00:48:04 +00:00
2012-11-27 05:20:16 +00:00
// A public message with no listed recipients can be delivered to anybody who
// has PERMS_NETWORK for that type of post, or PERMS_SITE and is one the same
// site, or PERMS_SPECIFIC and the sender is a contact who is granted
// permissions via their connection permissions in the address book.
// Here we take a given message and construct a list of hashes of everybody
// on the site that we should deliver to.
2012-11-27 00:48:04 +00:00
function public_recips ( $msg ) {
2013-08-22 12:50:15 +00:00
$check_mentions = false ;
2012-11-27 00:48:04 +00:00
if ( $msg [ 'message' ][ 'type' ] === 'activity' ) {
2013-09-13 03:11:56 +00:00
$col = 'channel_w_stream' ;
$field = PERMS_W_STREAM ;
2012-11-27 00:48:04 +00:00
if ( array_key_exists ( 'flags' , $msg [ 'message' ]) && in_array ( 'thread_parent' , $msg [ 'message' ][ 'flags' ])) {
2013-09-13 03:11:56 +00:00
// check mention recipient permissions on top level posts only
2013-08-22 12:50:15 +00:00
$check_mentions = true ;
2012-11-27 00:48:04 +00:00
}
else {
2013-09-13 03:11:56 +00:00
// if this is a comment and it wasn't sent by the post owner, check to see who is allowing them to comment.
// We should have one specific recipient and this step shouldn't be needed unless somebody stuffed up their software.
// We may need this step to protect us from bad guys intentionally stuffing up their software.
// If it is sent by the post owner, we don't need to do this. We only need to see who is receiving the
// owner's stream (which was already set above) - as they control the comment permissions
if ( $msg [ 'notify' ][ 'sender' ][ 'guid_sig' ] != $msg [ 'message' ][ 'owner' ][ 'guid_sig' ]) {
$col = 'channel_w_comment' ;
$field = PERMS_W_COMMENT ;
}
2012-11-27 00:48:04 +00:00
}
}
elseif ( $msg [ 'message' ][ 'type' ] === 'mail' ) {
$col = 'channel_w_mail' ;
$field = PERMS_W_MAIL ;
}
if ( ! $col )
return NULL ;
2013-08-22 12:50:15 +00:00
2012-11-27 00:48:04 +00:00
if ( $msg [ 'notify' ][ 'sender' ][ 'url' ] === z_root ())
2013-09-11 05:45:04 +00:00
$sql = " where (( " . $col . " & " . PERMS_NETWORK . " ) or ( " . $col . " & " . PERMS_SITE . " ) or ( " . $col . " & " . PERMS_PUBLIC . " )) " ;
2012-11-27 00:48:04 +00:00
else
2013-09-11 05:45:04 +00:00
$sql = " where (( " . $col . " & " . PERMS_NETWORK . " ) or ( " . $col . " & " . PERMS_PUBLIC . " )) " ;
2012-11-27 00:48:04 +00:00
2013-09-20 12:45:11 +00:00
$r = q ( " select channel_hash as hash from channel $sql or channel_hash = '%s' " ,
dbesc ( $msg [ 'notify' ][ 'sender' ][ 'hash' ])
);
2012-11-27 00:48:04 +00:00
if ( ! $r )
$r = array ();
$x = q ( " select channel_hash as hash from channel left join abook on abook_channel = channel_id where abook_xchan = '%s'
2013-09-11 09:03:37 +00:00
and (( " . $col . " & " . PERMS_SPECIFIC . " ) and ( abook_my_perms & " . $field . " )) OR ( " . $col . " & " . PERMS_CONTACTS . " ) " ,
2012-11-27 05:20:16 +00:00
dbesc ( $msg [ 'notify' ][ 'sender' ][ 'hash' ])
2012-11-27 00:48:04 +00:00
);
if ( ! $x )
$x = array ();
$r = array_merge ( $r , $x );
2013-08-22 12:50:15 +00:00
// look for any public mentions on this site
// They will get filtered by tgroup_check() so we don't need to check permissions now
if ( $check_mentions && $msg [ 'message' ][ 'tags' ]) {
if ( is_array ( $msg [ 'message' ][ 'tags' ]) && $msg [ 'message' ][ 'tags' ]) {
foreach ( $msg [ 'message' ][ 'tags' ] as $tag ) {
if (( $tag [ 'type' ] === 'mention' ) && ( strpos ( $tag [ 'url' ], z_root ()) !== false )) {
$address = basename ( $tag [ 'url' ]);
if ( $address ) {
$z = q ( " select channel_hash as hash from channel where channel_address = '%s' limit 1 " ,
dbesc ( $address )
);
if ( $z )
$r = array_merge ( $r , $z );
}
}
}
}
}
2013-07-15 10:12:51 +00:00
logger ( 'public_recips: ' . print_r ( $r , true ), LOGGER_DATA );
2012-11-27 00:48:04 +00:00
return $r ;
2012-11-27 05:20:16 +00:00
}
2013-02-15 22:13:58 +00:00
// This is the second part of the above function. We'll find all the channels willing to accept public posts from us,
// then match them against the sender privacy scope and see who in that list that the sender is allowing.
function allowed_public_recips ( $msg ) {
logger ( 'allowed_public_recips: ' . print_r ( $msg , true ));
$recips = public_recips ( $msg );
if ( ! $recips )
return $recips ;
if ( $msg [ 'message' ][ 'type' ] === 'mail' )
return $recips ;
if ( array_key_exists ( 'public_scope' , $msg [ 'message' ]))
$scope = $msg [ 'message' ][ 'public_scope' ];
// we can pull out these two lines once everybody has upgraded to >= 2013-02-15.225
else
$scope = 'public' ;
$hash = base64url_encode ( hash ( 'whirlpool' , $msg [ 'notify' ][ 'sender' ][ 'guid' ] . $msg [ 'notify' ][ 'sender' ][ 'guid_sig' ], true ));
if ( $scope === 'public' || $scope === 'network: red' )
return $recips ;
if ( strpos ( $scope , 'site:' ) === 0 ) {
if (( $scope === 'site: ' . get_app () -> get_hostname ()) && ( $msg [ 'notify' ][ 'sender' ][ 'url' ] === z_root ()))
return $recips ;
else
return array ();
}
if ( $scope === 'self' ) {
foreach ( $recips as $r )
if ( $r [ 'hash' ] === $hash )
return array ( 'hash' => $hash );
}
if ( $scope === 'contacts' ) {
$condensed_recips = array ();
foreach ( $recips as $rr )
$condensed_recips [] = $rr [ 'hash' ];
$results = array ();
2013-03-07 02:52:42 +00:00
$r = q ( " select channel_hash as hash from channel left join abook on abook_channel = channel_id where abook_xchan = '%s' " ,
2013-02-15 22:13:58 +00:00
dbesc ( $hash )
);
if ( $r ) {
foreach ( $r as $rr )
if ( in_array ( $rr [ 'hash' ], $condensed_recips ))
$results [] = array ( 'hash' => $rr [ 'hash' ]);
}
return $results ;
}
return array ();
}
2012-11-27 05:20:16 +00:00
2012-11-28 01:09:01 +00:00
function process_delivery ( $sender , $arr , $deliveries , $relay ) {
2012-11-27 05:20:16 +00:00
2013-01-01 05:33:11 +00:00
$result = array ();
2013-10-02 09:50:02 +00:00
// We've validated the sender. Now make sure that the sender is the owner or author
2013-10-02 11:13:35 +00:00
if ( $sender [ 'hash' ] != $arr [ 'owner_xchan' ] && $sender [ 'hash' ] != $arr [ 'author_xchan' ]) {
2013-10-02 09:50:02 +00:00
logger ( 'process_delivery: sender is not owner or author' );
return ;
}
2012-11-27 05:20:16 +00:00
foreach ( $deliveries as $d ) {
$r = q ( " select * from channel where channel_hash = '%s' limit 1 " ,
dbesc ( $d [ 'hash' ])
);
2013-01-01 05:33:11 +00:00
if ( ! $r ) {
2013-07-22 00:19:16 +00:00
$result [] = array ( $d [ 'hash' ], 'recipients not found' );
2012-11-27 05:20:16 +00:00
continue ;
2013-01-01 05:33:11 +00:00
}
2013-01-01 08:45:44 +00:00
2012-11-27 05:20:16 +00:00
$channel = $r [ 0 ];
2013-06-16 07:57:39 +00:00
$tag_delivery = tgroup_check ( $channel [ 'channel_id' ], $arr );
2013-03-22 01:25:41 +00:00
$perm = (( $arr [ 'mid' ] == $arr [ 'parent_mid' ]) ? 'send_stream' : 'post_comments' );
2012-11-27 05:20:16 +00:00
2013-07-30 00:30:46 +00:00
// This is our own post, possibly coming from a channel clone
if ( $arr [ 'owner_xchan' ] == $d [ 'hash' ]) {
$arr [ 'item_flags' ] = $arr [ 'item_flags' ] | ITEM_WALL ;
}
else {
// clear the wall flag if it is set
if ( $arr [ 'item_flags' ] & ITEM_WALL ) {
$arr [ 'item_flags' ] = ( $arr [ 'item_flags' ] ^ ITEM_WALL );
}
}
2013-06-16 07:57:39 +00:00
if (( ! perm_is_allowed ( $channel [ 'channel_id' ], $sender [ 'hash' ], $perm )) && ( ! $tag_delivery )) {
2012-11-27 05:20:16 +00:00
logger ( " permission denied for delivery { $channel [ 'channel_id' ] } " );
2013-07-22 00:19:16 +00:00
$result [] = array ( $d [ 'hash' ], 'permission denied' , $channel [ 'channel_name' ] . ' <' . $channel [ 'channel_address' ] . '@' . get_app () -> get_hostname () . '>' );
2012-11-27 05:20:16 +00:00
continue ;
}
2012-11-28 01:09:01 +00:00
2012-11-27 05:20:16 +00:00
if ( $arr [ 'item_restrict' ] & ITEM_DELETED ) {
2013-07-02 02:41:11 +00:00
// remove_community_tag is a no-op if this isn't a community tag activity
remove_community_tag ( $sender , $arr , $channel [ 'channel_id' ]);
2013-01-29 03:24:36 +00:00
$item_id = delete_imported_item ( $sender , $arr , $channel [ 'channel_id' ]);
2013-07-22 00:19:16 +00:00
$result [] = array ( $d [ 'hash' ], 'deleted' , $channel [ 'channel_name' ] . ' <' . $channel [ 'channel_address' ] . '@' . get_app () -> get_hostname () . '>' );
2013-01-29 03:24:36 +00:00
if ( $relay && $item_id ) {
logger ( 'process_delivery: invoking relay' );
proc_run ( 'php' , 'include/notifier.php' , 'relay' , intval ( $item_id ));
2013-07-22 00:19:16 +00:00
$result [] = array ( $d [ 'hash' ], 'relayed' , $channel [ 'channel_name' ] . ' <' . $channel [ 'channel_address' ] . '@' . get_app () -> get_hostname () . '>' );
2013-01-29 03:24:36 +00:00
}
2012-11-27 05:20:16 +00:00
continue ;
}
2013-06-24 06:13:07 +00:00
// for events, extract the event info and create an event linked to an item
2013-01-16 08:59:43 +00:00
2013-01-16 11:18:32 +00:00
if (( x ( $arr , 'obj_type' )) && ( activity_match ( $arr [ 'obj_type' ], ACTIVITY_OBJ_EVENT ))) {
2013-01-16 08:59:43 +00:00
require_once ( 'include/event.php' );
$ev = bbtoevent ( $arr [ 'body' ]);
if ( x ( $ev , 'desc' ) && x ( $ev , 'start' )) {
$ev [ 'event_xchan' ] = $arr [ 'author_xchan' ];
$ev [ 'uid' ] = $channel [ 'channel_id' ];
$ev [ 'account' ] = $channel [ 'channel_account_id' ];
$ev [ 'edited' ] = $arr [ 'edited' ];
2013-03-22 01:25:41 +00:00
$ev [ 'mid' ] = $arr [ 'mid' ];
2013-01-20 23:36:04 +00:00
$ev [ 'private' ] = $arr [ 'item_private' ];
2013-01-16 08:59:43 +00:00
// is this an edit?
2013-03-22 01:25:41 +00:00
$r = q ( " SELECT resource_id FROM item where mid = '%s' and uid = %d and resource_type = 'event' limit 1 " ,
dbesc ( $arr [ 'mid' ]),
2013-01-16 11:18:32 +00:00
intval ( $channel [ 'channel_id' ])
2013-01-16 08:59:43 +00:00
);
2013-01-20 23:36:04 +00:00
if ( $r ) {
$ev [ 'event_hash' ] = $r [ 0 ][ 'resource_id' ];
}
2013-01-25 03:45:08 +00:00
2013-01-16 08:59:43 +00:00
$xyz = event_store ( $ev );
2013-01-25 03:45:08 +00:00
2013-07-22 00:19:16 +00:00
$result = array ( $d [ 'hash' ], 'event processed' , $channel [ 'channel_name' ] . ' <' . $channel [ 'channel_address' ] . '@' . get_app () -> get_hostname () . '>' );
2013-01-16 08:59:43 +00:00
continue ;
}
}
2013-03-22 01:25:41 +00:00
$r = q ( " select id, edited from item where mid = '%s' and uid = %d limit 1 " ,
dbesc ( $arr [ 'mid' ]),
2012-11-28 01:09:01 +00:00
intval ( $channel [ 'channel_id' ])
2012-11-27 05:20:16 +00:00
);
2012-11-28 01:09:01 +00:00
if ( $r ) {
2013-03-01 02:20:42 +00:00
if ( $arr [ 'edited' ] > $r [ 0 ][ 'edited' ]) {
$arr [ 'id' ] = $r [ 0 ][ 'id' ];
2013-03-01 02:59:03 +00:00
$arr [ 'uid' ] = $channel [ 'channel_id' ];
2012-11-28 01:09:01 +00:00
update_imported_item ( $sender , $arr , $channel [ 'channel_id' ]);
2013-03-01 02:20:42 +00:00
}
2013-07-22 00:19:16 +00:00
$result [] = array ( $d [ 'hash' ], 'updated' , $channel [ 'channel_name' ] . ' <' . $channel [ 'channel_address' ] . '@' . get_app () -> get_hostname () . '>' );
2012-11-28 01:09:01 +00:00
$item_id = $r [ 0 ][ 'id' ];
}
2012-11-27 05:20:16 +00:00
else {
$arr [ 'aid' ] = $channel [ 'channel_account_id' ];
$arr [ 'uid' ] = $channel [ 'channel_id' ];
2013-09-11 02:06:06 +00:00
$item_result = item_store ( $arr );
$item_id = $item_result [ 'item_id' ];
$result [] = array ( $d [ 'hash' ],(( $item_id ) ? 'posted' : 'storage failed:' . $item_result [ 'message' ]), $channel [ 'channel_name' ] . ' <' . $channel [ 'channel_address' ] . '@' . get_app () -> get_hostname () . '>' );
2012-11-27 05:20:16 +00:00
}
2012-11-28 01:09:01 +00:00
if ( $relay && $item_id ) {
logger ( 'process_delivery: invoking relay' );
proc_run ( 'php' , 'include/notifier.php' , 'relay' , intval ( $item_id ));
2013-07-22 00:19:16 +00:00
$result [] = array ( $d [ 'hash' ], 'relayed' , $channel [ 'channel_name' ] . ' <' . $channel [ 'channel_address' ] . '@' . get_app () -> get_hostname () . '>' );
2012-11-28 01:09:01 +00:00
}
2012-11-27 05:20:16 +00:00
}
2013-01-01 08:45:44 +00:00
if ( ! $deliveries )
$result [] = array ( '' , 'no recipients' );
2013-01-25 03:45:08 +00:00
logger ( 'process_delivery: local results: ' . print_r ( $result , true ), LOGGER_DEBUG );
2013-01-03 10:21:35 +00:00
2013-01-01 05:33:11 +00:00
return $result ;
2012-11-27 05:20:16 +00:00
}
2012-12-06 00:44:07 +00:00
2013-07-02 02:41:11 +00:00
function remove_community_tag ( $sender , $arr , $uid ) {
if ( ! ( activity_match ( $arr [ 'verb' ], ACTIVITY_TAG ) && ( $arr [ 'obj_type' ] == ACTIVITY_OBJ_TAGTERM )))
return ;
logger ( 'remove_community_tag: invoked' );
if ( ! get_pconfig ( $uid , 'system' , 'blocktags' )) {
logger ( 'remove_community tag: permission denied.' );
return ;
}
$r = q ( " select * from item where mid = '%s' and uid = %d limit 1 " ,
dbesc ( $arr [ 'mid' ]),
intval ( $uid )
);
if ( ! $r ) {
logger ( 'remove_community_tag: no item' );
return ;
}
if (( $sender [ 'hash' ] != $r [ 0 ][ 'owner_xchan' ]) && ( $sender [ 'hash' ] != $r [ 0 ][ 'author_xchan' ])) {
logger ( 'remove_community_tag: sender not authorised.' );
return ;
}
$i = $r [ 0 ];
if ( $i [ 'target' ])
2013-08-06 10:54:49 +00:00
$i [ 'target' ] = json_decode_plus ( $i [ 'target' ]);
2013-07-02 02:41:11 +00:00
if ( $i [ 'object' ])
2013-08-06 10:54:49 +00:00
$i [ 'object' ] = json_decode_plus ( $i [ 'object' ]);
2013-07-02 02:41:11 +00:00
if ( ! ( $i [ 'target' ] && $i [ 'object' ])) {
logger ( 'remove_community_tag: no target/object' );
return ;
}
$message_id = $i [ 'target' ][ 'id' ];
$r = q ( " select id from item where mid = '%s' and uid = %d limit 1 " ,
dbesc ( $message_id ),
intval ( $uid )
);
if ( ! $r ) {
logger ( 'remove_community_tag: no parent message' );
return ;
}
$x = q ( " delete from term where uid = %d and oid = %d and otype = %d and type = %d and term = '%s' and url = '%s' limit 1 " ,
intval ( $uid ),
intval ( $r [ 0 ][ 'id' ]),
intval ( TERM_OBJ_POST ),
intval ( TERM_HASHTAG ),
dbesc ( $i [ 'object' ][ 'title' ]),
dbesc ( get_rel_link ( $i [ 'object' ][ 'link' ], 'alternate' ))
);
return ;
}
2012-11-27 05:20:16 +00:00
function update_imported_item ( $sender , $item , $uid ) {
2013-03-01 02:20:42 +00:00
2013-09-11 02:06:06 +00:00
$x = item_store_update ( $item );
if ( ! $x [ 'item_id' ])
logger ( 'update_imported_item: failed: ' . $x [ 'message' ]);
else
logger ( 'update_imported_item' );
2012-11-27 05:20:16 +00:00
}
function delete_imported_item ( $sender , $item , $uid ) {
2013-01-29 03:24:36 +00:00
logger ( 'delete_imported_item invoked' , LOGGER_DEBUG );
$r = q ( " select id from item where ( author_xchan = '%s' or owner_xchan = '%s' )
2013-03-22 01:25:41 +00:00
and mid = '%s' and uid = % d limit 1 " ,
2012-11-27 05:20:16 +00:00
dbesc ( $sender [ 'hash' ]),
dbesc ( $sender [ 'hash' ]),
2013-03-22 01:25:41 +00:00
dbesc ( $item [ 'mid' ]),
2012-11-27 05:20:16 +00:00
intval ( $uid )
);
2013-01-29 03:24:36 +00:00
2012-11-27 05:20:16 +00:00
if ( ! $r ) {
logger ( 'delete_imported_item: failed: ownership issue' );
2013-01-29 03:24:36 +00:00
return false ;
2012-11-27 05:20:16 +00:00
}
2013-01-25 00:44:10 +00:00
require_once ( 'include/items.php' );
drop_item ( $r [ 0 ][ 'id' ], false );
2013-01-29 03:24:36 +00:00
return $r [ 0 ][ 'id' ];
2012-11-27 05:20:16 +00:00
}
2012-12-06 00:44:07 +00:00
function process_mail_delivery ( $sender , $arr , $deliveries ) {
2013-05-17 03:43:24 +00:00
$result = array ();
2013-10-03 04:04:48 +00:00
if ( $sender [ 'hash' ] != $arr [ 'from_xchan' ]) {
logger ( 'process_mail_delivery: sender is not mail author' );
return ;
}
2012-12-06 00:44:07 +00:00
foreach ( $deliveries as $d ) {
$r = q ( " select * from channel where channel_hash = '%s' limit 1 " ,
dbesc ( $d [ 'hash' ])
);
2013-05-17 03:43:24 +00:00
if ( ! $r ) {
$result [] = array ( $d [ 'hash' ], 'not found' );
2012-12-06 00:44:07 +00:00
continue ;
2013-05-17 03:43:24 +00:00
}
2012-12-06 00:44:07 +00:00
$channel = $r [ 0 ];
if ( ! perm_is_allowed ( $channel [ 'channel_id' ], $sender [ 'hash' ], 'post_mail' )) {
logger ( " permission denied for mail delivery { $channel [ 'channel_id' ] } " );
2013-07-16 02:04:23 +00:00
$result [] = array ( $d [ 'hash' ], 'permission denied' , $channel [ 'channel_name' ]);
2012-12-06 00:44:07 +00:00
continue ;
}
2013-03-22 01:25:41 +00:00
$r = q ( " select id from mail where mid = '%s' and channel_id = %d limit 1 " ,
dbesc ( $arr [ 'mid' ]),
2012-12-06 00:44:07 +00:00
intval ( $channel [ 'channel_id' ])
);
if ( $r ) {
2013-02-28 04:38:33 +00:00
if ( $arr [ 'mail_flags' ] & MAIL_RECALLED ) {
$x = q ( " delete from mail where id = %d and channel_id = %d limit 1 " ,
intval ( $r [ 0 ][ 'id' ]),
intval ( $channel [ 'channel_id' ])
);
2013-07-16 02:04:23 +00:00
$result [] = array ( $d [ 'hash' ], 'mail recalled' , $channel [ 'channel_name' ]);
2013-02-28 04:38:33 +00:00
logger ( 'mail_recalled' );
}
else {
2013-07-16 02:04:23 +00:00
$result [] = array ( $d [ 'hash' ], 'duplicate mail received' , $channel [ 'channel_name' ]);
2013-02-28 04:38:33 +00:00
logger ( 'duplicate mail received' );
}
2012-12-06 00:44:07 +00:00
continue ;
}
else {
$arr [ 'account_id' ] = $channel [ 'channel_account_id' ];
$arr [ 'channel_id' ] = $channel [ 'channel_id' ];
$item_id = mail_store ( $arr );
2013-07-16 02:04:23 +00:00
$result [] = array ( $d [ 'hash' ], 'mail delivered' , $channel [ 'channel_name' ]);
2013-01-06 02:08:06 +00:00
2012-12-06 00:44:07 +00:00
}
}
2013-05-17 03:43:24 +00:00
return $result ;
2012-12-06 00:44:07 +00:00
}
2012-12-22 12:33:32 +00:00
function process_profile_delivery ( $sender , $arr , $deliveries ) {
2012-12-28 07:33:37 +00:00
// deliveries is irrelevant, what to do about birthday notification....?
2013-01-25 03:45:08 +00:00
logger ( 'process_profile_delivery' , LOGGER_DEBUG );
2013-09-25 03:13:53 +00:00
$r = q ( " select xchan_addr from xchan where xchan_hash = '%s' limit 1 " ,
dbesc ( $sender [ 'hash' ])
);
if ( $r )
2013-09-26 04:22:36 +00:00
import_directory_profile ( $sender [ 'hash' ], $arr , $r [ 0 ][ 'xchan_addr' ], 1 , 0 );
2012-12-27 02:18:56 +00:00
}
2013-05-01 01:16:51 +00:00
/*
* @ function import_directory_profile
*
* @ returns boolean $updated if something changed
*
*/
2013-09-26 04:22:36 +00:00
function import_directory_profile ( $hash , $profile , $addr , $ud_flags = 1 , $suppress_update = 0 ) {
2012-12-27 02:18:56 +00:00
2013-01-25 03:45:08 +00:00
logger ( 'import_directory_profile' , LOGGER_DEBUG );
2012-12-27 02:18:56 +00:00
if ( ! $hash )
2013-05-01 01:16:51 +00:00
return false ;
2012-12-27 02:18:56 +00:00
$arr = array ();
$arr [ 'xprof_hash' ] = $hash ;
2013-01-11 22:53:14 +00:00
$arr [ 'xprof_desc' ] = (( $profile [ 'description' ]) ? htmlentities ( $profile [ 'description' ], ENT_COMPAT , 'UTF-8' , false ) : '' );
2012-12-27 02:18:56 +00:00
$arr [ 'xprof_dob' ] = datetime_convert ( '' , '' , $profile [ 'birthday' ], 'Y-m-d' ); // !!!! check this for 0000 year
2013-06-30 07:38:02 +00:00
$arr [ 'xprof_age' ] = (( $profile [ 'age' ]) ? intval ( $profile [ 'age' ]) : 0 );
2013-01-11 22:53:14 +00:00
$arr [ 'xprof_gender' ] = (( $profile [ 'gender' ]) ? htmlentities ( $profile [ 'gender' ], ENT_COMPAT , 'UTF-8' , false ) : '' );
$arr [ 'xprof_marital' ] = (( $profile [ 'marital' ]) ? htmlentities ( $profile [ 'marital' ], ENT_COMPAT , 'UTF-8' , false ) : '' );
$arr [ 'xprof_sexual' ] = (( $profile [ 'sexual' ]) ? htmlentities ( $profile [ 'sexual' ], ENT_COMPAT , 'UTF-8' , false ) : '' );
$arr [ 'xprof_locale' ] = (( $profile [ 'locale' ]) ? htmlentities ( $profile [ 'locale' ], ENT_COMPAT , 'UTF-8' , false ) : '' );
$arr [ 'xprof_region' ] = (( $profile [ 'region' ]) ? htmlentities ( $profile [ 'region' ], ENT_COMPAT , 'UTF-8' , false ) : '' );
$arr [ 'xprof_postcode' ] = (( $profile [ 'postcode' ]) ? htmlentities ( $profile [ 'postcode' ], ENT_COMPAT , 'UTF-8' , false ) : '' );
$arr [ 'xprof_country' ] = (( $profile [ 'country' ]) ? htmlentities ( $profile [ 'country' ], ENT_COMPAT , 'UTF-8' , false ) : '' );
2012-12-27 02:18:56 +00:00
2012-12-27 22:36:06 +00:00
$clean = array ();
2012-12-27 02:18:56 +00:00
if ( array_key_exists ( 'keywords' , $profile ) and is_array ( $profile [ 'keywords' ])) {
2012-12-28 07:33:37 +00:00
import_directory_keywords ( $hash , $profile [ 'keywords' ]);
2012-12-27 22:36:06 +00:00
foreach ( $profile [ 'keywords' ] as $kw ) {
2013-01-11 22:53:14 +00:00
$kw = trim ( htmlentities ( $kw , ENT_COMPAT , 'UTF-8' , false ));
2013-05-09 04:30:54 +00:00
$kw = trim ( $kw , ',' );
2013-09-15 00:20:24 +00:00
$clean [] = $kw ;
2012-12-27 22:36:06 +00:00
}
2012-12-27 02:18:56 +00:00
}
2012-12-27 22:36:06 +00:00
$arr [ 'xprof_keywords' ] = implode ( ' ' , $clean );
2013-09-20 02:50:13 +00:00
// Self censored, make it so
// These are not translated, so the German "erwachsenen" keyword will not censor the directory profile. Only the English form - "adult".
2013-09-26 23:25:28 +00:00
2013-09-20 02:50:13 +00:00
if ( in_arrayi ( 'nsfw' , $clean ) || in_arrayi ( 'adult' , $clean )) {
q ( " update xchan set xchan_flags = (xchan_flags | %d) where xchan_hash = '%s' limit 1 " ,
2013-09-26 23:25:28 +00:00
intval ( XCHAN_FLAGS_SELFCENSORED ),
2013-09-20 04:13:45 +00:00
dbesc ( $hash )
2013-09-20 02:50:13 +00:00
);
}
2012-12-27 02:18:56 +00:00
$r = q ( " select * from xprof where xprof_hash = '%s' limit 1 " ,
dbesc ( $hash )
);
if ( $r ) {
2013-05-01 01:16:51 +00:00
$update = false ;
foreach ( $r [ 0 ] as $k => $v ) {
if (( array_key_exists ( $k , $arr )) && ( $arr [ $k ] != $v )) {
2013-09-15 10:48:43 +00:00
logger ( 'import_directory_profile: update' . $k . ' => ' . $arr [ $k ]);
2013-05-01 01:16:51 +00:00
$update = true ;
break ;
}
}
if ( $update ) {
$x = q ( " update xprof set
xprof_desc = '%s' ,
xprof_dob = '%s' ,
2013-07-03 05:29:24 +00:00
xprof_age = % d ,
2013-05-01 01:16:51 +00:00
xprof_gender = '%s' ,
xprof_marital = '%s' ,
xprof_sexual = '%s' ,
xprof_locale = '%s' ,
xprof_region = '%s' ,
xprof_postcode = '%s' ,
xprof_country = '%s' ,
xprof_keywords = '%s'
where xprof_hash = '%s' limit 1 " ,
dbesc ( $arr [ 'xprof_desc' ]),
dbesc ( $arr [ 'xprof_dob' ]),
2013-07-03 05:22:13 +00:00
intval ( $arr [ 'xprof_age' ]),
2013-05-01 01:16:51 +00:00
dbesc ( $arr [ 'xprof_gender' ]),
dbesc ( $arr [ 'xprof_marital' ]),
dbesc ( $arr [ 'xprof_sexual' ]),
dbesc ( $arr [ 'xprof_locale' ]),
dbesc ( $arr [ 'xprof_region' ]),
dbesc ( $arr [ 'xprof_postcode' ]),
dbesc ( $arr [ 'xprof_country' ]),
dbesc ( $arr [ 'xprof_keywords' ]),
dbesc ( $arr [ 'xprof_hash' ])
);
}
2012-12-27 02:18:56 +00:00
}
else {
2013-05-01 01:16:51 +00:00
$update = true ;
2013-09-15 10:48:43 +00:00
logger ( 'import_directory_profile: new profile' );
2013-07-09 05:01:57 +00:00
$x = q ( " insert into xprof (xprof_hash, xprof_desc, xprof_dob, xprof_age, xprof_gender, xprof_marital, xprof_sexual, xprof_locale, xprof_region, xprof_postcode, xprof_country, xprof_keywords) values ('%s', '%s', '%s', %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s') " ,
2012-12-27 02:18:56 +00:00
dbesc ( $arr [ 'xprof_hash' ]),
dbesc ( $arr [ 'xprof_desc' ]),
dbesc ( $arr [ 'xprof_dob' ]),
2013-07-03 05:22:13 +00:00
intval ( $arr [ 'xprof_age' ]),
2012-12-27 02:18:56 +00:00
dbesc ( $arr [ 'xprof_gender' ]),
dbesc ( $arr [ 'xprof_marital' ]),
dbesc ( $arr [ 'xprof_sexual' ]),
dbesc ( $arr [ 'xprof_locale' ]),
dbesc ( $arr [ 'xprof_region' ]),
dbesc ( $arr [ 'xprof_postcode' ]),
2012-12-27 22:36:06 +00:00
dbesc ( $arr [ 'xprof_country' ]),
dbesc ( $arr [ 'xprof_keywords' ])
2012-12-27 02:18:56 +00:00
);
}
2012-12-27 03:39:37 +00:00
2013-07-24 05:33:56 +00:00
$d = array ( 'xprof' => $arr , 'profile' => $profile , 'update' => $update );
call_hooks ( 'import_directory_profile' , $d );
2013-09-26 04:22:36 +00:00
if (( $d [ 'update' ]) && ( ! $suppress_update ))
2013-09-25 03:13:53 +00:00
update_modtime ( $arr [ 'xprof_hash' ], random_string () . '@' . get_app () -> get_hostname (), $addr , $ud_flags );
2013-07-24 05:33:56 +00:00
return $d [ 'update' ];
2012-12-27 02:18:56 +00:00
}
2012-12-28 07:33:37 +00:00
function import_directory_keywords ( $hash , $keywords ) {
$existing = array ();
$r = q ( " select * from xtag where xtag_hash = '%s' " ,
dbesc ( $hash )
);
if ( $r ) {
foreach ( $r as $rr )
$existing [] = $rr [ 'xtag_term' ];
}
$clean = array ();
foreach ( $keywords as $kw ) {
2013-01-11 22:53:14 +00:00
$kw = trim ( htmlentities ( $kw , ENT_COMPAT , 'UTF-8' , false ));
2013-09-19 08:45:06 +00:00
$kw = trim ( $kw , ',' );
2012-12-28 07:33:37 +00:00
$clean [] = $kw ;
}
foreach ( $existing as $x ) {
if ( ! in_array ( $x , $clean ))
$r = q ( " delete from xtag where xtag_hash = '%s' and xtag_term = '%s' limit 1 " ,
dbesc ( $hash ),
dbesc ( $x )
);
}
foreach ( $clean as $x ) {
if ( ! in_array ( $x , $existing ))
2013-05-09 04:30:54 +00:00
$r = q ( " insert into xtag ( xtag_hash, xtag_term) values ( '%s' ,'%s' ) " ,
2012-12-28 07:33:37 +00:00
dbesc ( $hash ),
dbesc ( $x )
);
}
2013-03-14 00:27:17 +00:00
}
2013-09-25 03:13:53 +00:00
function update_modtime ( $hash , $guid , $addr , $flags = 0 ) {
2013-10-01 01:33:27 +00:00
if ( $flags ) {
q ( " insert into updates (ud_hash, ud_guid, ud_date, ud_flags, ud_addr ) values ( '%s', '%s', '%s', %d, '%s' ) " ,
dbesc ( $hash ),
dbesc ( $guid ),
dbesc ( datetime_convert ()),
intval ( $flags ),
dbesc ( $addr )
);
}
else {
q ( " update updates set ud_flags = ( ud_flags | %d ) where ud_addr = '%s' and not (ud_flags & %d) " ,
intval ( UPDATE_FLAGS_UPDATED ),
intval ( UPDATE_FLAGS_UPDATED )
);
}
2013-03-14 00:27:17 +00:00
}
2013-07-24 05:33:56 +00:00
function import_site ( $arr , $pubkey ) {
if ( ( ! is_array ( $arr )) || ( ! $arr [ 'url' ]) || ( ! $arr [ 'url_sig' ]))
return false ;
if ( ! rsa_verify ( $arr [ 'url' ], base64url_decode ( $arr [ 'url_sig' ]), $pubkey )) {
logger ( 'import_site: bad url_sig' );
return false ;
}
$update = false ;
2013-09-16 02:04:11 +00:00
$exists = false ;
2013-07-24 05:33:56 +00:00
$r = q ( " select * from site where site_url = '%s' limit 1 " ,
dbesc ( $arr [ 'url' ])
);
2013-09-16 02:04:11 +00:00
if ( $r ) {
$exists = true ;
$siterecord = $r [ 0 ];
}
2013-07-24 05:33:56 +00:00
$site_directory = 0 ;
if ( $arr [ 'directory_mode' ] == 'normal' )
$site_directory = DIRECTORY_MODE_NORMAL ;
if ( $arr [ 'directory_mode' ] == 'primary' )
$site_directory = DIRECTORY_MODE_PRIMARY ;
if ( $arr [ 'directory_mode' ] == 'secondary' )
$site_directory = DIRECTORY_MODE_SECONDARY ;
if ( $arr [ 'directory_mode' ] == 'standalone' )
$site_directory = DIRECTORY_MODE_STANDALONE ;
$register_policy = 0 ;
if ( $arr [ 'register_policy' ] == 'closed' )
$register_policy = REGISTER_CLOSED ;
if ( $arr [ 'register_policy' ] == 'open' )
$register_policy = REGISTER_OPEN ;
if ( $arr [ 'register_policy' ] == 'approve' )
$register_policy = REGISTER_APPROVE ;
2013-09-06 05:00:06 +00:00
$access_policy = 0 ;
if ( array_key_exists ( 'access_policy' , $arr )) {
if ( $arr [ 'access_policy' ] === 'private' )
$access_policy = ACCESS_PRIVATE ;
if ( $arr [ 'access_policy' ] === 'paid' )
$access_policy = ACCESS_PAID ;
if ( $arr [ 'access_policy' ] === 'free' )
$access_policy = ACCESS_FREE ;
2013-09-19 00:47:26 +00:00
if ( $arr [ 'access_policy' ] === 'tiered' )
$access_policy = ACCESS_TIERED ;
2013-09-06 05:00:06 +00:00
}
2013-09-16 02:04:11 +00:00
$directory_url = htmlentities ( $arr [ 'directory_url' ], ENT_COMPAT , 'UTF-8' , false );
$url = htmlentities ( $arr [ 'url' ], ENT_COMPAT , 'UTF-8' , false );
2013-09-18 05:27:51 +00:00
$sellpage = htmlentities ( $arr [ 'sellpage' ], ENT_COMPAT , 'UTF-8' , false );
2013-09-16 02:04:11 +00:00
if ( $exists ) {
if (( $siterecord [ 'site_flags' ] != $site_directory )
|| ( $siterecord [ 'site_access' ] != $access_policy )
|| ( $siterecord [ 'site_directory' ] != $directory_url )
2013-09-18 05:27:51 +00:00
|| ( $siterecord [ 'site_sellpage' ] != $sellpage )
2013-09-16 02:04:11 +00:00
|| ( $siterecord [ 'site_register' ] != $register_policy )) {
$update = true ;
2013-09-16 06:02:18 +00:00
// logger('import_site: input: ' . print_r($arr,true));
// logger('import_site: stored: ' . print_r($siterecord,true));
2013-09-16 05:19:24 +00:00
2013-09-18 05:27:51 +00:00
$r = q ( " update site set site_flags = %d, site_access = %d, site_directory = '%s', site_register = %d, site_update = '%s', site_sellpage = '%s'
2013-09-16 02:04:11 +00:00
where site_url = '%s' limit 1 " ,
intval ( $site_directory ),
intval ( $access_policy ),
dbesc ( $directory_url ),
intval ( $register_policy ),
dbesc ( datetime_convert ()),
2013-09-18 05:27:51 +00:00
dbesc ( $sellpage ),
2013-09-16 02:04:11 +00:00
dbesc ( $url )
);
if ( ! $r ) {
logger ( 'import_site: update failed. ' . print_r ( $arr , true ));
}
2013-07-24 05:33:56 +00:00
}
}
else {
2013-09-16 02:04:11 +00:00
$update = true ;
2013-09-18 05:27:51 +00:00
$r = q ( " insert into site ( site_url, site_access, site_flags, site_update, site_directory, site_register, site_sellpage )
values ( '%s' , % d , % d , '%s' , '%s' , % d , '%s' ) " ,
2013-09-16 02:04:11 +00:00
dbesc ( $url ),
2013-07-24 05:33:56 +00:00
intval ( $site_directory ),
2013-09-06 05:00:06 +00:00
intval ( $access_policy ),
2013-07-24 05:33:56 +00:00
dbesc ( datetime_convert ()),
2013-09-16 02:04:11 +00:00
dbesc ( $directory_url ),
2013-09-18 05:27:51 +00:00
intval ( $register_policy ),
dbesc ( $sellpage )
2013-07-24 05:33:56 +00:00
);
if ( ! $r ) {
logger ( 'import_site: record create failed. ' . print_r ( $arr , true ));
}
}
2013-09-16 06:02:18 +00:00
return $update ;
2013-07-24 05:33:56 +00:00
}
2013-07-25 23:00:04 +00:00
/**
* Send a zot packet to all hubs where this channel is duplicated , refreshing
* such things as personal settings , channel permissions , address book updates , etc .
*/
function build_sync_packet ( $uid = 0 , $packet = null ) {
$a = get_app ();
logger ( 'build_sync_packet' );
2013-07-26 03:10:53 +00:00
2013-07-25 23:00:04 +00:00
if ( ! $uid )
$uid = local_user ();
if ( ! $uid )
return ;
2013-07-26 03:10:53 +00:00
$r = q ( " select * from channel where channel_id = %d limit 1 " ,
intval ( $uid )
);
if ( ! $r )
return ;
$channel = $r [ 0 ];
2013-07-25 23:00:04 +00:00
$h = q ( " select * from hubloc where hubloc_hash = '%s' " ,
dbesc ( $channel [ 'channel_hash' ])
);
if ( ! $h )
return ;
$synchubs = array ();
foreach ( $h as $x ) {
if ( $x [ 'hubloc_host' ] == $a -> get_hostname ())
continue ;
$synchubs [] = $x ;
}
if ( ! $synchubs )
return ;
$r = q ( " select xchan_guid, xchan_guid_sig from xchan where xchan_hash = '%s' limit 1 " ,
dbesc ( $channel [ 'channel_hash' ])
);
if ( ! $r )
return ;
$env_recips = array ();
$env_recips [] = array ( 'guid' => $r [ 0 ][ 'xchan_guid' ], 'guid_sig' => $r [ 0 ][ 'xchan_guid_sig' ]);
$info = (( $packet ) ? $packet : array ());
$info [ 'type' ] = 'channel_sync' ;
if ( array_key_exists ( $uid , $a -> config ) && array_key_exists ( 'transient' , $a -> config [ $uid ])) {
$settings = $a -> config [ $uid ][ 'transient' ];
if ( $settings ) {
$info [ 'config' ] = $settings ;
}
}
if ( $channel ) {
$info [ 'channel' ] = array ();
foreach ( $channel as $k => $v ) {
// filter out any joined tables like xchan
if ( strpos ( $k , 'channel_' ) !== 0 )
continue ;
// don't pass these elements, they should not be synchronised
2013-07-29 04:04:03 +00:00
$disallowed = array ( 'channel_id' , 'channel_account_id' , 'channel_primary' , 'channel_prvkey' , 'channel_address' );
2013-07-25 23:00:04 +00:00
if ( in_array ( $k , $disallowed ))
continue ;
$info [ 'channel' ][ $k ] = $v ;
}
}
$interval = (( get_config ( 'system' , 'delivery_interval' ) !== false )
? intval ( get_config ( 'system' , 'delivery_interval' )) : 2 );
2013-07-26 02:50:55 +00:00
logger ( 'build_sync_packet: packet: ' . print_r ( $info , true ), LOGGER_DATA );
2013-07-25 23:00:04 +00:00
foreach ( $synchubs as $hub ) {
$hash = random_string ();
$n = zot_build_packet ( $channel , 'notify' , $env_recips , $hub [ 'hubloc_sitekey' ], $hash );
q ( " insert into outq ( outq_hash, outq_account, outq_channel, outq_posturl, outq_async, outq_created, outq_updated, outq_notify, outq_msg ) values ( '%s', %d, %d, '%s', %d, '%s', '%s', '%s', '%s' ) " ,
dbesc ( $hash ),
intval ( $channel [ 'channel_account' ]),
intval ( $channel [ 'channel_id' ]),
dbesc ( $hub [ 'hubloc_callback' ]),
intval ( 1 ),
dbesc ( datetime_convert ()),
dbesc ( datetime_convert ()),
dbesc ( $n ),
dbesc ( json_encode ( $info ))
);
proc_run ( 'php' , 'include/deliver.php' , $hash );
if ( $interval )
@ time_sleep_until ( microtime ( true ) + ( float ) $interval );
}
}
2013-07-26 05:57:06 +00:00
function process_channel_sync_delivery ( $sender , $arr , $deliveries ) {
2013-07-26 10:50:46 +00:00
// FIXME - this will sync red structures (channel, pconfig and abook). Eventually we need to make this application agnostic.
// TODO: missing group membership changes
2013-07-26 05:57:06 +00:00
$result = array ();
foreach ( $deliveries as $d ) {
$r = q ( " select * from channel where channel_hash = '%s' limit 1 " ,
dbesc ( $d [ 'hash' ])
);
if ( ! $r ) {
$result [] = array ( $d [ 'hash' ], 'not found' );
continue ;
}
$channel = $r [ 0 ];
if ( $channel [ 'channel_hash' ] != $sender [ 'hash' ]) {
logger ( 'process_channel_sync_delivery: possible forgery. Sender ' . $sender [ 'hash' ] . ' is not ' . $channel [ 'channel_hash' ]);
$result [] = array ( $d [ 'hash' ], 'channel mismatch' , $channel [ 'channel_name' ]);
continue ;
}
if ( array_key_exists ( 'config' , $arr ) && is_array ( $arr [ 'config' ]) && count ( $arr [ 'config' ])) {
foreach ( $arr [ 'config' ] as $cat => $k ) {
foreach ( $arr [ 'config' ][ $cat ] as $k => $v )
set_pconfig ( $channel [ 'channel_id' ], $cat , $k , $v );
}
}
if ( array_key_exists ( 'channel' , $arr ) && is_array ( $arr [ 'channel' ]) && count ( $arr [ 'channel' ])) {
2013-07-29 04:04:03 +00:00
$disallowed = array ( 'channel_id' , 'channel_account_id' , 'channel_primary' , 'channel_prvkey' , 'channel_address' );
2013-07-26 05:57:06 +00:00
$clean = array ();
foreach ( $arr [ 'channel' ] as $k => $v ) {
if ( in_array ( $k , $disallowed ))
continue ;
$clean [ $k ] = $v ;
}
if ( count ( $clean )) {
foreach ( $clean as $k => $v ) {
$r = dbq ( " UPDATE channel set " . dbesc ( $k ) . " = ' " . dbesc ( $v )
. " ' where channel_id = " . intval ( $channel [ 'channel_id' ]) . " limit 1 " );
}
}
}
if ( array_key_exists ( 'abook' , $arr ) && is_array ( $arr [ 'abook' ]) && count ( $arr [ 'abook' ])) {
$disallowed = array ( 'abook_id' , 'abook_account' , 'abook_channel' );
$clean = array ();
foreach ( $arr [ 'abook' ] as $abook ) {
foreach ( $abook as $k => $v ) {
2013-08-27 03:58:07 +00:00
if ( in_array ( $k , $disallowed ) || ( strpos ( $k , 'abook' ) !== 0 ))
2013-07-26 05:57:06 +00:00
continue ;
$clean [ $k ] = $v ;
}
if ( ! array_key_exists ( 'abook_xchan' , $clean ))
continue ;
2013-09-09 03:38:15 +00:00
$r = q ( " select * from abook where abook_xchan = '%s' and abook_channel = %d limit 1 " ,
dbesc ( $clean [ 'abook_xchan' ]),
intval ( $channel [ 'channel_id' ])
);
// make sure we have an abook entry for this xchan on this system
if ( ! $r ) {
q ( " insert into abook ( abook_xchan, abook_channel ) values ('%s', %d ) " ,
dbesc ( $clean [ 'abook_xchan' ]),
intval ( $channel [ 'channel_id' ])
);
}
2013-07-26 05:57:06 +00:00
if ( count ( $clean )) {
foreach ( $clean as $k => $v ) {
$r = dbq ( " UPDATE abook set " . dbesc ( $k ) . " = ' " . dbesc ( $v )
. " ' where abook_xchan = ' " . dbesc ( $clean [ 'abook_xchan' ]) . " ' and abook_channel = " . intval ( $channel [ 'channel_id' ])
. " limit 1 " );
}
}
}
}
$result [] = array ( $d [ 'hash' ], 'channel sync updated' , $channel [ 'channel_name' ]);
}
return $result ;
}