diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/Contact.php | 2 | ||||
-rw-r--r-- | include/ItemObject.php | 16 | ||||
-rw-r--r-- | include/account.php | 2 | ||||
-rw-r--r-- | include/api.php | 75 | ||||
-rw-r--r-- | include/apps.php | 2 | ||||
-rw-r--r-- | include/attach.php | 73 | ||||
-rw-r--r-- | include/conversation.php | 34 | ||||
-rw-r--r-- | include/deliver.php | 18 | ||||
-rw-r--r-- | include/enotify.php | 23 | ||||
-rw-r--r-- | include/follow.php | 28 | ||||
-rw-r--r-- | include/identity.php | 24 | ||||
-rw-r--r-- | include/import.php | 67 | ||||
-rwxr-xr-x | include/items.php | 32 | ||||
-rw-r--r-- | include/message.php | 103 | ||||
-rw-r--r-- | include/network.php | 33 | ||||
-rw-r--r-- | include/notifier.php | 113 | ||||
-rw-r--r-- | include/photos.php | 86 | ||||
-rw-r--r-- | include/taxonomy.php | 2 | ||||
-rw-r--r-- | include/text.php | 142 | ||||
-rw-r--r-- | include/widgets.php | 6 | ||||
-rw-r--r-- | include/zot.php | 108 |
21 files changed, 687 insertions, 302 deletions
diff --git a/include/Contact.php b/include/Contact.php index 008574d8f..8e22c608e 100644 --- a/include/Contact.php +++ b/include/Contact.php @@ -319,6 +319,8 @@ function channel_remove($channel_id, $local = true, $unset_session=true) { q("DELETE FROM `pconfig` WHERE `uid` = %d", intval($channel_id)); q("DELETE FROM `spam` WHERE `uid` = %d", intval($channel_id)); + // @FIXME At this stage we need to remove the file resources located under /store/$nickname + q("delete from abook where abook_xchan = '%s' and abook_self = 1 ", dbesc($channel['channel_hash']) diff --git a/include/ItemObject.php b/include/ItemObject.php index 5296a1cf0..ee431dccb 100644 --- a/include/ItemObject.php +++ b/include/ItemObject.php @@ -278,13 +278,21 @@ class Item extends BaseObject { $children = $this->get_children(); + $is_photo = ((($item['resource_type'] == 'photo') && (feature_enabled($conv->get_profile_owner(),'large_photos'))) ? true : false); + + $has_tags = (($body['tags'] || $body['categories'] || $body['mentions'] || $body['attachments'] || $body['folders']) ? true : false); + $tmp_item = array( 'template' => $this->get_template(), 'mode' => $mode, 'type' => implode("",array_slice(explode("/",$item['verb']),-1)), - 'tags' => array(), - 'body' => $body, - 'text' => strip_tags($body), + 'body' => $body['html'], + 'tags' => $body['tags'], + 'categories' => $body['categories'], + 'mentions' => $body['mentions'], + 'attachments' => $body['attachments'], + 'folders' => $body['folders'], + 'text' => strip_tags($body['html']), 'id' => $this->get_id(), 'mid' => $item['mid'], 'isevent' => $isevent, @@ -325,6 +333,8 @@ class Item extends BaseObject { 'owner_url' => $this->get_owner_url(), 'owner_photo' => $this->get_owner_photo(), 'owner_name' => $this->get_owner_name(), + 'is_photo' => $is_photo, + 'has_tags' => $has_tags, // Item toolbar buttons 'like' => $like, diff --git a/include/account.php b/include/account.php index 5926e05c1..b3a520fd4 100644 --- a/include/account.php +++ b/include/account.php @@ -217,6 +217,8 @@ function create_account($arr) { $result['email'] = $email; $result['password'] = $password; + call_hooks('register_account',$result); + return $result; } diff --git a/include/api.php b/include/api.php index a77bf15f7..16dbb569b 100644 --- a/include/api.php +++ b/include/api.php @@ -8,6 +8,7 @@ require_once("html2plain.php"); require_once('include/security.php'); require_once('include/photos.php'); require_once('include/items.php'); +require_once('include/attach.php'); /* * @@ -619,6 +620,36 @@ require_once('include/items.php'); } api_register_func('api/red/channel/stream','api_channel_stream', true); + function api_attach_list(&$a,$type) { + logger('api_user: ' . api_user()); + json_return_and_die(attach_list_files(api_user(),get_observer_hash(),'','','','created asc')); + } + api_register_func('api/red/files','api_attach_list', true); + + + function api_file_detail(&$a,$type) { + if (api_user()===false) return false; + if(! $_REQUEST['file_id']) return false; + $r = q("select * from attach where uid = %d and hash = '%s' limit 1", + intval(api_user()), + dbesc($_REQUEST['file_id']) + ); + if($r) { + if($r[0]['is_dir']) + $r[0]['data'] = ''; + elseif(intval($r[0]['os_storage'])) + $r[0]['data'] = base64_encode(file_get_contents(dbunescbin($r[0]['data']))); + else + $r[0]['data'] = base64_encode(dbunescbin($r[0]['data'])); + + $ret = array('attach' => $r[0]); + json_return_and_die($ret); + } + killme(); + } + + api_register_func('api/red/file', 'api_file_detail', true); + function api_albums(&$a,$type) { json_return_and_die(photos_albums_list($a->get_channel(),$a->get_observer())); @@ -1456,7 +1487,7 @@ require_once('include/items.php'); * */ -// FIXME + function api_statuses_mentions(&$a, $type){ if (api_user()===false) return false; @@ -1481,39 +1512,25 @@ require_once('include/items.php'); $myurl = str_replace(array('www.','.'),array('','\\.'),$myurl); $diasp_url = str_replace('/channel/','/u/',$myurl); - if (get_config('system','use_fulltext_engine')) - $sql_extra .= sprintf(" AND `item`.`parent` IN (SELECT distinct(`parent`) from item where (MATCH(`author-link`) AGAINST ('".'"%s"'."' in boolean mode) or MATCH(`tag`) AGAINST ('".'"%s"'."' in boolean mode) or MATCH(tag) AGAINST ('".'"%s"'."' in boolean mode))) ", - dbesc(protect_sprintf($myurl)), - dbesc(protect_sprintf($myurl)), - dbesc(protect_sprintf($diasp_url)) - ); - else - $sql_extra .= sprintf(" AND `item`.`parent` IN (SELECT distinct(`parent`) from item where ( `author-link` like '%s' or `tag` like '%s' or tag like '%s' )) ", - dbesc(protect_sprintf('%' . $myurl)), - dbesc(protect_sprintf('%' . $myurl . ']%')), - dbesc(protect_sprintf('%' . $diasp_url . ']%')) - ); - + $sql_extra .= " AND item_mentionsme = 1 "; if ($max_id > 0) - $sql_extra .= ' AND `item`.`id` <= '.intval($max_id); + $sql_extra .= " AND item.id <= " . intval($max_id) . " "; - $r = q("SELECT `item`.*, `item`.`id` AS `item_id`, - `contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`rel`, - `contact`.`network`, `contact`.`thumb`, `contact`.`dfrn_id`, `contact`.`self`, - `contact`.`id` AS `cid`, `contact`.`uid` AS `contact-uid` - FROM `item`, `contact` - WHERE `item`.`uid` = %d - AND `item`.`visible` = 1 and `item`.`moderated` = 0 AND `item`.`deleted` = 0 - AND `contact`.`id` = `item`.`contact-id` - AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0 - $sql_extra - AND `item`.`id`>%d - ORDER BY `item`.`received` DESC LIMIT %d ,%d ", - intval($user_info['uid']), + require_once('include/security.php'); + $item_normal = item_normal(); + + $r = q("select * from item where uid = " . intval(api_user()) . " + $item_normal $sql_extra + AND id > %d group by mid + order by received desc LIMIT %d OFFSET %d ", intval($since_id), - intval($start), intval($count) + intval($count), + intval($start) ); + xchan_query($r,true); + + $ret = api_format_items($r,$user_info); diff --git a/include/apps.php b/include/apps.php index 661fc2163..c036867b1 100644 --- a/include/apps.php +++ b/include/apps.php @@ -130,7 +130,7 @@ function translate_system_apps(&$arr) { 'Address Book' => t('Address Book'), 'Login' => t('Login'), 'Channel Manager' => t('Channel Manager'), - 'Matrix' => t('Matrix'), + 'Grid' => t('Grid'), 'Settings' => t('Settings'), 'Files' => t('Files'), 'Webpages' => t('Webpages'), diff --git a/include/attach.php b/include/attach.php index 39fdb5c3a..f95feed2d 100644 --- a/include/attach.php +++ b/include/attach.php @@ -181,7 +181,7 @@ function attach_list_files($channel_id, $observer, $hash = '', $filename = '', $ $ret = array('success' => false); - if(! perm_is_allowed($channel_id,$observer, 'read_storage')) { + if(! perm_is_allowed($channel_id,$observer, 'view_storage')) { $ret['message'] = t('Permission denied.'); return $ret; } @@ -203,7 +203,7 @@ function attach_list_files($channel_id, $observer, $hash = '', $filename = '', $ // Retrieve all columns except 'data' - $r = q("select id, aid, uid, hash, filename, filetype, filesize, revision, folder, os_storage, is_dir, is_photo, flags, created, edited, allow_cid, allow_gid, deny_cid, deny_gid from attach where uid = %d $sql_extra $orderby $limit", + $r = q("select id, aid, uid, hash, filename, filetype, filesize, revision, folder, os_storage, is_dir, is_photo, flags, created, edited, allow_cid, allow_gid, deny_cid, deny_gid from attach where uid = %d $sql_extra ORDER BY $orderby $limit", intval($channel_id) ); @@ -405,7 +405,6 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) { require_once('include/photos.php'); - call_hooks('photo_upload_begin',$arr); $ret = array('success' => false); @@ -416,6 +415,7 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) { $newalbum = (($arr) ? $arr['newalbum'] : ''); $hash = (($arr && $arr['hash']) ? $arr['hash'] : null); $upload_path = (($arr && $arr['directory']) ? $arr['directory'] : ''); + $visible = (($arr && $arr['visible']) ? $arr['visible'] : ''); $observer = array(); @@ -447,11 +447,33 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) { // revise or update must provide $arr['hash'] of the thing to revise/update + // By default remove $src when finished + + $remove_when_processed = true; + if($options === 'import') { $src = $arr['src']; $filename = $arr['filename']; $filesize = @filesize($src); + $hash = $arr['resource_id']; + + if(array_key_exists('hash',$arr)) + $hash = $arr['hash']; + if(array_key_exists('type',$arr)) + $type = $arr['type']; + + if($arr['preserve_original']) + $remove_when_processed = false; + + // if importing a directory, just do it now and go home - we're done. + + if(array_key_exists('is_dir',$arr) && intval($arr['is_dir'])) { + $x = attach_mkdir($channel,$observer_hash,$arr); + if($x['message']) + logger('import_directory: ' . $x['message']); + return; + } } elseif($options !== 'update') { $f = array('src' => '', 'filename' => '', 'filesize' => 0, 'type' => ''); @@ -530,10 +552,20 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) { $pathname = ''; if($is_photo) { - if($newalbum) + if($newalbum) { $pathname = filepath_macro($newalbum); - else + } + elseif(array_key_exists('folder',$arr)) { + $x = q("select filename from attach where hash = '%s' and uid = %d limit 1", + dbesc($arr['folder']), + intval($channel['channel_id']) + ); + if($x) + $pathname = $x[0]['filename']; + } + else { $pathname = filepath_macro($album); + } } else { $pathname = filepath_macro($upload_path); @@ -563,7 +595,7 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) { } } else { - $folder_hash = ''; + $folder_hash = ((($arr) && array_key_exists('folder',$arr)) ? $arr['folder'] : ''); } if((! $options) || ($options === 'import')) { @@ -630,7 +662,8 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) { if(($maxfilesize) && ($filesize > $maxfilesize)) { $ret['message'] = sprintf( t('File exceeds size limit of %d'), $maxfilesize); - @unlink($src); + if($remove_when_processed) + @unlink($src); call_hooks('photo_upload_end',$ret); return $ret; } @@ -643,7 +676,9 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) { ); if(($r) && (($r[0]['total'] + $filesize) > ($limit - $existing_size))) { $ret['message'] = upgrade_message(true) . sprintf(t("You have reached your limit of %1$.0f Mbytes attachment storage."), $limit / 1024000); - @unlink($src); + if($remove_when_processed) + @unlink($src); + call_hooks('photo_upload_end',$ret); return $ret; } @@ -757,7 +792,7 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) { if($is_photo) { - $args = array( 'source' => $source, 'visible' => 0, 'resource_id' => $hash, 'album' => basename($pathname), 'os_path' => $os_basepath . $os_relpath, 'filename' => $filename, 'getimagesize' => $gis, 'directory' => $direct); + $args = array( 'source' => $source, 'visible' => $visible, 'resource_id' => $hash, 'album' => basename($pathname), 'os_path' => $os_basepath . $os_relpath, 'filename' => $filename, 'getimagesize' => $gis, 'directory' => $direct); if($arr['contact_allow']) $args['contact_allow'] = $arr['contact_allow']; if($arr['group_allow']) @@ -786,7 +821,7 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) { } } - if($options !== 'update') + if(($options !== 'update') && ($remove_when_processed)) @unlink($src); if(! $r) { @@ -959,7 +994,6 @@ function attach_mkdir($channel, $observer_hash, $arr = null) { intval($channel['channel_id']), dbesc($lfile) ); - if(! $r) { logger('attach_mkdir: hash ' . $lfile . ' not found in ' . $lpath); $ret['message'] = t('Path not found.'); @@ -1195,7 +1229,7 @@ function attach_delete($channel_id, $resource, $is_photo = 0) { $channel_address = (($c) ? $c[0]['channel_address'] : 'notfound'); $photo_sql = (($is_photo) ? " and is_photo = 1 " : ''); - $r = q("SELECT hash, flags, is_dir, folder FROM attach WHERE hash = '%s' AND uid = %d $photo_sql limit 1", + $r = q("SELECT hash, flags, is_dir, is_photo, folder FROM attach WHERE hash = '%s' AND uid = %d $photo_sql limit 1", dbesc($resource), intval($channel_id) ); @@ -1241,6 +1275,21 @@ function attach_delete($channel_id, $resource, $is_photo = 0) { intval($channel_id) ); + if($r[0]['is_photo']) { + $x = q("select id, item_hidden from item where resource_id = '%s' and resource_type = 'photo' and uid = %d", + dbesc($resource), + intval($channel_id) + ); + if($x) { + drop_item($x[0]['id'],false,(($x[0]['item_hidden']) ? DROPITEM_NORMAL : DROPITEM_PHASE1),true); + + q("DELETE FROM photo WHERE uid = %d AND resource_id = '%s'", + intval($channel_id), + dbesc($resource) + ); + } + } + // update the parent folder's lastmodified timestamp $e = q("UPDATE attach SET edited = '%s' WHERE hash = '%s' AND uid = %d", dbesc(datetime_convert()), diff --git a/include/conversation.php b/include/conversation.php index 0f6f8685b..ebbc6684c 100644 --- a/include/conversation.php +++ b/include/conversation.php @@ -629,11 +629,6 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional', $ if($item['author-link'] && (! $item['author-name'])) $profile_name = $item['author-link']; - - $tags=array(); - $hashtags = array(); - $mentions = array(); - $sp = false; $profile_link = best_link_url($item,$sp); if($sp) @@ -678,14 +673,17 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional', $ $unverified = ''; - $tags=array(); - $terms = get_terms_oftype($item['term'],array(TERM_HASHTAG,TERM_MENTION,TERM_UNKNOWN)); - if(count($terms)) - foreach($terms as $tag) - $tags[] = format_term_for_display($tag); +// $tags=array(); +// $terms = get_terms_oftype($item['term'],array(TERM_HASHTAG,TERM_MENTION,TERM_UNKNOWN)); +// if(count($terms)) +// foreach($terms as $tag) +// $tags[] = format_term_for_display($tag); $body = prepare_body($item,true); + $is_photo = ((($item['resource_type'] == 'photo') && (feature_enabled($profile_owner,'large_photos'))) ? true : false); + $has_tags = (($body['tags'] || $body['categories'] || $body['mentions'] || $body['attachments'] || $body['folders']) ? true : false); + $tmp_item = array( 'template' => $tpl, 'toplevel' => 'toplevel_item', @@ -699,10 +697,12 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional', $ 'lock' => $lock, 'thumb' => $profile_avatar, 'title' => $item['title'], - 'body' => $body, - 'tags' => $tags, - 'hashtags' => $hashtags, - 'mentions' => $mentions, + 'body' => $body['html'], + 'tags' => $body['tags'], + 'categories' => $body['categories'], + 'mentions' => $body['mentions'], + 'attachments' => $body['attachments'], + 'folders' => $body['folders'], 'verified' => $verified, 'unverified' => $unverified, 'forged' => $forged, @@ -712,7 +712,7 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional', $ 'has_folders' => ((count($folders)) ? 'true' : ''), 'categories' => $categories, 'folders' => $folders, - 'text' => strip_tags($body), + 'text' => strip_tags($body['html']), 'ago' => relative_date($item['created']), 'app' => $item['app'], 'str_app' => sprintf( t('from %s'), $item['app']), @@ -738,6 +738,8 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional', $ 'previewing' => $previewing, 'wait' => t('Please wait'), 'thread_level' => 1, + 'is_photo' => $is_photo, + 'has_tags' => $has_tags, ); $arr = array('item' => $item, 'output' => $tmp_item); @@ -1414,7 +1416,7 @@ function prepare_page($item) { '$auth_url' => (($naked) ? '' : zid($item['author']['xchan_url'])), '$date' => (($naked) ? '' : datetime_convert('UTC', date_default_timezone_get(), $item['created'], 'Y-m-d H:i')), '$title' => smilies(bbcode($item['title'])), - '$body' => $body, + '$body' => $body['html'], '$preview' => $preview, '$link' => $link, )); diff --git a/include/deliver.php b/include/deliver.php index a338d1a89..11c1b249e 100644 --- a/include/deliver.php +++ b/include/deliver.php @@ -138,14 +138,16 @@ function deliver_run($argv, $argc) { if($dresult && is_array($dresult)) { foreach($dresult as $xx) { if(is_array($xx) && array_key_exists('message_id',$xx)) { - q("insert into dreport ( dreport_mid, dreport_site, dreport_recip, dreport_result, dreport_time, dreport_xchan ) values ( '%s', '%s','%s','%s','%s','%s' ) ", - dbesc($xx['message_id']), - dbesc($xx['location']), - dbesc($xx['recipient']), - dbesc($xx['status']), - dbesc(datetime_convert($xx['date'])), - dbesc($xx['sender']) - ); + if(delivery_report_is_storable($xx)) { + q("insert into dreport ( dreport_mid, dreport_site, dreport_recip, dreport_result, dreport_time, dreport_xchan ) values ( '%s', '%s','%s','%s','%s','%s' ) ", + dbesc($xx['message_id']), + dbesc($xx['location']), + dbesc($xx['recipient']), + dbesc($xx['status']), + dbesc(datetime_convert($xx['date'])), + dbesc($xx['sender']) + ); + } } } } diff --git a/include/enotify.php b/include/enotify.php index d0228bf50..bbddcdd14 100644 --- a/include/enotify.php +++ b/include/enotify.php @@ -97,7 +97,7 @@ function notification($params) { if ($params['type'] == NOTIFY_MAIL) { logger('notification: mail'); - $subject = sprintf( t('[Red:Notify] New mail received at %s'),$sitename); + $subject = sprintf( t('[Hubzilla:Notify] New mail received at %s'),$sitename); $preamble = sprintf( t('%1$s, %2$s sent you a new private message at %3$s.'),$recip['channel_name'], $sender['xchan_name'],$sitename); $epreamble = sprintf( t('%1$s sent you %2$s.'),'[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]', '[zrl=$itemlink]' . t('a private message') . '[/zrl]'); @@ -183,7 +183,7 @@ function notification($params) { // Before this we have the name of the replier on the subject rendering // differents subjects for messages on the same thread. - $subject = sprintf( t('[Red:Notify] Comment to conversation #%1$d by %2$s'), $parent_id, $sender['xchan_name']); + $subject = sprintf( t('[Hubzilla:Notify] Comment to conversation #%1$d by %2$s'), $parent_id, $sender['xchan_name']); $preamble = sprintf( t('%1$s, %2$s commented on an item/conversation you have been following.'), $recip['channel_name'], $sender['xchan_name']); $epreamble = $dest_str; @@ -193,7 +193,7 @@ function notification($params) { } if($params['type'] == NOTIFY_WALL) { - $subject = sprintf( t('[Red:Notify] %s posted to your profile wall') , $sender['xchan_name']); + $subject = sprintf( t('[Hubzilla:Notify] %s posted to your profile wall') , $sender['xchan_name']); $preamble = sprintf( t('%1$s, %2$s posted to your profile wall at %3$s') , $recip['channel_name'], $sender['xchan_name'], $sitename); @@ -221,7 +221,7 @@ function notification($params) { return; } - $subject = sprintf( t('[Red:Notify] %s tagged you') , $sender['xchan_name']); + $subject = sprintf( t('[Hubzilla:Notify] %s tagged you') , $sender['xchan_name']); $preamble = sprintf( t('%1$s, %2$s tagged you at %3$s') , $recip['channel_name'], $sender['xchan_name'], $sitename); $epreamble = sprintf( t('%1$s, %2$s [zrl=%3$s]tagged you[/zrl].') , $recip['channel_name'], @@ -235,7 +235,7 @@ function notification($params) { } if ($params['type'] == NOTIFY_POKE) { - $subject = sprintf( t('[Red:Notify] %1$s poked you') , $sender['xchan_name']); + $subject = sprintf( t('[Hubzilla:Notify] %1$s poked you') , $sender['xchan_name']); $preamble = sprintf( t('%1$s, %2$s poked you at %3$s') , $recip['channel_name'], $sender['xchan_name'], $sitename); $epreamble = sprintf( t('%1$s, %2$s [zrl=%2$s]poked you[/zrl].') , $recip['channel_name'], @@ -253,7 +253,7 @@ function notification($params) { } if ($params['type'] == NOTIFY_TAGSHARE) { - $subject = sprintf( t('[Red:Notify] %s tagged your post') , $sender['xchan_name']); + $subject = sprintf( t('[Hubzilla:Notify] %s tagged your post') , $sender['xchan_name']); $preamble = sprintf( t('%1$s, %2$s tagged your post at %3$s') , $recip['channel_name'],$sender['xchan_name'], $sitename); $epreamble = sprintf( t('%1$s, %2$s tagged [zrl=%3$s]your post[/zrl]') , $recip['channel_name'], @@ -267,7 +267,7 @@ function notification($params) { } if ($params['type'] == NOTIFY_INTRO) { - $subject = sprintf( t('[Red:Notify] Introduction received')); + $subject = sprintf( t('[Hubzilla:Notify] Introduction received')); $preamble = sprintf( t('%1$s, you\'ve received an new connection request from \'%2$s\' at %3$s'), $recip['channel_name'], $sender['xchan_name'], $sitename); $epreamble = sprintf( t('%1$s, you\'ve received [zrl=%2$s]a new connection request[/zrl] from %3$s.'), $recip['channel_name'], @@ -282,7 +282,7 @@ function notification($params) { } if ($params['type'] == NOTIFY_SUGGEST) { - $subject = sprintf( t('[Red:Notify] Friend suggestion received')); + $subject = sprintf( t('[Hubzilla:Notify] Friend suggestion received')); $preamble = sprintf( t('%1$s, you\'ve received a friend suggestion from \'%2$s\' at %3$s'), $recip['channel_name'], $sender['xchan_name'], $sitename); $epreamble = sprintf( t('%1$s, you\'ve received [zrl=%2$s]a friend suggestion[/zrl] for %3$s from %4$s.'), $recip['channel_name'], @@ -315,9 +315,12 @@ function notification($params) { 'epreamble' => $epreamble, 'body' => $body, 'sitelink' => $sitelink, + 'sitename' => $sitename, 'tsitelink' => $tsitelink, 'hsitelink' => $hsitelink, - 'itemlink' => $itemlink + 'itemlink' => $itemlink, + 'sender' => $sender, + 'recipient' => $recip ); call_hooks('enotify', $h); @@ -505,7 +508,7 @@ function notification($params) { $private_activity = true; case NOTIFY_MAIL: $datarray['textversion'] = $datarray['htmlversion'] = $datarray['title'] = ''; - $datarray['subject'] = preg_replace('/' . preg_quote(t('[Red:Notify]')) . '/','$0*',$datarray['subject']); + $datarray['subject'] = preg_replace('/' . preg_quote(t('[Hubzilla:Notify]')) . '/','$0*',$datarray['subject']); break; default: break; diff --git a/include/follow.php b/include/follow.php index 960138743..40ad2c299 100644 --- a/include/follow.php +++ b/include/follow.php @@ -133,27 +133,27 @@ function new_contact($uid,$url,$channel,$interactive = false, $confirm = false) $their_perms = 0; $xchan_hash = ''; + $r = q("select * from xchan where xchan_hash = '%s' or xchan_url = '%s' limit 1", dbesc($url), dbesc($url) ); + if(! $r) { // attempt network auto-discovery if(strpos($url,'@') && (! $is_http)) { - $r = discover_by_webbie($url); + $d = discover_by_webbie($url); } elseif($is_http) { - $r = discover_by_url($url); - $r['allowed'] = intval(get_config('system','feed_contacts')); - } - if($r) { - $r['channel_id'] = $uid; - call_hooks('follow_allow',$r); - if(! $r['allowed']) { + if(get_config('system','feed_contacts')) + $d = discover_by_url($url); + else { $result['message'] = t('Protocol disabled.'); return $result; } + } + if($d) { $r = q("select * from xchan where xchan_hash = '%s' or xchan_url = '%s' limit 1", dbesc($url), dbesc($url) @@ -172,6 +172,16 @@ function new_contact($uid,$url,$channel,$interactive = false, $confirm = false) return $result; } + $x = array('channel_id' => $uid, 'follow_address' => $url, 'xchan' => $r[0], 'allowed' => 1); + + call_hooks('follow_allow',$x); + + if(! $x['allowed']) { + $result['message'] = t('Protocol disabled.'); + return $result; + } + + if((local_channel()) && $uid == local_channel()) { $aid = get_account_id(); $hash = get_observer_hash(); @@ -251,7 +261,7 @@ function new_contact($uid,$url,$channel,$interactive = false, $confirm = false) ); if($r) { $result['abook'] = $r[0]; - proc_run('php', 'include/notifier.php', 'permission_update', $result['abook']['abook_id']); + proc_run('php', 'include/notifier.php', 'permission_create', $result['abook']['abook_id']); } $arr = array('channel_id' => $uid, 'abook' => $result['abook']); diff --git a/include/identity.php b/include/identity.php index 47738a8fa..0c4a9df45 100644 --- a/include/identity.php +++ b/include/identity.php @@ -631,6 +631,30 @@ function identity_basic_export($channel_id, $items = false) { if($r) $ret['likes'] = $r; + + $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; + } + $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) ); diff --git a/include/import.php b/include/import.php index ad8bcd84e..0fd1ab2a5 100644 --- a/include/import.php +++ b/include/import.php @@ -790,7 +790,7 @@ function import_likes($channel,$likes) { if($r) continue; - dbesc_array($config); + dbesc_array($like); $r = dbq("INSERT INTO likes (`" . implode("`, `", array_keys($like)) . "`) VALUES ('" @@ -800,6 +800,71 @@ function import_likes($channel,$likes) { } } +function import_conv($channel,$convs) { + if($channel && $convs) { + foreach($convs as $conv) { + if($conv['deleted']) { + q("delete from conv where guid = '%s' and uid = %d limit 1", + dbesc($conv['guid']), + intval($channel['channel_id']) + ); + continue; + } + + unset($conv['id']); + + $conv['uid'] = $channel['channel_id']; + $conv['subject'] = str_rot47(base64url_encode($conv['subject'])); + + $r = q("select id from conv where guid = '%s' and uid = %d limit 1", + dbesc($conv['guid']), + intval($channel['channel_id']) + ); + if($r) + continue; + + dbesc_array($conv); + $r = dbq("INSERT INTO conv (`" + . implode("`, `", array_keys($conv)) + . "`) VALUES ('" + . implode("', '", array_values($conv)) + . "')" ); + } + } +} + + + +function import_mail($channel,$mails) { + if($channel && $mails) { + foreach($mails as $mail) { + if(array_key_exists('flags',$mail) && in_array('deleted',$mail['flags'])) { + q("delete from mail where mid = '%s' and uid = %d limit 1", + dbesc($mail['message_id']), + intval($channel['channel_id']) + ); + continue; + } + if(array_key_exists('flags',$mail) && in_array('recalled',$mail['flags'])) { + q("update mail set mail_recalled = 1 where mid = '%s' and uid = %d limit 1", + dbesc($mail['message_id']), + intval($channel['channel_id']) + ); + continue; + } + + $m = get_mail_elements($mail); + if(! $m) + continue; + + $m['aid'] = $channel['channel_account_id']; + $m['uid'] = $channel['channel_id']; + mail_store($m); + } + } +} + + diff --git a/include/items.php b/include/items.php index e7cc02579..9159f6da3 100755 --- a/include/items.php +++ b/include/items.php @@ -889,6 +889,7 @@ function get_item_elements($x,$allow_code = false) { $arr['mimetype'] = (($x['mimetype']) ? htmlspecialchars($x['mimetype'], ENT_COMPAT,'UTF-8',false) : ''); $arr['obj_type'] = (($x['object_type']) ? htmlspecialchars($x['object_type'], ENT_COMPAT,'UTF-8',false) : ''); $arr['tgt_type'] = (($x['target_type']) ? htmlspecialchars($x['target_type'], ENT_COMPAT,'UTF-8',false) : ''); + $arr['resource_type'] = (($x['resource_type']) ? htmlspecialchars($x['resource_type'], ENT_COMPAT,'UTF-8',false) : ''); $arr['public_policy'] = (($x['public_scope']) ? htmlspecialchars($x['public_scope'], ENT_COMPAT,'UTF-8',false) : ''); if($arr['public_policy'] === 'public') @@ -1285,6 +1286,7 @@ function encode_item($item,$mirror = false) { $x['verb'] = $item['verb']; $x['object_type'] = $item['obj_type']; $x['target_type'] = $item['tgt_type']; + $x['resource_type'] = $item['resource_type']; $x['permalink'] = $item['plink']; $x['location'] = $item['location']; $x['longlat'] = $item['coord']; @@ -1559,7 +1561,7 @@ function encode_item_flags($item) { return $ret; } -function encode_mail($item) { +function encode_mail($item,$extended = false) { $x = array(); $x['type'] = 'mail'; $x['encoding'] = 'zot'; @@ -1592,6 +1594,18 @@ function encode_mail($item) { $x['body'] = ''; } + if($extended) { + $x['conv_guid'] = $item['conv_guid']; + if(intval($item['mail_deleted'])) + $x['flags'][] = 'deleted'; + if(intval($item['mail_replied'])) + $x['flags'][] = 'replied'; + if(intval($item['mail_isreply'])) + $x['flags'][] = 'isreply'; + if(intval($item['mail_seen'])) + $x['flags'][] = 'seen'; + } + return $x; } @@ -1604,6 +1618,8 @@ function get_mail_elements($x) { $arr['body'] = (($x['body']) ? htmlspecialchars($x['body'], ENT_COMPAT,'UTF-8',false) : ''); $arr['title'] = (($x['title'])? htmlspecialchars($x['title'],ENT_COMPAT,'UTF-8',false) : ''); + $arr['conv_guid'] = (($x['conv_guid'])? htmlspecialchars($x['conv_guid'],ENT_COMPAT,'UTF-8',false) : ''); + $arr['created'] = datetime_convert('UTC','UTC',$x['created']); if((! array_key_exists('expires',$x)) || ($x['expires'] === NULL_DATE)) $arr['expires'] = NULL_DATE; @@ -1616,6 +1632,18 @@ function get_mail_elements($x) { if(in_array('recalled',$x['flags'])) { $arr['mail_recalled'] = 1; } + if(in_array('replied',$x['flags'])) { + $arr['mail_replied'] = 1; + } + if(in_array('isreply',$x['flags'])) { + $arr['mail_isreply'] = 1; + } + if(in_array('seen',$x['flags'])) { + $arr['mail_seen'] = 1; + } + if(in_array('deleted',$x['flags'])) { + $arr['mail_deleted'] = 1; + } } $key = get_config('system','pubkey'); @@ -1630,6 +1658,7 @@ function get_mail_elements($x) { if($arr['created'] > datetime_convert()) $arr['created'] = datetime_convert(); + $arr['mid'] = (($x['message_id']) ? htmlspecialchars($x['message_id'], ENT_COMPAT,'UTF-8',false) : ''); $arr['parent_mid'] = (($x['message_parent']) ? htmlspecialchars($x['message_parent'], ENT_COMPAT,'UTF-8',false) : ''); @@ -3510,6 +3539,7 @@ function mail_store($arr) { $arr['title'] = ((x($arr,'title')) ? trim($arr['title']) : ''); $arr['parent_mid'] = ((x($arr,'parent_mid')) ? notags(trim($arr['parent_mid'])) : ''); $arr['body'] = ((x($arr,'body')) ? trim($arr['body']) : ''); + $arr['conv_guid'] = ((x($arr,'conv_guid')) ? trim($arr['conv_guid']) : ''); $arr['mail_flags'] = ((x($arr,'mail_flags')) ? intval($arr['mail_flags']) : 0 ); diff --git a/include/message.php b/include/message.php index 4b0236db8..820d814b6 100644 --- a/include/message.php +++ b/include/message.php @@ -28,8 +28,6 @@ function send_message($uid = 0, $recipient='', $body='', $subject='', $replyto=' // $expires = datetime_convert(date_default_timezone_get(),'UTC',$expires); - - if($uid) { $r = q("select * from channel where channel_id = %d limit 1", intval($uid) @@ -49,18 +47,20 @@ function send_message($uid = 0, $recipient='', $body='', $subject='', $replyto=' // look for any existing conversation structure + $conv_guid = ''; if(strlen($replyto)) { - $r = q("select convid from mail where channel_id = %d and ( mid = '%s' or parent_mid = '%s' ) limit 1", + $r = q("select conv_guid from mail where channel_id = %d and ( mid = '%s' or parent_mid = '%s' ) limit 1", intval(local_channel()), dbesc($replyto), dbesc($replyto) ); - if($r) - $convid = $r[0]['convid']; + if($r) { + $conv_guid = $r[0]['conv_guid']; + } } - if(! $convid) { + if(! $conv_guid) { // create a new conversation @@ -93,16 +93,28 @@ function send_message($uid = 0, $recipient='', $body='', $subject='', $replyto=' dbesc($conv_guid), intval(local_channel()) ); - if($r) - $convid = $r[0]['id']; + if($r) { + $retconv = $r[0]; + $retconv['subject'] = base64url_decode(str_rot47($retconv['subject'])); + } + } + + if(! $retconv) { + $r = q("select * from conv where guid = '%s' and uid = %d limit 1", + dbesc($conv_guid), + intval(local_channel()) + ); + if($r) { + $retconv = $r[0]; + $retconv['subject'] = base64url_decode(str_rot47($retconv['subject'])); + } } - if(! $convid) { + if(! $retconv) { $ret['message'] = 'conversation not found'; return $ret; } - // generate a unique message_id do { @@ -174,10 +186,10 @@ function send_message($uid = 0, $recipient='', $body='', $subject='', $replyto=' - $r = q("INSERT INTO mail ( account_id, convid, mail_obscured, channel_id, from_xchan, to_xchan, title, body, attach, mid, parent_mid, created, expires ) - VALUES ( %d, %d, %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s' )", + $r = q("INSERT INTO mail ( account_id, conv_guid, mail_obscured, channel_id, from_xchan, to_xchan, title, body, attach, mid, parent_mid, created, expires ) + VALUES ( %d, '%s', %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s' )", intval($channel['channel_account_id']), - intval($convid), + dbesc($conv_guid), intval(1), intval($channel['channel_id']), dbesc($channel['channel_hash']), @@ -197,8 +209,11 @@ function send_message($uid = 0, $recipient='', $body='', $subject='', $replyto=' dbesc($mid), intval($channel['channel_id']) ); - if($r) + if($r) { $post_id = $r[0]['id']; + $retmail = $r[0]; + xchan_mail_query($retmail); + } else { $ret['message'] = t('Stored post could not be verified.'); return $ret; @@ -242,6 +257,9 @@ function send_message($uid = 0, $recipient='', $body='', $subject='', $replyto=' $ret['success'] = true; $ret['message_item'] = intval($post_id); + $ret['conv'] = $retconv; + $ret['mail'] = $retmail; + return $ret; } @@ -367,30 +385,67 @@ function private_messages_fetch_message($channel_id, $messageitem_id, $updatesee function private_messages_drop($channel_id, $messageitem_id, $drop_conversation = false) { + + $x = q("select * from mail where id = %d and channel_id = %d limit 1", + intval($messageitem_id), + intval($channel_id) + ); + if(! $x) + return false; + + $conversation = null; + + if($x[0]['conv_guid']) { + $y = q("select * from conv where guid = '%s' and uid = %d limit 1", + dbesc($x[0]['conv_guid']), + intval($channel_id) + ); + if($y) { + $conversation = $y[0]; + $conversation['subject'] = base64url_decode(str_rot47($conversation['subject'])); + } + } + if($drop_conversation) { - // find the parent_id - $p = q("SELECT parent_mid FROM mail WHERE id = %d AND channel_id = %d LIMIT 1", - intval($messageitem_id), + $m = array(); + $m['conv'] = array($conversation); + $m['conv'][0]['deleted'] = 1; + + $z = q("select * from mail where parent_mid = '%s' and channel_id = %d", + dbesc($x[0]['parent_mid']), intval($channel_id) ); - if($p) { - $r = q("DELETE FROM mail WHERE parent_mid = '%s' AND channel_id = %d ", - dbesc($p[0]['parent_mid']), + if($z) { + q("delete from conv where guid = '%s' and uid = %d limit 1", + dbesc($x[0]['conv_guid']), + intval($channel_id) + ); + $m['mail'] = array(); + foreach($z as $zz) { + xchan_mail_query($zz); + $zz['mail_deleted'] = 1; + $m['mail'][] = encode_mail($zz,true); + } + q("DELETE FROM mail WHERE parent_mid = '%s' AND channel_id = %d ", + dbesc($x[0]['parent_mid']), intval($channel_id) ); - if($r) - return true; } + build_sync_packet($channel_id,$m); + return true; } else { + xchan_mail_query($x[0]); + $x[0]['mail_deleted'] = true; $r = q("DELETE FROM mail WHERE id = %d AND channel_id = %d", intval($messageitem_id), intval($channel_id) ); - if($r) - return true; + build_sync_packet($channel_id,array('mail' => array(encode_mail($x,true)))); + return true; } return false; + } diff --git a/include/network.php b/include/network.php index 41e1ff37c..c67c019ef 100644 --- a/include/network.php +++ b/include/network.php @@ -586,7 +586,7 @@ function scale_external_images($s, $include_link = true, $scale_replace = false) if(substr($mtch[1],0,1) == '=') { $owidth = intval(substr($mtch[2],1)); - if(intval($owidth) > 0 && intval($owidth) < 640) + if(intval($owidth) > 0 && intval($owidth) < 1024) continue; } @@ -624,9 +624,9 @@ function scale_external_images($s, $include_link = true, $scale_replace = false) $orig_width = $ph->getWidth(); $orig_height = $ph->getHeight(); - if($orig_width > 640 || $orig_height > 640) { + if($orig_width > 1024 || $orig_height > 1024) { $tag = (($match[1] == 'z') ? 'zmg' : 'img'); - $ph->scaleImage(640); + $ph->scaleImage(1024); $new_width = $ph->getWidth(); $new_height = $ph->getHeight(); logger('scale_external_images: ' . $orig_width . '->' . $new_width . 'w ' . $orig_height . '->' . $new_height . 'h' . ' match: ' . $mtch[0], LOGGER_DEBUG); @@ -1677,13 +1677,40 @@ function format_and_send_email($sender,$xchan,$item) { 'additionalMailHeader' => '', )); +} + +function do_delivery($deliveries) { + if(! (is_array($deliveries) && count($deliveries))) + return; + $interval = ((get_config('system','delivery_interval') !== false) + ? intval(get_config('system','delivery_interval')) : 2 ); + $deliveries_per_process = intval(get_config('system','delivery_batch_count')); + if($deliveries_per_process <= 0) + $deliveries_per_process = 1; + $deliver = array(); + foreach($deliveries as $d) { + $deliver[] = $d; + + if(count($deliver) >= $deliveries_per_process) { + proc_run('php','include/deliver.php',$deliver); + $deliver = array(); + if($interval) + @time_sleep_until(microtime(true) + (float) $interval); + } + } + + // catch any stragglers + + if($deliver) + proc_run('php','include/deliver.php',$deliver); + } diff --git a/include/notifier.php b/include/notifier.php index db1aa9690..b7cea629d 100644 --- a/include/notifier.php +++ b/include/notifier.php @@ -96,7 +96,19 @@ function notifier_run($argv, $argc){ require_once('include/identity.php'); $sys = get_sys_channel(); - if($cmd == 'permission_update') { + $deliveries = array(); + + $dead_hubs = array(); + + $dh = q("select site_url from site where site_dead = 1"); + if(dh) { + foreach($dh as $dead) { + $dead_hubs[] = $dead['site_url']; + } + } + + + if($cmd == 'permission_update' || $cmd == 'permission_create') { // Get the recipient $r = q("select abook.*, hubloc.* from abook left join hubloc on hubloc_hash = abook_xchan @@ -113,8 +125,16 @@ function notifier_run($argv, $argc){ intval($r[0]['abook_channel']) ); if($s) { - $perm_update = array('sender' => $s[0], 'recipient' => $r[0], 'success' => false); - call_hooks('permissions_update',$perm_update); + $perm_update = array('sender' => $s[0], 'recipient' => $r[0], 'success' => false, 'deliveries' => ''); + + if($cmd == 'permission_create']) + call_hooks('permissions_create',$perm_update); + else + call_hooks('permissions_update',$perm_update); + + if($perm_update['success'] && $perm_update['deliveries']) + $deliveries[] = $perm_update['deliveries']; + if(! $perm_update['success']) { // send a refresh message to each hub they have registered here $h = q("select * from hubloc where hubloc_hash = '%s' @@ -125,36 +145,40 @@ function notifier_run($argv, $argc){ ); if($h) { foreach($h as $hh) { + if(in_array($hh['hubloc_url'],$dead_hubs)) { + logger('skipping dead hub: ' . $hh['hubloc_url'], LOGGER_DEBUG); + continue; + } + $data = zot_build_packet($s[0],'refresh',array(array( 'guid' => $hh['hubloc_guid'], 'guid_sig' => $hh['hubloc_guid_sig'], 'url' => $hh['hubloc_url']) )); if($data) { - $result = zot_zot($hh['hubloc_callback'],$data); - - // if immediate delivery failed, stick it in the queue to try again later. - - if(! $result['success']) { - $hash = random_string(); - q("insert into outq ( outq_hash, outq_account, outq_channel, outq_driver, outq_posturl, outq_async, outq_created, outq_updated, outq_notify, outq_msg ) - values ( '%s', %d, %d, '%s', '%s', %d, '%s', '%s', '%s', '%s' )", - dbesc($hash), - intval($s[0]['channel_account_id']), - intval($s[0]['channel_id']), - dbesc('zot'), - dbesc($hh['hubloc_callback']), - intval(1), - dbesc(datetime_convert()), - dbesc(datetime_convert()), - dbesc($data), - dbesc('') - ); - } + $hash = random_string(); + q("insert into outq ( outq_hash, outq_account, outq_channel, outq_driver, outq_posturl, outq_async, outq_created, outq_updated, outq_notify, outq_msg ) + values ( '%s', %d, %d, '%s', '%s', %d, '%s', '%s', '%s', '%s' )", + dbesc($hash), + intval($s[0]['channel_account_id']), + intval($s[0]['channel_id']), + dbesc('zot'), + dbesc($hh['hubloc_callback']), + intval(1), + dbesc(datetime_convert()), + dbesc(datetime_convert()), + dbesc($data), + dbesc('') + ); + $deliveries[] = $hash; } - } + } + } } + + if($deliveries) + do_delivery($deliveries); } } return; @@ -524,14 +548,6 @@ function notifier_run($argv, $argc){ $hubs = $r; - $dead_hubs = array(); - - $dh = q("select site_url from site where site_dead = 1"); - if(dh) { - foreach($dh as $dead) { - $dead_hubs[] = $dead['site_url']; - } - } /** @@ -571,15 +587,6 @@ function notifier_run($argv, $argc){ logger('notifier: will notify/deliver to these hubs: ' . print_r($hublist,true), LOGGER_DEBUG); - $interval = ((get_config('system','delivery_interval') !== false) - ? intval(get_config('system','delivery_interval')) : 2 ); - - $deliveries_per_process = intval(get_config('system','delivery_batch_count')); - - if($deliveries_per_process <= 0) - $deliveries_per_process = 1; - - $deliveries = array(); foreach($dhubs as $hub) { @@ -687,29 +694,11 @@ function notifier_run($argv, $argc){ if($normal_mode) { $x = q("select * from hook where hook = 'notifier_normal'"); if($x) - proc_run('php','deliver_hooks.php', $target_item['id']); + proc_run('php','include/deliver_hooks.php', $target_item['id']); } - if($deliveries) { - $deliver = array(); - - foreach($deliveries as $d) { - - $deliver[] = $d; - - if(count($deliver) >= $deliveries_per_process) { - proc_run('php','include/deliver.php',$deliver); - $deliver = array(); - if($interval) - @time_sleep_until(microtime(true) + (float) $interval); - } - } - } - - // catch any stragglers - - if($deliver) - proc_run('php','include/deliver.php',$deliver); + if($deliveries) + do_delivery($deliveries); logger('notifier: basic loop complete.', LOGGER_DEBUG); diff --git a/include/photos.php b/include/photos.php index 49aab6865..e78b899e0 100644 --- a/include/photos.php +++ b/include/photos.php @@ -185,31 +185,40 @@ function photo_upload($channel, $observer, $args) { if($args['description']) $p['description'] = $args['description']; - $r1 = $ph->save($p); - if(! $r1) + $r0 = $ph->save($p); + $r0wxh = $ph->getWidth() . 'x' . $ph->getHeight(); + if(! $r0) $errors = true; - unset($p['os_storage']); unset($p['os_path']); - if(($width > 640 || $height > 640) && (! $errors)) { + if(($width > 1024 || $height > 1024) && (! $errors)) + $ph->scaleImage(1024); + + $p['scale'] = 1; + $r1 = $ph->save($p); + $r1wxh = $ph->getWidth() . 'x' . $ph->getHeight(); + if(! $r1) + $errors = true; + + if(($width > 640 || $height > 640) && (! $errors)) $ph->scaleImage(640); - $p['scale'] = 1; - $r2 = $ph->save($p); - $smallest = 1; - if(! $r2) - $errors = true; - } - if(($width > 320 || $height > 320) && (! $errors)) { + $p['scale'] = 2; + $r2 = $ph->save($p); + $r2wxh = $ph->getWidth() . 'x' . $ph->getHeight(); + if(! $r2) + $errors = true; + + if(($width > 320 || $height > 320) && (! $errors)) $ph->scaleImage(320); - $p['scale'] = 2; - $r3 = $ph->save($p); - $smallest = 2; - if(! $r3) - $errors = true; - } + + $p['scale'] = 3; + $r3 = $ph->save($p); + $r3wxh = $ph->getWidth() . 'x' . $ph->getHeight(); + if(! $r3) + $errors = true; if($errors) { q("delete from photo where resource_id = '%s' and uid = %d", @@ -222,12 +231,6 @@ function photo_upload($channel, $observer, $args) { return $ret; } - // This will be the width and height of the smallest representation - - $width_x_height = $ph->getWidth() . 'x' . $ph->getHeight(); - - // Create item container - $item_hidden = (($visible) ? 0 : 1 ); $lat = $lon = null; @@ -239,6 +242,19 @@ function photo_upload($channel, $observer, $args) { } } + $larger = feature_enabled($channel['channel_id'], 'large_photos'); + + if($larger) { + $tag = (($r1wxh) ? '[zmg=' . $r1wxh . ']' : '[zmg]'); + $scale = 1; + } + else { + $tag = (($r2wxh) ? '[zmg=' . $r2wxh . ']' : '[zmg]'); + $scale = 2; + } + + // Create item container + if($args['item']) { foreach($args['item'] as $i) { @@ -248,7 +264,7 @@ function photo_upload($channel, $observer, $args) { if($item['mid'] === $item['parent_mid']) { $item['body'] = '[zrl=' . z_root() . '/photos/' . $channel['channel_address'] . '/image/' . $photo_hash . ']' - . $tag . z_root() . "/photo/{$photo_hash}-{$smallest}.".$ph->getExt() . '[/zmg]' + . $tag . z_root() . "/photo/{$photo_hash}-{$scale}.".$ph->getExt() . '[/zmg]' . '[/zrl]'; if($item['author_xchan'] === $channel['channel_hash']) { @@ -281,7 +297,7 @@ function photo_upload($channel, $observer, $args) { } } else { - $title = ''; + $title = $args['filename'] ? $args['filename'] : ''; $mid = item_message_id(); $arr = array(); @@ -310,26 +326,8 @@ function photo_upload($channel, $observer, $args) { $arr['item_private'] = intval($acl->is_private()); $arr['plink'] = z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . $arr['mid']; - // We should also put a width_x_height on large photos. Left as an exercise for - // devs looking for simple stuff to fix. - - $larger = feature_enabled($channel['channel_id'], 'large_photos'); - if($larger) { - $tag = '[zmg]'; - if($r2) - $smallest = 1; - else - $smallest = 0; - } - else { - if ($width_x_height) - $tag = '[zmg=' . $width_x_height. ']'; - else - $tag = '[zmg]'; - } - $arr['body'] = '[zrl=' . z_root() . '/photos/' . $channel['channel_address'] . '/image/' . $photo_hash . ']' - . $tag . z_root() . "/photo/{$photo_hash}-{$smallest}.".$ph->getExt() . '[/zmg]' + . $tag . z_root() . "/photo/{$photo_hash}-{$scale}.".$ph->getExt() . '[/zmg]' . '[/zrl]'; $result = item_store($arr); diff --git a/include/taxonomy.php b/include/taxonomy.php index a82cf94f7..e68b9659f 100644 --- a/include/taxonomy.php +++ b/include/taxonomy.php @@ -185,7 +185,7 @@ function dir_tagadelic($count = 0) { $count = intval($count); // Fetch tags - $r = q("select xtag_term, count(xtag_term) as total from xtag + $r = q("select xtag_term, count(xtag_term) as total from xtag where xtag_flags = 0 group by xtag_term order by total desc %s", ((intval($count)) ? "limit $count" : '') ); diff --git a/include/text.php b/include/text.php index b1af62fc5..25743e872 100644 --- a/include/text.php +++ b/include/text.php @@ -1216,36 +1216,15 @@ function theme_attachments(&$item) { if(is_array($arr) && count($arr)) { $attaches = array(); foreach($arr as $r) { - $icon = ''; - $icontype = substr($r['type'],0,strpos($r['type'],'/')); - /** - * @FIXME This should probably be a giant "if" statement in the - * template so that we don't have icon names embedded in php code. - */ - - switch($icontype) { - case 'video': - $icon = 'icon-facetime-video'; - break; - case 'audio': - $icon = 'icon-volume-up'; - break; - case 'image': - $icon = 'icon-picture'; - break; - case 'text': - $icon = 'icon-align-justify'; - break; - default: - $icon = 'icon-question'; - break; - } - - $title = htmlspecialchars($r['title'], ENT_COMPAT,'UTF-8'); - if(! $title) - $title = t('unknown.???'); - $title .= ' ' . (($r['length']) ? $r['length'] . ' ' . t('bytes') : ''); + $icon = getIconFromType($r['type']); + $label = (($r['title']) ? urldecode(htmlspecialchars($r['title'], ENT_COMPAT, 'UTF-8')) : t('Unknown Attachment')); + + //some feeds provide an attachment where title an empty space + if($label == ' ') + $label = t('Unknown Attachment'); + + $title = t('Attachment') . ' - ' . (($r['length']) ? userReadableSize($r['length']) : t('Size Unknown')); require_once('include/identity.php'); if(is_foreigner($item['author_xchan'])) @@ -1253,14 +1232,14 @@ function theme_attachments(&$item) { else $url = z_root() . '/magic?f=&hash=' . $item['author_xchan'] . '&dest=' . $r['href'] . '/' . $r['revision']; - $s .= '<a href="' . $url . '" title="' . $title . '" class="attachlink" >' . $icon . '</a>'; - $attaches[] = array('title' => $title, 'url' => $url, 'icon' => $icon ); + //$s .= '<a href="' . $url . '" title="' . $title . '" class="attachlink" >' . $icon . '</a>'; + $attaches[] = array('label' => $label, 'url' => $url, 'icon' => $icon, 'title' => $title); } - } - $s = replace_macros(get_markup_template('item_attach.tpl'), array( - '$attaches' => $attaches - )); + $s = replace_macros(get_markup_template('item_attach.tpl'), array( + '$attaches' => $attaches + )); + } return $s; } @@ -1279,11 +1258,12 @@ function format_categories(&$item,$writeable) { $removelink = (($writeable) ? z_root() . '/filerm/' . $item['id'] . '?f=&cat=' . urlencode($t['term']) : ''); $categories[] = array('term' => $term, 'writeable' => $writeable, 'removelink' => $removelink, 'url' => zid($t['url'])); } + + $s = replace_macros(get_markup_template('item_categories.tpl'),array( + '$remove' => t('remove category'), + '$categories' => $categories + )); } - $s = replace_macros(get_markup_template('item_categories.tpl'),array( - '$remove' => t('remove category'), - '$categories' => $categories - )); return $s; } @@ -1294,6 +1274,7 @@ function format_categories(&$item,$writeable) { * @param[in] array &$item * @return string HTML link of hashtag */ + function format_hashtags(&$item) { $s = ''; @@ -1354,11 +1335,12 @@ function format_filer(&$item) { $removelink = z_root() . '/filerm/' . $item['id'] . '?f=&term=' . urlencode($t['term']); $categories[] = array('term' => $term, 'removelink' => $removelink); } + + $s = replace_macros(get_markup_template('item_filer.tpl'),array( + '$remove' => t('remove from file'), + '$categories' => $categories + )); } - $s = replace_macros(get_markup_template('item_filer.tpl'),array( - '$remove' => t('remove from file'), - '$categories' => $categories - )); return $s; } @@ -1411,19 +1393,19 @@ function prepare_body(&$item,$attach = false) { } } - $s .= theme_attachments($item); + $attachments = theme_attachments($item); $writeable = ((get_observer_hash() == $item['owner_xchan']) ? true : false); - $s .= format_hashtags($item); + $tags = format_hashtags($item); if($item['resource_type']) - $s .= format_mentions($item); + $mentions = format_mentions($item); - $s .= format_categories($item,$writeable); + $categories = format_categories($item,$writeable); if(local_channel() == $item['uid']) - $s .= format_filer($item); + $filer = format_filer($item); $s = sslify($s); @@ -1456,9 +1438,19 @@ function prepare_body(&$item,$attach = false) { $s = substr($s, 0, $pos).$authorreplace.substr($s, $pos+strlen($authorsearch)); } - $prep_arr = array('item' => $item, 'html' => $s); + $prep_arr = array( + //'item' => $item, + 'html' => $s, + 'categories' => $categories, + 'folders' => $filer, + 'tags' => $tags, + 'mentions' => $mentions, + 'attachments' => $attachments + ); + call_hooks('prepare_body_final', $prep_arr); - return $prep_arr['html']; + + return $prep_arr; } /** @@ -1983,7 +1975,7 @@ function xchan_query(&$items,$abook = true,$effective_uid = 0) { $chans = q("select xchan.*,hubloc.* from xchan left join hubloc on hubloc_hash = xchan_hash where xchan_hash in (" . implode(',', $arr) . ") and hubloc_primary = 1"); } - $xchans = q("select * from xchan where xchan_hash in (" . implode(',',$arr) . ") and xchan_network in ('rss','unknown')"); + $xchans = q("select * from xchan where xchan_hash in (" . protect_sprintf(implode(',',$arr)) . ") and xchan_network in ('rss','unknown')"); if(! $chans) $chans = $xchans; else @@ -2221,7 +2213,7 @@ function handle_tag($a, &$body, &$access_tag, &$str_tags, $profile_uid, $tag, $d } if($tag == '#getzot') { $basetag = 'getzot'; - $url = 'https://redmatrix.me'; + $url = 'http://hubzilla.org'; $newtag = '#[zrl=' . $url . ']' . $basetag . '[/zrl]'; $body = str_replace($tag,$newtag,$body); $replaced = true; @@ -2490,6 +2482,7 @@ function linkify_tags($a, &$body, $uid, $diaspora = false) { * * @param string $type mime type * @return string + * @todo rename to get_icon_from_type() */ function getIconFromType($type) { $iconMap = array( @@ -2542,6 +2535,7 @@ function getIconFromType($type) { * * @param int $size filesize in bytes * @return string human readable formatted filesize + * @todo rename to user_readable_size() */ function userReadableSize($size) { $ret = ''; @@ -2564,3 +2558,47 @@ function str_rot47($str) { '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~', 'PQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNO'); } + + +function string_replace($old,$new,&$s) { + + $x = str_replace($old,$new,$s); + $replaced = false; + if($x !== $s) { + $replaced = true; + } + $s = $x; + return $replaced; +} + + +function json_url_replace($old,$new,&$s) { + + $old = str_replace('/','\\/',$old); + $new = str_replace('/','\\/',$new); + + $x = str_replace($old,$new,$s); + $replaced = false; + if($x !== $s) { + $replaced = true; + } + $s = $x; + return $replaced; +} + + +function item_url_replace($channel,&$item,$old,$new) { + + if($item['attach']) + json_url_replace($old,$new,$item['attach']); + if($item['object']) + json_url_replace($old,$new,$item['object']); + if($item['target']) + json_url_replace($old,$new,$item['target']); + + if(string_replace($old,$new,$item['body'])) { + $item['sig'] = base64url_encode(rsa_sign($item['body'],$channel['channel_prvkey'])); + $item['item_verified'] = 1; + } + +} diff --git a/include/widgets.php b/include/widgets.php index 9c8596a66..3e6fdb04c 100644 --- a/include/widgets.php +++ b/include/widgets.php @@ -565,12 +565,6 @@ function widget_mailmenu($arr) { return replace_macros(get_markup_template('message_side.tpl'), array( '$title' => t('Private Mail Menu'), - '$check'=>array( - 'label' => t('Check Mail'), - 'url' => $a->get_baseurl(true) . '/mail/combined', - 'sel' => (argv(1) == ''), - ), - '$combined'=>array( 'label' => t('Combined View'), 'url' => $a->get_baseurl(true) . '/mail/combined', diff --git a/include/zot.php b/include/zot.php index 7707f34fc..02dab3617 100644 --- a/include/zot.php +++ b/include/zot.php @@ -11,6 +11,7 @@ require_once('include/crypto.php'); require_once('include/items.php'); require_once('include/hubloc.php'); +require_once('include/DReport.php'); /** @@ -502,7 +503,7 @@ function zot_refresh($them, $channel = null, $force = false) { if($new_connection) { if($new_perms != $previous_perms) - proc_run('php','include/notifier.php','permission_update',$new_connection[0]['abook_id']); + proc_run('php','include/notifier.php','permission_create',$new_connection[0]['abook_id']); require_once('include/enotify.php'); notification(array( 'type' => NOTIFY_INTRO, @@ -901,7 +902,7 @@ function import_xchan($arr,$ud_flags = UPDATE_FLAGS_UPDATED, $ud_arr = null) { $r = q("delete from xprof where xprof_hash = '%s'", dbesc($xchan_hash) ); - $r = q("delete from xtag where xtag_hash = '%s'", + $r = q("delete from xtag where xtag_hash = '%s' and xtag_flags = 0", dbesc($xchan_hash) ); } @@ -964,7 +965,7 @@ function zot_process_response($hub, $arr, $outq) { if(is_array($x) && array_key_exists('delivery_report',$x) && is_array($x['delivery_report'])) { foreach($x['delivery_report'] as $xx) { - if(is_array($xx) && array_key_exists('message_id',$xx)) { + if(is_array($xx) && array_key_exists('message_id',$xx) && delivery_report_is_storable($xx)) { q("insert into dreport ( dreport_mid, dreport_site, dreport_recip, dreport_result, dreport_time, dreport_xchan ) values ( '%s', '%s','%s','%s','%s','%s' ) ", dbesc($xx['message_id']), dbesc($xx['location']), @@ -1556,7 +1557,6 @@ function allowed_public_recips($msg) { function process_delivery($sender, $arr, $deliveries, $relay, $public = false, $request = false) { $result = array(); - require_once('include/DReport.php'); $result['site'] = z_root(); @@ -1569,6 +1569,7 @@ function process_delivery($sender, $arr, $deliveries, $relay, $public = false, $ } } + foreach($deliveries as $d) { $local_public = $public; @@ -1587,11 +1588,21 @@ function process_delivery($sender, $arr, $deliveries, $relay, $public = false, $ $channel = $r[0]; $DR->addto_recipient($channel['channel_name'] . ' <' . $channel['channel_address'] . '@' . get_app()->get_hostname() . '>'); - if($d['hash'] === $sender['hash']) { - $DR->update('self delivery ignored'); - $result[] = $DR->get(); - continue; - } + /** + * @FIXME: Somehow we need to block normal message delivery from our clones, as the delivered + * message doesn't have ACL information in it as the cloned copy does. That copy + * will normally arrive first via sync delivery, but this isn't guaranteed. + * There's a chance the current delivery could take place before the cloned copy arrives + * hence the item could have the wrong ACL and *could* be used in subsequent deliveries or + * access checks. So far all attempts at identifying this situation precisely + * have caused issues with delivery of relayed comments. + */ + +// if(($d['hash'] === $sender['hash']) && ($sender['url'] !== z_root()) && (! $relay)) { +// $DR->update('self delivery ignored'); +// $result[] = $DR->get(); +// continue; +// } // allow public postings to the sys channel regardless of permissions, but not // for comments travelling upstream. Wait and catch them on the way down. @@ -1949,8 +1960,7 @@ function delete_imported_item($sender, $item, $uid, $relay) { $item_found = false; $post_id = 0; - - $r = q("select id, item_deleted from item where ( author_xchan = '%s' or owner_xchan = '%s' or source_xchan = '%s' ) + $r = q("select id, author_xchan, owner_xchan, source_xchan, item_deleted from item where ( author_xchan = '%s' or owner_xchan = '%s' or source_xchan = '%s' ) and mid = '%s' and uid = %d limit 1", dbesc($sender['hash']), dbesc($sender['hash']), @@ -1958,6 +1968,7 @@ function delete_imported_item($sender, $item, $uid, $relay) { dbesc($item['mid']), intval($uid) ); + if ($r) { if ($r[0]['author_xchan'] === $sender['hash'] || $r[0]['owner_xchan'] === $sender['hash'] || $r[0]['source_xchan'] === $sender['hash']) $ownership_valid = true; @@ -2031,20 +2042,26 @@ function process_mail_delivery($sender, $arr, $deliveries) { } foreach($deliveries as $d) { + + $DR = new DReport(z_root(),$sender['hash'],$d['hash'],$arr['mid']); + $r = q("select * from channel where channel_hash = '%s' limit 1", dbesc($d['hash']) ); if(! $r) { - $result[] = array($d['hash'],'not found'); + $DR->update('recipient not found'); + $result[] = $DR->get(); continue; } $channel = $r[0]; + $DR->addto_recipient($channel['channel_name'] . ' <' . $channel['channel_address'] . '@' . get_app()->get_hostname() . '>'); if(! perm_is_allowed($channel['channel_id'],$sender['hash'],'post_mail')) { logger("permission denied for mail delivery {$channel['channel_id']}"); - $result[] = array($d['hash'],'permission denied',$channel['channel_name'],$arr['mid']); + $DR->update('permission denied'); + $result[] = $DR->get(); continue; } @@ -2058,11 +2075,13 @@ function process_mail_delivery($sender, $arr, $deliveries) { intval($r[0]['id']), intval($channel['channel_id']) ); - $result[] = array($d['hash'],'mail recalled',$channel['channel_name'],$arr['mid']); + $DR->update('mail recalled'); + $result[] = $DR->get(); logger('mail_recalled'); } else { - $result[] = array($d['hash'],'duplicate mail received',$channel['channel_name'],$arr['mid']); + $DR->update('duplicate mail received'); + $result[] = $DR->get(); logger('duplicate mail received'); } continue; @@ -2071,7 +2090,8 @@ function process_mail_delivery($sender, $arr, $deliveries) { $arr['account_id'] = $channel['channel_account_id']; $arr['channel_id'] = $channel['channel_id']; $item_id = mail_store($arr); - $result[] = array($d['hash'],'mail delivered',$channel['channel_name'],$arr['mid']); + $DR->update('mail delivered'); + $result[] = $DR->get(); } } @@ -2580,7 +2600,7 @@ function import_directory_profile($hash, $profile, $addr, $ud_flags = UPDATE_FLA function import_directory_keywords($hash, $keywords) { $existing = array(); - $r = q("select * from xtag where xtag_hash = '%s'", + $r = q("select * from xtag where xtag_hash = '%s' and xtag_flags = 0", dbesc($hash) ); @@ -2598,14 +2618,14 @@ function import_directory_keywords($hash, $keywords) { foreach($existing as $x) { if(! in_array($x, $clean)) - $r = q("delete from xtag where xtag_hash = '%s' and xtag_term = '%s'", + $r = q("delete from xtag where xtag_hash = '%s' and xtag_term = '%s' and xtag_flags = 0", dbesc($hash), dbesc($x) ); } foreach($clean as $x) { if(! in_array($x, $existing)) { - $r = q("insert into xtag ( xtag_hash, xtag_term) values ( '%s' ,'%s' )", + $r = q("insert into xtag ( xtag_hash, xtag_term, xtag_flags) values ( '%s' ,'%s', 0 )", dbesc($hash), dbesc($x) ); @@ -2982,6 +3002,12 @@ function process_channel_sync_delivery($sender, $arr, $deliveries) { if(array_key_exists('chatroom',$arr) && $arr['chatroom']) sync_chatrooms($channel,$arr['chatroom']); + if(array_key_exists('conv',$arr) && $arr['conv']) + import_conv($channel,$arr['conv']); + + if(array_key_exists('mail',$arr) && $arr['mail']) + import_mail($channel,$arr['mail']); + if(array_key_exists('event',$arr) && $arr['event']) sync_events($channel,$arr['event']); @@ -3855,4 +3881,46 @@ function check_zotinfo($channel,$locations,&$ret) { } } } -}
\ No newline at end of file +} + +function delivery_report_is_storable($dr) { + + call_hooks('dreport_is_storable',$dr); + + // let plugins accept or reject - if neither, continue on + if(array_key_exists('accept',$dr) && intval($dr['accept'])) + return true; + if(array_key_exists('reject',$dr) && intval($dr['reject'])) + return false; + + if(! ($dr['sender'])) + return false; + + // Is the sender one of our channels? + + $c = q("select channel_id from channel where channel_hash = '%s' limit 1", + dbesc($dr['sender']) + ); + if(! $c) + return false; + + // is the recipient one of our connections, or do we want to store every report? + + $r = explode(' ', $dr['recipient']); + $rxchan = $r[0]; + $pcf = get_pconfig($c[0]['channel_id'],'system','dreport_store_all'); + if($pcf) + return true; + + $r = q("select abook_id from abook where abook_xchan = '%s' and abook_channel = %d limit 1", + dbesc($rxchan), + intval($c[0]['channel_id']) + ); + if($r) + return true; + + return false; + +} + + |