diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/attach.php | 133 | ||||
-rw-r--r-- | include/bbcode.php | 1 | ||||
-rw-r--r-- | include/channel.php | 117 | ||||
-rw-r--r-- | include/conversation.php | 112 | ||||
-rwxr-xr-x | include/dba/dba_driver.php | 8 | ||||
-rwxr-xr-x | include/dba/dba_pdo.php | 14 | ||||
-rw-r--r-- | include/event.php | 10 | ||||
-rw-r--r-- | include/help.php | 2 | ||||
-rw-r--r-- | include/import.php | 40 | ||||
-rwxr-xr-x | include/items.php | 269 | ||||
-rw-r--r-- | include/markdown.php | 431 | ||||
-rw-r--r-- | include/network.php | 595 | ||||
-rw-r--r-- | include/photo/photo_driver.php | 88 | ||||
-rw-r--r-- | include/photos.php | 151 | ||||
-rw-r--r-- | include/text.php | 57 |
15 files changed, 457 insertions, 1571 deletions
diff --git a/include/attach.php b/include/attach.php index 79313ab1a..ac50b05b1 100644 --- a/include/attach.php +++ b/include/attach.php @@ -209,7 +209,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 ORDER BY $orderby $limit", + $r = q("select id, aid, uid, hash, filename, filetype, filesize, revision, folder, os_path, display_path, 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) ); @@ -284,6 +284,7 @@ function attach_by_hash($hash, $observer_hash, $rev = 0) { return $ret; } + function attach_can_view_folder($uid,$ob_hash,$folder_hash) { $sql_extra = permissions_sql($uid,$ob_hash); @@ -348,7 +349,7 @@ function attach_by_hash_nodata($hash, $observer_hash, $rev = 0) { // Now we'll see if we can access the attachment - $r = q("select id, aid, uid, hash, creator, filename, filetype, filesize, revision, folder, os_storage, is_photo, is_dir, flags, created, edited, allow_cid, allow_gid, deny_cid, deny_gid from attach where uid = %d and hash = '%s' $sql_extra limit 1", + $r = q("select id, aid, uid, hash, creator, filename, filetype, filesize, revision, folder, os_storage, is_photo, os_path, display_path, is_dir, flags, created, edited, allow_cid, allow_gid, deny_cid, deny_gid from attach where uid = %d and hash = '%s' $sql_extra limit 1", intval($r[0]['uid']), dbesc($hash) ); @@ -531,7 +532,7 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) { if($options === 'update' && $arr && array_key_exists('revision',$arr)) $sql_options = " and revision = " . intval($arr['revision']) . " "; - $x = q("select id, aid, uid, filename, filetype, filesize, hash, revision, folder, os_storage, is_photo, flags, created, edited, allow_cid, allow_gid, deny_cid, deny_gid from attach where hash = '%s' and uid = %d $sql_options limit 1", + $x = q("select id, aid, uid, filename, filetype, filesize, hash, revision, folder, os_storage, is_photo, os_path, display_path, flags, created, edited, allow_cid, allow_gid, deny_cid, deny_gid from attach where hash = '%s' and uid = %d $sql_options limit 1", dbesc($arr['hash']), intval($channel_id) ); @@ -702,11 +703,11 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) { $os_relpath .= $folder_hash . '/'; } - $os_relpath .= $hash; + $os_relpath .= $hash; + $os_relpath = ltrim($os_relpath,'/'); - // not yet used - $os_path = ''; - $display_path = ''; + $os_path = $os_relpath; + $display_path = $pathname . '/' . $filename; if($src) @file_put_contents($os_basepath . $os_relpath,@file_get_contents($src)); @@ -810,7 +811,7 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) { if($is_photo) { - $args = array( 'source' => $source, 'visible' => $visible, 'resource_id' => $hash, 'album' => basename($pathname), 'os_path' => $os_basepath . $os_relpath, 'filename' => $filename, 'getimagesize' => $gis, 'directory' => $direct, 'options' => $options ); + $args = array( 'source' => $source, 'visible' => $visible, 'resource_id' => $hash, 'album' => $pathname, 'os_syspath' => $os_basepath . $os_relpath, 'os_path' => $os_path, 'display_path' => $display_path, 'filename' => $filename, 'getimagesize' => $gis, 'directory' => $direct, 'options' => $options ); if($arr['contact_allow']) $args['contact_allow'] = $arr['contact_allow']; if($arr['group_allow']) @@ -914,7 +915,7 @@ function z_readdir($channel_id, $observer_hash, $pathname, $parent_hash = '') { if(count($paths) > 1) { $curpath = array_shift($paths); - $r = q("select hash, id, is_dir from attach where uid = %d and filename = '%s' and is_dir != 0 " . permissions_sql($channel_id) . " limit 1", + $r = q("select hash, id, is_dir from attach where uid = %d and filename = '%s' and is_dir != 0 " . permissions_sql($channel_id,$observer_hash) . " limit 1", intval($channel_id), dbesc($curpath) ); @@ -929,7 +930,7 @@ function z_readdir($channel_id, $observer_hash, $pathname, $parent_hash = '') { else $paths = array($pathname); - $r = q("select id, aid, uid, hash, creator, filename, filetype, filesize, revision, folder, is_photo, is_dir, os_storage, flags, created, edited, allow_cid, allow_gid, deny_cid, deny_gid from attach where id = %d and folder = '%s' and filename = '%s' and is_dir != 0 " . permissions_sql($channel_id), + $r = q("select id, aid, uid, hash, creator, filename, filetype, filesize, revision, folder, os_path, display_path, is_photo, is_dir, os_storage, flags, created, edited, allow_cid, allow_gid, deny_cid, deny_gid from attach where id = %d and folder = '%s' and filename = '%s' and is_dir != 0 " . permissions_sql($channel_id), intval($channel_id), dbesc($parent_hash), dbesc($paths[0]) @@ -968,12 +969,15 @@ function attach_mkdir($channel, $observer_hash, $arr = null) { $sql_options = ''; - $basepath = 'store/' . $channel['channel_address']; + $os_basepath = 'store/' . $channel['channel_address']; - logger('attach_mkdir: basepath: ' . $basepath); + logger('attach_mkdir: basepath: ' . $os_basepath); - if(! is_dir($basepath)) - os_mkdir($basepath,STORAGE_DEFAULT_PERMISSIONS, true); + if(! is_dir($os_basepath)) + os_mkdir($os_basepath,STORAGE_DEFAULT_PERMISSIONS, true); + + + $os_basepath .= '/'; if(! perm_is_allowed($channel_id, $observer_hash, 'write_storage')) { $ret['message'] = t('Permission denied.'); @@ -1019,10 +1023,13 @@ function attach_mkdir($channel, $observer_hash, $arr = null) { $lpath = ''; $lfile = $arr['folder']; + $dpath = ''; + $sql_options = permissions_sql($channel['channel_id']); + do { - $r = q("select filename, hash, flags, is_dir, folder from attach where uid = %d and hash = '%s' and is_dir != 0 + $r = q("select filename, hash, flags, is_dir, folder, display_path from attach where uid = %d and hash = '%s' and is_dir = 1 $sql_options limit 1", intval($channel['channel_id']), dbesc($lfile) @@ -1032,22 +1039,26 @@ function attach_mkdir($channel, $observer_hash, $arr = null) { $ret['message'] = t('Path not found.'); return $ret; } + + $dpath = $r[0]['filename'] . (($dpath) ? '/' . $dpath : ''); + if($lfile) - $lpath = $r[0]['hash'] . '/' . $lpath; + $lpath = $r[0]['hash'] . (($lpath) ? '/' . $lpath : ''); + $lfile = $r[0]['folder']; + } while ( ($r[0]['folder']) && intval($r[0]['is_dir'])) ; - $path = $basepath . '/' . $lpath; + + $path = $lpath; } else - $path = $basepath . '/'; - - $path .= $arr['hash']; + $path = ''; $created = datetime_convert(); - // not yet used - $os_path = ''; - $display_path = ''; + $os_path = ltrim($path . '/' . $arr['hash'],'/'); + $display_path = ltrim($dpath . '/' . $arr['filename'],'/'); + $r = q("INSERT INTO attach ( aid, uid, hash, creator, filename, filetype, filesize, revision, folder, os_storage, is_dir, content, created, edited, os_path, display_path, allow_cid, allow_gid, deny_cid, deny_gid ) VALUES ( %d, %d, '%s', '%s', '%s', '%s', %d, %d, '%s', %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s' ) ", @@ -1062,7 +1073,7 @@ function attach_mkdir($channel, $observer_hash, $arr = null) { dbesc($arr['folder']), intval(1), intval(1), - dbescbin($path), + dbescbin($os_basepath . $os_path), dbesc($created), dbesc($created), dbesc($os_path), @@ -1074,7 +1085,7 @@ function attach_mkdir($channel, $observer_hash, $arr = null) { ); if($r) { - if(os_mkdir($path, STORAGE_DEFAULT_PERMISSIONS, true)) { + if(os_mkdir($os_basepath . $os_path, STORAGE_DEFAULT_PERMISSIONS, true)) { $ret['success'] = true; // update the parent folder's lastmodified timestamp @@ -1092,7 +1103,7 @@ function attach_mkdir($channel, $observer_hash, $arr = null) { $ret['data'] = $z[0]; } else { - logger('attach_mkdir: ' . mkdir . ' ' . $path . ' failed.'); + logger('attach_mkdir: ' . mkdir . ' ' . $os_basepath . $os_path . ' failed.'); $ret['message'] = t('mkdir failed.'); } } @@ -2212,10 +2223,23 @@ function attach_move($channel_id, $resource_id, $new_folder_hash) { intval($r[0]['id']) ); + + $x = attach_syspaths($channel_id,$resource_id); + + $t1 = q("update attach set os_path = '%s', display_path = '%s' where id = %d", + dbesc($x['os_path']), + dbesc($x['path']), + intval($r[0]['id']) + ); + + if($r[0]['is_photo']) { - $t = q("update photo set album = '%s', filename = '%s' where resource_id = '%s' and uid = %d", + $t = q("update photo set album = '%s', filename = '%s', os_path = '%s', display_path = '%s' + where resource_id = '%s' and uid = %d", dbesc($newdirname), dbesc($filename), + dbesc($x['os_path']), + dbesc($x['path']), dbesc($resource_id), intval($channel_id) ); @@ -2243,8 +2267,9 @@ function attach_folder_select_list($channel_id) { if($r) { foreach($r as $rv) { $x = attach_folder_rpaths($r,$rv); - if($x) + if($x) { $out[$x[0]] = $x[1]; + } } } @@ -2266,7 +2291,6 @@ function attach_folder_rpaths($all_folders,$that_folder) { continue; if($selected['hash'] == $parent_hash) { $path = '/' . $selected['filename'] . $path; - $current_hash = $selected['hash']; $parent_hash = $selected['folder']; $found = true; break; @@ -2280,3 +2304,54 @@ function attach_folder_rpaths($all_folders,$that_folder) { return (($error) ? false : [ $current_hash , $path ]); } + + +function attach_syspaths($channel_id,$attach_hash) { + + $os_path = ''; + $path = ''; + do { + + $r = q("select folder, filename, hash from attach where hash = '%s' and uid = %d", + dbesc($attach_hash), + intval($channel_id) + ); + if(! $r) + break; + + $os_path = $r[0]['hash'] . (($os_path) ? '/' . $os_path : ''); + $path = $r[0]['filename'] . (($path) ? '/' . $path : ''); + $attach_hash = $r[0]['folder']; + } + while($attach_hash); + + return [ 'os_path' => $os_path, 'path' => $path ]; + + +} + + + +function attach_upgrade() { + + $r = q("select id, uid, hash from attach where os_path = '' and display_path = '' limit 100"); + if($r) { + foreach($r as $rv) { + $x = attach_syspaths($rv['uid'],$rv['hash']); + if($x) { + $w = q("update attach set os_path = '%s', display_path = '%s' where id = %d", + dbesc($x['os_path']), + dbesc($x['path']), + intval($rv['id']) + ); + $y = q("update photo set os_path = '%s', display_path = '%s' where uid = %d and resource_id = '%s'", + dbesc($x['os_path']), + dbesc($x['path']), + intval($rv['uid']), + dbesc($rv['hash']) + ); + } + } + } +} + diff --git a/include/bbcode.php b/include/bbcode.php index c0033f280..5aa61760f 100644 --- a/include/bbcode.php +++ b/include/bbcode.php @@ -1174,6 +1174,7 @@ function bbcode($Text, $preserve_nl = false, $tryoembed = true, $cache = false) $Text = preg_replace("/\[event\-start\](.*?)\[\/event\-start\]/ism",$sub,$Text); + $Text = preg_replace("/\event\](.*?)\[\/event\]/ism",'',$Text); $Text = preg_replace("/\[event\-summary\](.*?)\[\/event\-summary\]/ism",'',$Text); $Text = preg_replace("/\[event\-description\](.*?)\[\/event\-description\]/ism",'',$Text); $Text = preg_replace("/\[event\-finish\](.*?)\[\/event\-finish\]/ism",'',$Text); diff --git a/include/channel.php b/include/channel.php index b838f8393..465a1524a 100644 --- a/include/channel.php +++ b/include/channel.php @@ -242,24 +242,22 @@ function create_identity($arr) { $expire = 0; - $r = q("insert into channel ( channel_account_id, channel_primary, - channel_name, channel_address, channel_guid, channel_guid_sig, - channel_hash, channel_prvkey, channel_pubkey, channel_pageflags, channel_system, channel_expire_days, channel_timezone ) - values ( %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, %d, '%s' ) ", - - intval($arr['account_id']), - intval($primary), - dbesc($name), - dbesc($nick), - dbesc($guid), - dbesc($sig), - dbesc($hash), - dbesc($key['prvkey']), - dbesc($key['pubkey']), - intval($pageflags), - intval($system), - intval($expire), - dbesc(App::$timezone) + $r = channel_store_lowlevel( + [ + channel_account_id => intval($arr['account_id']), + channel_primary => intval($primary), + channel_name => $name, + channel_address => $nick, + channel_guid => $guid, + channel_guid_sig => $sig, + channel_hash => $hash, + channel_prvkey => $key['prvkey'], + channel_pubkey => $key['pubkey'], + channel_pageflags => intval($pageflags), + channel_system => intval($system), + channel_expire_days => intval($expire), + channel_timezone => App::$timezone + ] ); $r = q("select * from channel where channel_account_id = %d @@ -1153,25 +1151,6 @@ function profile_sidebar($profile, $block = 0, $show_connect = true, $zcard = fa // @fixme move this to the diaspora plugin itself - if(plugin_is_installed('diaspora')) { - $diaspora = array( - 'podloc' => z_root(), - 'guid' => $profile['channel_guid'] . str_replace('.','',App::get_hostname()), - 'pubkey' => pemtorsa($profile['channel_pubkey']), - 'searchable' => (($block) ? 'false' : 'true'), - 'nickname' => $profile['channel_address'], - 'fullname' => $profile['channel_name'], - 'firstname' => $firstname, - 'lastname' => $lastname, - 'photo300' => z_root() . '/photo/profile/300/' . $profile['uid'] . '.jpg', - 'photo100' => z_root() . '/photo/profile/100/' . $profile['uid'] . '.jpg', - 'photo50' => z_root() . '/photo/profile/50/' . $profile['uid'] . '.jpg', - ); - } - else - $diaspora = ''; - - $contact_block = contact_block(); $channel_menu = false; @@ -1193,11 +1172,6 @@ function profile_sidebar($profile, $block = 0, $show_connect = true, $zcard = fa else $tpl = get_markup_template('profile_vcard.tpl'); - require_once('include/widgets.php'); - -// if(! feature_enabled($profile['uid'],'hide_rating')) - $z = widget_rating(array('target' => $profile['channel_hash'])); - $o .= replace_macros($tpl, array( '$zcard' => $zcard, '$profile' => $profile, @@ -1209,9 +1183,8 @@ function profile_sidebar($profile, $block = 0, $show_connect = true, $zcard = fa '$marital' => $marital, '$homepage' => $homepage, '$chanmenu' => $channel_menu, - '$diaspora' => $diaspora, '$reddress' => $reddress, - '$rating' => $z, + '$rating' => '', '$contact_block' => $contact_block, '$editmenu' => profile_edit_menu($profile['uid']) )); @@ -1994,6 +1967,45 @@ function remote_login() { } +function channel_store_lowlevel($arr) { + $store = [ + 'channel_account_id' => ((array_key_exists('channel_account_id',$arr)) ? $arr['channel_account_id'] : '0'), + 'channel_primary' => ((array_key_exists('channel_primary',$arr)) ? $arr['channel_primary'] : '0'), + 'channel_name' => ((array_key_exists('channel_name',$arr)) ? $arr['channel_name'] : ''), + 'channel_address' => ((array_key_exists('channel_address',$arr)) ? $arr['channel_address'] : ''), + 'channel_guid' => ((array_key_exists('channel_guid',$arr)) ? $arr['channel_guid'] : ''), + 'channel_guid_sig' => ((array_key_exists('channel_guid_sig',$arr)) ? $arr['channel_guid_sig'] : ''), + 'channel_hash' => ((array_key_exists('channel_hash',$arr)) ? $arr['channel_hash'] : ''), + 'channel_timezone' => ((array_key_exists('channel_timezone',$arr)) ? $arr['channel_timezone'] : 'UTC'), + 'channel_location' => ((array_key_exists('channel_location',$arr)) ? $arr['channel_location'] : ''), + 'channel_theme' => ((array_key_exists('channel_theme',$arr)) ? $arr['channel_theme'] : ''), + 'channel_startpage' => ((array_key_exists('channel_startpage',$arr)) ? $arr['channel_startpage'] : ''), + 'channel_pubkey' => ((array_key_exists('channel_pubkey',$arr)) ? $arr['channel_pubkey'] : ''), + 'channel_prvkey' => ((array_key_exists('channel_prvkey',$arr)) ? $arr['channel_prvkey'] : ''), + 'channel_notifyflags' => ((array_key_exists('channel_notifyflags',$arr)) ? $arr['channel_notifyflags'] : '65535'), + 'channel_pageflags' => ((array_key_exists('channel_pageflags',$arr)) ? $arr['channel_pageflags'] : '0'), + 'channel_dirdate' => ((array_key_exists('channel_dirdate',$arr)) ? $arr['channel_dirdate'] : NULL_DATE), + 'channel_lastpost' => ((array_key_exists('channel_lastpost',$arr)) ? $arr['channel_lastpost'] : NULL_DATE), + 'channel_deleted' => ((array_key_exists('channel_deleted',$arr)) ? $arr['channel_deleted'] : NULL_DATE), + 'channel_max_anon_mail' => ((array_key_exists('channel_max_anon_mail',$arr)) ? $arr['channel_max_anon_mail'] : '10'), + 'channel_max_friend_req' => ((array_key_exists('channel_max_friend_req',$arr)) ? $arr['channel_max_friend_req'] : '10'), + 'channel_expire_days' => ((array_key_exists('channel_expire_days',$arr)) ? $arr['channel_expire_days'] : '0'), + 'channel_passwd_reset' => ((array_key_exists('channel_passwd_reset',$arr)) ? $arr['channel_passwd_reset'] : ''), + 'channel_default_group' => ((array_key_exists('channel_default_group',$arr)) ? $arr['channel_default_group'] : ''), + 'channel_allow_cid' => ((array_key_exists('channel_allow_cid',$arr)) ? $arr['channel_allow_cid'] : ''), + 'channel_allow_gid' => ((array_key_exists('channel_allow_gid',$arr)) ? $arr['channel_allow_gid'] : ''), + 'channel_deny_cid' => ((array_key_exists('channel_deny_cid',$arr)) ? $arr['channel_deny_cid'] : ''), + 'channel_deny_gid' => ((array_key_exists('channel_deny_gid',$arr)) ? $arr['channel_deny_gid'] : ''), + 'channel_removed' => ((array_key_exists('channel_removed',$arr)) ? $arr['channel_removed'] : '0'), + 'channel_system' => ((array_key_exists('channel_system',$arr)) ? $arr['channel_system'] : '0'), + 'channel_moved' => ((array_key_exists('channel_moved',$arr)) ? $arr['channel_moved'] : '') + + ]; + + return create_table_from_array('channel',$store); + +} + function profile_store_lowlevel($arr) { @@ -2252,3 +2264,20 @@ function channel_remove($channel_id, $local = true, $unset_session=false) { } } + +/* + * This checks if a channel is allowed to publish executable code. + * It is up to the caller to determine if the observer or local_channel + * is in fact the resource owner whose channel_id is being checked + */ + +function channel_codeallowed($channel_id) { + + if(! intval($channel_id)) + return false; + + $x = channelx_by_n($channel_id); + if(($x) && ($x['channel_pageflags'] & PAGE_ALLOWCODE)) + return true; + return false; +}
\ No newline at end of file diff --git a/include/conversation.php b/include/conversation.php index da4f974a6..b4f959afa 100644 --- a/include/conversation.php +++ b/include/conversation.php @@ -2,10 +2,6 @@ require_once('include/items.php'); -// Note: the code in 'item_extract_images' and 'item_redir_and_replace_images' -// is identical to the code in mod/message.php for 'item_extract_images' and -// 'item_redir_and_replace_images' - function item_extract_images($body) { @@ -375,13 +371,14 @@ function localize_item(&$item){ * * \e array \b children * @return number */ + function count_descendants($item) { $total = count($item['children']); - if ($total > 0) { - foreach ($item['children'] as $child) { - if (! visible_activity($child)) + if($total > 0) { + foreach($item['children'] as $child) { + if(! visible_activity($child)) $total --; $total += count_descendants($child); @@ -408,8 +405,8 @@ function visible_activity($item) { if(intval($item['item_notshown'])) return false; - foreach ($hidden_activities as $act) { - if ((activity_match($item['verb'], $act)) && ($item['mid'] != $item['parent_mid'])) { + foreach($hidden_activities as $act) { + if((activity_match($item['verb'], $act)) && ($item['mid'] != $item['parent_mid'])) { return false; } } @@ -875,98 +872,6 @@ function best_link_url($item) { -function item_photo_menu($item){ - - $contact = null; - - $ssl_state = false; - - $sub_link=""; - $poke_link=""; - $contact_url=""; - $pm_url=""; - $vsrc_link = ""; - $follow_url = ""; - - $local_channel = local_channel(); - - if($local_channel) { - $ssl_state = true; - if(! count(App::$contacts)) - load_contact_links($local_channel); - $channel = App::get_channel(); - $channel_hash = (($channel) ? $channel['channel_hash'] : ''); - } - - if(($local_channel) && $local_channel == $item['uid']) { - $vsrc_link = 'javascript:viewsrc(' . $item['id'] . '); return false;'; - if($item['parent'] == $item['id'] && $channel && ($channel_hash != $item['author_xchan'])) { - $sub_link = 'javascript:dosubthread(' . $item['id'] . '); return false;'; - } - if($channel) { - $unsub_link = 'javascript:dounsubthread(' . $item['id'] . '); return false;'; - } - } - - $profile_link = chanlink_hash($item['author_xchan']); - if($item['uid'] > 0) - $pm_url = z_root() . '/mail/new/?f=&hash=' . $item['author_xchan']; - - if(App::$contacts && array_key_exists($item['author_xchan'],App::$contacts)) - $contact = App::$contacts[$item['author_xchan']]; - else - if($local_channel && $item['author']['xchan_addr']) - $follow_url = z_root() . '/follow/?f=&url=' . $item['author']['xchan_addr']; - - if($contact) { - $poke_link = z_root() . '/poke/?f=&c=' . $contact['abook_id']; - if (! intval($contact['abook_self'])) - $contact_url = z_root() . '/connedit/' . $contact['abook_id']; - $posts_link = z_root() . '/network/?cid=' . $contact['abook_id']; - - $clean_url = normalise_link($item['author-link']); - } - - $rating_enabled = get_config('system','rating_enabled'); - - $ratings_url = (($rating_enabled) ? z_root() . '/ratings/' . urlencode($item['author_xchan']) : ''); - - $post_menu = Array( - t("View Source") => $vsrc_link, - t("Follow Thread") => $sub_link, - t("Unfollow Thread") => $unsub_link, - ); - - $author_menu = array( - t("View Profile") => $profile_link, - t("Activity/Posts") => $posts_link, - t("Connect") => $follow_url, - t("Edit Connection") => $contact_url, - t("Message") => $pm_url, - t('Ratings') => $ratings_url, - t("Poke") => $poke_link - ); - - - $args = array('item' => $item, 'post_menu' => $post_menu, 'author_menu' => $author_menu); - - call_hooks('item_photo_menu', $args); - - $menu = array_merge($args['post_menu'],$args['author_menu']); - - $o = ""; - foreach($menu as $k=>$v){ - if(strpos($v,'javascript:') === 0) { - $v = substr($v,11); - $o .= "<li><a href=\"#\" onclick=\"$v\">$k</a></li>\n"; - } - elseif ($v!="") $o .= "<li><a href=\"$v\">$k</a></li>\n"; - } - - return $o; -} - - function thread_action_menu($item,$mode = '') { $menu = []; @@ -1026,14 +931,15 @@ function thread_author_menu($item, $mode = '') { } $profile_link = chanlink_hash($item['author_xchan']); + if($item['uid'] > 0) - $pm_url = z_root() . '/mail/new/?f=&hash=' . $item['author_xchan']; + $pm_url = z_root() . '/mail/new/?f=&hash=' . urlencode($item['author_xchan']); if(App::$contacts && array_key_exists($item['author_xchan'],App::$contacts)) $contact = App::$contacts[$item['author_xchan']]; else if($local_channel && $item['author']['xchan_addr']) - $follow_url = z_root() . '/follow/?f=&url=' . $item['author']['xchan_addr']; + $follow_url = z_root() . '/follow/?f=&url=' . urlencode($item['author']['xchan_addr']); if($contact) { $poke_link = z_root() . '/poke/?f=&c=' . $contact['abook_id']; diff --git a/include/dba/dba_driver.php b/include/dba/dba_driver.php index e47f97387..ad1d9d194 100755 --- a/include/dba/dba_driver.php +++ b/include/dba/dba_driver.php @@ -15,7 +15,7 @@ class DBA { static public $scheme = 'mysql'; static public $logging = false; - static public $install_script = 'install/schema_mysql.sql'; + static public $install_script = 'schema_mysql.sql'; static public $null_date = '0001-01-01 00:00:00'; static public $utc_now = 'UTC_TIMESTAMP()'; static public $tquot = "`"; @@ -46,7 +46,7 @@ class DBA { if(!($port)) $port = 5432; - self::$install_script = 'install/schema_postgres.sql'; + self::$install_script = 'schema_postgres.sql'; self::$utc_now = "now() at time zone 'UTC'"; self::$tquot = '"'; self::$scheme = 'pgsql'; @@ -163,7 +163,9 @@ abstract class dba_driver { } function get_install_script() { - return \DBA::$install_script; + if(file_exists('install/' . PLATFORM_NAME . '/' . \DBA::$install_script)) + return 'install/' . PLATFORM_NAME . '/' . \DBA::$install_script; + return 'install/' . \DBA::$install_script; } function get_table_quote() { diff --git a/include/dba/dba_pdo.php b/include/dba/dba_pdo.php index f76e6cdd7..f119d8926 100755 --- a/include/dba/dba_pdo.php +++ b/include/dba/dba_pdo.php @@ -74,19 +74,19 @@ class dba_pdo extends dba_driver { return $result; } - if($this->debug) { - db_logger('dba_pdo: DEBUG: ' . printable($sql) . ' returned ' . count($result) . ' results.', LOGGER_NORMAL, LOG_INFO); - } - $r = array(); if($result) { foreach($result as $x) { $r[] = $x; } - if($this->debug) { - db_logger('dba_pdo: ' . printable(print_r($r,true)), LOGGER_NORMAL, LOG_INFO); - } } + + if($this->debug) { + db_logger('dba_pdo: DEBUG: ' . printable($sql) . ' returned ' . count($r) . ' results.', LOGGER_NORMAL, LOG_INFO); + db_logger('dba_pdo: ' . printable(print_r($r,true)), LOGGER_NORMAL, LOG_INFO); + } + + return (($this->error) ? false : $r); } diff --git a/include/event.php b/include/event.php index a9634d7a5..001bd7dd3 100644 --- a/include/event.php +++ b/include/event.php @@ -210,6 +210,10 @@ function format_event_bbcode($ev) { $o = ''; + if($ev['event_vdata']) { + $o .= '[event]' . $ev['event_vdata'] . '[/event]'; + } + if($ev['summary']) $o .= '[event-summary]' . $ev['summary'] . '[/event-summary]'; @@ -610,7 +614,7 @@ function parse_vobject($ical, $type) { $ev['etype'] = $type; $dtstart = $ical->DTSTART->getDateTime(); - $ev['adjust'] = (($ical->DTSTART->isFloating()) ? 1 : 0); + $ev['adjust'] = (($ical->DTSTART->isFloating()) ? 0 : 1); $ev['dtstart'] = datetime_convert((($ev['adjust']) ? 'UTC' : date_default_timezone_get()),'UTC', $dtstart->format(\DateTime::W3C)); @@ -751,7 +755,7 @@ function event_import_ical($ical, $uid) { } $dtstart = $ical->DTSTART->getDateTime(); - $ev['adjust'] = (($ical->DTSTART->isFloating()) ? 1 : 0); + $ev['adjust'] = (($ical->DTSTART->isFloating()) ? 0 : 1); // logger('dtstart: ' . var_export($dtstart,true)); @@ -854,7 +858,7 @@ function event_import_ical_task($ical, $uid) { $dtstart = $ical->DTSTART->getDateTime(); - $ev['adjust'] = (($ical->DTSTART->isFloating()) ? 1 : 0); + $ev['adjust'] = (($ical->DTSTART->isFloating()) ? 0 : 1); // logger('dtstart: ' . var_export($dtstart,true)); diff --git a/include/help.php b/include/help.php index e4725575d..ab31e9400 100644 --- a/include/help.php +++ b/include/help.php @@ -57,7 +57,7 @@ function get_help_content($tocpath = false) { if(! $text) { $doctype = 'bbcode'; $text = load_doc_file('doc/main.bb'); - goaway('/help/about/about_hubzilla'); + goaway('/help/about/about'); \App::$page['title'] = t('Help'); } diff --git a/include/import.php b/include/import.php index 5c73b7ca3..d0e15c89d 100644 --- a/include/import.php +++ b/include/import.php @@ -85,12 +85,6 @@ function import_channel($channel, $account_id, $seize) { create_table_from_array('channel',$clean); } - if(! $r) { - logger('mod_import: channel clone failed. ' . print_r($channel,true)); - notice( t('Channel clone failed. Import failed.') . EOL); - return false; - } - $r = q("select * from channel where channel_account_id = %d and channel_guid = '%s' limit 1", intval($account_id), $channel['channel_guid'] // Already dbesc'd @@ -534,16 +528,8 @@ function sync_chatrooms($channel,$chatrooms) { function import_items($channel,$items,$sync = false,$relocate = null) { if($channel && $items) { - $allow_code = false; - $r = q("select account_id, account_roles, channel_pageflags from account left join channel on channel_account_id = account_id - where channel_id = %d limit 1", - intval($channel['channel_id']) - ); - if($r) { - if(($r[0]['account_roles'] & ACCOUNT_ROLE_ALLOWCODE) || ($r[0]['channel_pageflags'] & PAGE_ALLOWCODE)) { - $allow_code = true; - } - } + + $allow_code = channel_codeallowed($channel['channel_id']); $deliver = false; // Don't deliver any messages or notifications when importing @@ -1358,28 +1344,8 @@ function import_webpage_element($element, $channel, $type) { } // Verify ability to use html or php!!! - $execflag = false; - if($arr['mimetype'] === 'application/x-php' || $arr['mimetype'] === 'text/html') { - $z = q("select account_id, account_roles, channel_pageflags from account " - . "left join channel on channel_account_id = account_id where channel_id = %d limit 1", - intval(local_channel()) - ); - if($z && (($z[0]['account_roles'] & ACCOUNT_ROLE_ALLOWCODE) || ($z[0]['channel_pageflags'] & PAGE_ALLOWCODE))) { - $execflag = true; - } - else { - logger('Unable to import element "' . $name .'" because AllowCode permission is denied.'); - notice( t('Unable to import element "' . $name .'" because AllowCode permission is denied.') . EOL); - $element['import_success'] = 0; - return $element; - } - } - -// $z = q("select * from iconfig where v = '%s' and k = '%s' and cat = 'system' limit 1", -// dbesc($name), -// dbesc($namespace) -// ); + $execflag = channel_codeallowed(local_channel()); $i = q("select id, edited, item_deleted from item where mid = '%s' and uid = %d limit 1", dbesc($arr['mid']), diff --git a/include/items.php b/include/items.php index 36445a46b..3d0f380b4 100755 --- a/include/items.php +++ b/include/items.php @@ -248,8 +248,6 @@ function can_comment_on_post($observer_xchan, $item) { } if(strstr($item['comment_policy'],'network:') && strstr($item['comment_policy'],'red')) return true; - if(strstr($item['comment_policy'],'network:') && strstr($item['comment_policy'],'diaspora')) - return true; if(strstr($item['comment_policy'],'site:') && strstr($item['comment_policy'],App::get_hostname())) return true; @@ -336,18 +334,6 @@ function post_activity_item($arr,$allow_code = false,$deliver = true) { if(! array_key_exists('mimetype',$arr)) $arr['mimetype'] = 'text/bbcode'; - if(array_key_exists('item_private',$arr) && $arr['item_private']) { - - $arr['body'] = trim(z_input_filter($arr['uid'],$arr['body'],$arr['mimetype'])); - - if($channel) { - if($channel['channel_hash'] === $arr['author_xchan']) { - $arr['sig'] = base64url_encode(rsa_sign($arr['body'],$channel['channel_prvkey'])); - $arr['item_verified'] = 1; - } - } - } - $arr['mid'] = ((x($arr,'mid')) ? $arr['mid'] : item_message_id()); $arr['parent_mid'] = ((x($arr,'parent_mid')) ? $arr['parent_mid'] : $arr['mid']); $arr['thr_parent'] = ((x($arr,'thr_parent')) ? $arr['thr_parent'] : $arr['mid']); @@ -542,12 +528,7 @@ function get_item_elements($x,$allow_code = false) { $arr = array(); - if($allow_code) - $arr['body'] = $x['body']; - else - $arr['body'] = (($x['body']) ? htmlspecialchars($x['body'],ENT_COMPAT,'UTF-8',false) : ''); - - $key = get_config('system','pubkey'); + $arr['body'] = $x['body']; $maxlen = get_max_import_size(); @@ -602,11 +583,6 @@ function get_item_elements($x,$allow_code = false) { $arr['sig'] = (($x['signature']) ? htmlspecialchars($x['signature'], ENT_COMPAT,'UTF-8',false) : ''); - if(array_key_exists('diaspora_signature',$x) && is_array($x['diaspora_signature'])) - $x['diaspora_signature'] = json_encode($x['diaspora_signature']); - - $arr['diaspora_meta'] = (($x['diaspora_signature']) ? $x['diaspora_signature'] : ''); - $arr['obj'] = activity_sanitise($x['object']); $arr['target'] = activity_sanitise($x['target']); @@ -659,7 +635,17 @@ function get_item_elements($x,$allow_code = false) { return array(); } + // Check signature on the body text received. + // This presents an issue that we aren't verifying the text that is actually displayed + // on this site. We are however verifying the received text was exactly as received. + // We have every right to strip content that poses a security risk. You are welcome to + // create a plugin to verify the content after filtering if this offends you. + if($arr['sig']) { + + // check the supplied signature against the supplied content. + // Note that we will purify the content which could change it. + $r = q("select xchan_pubkey from xchan where xchan_hash = '%s' limit 1", dbesc($arr['author_xchan']) ); @@ -669,6 +655,14 @@ function get_item_elements($x,$allow_code = false) { logger('get_item_elements: message verification failed.'); } + // if the input is markdown, remove one level of html escaping. + // It will be re-applied in item_store() and/or item_store_update(). + // Do this after signature checking as the original signature + // was generated on the escaped content. + + if($arr['mimetype'] === 'text/markdown') + $arr['body'] = \Zotlabs\Lib\MarkdownSoap::unescape($arr['body']); + if(array_key_exists('revision',$x)) { // extended export encoding @@ -771,8 +765,6 @@ function import_author_xchan($x) { if((! array_key_exists('network', $x)) || ($x['network'] === 'zot')) { $y = import_author_zot($x); } - if(! $y) - $y = import_author_diaspora($x); if($x['network'] === 'rss') { $y = import_author_rss($x); @@ -786,36 +778,6 @@ function import_author_xchan($x) { } /** - * @brief Imports an author from Diaspora. - * - * @param array $x an associative array with - * * \e string \b address - * @return boolean|string false on error, otherwise xchan_hash of the new entry - */ -function import_author_diaspora($x) { - if(! $x['address']) - return false; - - $r = q("select * from xchan where xchan_addr = '%s' limit 1", - dbesc($x['address']) - ); - if($r) { - logger('in_cache: ' . $x['address'], LOGGER_DATA); - return $r[0]['xchan_hash']; - } - - if(discover_by_webbie($x['address'])) { - $r = q("select xchan_hash from xchan where xchan_addr = '%s' limit 1", - dbesc($x['address']) - ); - if($r) - return $r[0]['xchan_hash']; - } - - return false; -} - -/** * @brief Imports an author from a RSS feed. * * @param array $x an associative array with @@ -824,6 +786,7 @@ function import_author_diaspora($x) { * * \e string \b guid * @return boolean|string */ + function import_author_rss($x) { if(! $x['url']) return false; @@ -1037,17 +1000,7 @@ function encode_item($item,$mirror = false) { if($item['iconfig']) $x['meta'] = encode_item_meta($item['iconfig'],$mirror); - if($item['diaspora_meta']) { - $z = json_decode($item['diaspora_meta'],true); - if($z) { - if(is_array($z) && array_key_exists('iv',$z)) - $x['diaspora_signature'] = crypto_unencapsulate($z,$key); - else - $x['diaspora_signature'] = $z; - if(! is_array($z)) - logger('encode_item: diaspora meta is not an array: ' . print_r($z,true)); - } - } + logger('encode_item: ' . print_r($x,true), LOGGER_DATA); return $x; @@ -1326,7 +1279,6 @@ function encode_mail($item,$extended = false) { $x['message_parent'] = $item['parent_mid']; $x['created'] = $item['created']; $x['expires'] = $item['expires']; - $x['diaspora_meta'] = $item['diaspora_meta']; $x['title'] = $item['title']; $x['body'] = $item['body']; $x['from'] = encode_item_xchan($item['from']); @@ -1456,6 +1408,26 @@ function get_profile_elements($x) { } + + +function item_sign(&$item) { + + if(array_key_exists('sig',$item) && $item['sig']) + return; + + $r = q("select channel_prvkey from channel where channel_id = %d and channel_hash = '%s' ", + intval($item['uid']), + dbesc($item['author_xchan']) + ); + if(! $r) + return; + + $item['sig'] = base64url_encode(rsa_sign($item['body'],$r[0]['channel_prvkey'])); + $item['item_verified'] = 1; + +} + + /** * @brief * @@ -1519,7 +1491,6 @@ function item_store($arr, $allow_exec = false, $deliver = true) { $arr['title'] = ((array_key_exists('title',$arr) && strlen($arr['title'])) ? trim($arr['title']) : ''); $arr['body'] = ((array_key_exists('body',$arr) && strlen($arr['body'])) ? trim($arr['body']) : ''); - $arr['diaspora_meta'] = ((x($arr,'diaspora_meta')) ? $arr['diaspora_meta'] : ''); $arr['allow_cid'] = ((x($arr,'allow_cid')) ? trim($arr['allow_cid']) : ''); $arr['allow_gid'] = ((x($arr,'allow_gid')) ? trim($arr['allow_gid']) : ''); $arr['deny_cid'] = ((x($arr,'deny_cid')) ? trim($arr['deny_cid']) : ''); @@ -1533,35 +1504,30 @@ function item_store($arr, $allow_exec = false, $deliver = true) { // obsolete, but needed so as not to throw not-null constraints on some database driveres $arr['item_flags'] = ((x($arr,'item_flags')) ? intval($arr['item_flags']) : 0 ); - // only detect language if we have text content, and if the post is private but not yet - // obscured, make it so. - if((! array_key_exists('item_obscured',$arr)) || $arr['item_obscured'] == 0) { - $arr['lang'] = detect_language($arr['body']); - // apply the input filter here - if it is obscured it has been filtered already - $arr['body'] = trim(z_input_filter($arr['uid'],$arr['body'],$arr['mimetype'])); + $arr['lang'] = detect_language($arr['body']); - if(local_channel() && (local_channel() == $arr['uid']) && (! $arr['sig'])) { - $channel = App::get_channel(); - if($channel['channel_hash'] === $arr['author_xchan']) { - $arr['sig'] = base64url_encode(rsa_sign($arr['body'],$channel['channel_prvkey'])); - $arr['item_verified'] = 1; - } - } + // apply the input filter here - $allowed_languages = get_pconfig($arr['uid'],'system','allowed_languages'); + $arr['body'] = trim(z_input_filter($arr['body'],$arr['mimetype'],$allow_exec)); - if((is_array($allowed_languages)) && ($arr['lang']) && (! array_key_exists($arr['lang'],$allowed_languages))) { - $translate = array('item' => $arr, 'from' => $arr['lang'], 'to' => $allowed_languages, 'translated' => false); - call_hooks('item_translate', $translate); - if((! $translate['translated']) && (intval(get_pconfig($arr['uid'],'system','reject_disallowed_languages')))) { - logger('item_store: language ' . $arr['lang'] . ' not accepted for uid ' . $arr['uid']); - $ret['message'] = 'language not accepted'; - return $ret; - } - $arr = $translate['item']; + item_sign($arr); + + if(! array_key_exists('sig',$arr)) + $arr['sig'] = ''; + + $allowed_languages = get_pconfig($arr['uid'],'system','allowed_languages'); + + if((is_array($allowed_languages)) && ($arr['lang']) && (! array_key_exists($arr['lang'],$allowed_languages))) { + $translate = array('item' => $arr, 'from' => $arr['lang'], 'to' => $allowed_languages, 'translated' => false); + call_hooks('item_translate', $translate); + if((! $translate['translated']) && (intval(get_pconfig($arr['uid'],'system','reject_disallowed_languages')))) { + logger('item_store: language ' . $arr['lang'] . ' not accepted for uid ' . $arr['uid']); + $ret['message'] = 'language not accepted'; + return $ret; } + $arr = $translate['item']; } if((x($arr,'obj')) && is_array($arr['obj'])) { @@ -1957,33 +1923,25 @@ function item_store_update($arr,$allow_exec = false, $deliver = true) { return $ret; } - if((! array_key_exists('item_obscured', $arr)) || $arr['item_obscured'] == 0) { + $arr['lang'] = detect_language($arr['body']); - $arr['lang'] = detect_language($arr['body']); + // apply the input filter here - // apply the input filter here - if it is obscured it has been filtered already - $arr['body'] = trim(z_input_filter($arr['uid'],$arr['body'],$arr['mimetype'])); + $arr['body'] = trim(z_input_filter($arr['body'],$arr['mimetype'],$allow_exec)); - if(local_channel() && (local_channel() == $arr['uid']) && (! $arr['sig'])) { - $channel = App::get_channel(); - if($channel['channel_hash'] === $arr['author_xchan']) { - $arr['sig'] = base64url_encode(rsa_sign($arr['body'],$channel['channel_prvkey'])); - $arr['item_verified'] = 1; - } - } + item_sign($arr); - $allowed_languages = get_pconfig($arr['uid'],'system','allowed_languages'); + $allowed_languages = get_pconfig($arr['uid'],'system','allowed_languages'); - if((is_array($allowed_languages)) && ($arr['lang']) && (! array_key_exists($arr['lang'],$allowed_languages))) { - $translate = array('item' => $arr, 'from' => $arr['lang'], 'to' => $allowed_languages, 'translated' => false); - call_hooks('item_translate', $translate); - if((! $translate['translated']) && (intval(get_pconfig($arr['uid'],'system','reject_disallowed_languages')))) { - logger('item_store: language ' . $arr['lang'] . ' not accepted for uid ' . $arr['uid']); - $ret['message'] = 'language not accepted'; - return $ret; - } - $arr = $translate['item']; + if((is_array($allowed_languages)) && ($arr['lang']) && (! array_key_exists($arr['lang'],$allowed_languages))) { + $translate = array('item' => $arr, 'from' => $arr['lang'], 'to' => $allowed_languages, 'translated' => false); + call_hooks('item_translate', $translate); + if((! $translate['translated']) && (intval(get_pconfig($arr['uid'],'system','reject_disallowed_languages')))) { + logger('item_store: language ' . $arr['lang'] . ' not accepted for uid ' . $arr['uid']); + $ret['message'] = 'language not accepted'; + return $ret; } + $arr = $translate['item']; } if((x($arr,'obj')) && is_array($arr['obj'])) { @@ -2029,7 +1987,7 @@ function item_store_update($arr,$allow_exec = false, $deliver = true) { $arr['changed'] = $orig[0]['changed']; $arr['route'] = ((array_key_exists('route',$arr)) ? trim($arr['route']) : $orig[0]['route']); - $arr['diaspora_meta'] = ((x($arr,'diaspora_meta')) ? $arr['diaspora_meta'] : $orig[0]['diaspora_meta']); + $arr['location'] = ((x($arr,'location')) ? notags(trim($arr['location'])) : $orig[0]['location']); $arr['coord'] = ((x($arr,'coord')) ? notags(trim($arr['coord'])) : $orig[0]['coord']); $arr['verb'] = ((x($arr,'verb')) ? notags(trim($arr['verb'])) : $orig[0]['verb']); @@ -2188,55 +2146,6 @@ function item_store_update($arr,$allow_exec = false, $deliver = true) { -function store_diaspora_comment_sig($datarray, $channel, $parent_item, $post_id, $walltowall = false) { - - // We won't be able to sign Diaspora comments for authenticated visitors - // - we don't have their private key - - // since Diaspora doesn't handle edits we can only do this for the original text and not update it. - - require_once('include/markdown.php'); - $signed_body = bb2diaspora_itembody($datarray,$walltowall); - - if($walltowall) { - logger('wall to wall comment',LOGGER_DEBUG); - // post will come across with the owner's identity. Throw a preamble onto the post to indicate the true author. - $signed_body = "\n\n" - . '![' . $datarray['author']['xchan_name'] . '](' . $datarray['author']['xchan_photo_m'] . ')' - . '[' . $datarray['author']['xchan_name'] . '](' . $datarray['author']['xchan_url'] . ')' . "\n\n" - . $signed_body; - } - - logger('storing diaspora comment signature',LOGGER_DEBUG); - - $diaspora_handle = channel_reddress($channel); - - $signed_text = $datarray['mid'] . ';' . $parent_item['mid'] . ';' . $signed_body . ';' . $diaspora_handle; - - - if( $channel && $channel['channel_prvkey'] ) - $authorsig = base64_encode(rsa_sign($signed_text, $channel['channel_prvkey'], 'sha256')); - else - $authorsig = ''; - - $x = array('signer' => $diaspora_handle, 'body' => $signed_body, 'signed_text' => $signed_text, 'signature' => $authorsig); - - $y = json_encode($x); - - $r = q("update item set diaspora_meta = '%s' where id = %d", - dbesc($y), - intval($post_id) - ); - - - if(! $r) - logger('store_diaspora_comment_sig: DB write failed'); - - return; -} - - - function send_status_notifications($post_id,$item) { // only send notifications for comments @@ -3773,7 +3682,7 @@ function zot_feed($uid,$observer_hash,$arr) { if(! is_sys_channel($uid)) $sql_extra = item_permissions_sql($uid,$observer_hash); - $limit = " LIMIT 100 "; + $limit = " LIMIT 5000 "; if($mindate > NULL_DATE) { $sql_extra .= " and ( created > '$mindate' or changed > '$mindate' ) "; @@ -3785,15 +3694,7 @@ function zot_feed($uid,$observer_hash,$arr) { } - $items = array(); - - /** @FIXME re-unite these SQL statements. There is no need for them to be separate. The mySQL is convoluted with misuse of group by. As it stands, there is a slight difference where the postgres version doesn't remove the duplicate parents up to 100. In practice this doesn't matter. It could be made to match behavior by adding "distinct on (parent) " to the front of the selection list, at a not-worth-it performance penalty (page temp results to disk). duplicates are still ignored in the in() clause, you just get less than 100 parents if there are many children. */ - - if(ACTIVE_DBTYPE == DBTYPE_POSTGRES) { - $groupby = ''; - } else { - $groupby = 'GROUP BY parent'; - } + $items = []; $item_normal = item_normal(); @@ -3802,7 +3703,7 @@ function zot_feed($uid,$observer_hash,$arr) { WHERE uid != %d $item_normal AND item_wall = 1 - and item_private = 0 $sql_extra $groupby ORDER BY created ASC $limit", + and item_private = 0 $sql_extra ORDER BY created ASC $limit", intval($uid) ); } @@ -3810,19 +3711,25 @@ function zot_feed($uid,$observer_hash,$arr) { $r = q("SELECT parent, created, postopts from item WHERE uid = %d $item_normal AND item_wall = 1 - $sql_extra $groupby ORDER BY created ASC $limit", + $sql_extra ORDER BY created ASC $limit", intval($uid) ); } + $parents = []; + if($r) { - for($x = 0; $x < count($r); $x ++) { - if(strpos($r[$x]['postopts'],'nodeliver') !== false) { - unset($r[$x]); - } + foreach($r as $rv) { + if(array_key_exists($rv['parent'],$parents)) + continue; + if(strpos($rv['postopts'],'nodeliver') !== false) + continue; + $parents[$rv['parent']] = $rv; + if(count($parents) > 200) + break; } - $parents_str = ids_to_querystr($r,'parent'); + $parents_str = ids_to_querystr($parents,'parent'); $sys_query = ((is_sys_channel($uid)) ? $sql_extra : ''); $item_normal = item_normal(); diff --git a/include/markdown.php b/include/markdown.php index 7e1f1c42c..841540357 100644 --- a/include/markdown.php +++ b/include/markdown.php @@ -81,70 +81,6 @@ function share_unshield($m) { return str_replace($m[1], base64url_decode($x), $m[0]); } - -function diaspora_mention_callback($matches) { - - $webbie = $matches[2] . '@' . $matches[3]; - $link = ''; - if($webbie) { - $r = q("select * from hubloc left join xchan on hubloc_hash = xchan_hash where hubloc_addr = '%s' limit 1", - dbesc($webbie) - ); - if(! $r) { - $x = discover_by_webbie($webbie); - if($x) { - $r = q("select * from hubloc left join xchan on hubloc_hash = xchan_hash where hubloc_addr = '%s' limit 1", - dbesc($webbie) - ); - } - } - if($r) - $link = $r[0]['xchan_url']; - } - if(! $link) - $link = 'https://' . $matches[3] . '/u/' . $matches[2]; - - if($r && $r[0]['hubloc_network'] === 'zot') - return '@[zrl=' . $link . ']' . trim($matches[1]) . ((substr($matches[0],-1,1) === '+') ? '+' : '') . '[/zrl]' ; - else - return '@[url=' . $link . ']' . trim($matches[1]) . ((substr($matches[0],-1,1) === '+') ? '+' : '') . '[/url]' ; - -} - -function diaspora_mention_callback2($matches) { - - $webbie = $matches[1] . '@' . $matches[2]; - $link = ''; - if($webbie) { - $r = q("select * from hubloc left join xchan on hubloc_hash = xchan_hash where hubloc_addr = '%s' limit 1", - dbesc($webbie) - ); - if(! $r) { - $x = discover_by_webbie($webbie); - if($x) { - $r = q("select * from hubloc left join xchan on hubloc_hash = xchan_hash where hubloc_addr = '%s' limit 1", - dbesc($webbie) - ); - } - } - if($r) - $link = $r[0]['xchan_url']; - } - - $name = (($r) ? $r[0]['xchan_name'] : $matches[1]); - - if(! $link) - $link = 'https://' . $matches[2] . '/u/' . $matches[1]; - - if($r && $r[0]['hubloc_network'] === 'zot') - return '@[zrl=' . $link . ']' . trim($name) . ((substr($matches[0],-1,1) === '+') ? '+' : '') . '[/zrl]' ; - else - return '@[url=' . $link . ']' . trim($name) . ((substr($matches[0],-1,1) === '+') ? '+' : '') . '[/url]' ; - -} - - - /** * @brief * @@ -157,28 +93,29 @@ function diaspora_mention_callback2($matches) { * @param boolean $use_zrl default false * @return string */ -function markdown_to_bb($s, $use_zrl = false) { - $s = str_replace("
","\r",$s); - $s = str_replace("
\n>","",$s); +function markdown_to_bb($s, $use_zrl = false, $options = []) { + if(is_array($s)) { btlogger('markdown_to_bb called with array. ' . print_r($s,true), LOGGER_NORMAL, LOG_WARNING); return ''; } + + $s = str_replace("
","\r",$s); + $s = str_replace("
\n>","",$s); + $s = html_entity_decode($s,ENT_COMPAT,'UTF-8'); // if empty link text replace with the url $s = preg_replace("/\[\]\((.*?)\)/ism",'[$1]($1)',$s); - // first try plustags + $x = [ 'text' => $s , 'zrl' => $use_zrl, 'options' => $options ]; - $s = preg_replace_callback('/\@\{(.+?)\; (.+?)\@(.+?)\}\+/','diaspora_mention_callback',$s); - $s = preg_replace_callback('/\@\{(.+?)\; (.+?)\@(.+?)\}/','diaspora_mention_callback',$s); + call_hooks('markdown_to_bb_init',$x); - $s = preg_replace_callback('/\@\{(.+?)\@(.+?)\}\+/','diaspora_mention_callback2',$s); - $s = preg_replace_callback('/\@\{(.+?)\@(.+?)\}/','diaspora_mention_callback2',$s); + $s = $x['text']; // Escaping the hash tags - doesn't always seem to work // $s = preg_replace('/\#([^\s\#])/','\\#$1',$s); @@ -193,9 +130,6 @@ function markdown_to_bb($s, $use_zrl = false) { $s = html2bbcode($s); - // protect the recycle symbol from turning into a tag, but without unescaping angles and naked ampersands - $s = str_replace('♲',html_entity_decode('♲',ENT_QUOTES,'UTF-8'),$s); - // Convert everything that looks like a link to a link if($use_zrl) { $s = str_replace(array('[img','/img]'),array('[zmg','/zmg]'),$s); @@ -217,350 +151,3 @@ function markdown_to_bb($s, $use_zrl = false) { } -function stripdcode_br_cb($s) { - return '[code]' . str_replace('<br />', "\n\t", $s[1]) . '[/code]'; -} - - -////////////////////// -// The following "diaspora_ul" and "diaspora_ol" are only appropriate for the -// pre-Markdownify conversion. If Markdownify isn't used, use the non-Markdownify -// versions below -////////////////////// -/* -function diaspora_ul($s) { - // Replace "[*]" followed by any number (including zero) of - // spaces by "* " to match Diaspora's list format - if( strpos($s[0], "[list]") === 0 ) - return '<ul class="listbullet" style="list-style-type: circle;">' . preg_replace("/\[\*\]( *)/", "* ", $s[1]) . '</ul>'; - elseif( strpos($s[0], "[ul]") === 0 ) - return '<ul class="listbullet" style="list-style-type: circle;">' . preg_replace("/\[\*\]( *)/", "* ", $s[1]) . '</ul>'; - else - return $s[0]; -} - - -function diaspora_ol($s) { - // A hack: Diaspora will create a properly-numbered ordered list even - // if you use '1.' for each element of the list, like: - // 1. First element - // 1. Second element - // 1. Third element - if( strpos($s[0], "[list=1]") === 0 ) - return '<ul class="listdecimal" style="list-style-type: decimal;">' . preg_replace("/\[\*\]( *)/", "1. ", $s[1]) . '</ul>'; - elseif( strpos($s[0], "[list=i]") === 0 ) - return '<ul class="listlowerroman" style="list-style-type: lower-roman;">' . preg_replace("/\[\*\]( *)/", "1. ", $s[1]) . '</ul>'; - elseif( strpos($s[0], "[list=I]") === 0 ) - return '<ul class="listupperroman" style="list-style-type: upper-roman;">' . preg_replace("/\[\*\]( *)/", "1. ", $s[1]) . '</ul>'; - elseif( strpos($s[0], "[list=a]") === 0 ) - return '<ul class="listloweralpha" style="list-style-type: lower-alpha;">' . preg_replace("/\[\*\]( *)/", "1. ", $s[1]) . '</ul>'; - elseif( strpos($s[0], "[list=A]") === 0 ) - return '<ul class="listupperalpha" style="list-style-type: upper-alpha;">' . preg_replace("/\[\*\]( *)/", "1. ", $s[1]) . '</ul>'; - elseif( strpos($s[0], "[ol]") === 0 ) - return '<ul class="listdecimal" style="list-style-type: decimal;">' . preg_replace("/\[\*\]( *)/", "1. ", $s[1]) . '</ul>'; - else - return $s[0]; -} -*/ - -////////////////////// -// Non-Markdownify versions of "diaspora_ol" and "diaspora_ul" -////////////////////// -/** - * @brief - * - * Replace "[\\*]" followed by any number (including zero) of - * spaces by "* " to match Diaspora's list format. - * - * @param string $s - * @return string - */ -function diaspora_ul($s) { - return preg_replace("/\[\\\\\*\]( *)/", "* ", $s[1]); -} - -/** - * @brief - * - * A hack: Diaspora will create a properly-numbered ordered list even - * if you use '1.' for each element of the list, like: - * \code - * 1. First element - * 1. Second element - * 1. Third element - * \endcode - * @param string $s - * @return string - */ -function diaspora_ol($s) { - return preg_replace("/\[\\\\\*\]( *)/", "1. ", $s[1]); -} - -function bb2dmention_callback($match) { - - $r = q("select xchan_addr from xchan where xchan_url = '%s'", - dbesc($match[2]) - ); - - if($r) - return '@{' . $match[3] . ' ; ' . $r[0]['xchan_addr'] . '}'; - - return '@' . $match[3]; -} - - -function bb2diaspora_itemwallwall(&$item,$uplink = false) { - - // We will provide wallwall (embedded author on the Diaspora side) if - // 1. It is a wall-to-wall post - // 2. A comment arrived which has no Diaspora signature info - - - $wallwall = false; - $author_exists = true; - - if(! array_key_exists('author',$item)) { - $author_exists = false; - logger('bb2diaspora_itemwallwall: no author'); - $r = q("select * from xchan where xchan_hash = '%s' limit 1", - dbesc($item['author_xchan']) - ); - if($r) - $item['author'] = $r[0]; - } - - $has_meta = false; - if($item['diaspora_meta'] || get_iconfig($item,'diaspora','fields')) - $has_meta = true; - - if($item['author_xchan'] != $item['owner_xchan']) { - if($item['mid'] == $item['parent_mid']) - $wallwall = true; - else { - if(! $has_meta) { - $wallwall = true; - } - } - } - - if($uplink) - $wallwall = true; - - if(($wallwall) && (is_array($item['author'])) && $item['author']['xchan_url'] && $item['author']['xchan_name'] && $item['author']['xchan_photo_s']) { - logger('bb2diaspora_itemwallwall: wall to wall post',LOGGER_DEBUG); - // post will come across with the owner's identity. Throw a preamble onto the post to indicate the true author. - $item['body'] = "\n\n" - . '[quote]' - . '[img]' . $item['author']['xchan_photo_s'] . '[/img]' - . ' ' - . '[url=' . $item['author']['xchan_url'] . '][b]' . $item['author']['xchan_name'] . '[/b][/url]' . "\n\n" - . $item['body'] - . '[/quote]'; - } - - // $item['author'] might cause a surprise further down the line if it wasn't expected to be here. - - if(! $author_exists) - unset($item['author']); -} - - -function bb2diaspora_itembody($item, $force_update = false, $have_channel = false, $uplink = false) { - - if(! get_iconfig($item,'diaspora','fields')) { - $force_update = true; - } - - $matches = array(); - - if(($item['diaspora_meta']) && (! $force_update)) { - $diaspora_meta = json_decode($item['diaspora_meta'],true); - if($diaspora_meta) { - if(array_key_exists('iv',$diaspora_meta)) { - $key = get_config('system','prvkey'); - $meta = json_decode(crypto_unencapsulate($diaspora_meta,$key),true); - } - else { - $meta = $diaspora_meta; - } - if($meta) { - logger('bb2diaspora_itembody: cached '); - $newitem = $item; - $newitem['body'] = $meta['body']; - return $newitem['body']; - } - } - } - - create_export_photo_body($item); - - $newitem = $item; - - if(array_key_exists('item_obscured',$item) && intval($item['item_obscured'])) { - $key = get_config('system','prvkey'); - $b = json_decode($item['body'],true); - // if called from diaspora_process_outbound, this decoding has already been done. - // Everything else that calls us will not yet be decoded. - if($b && is_array($b) && array_key_exists('iv',$b)) { - $newitem['title'] = (($item['title']) ? crypto_unencapsulate(json_decode($item['title'],true),$key) : ''); - $newitem['body'] = (($item['body']) ? crypto_unencapsulate(json_decode($item['body'],true),$key) : ''); - } - } - - if(! $have_channel) - bb2diaspora_itemwallwall($newitem,$uplink); - - $title = $newitem['title']; - $body = preg_replace('/\#\^http/i', 'http', $newitem['body']); - - // protect tags and mentions from hijacking - - if(intval(get_pconfig($item['uid'],'system','prevent_tag_hijacking'))) { - $new_tag = html_entity_decode('⋕',ENT_COMPAT,'UTF-8'); - $new_mention = html_entity_decode('@',ENT_COMPAT,'UTF-8'); - - // #-tags - $body = preg_replace('/\#\[url/i', $new_tag . '[url', $body); - $body = preg_replace('/\#\[zrl/i', $new_tag . '[zrl', $body); - // @-mentions - $body = preg_replace('/\@\!?\[url/i', $new_mention . '[url', $body); - $body = preg_replace('/\@\!?\[zrl/i', $new_mention . '[zrl', $body); - } - - // remove multiple newlines - do { - $oldbody = $body; - $body = str_replace("\n\n\n", "\n\n", $body); - } while ($oldbody != $body); - - $body = bb2diaspora($body); - - if(strlen($title)) - $body = "## " . $title . "\n\n" . $body; - - if($item['attach']) { - $cnt = preg_match_all('/href=\"(.*?)\"(.*?)title=\"(.*?)\"/ism', $item['attach'], $matches, PREG_SET_ORDER); - if($cnt) { - $body .= "\n" . t('Attachments:') . "\n"; - foreach($matches as $mtch) { - $body .= '[' . $mtch[3] . '](' . $mtch[1] . ')' . "\n"; - } - } - } - -// logger('bb2diaspora_itembody : ' . $body, LOGGER_DATA); - - return html_entity_decode($body); -} - -function bb2diaspora($Text, $preserve_nl = false, $fordiaspora = true) { - - // Re-enabling the converter again. - // The bbcode parser now handles youtube-links (and the other stuff) correctly. - // Additionally the html code is now fixed so that lists are now working. - - /* - * Transform #tags, strip off the [url] and replace spaces with underscore - */ - $Text = preg_replace_callback('/#\[([zu])rl\=(\w+.*?)\](\w+.*?)\[\/[(zu)]rl\]/i', create_function('$match', - 'return \'#\'. str_replace(\' \', \'_\', $match[3]);' - ), $Text); - - $Text = preg_replace('/#\^\[([zu])rl\=(\w+.*?)\](\w+.*?)\[\/([zu])rl\]/i', '[$1rl=$2]$3[/$4rl]', $Text); - - $Text = preg_replace_callback('/\@\!?\[([zu])rl\=(\w+.*?)\](\w+.*?)\[\/([zu])rl\]/i', 'bb2dmention_callback', $Text); - - // strip map tags, as the rendering is performed in bbcode() and the resulting output - // is not compatible with Diaspora (at least in the case of openstreetmap and probably - // due to the inclusion of an html iframe) - - $Text = preg_replace("/\[map\=(.*?)\]/ism", '$1', $Text); - $Text = preg_replace("/\[map\](.*?)\[\/map\]/ism", '$1', $Text); - - // Converting images with size parameters to simple images. Markdown doesn't know it. - $Text = preg_replace("/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/ism", '[img]$3[/img]', $Text); - - // the following was added on 10-January-2012 due to an inability of Diaspora's - // new javascript markdown processor to handle links with images as the link "text" - // It is not optimal and may be removed if this ability is restored in the future - //if ($fordiaspora) - // $Text = preg_replace("/\[url\=([^\[\]]*)\]\s*\[img\](.*?)\[\/img\]\s*\[\/url\]/ism", - // "[url]$1[/url]\n[img]$2[/img]", $Text); - - // Convert it to HTML - don't try oembed - $Text = bbcode($Text, $preserve_nl, false); - - // Markdownify does not preserve previously escaped html entities such as <> and &. - - $Text = str_replace(array('<','>','&'),array('&_lt_;','&_gt_;','&_amp_;'),$Text); - - // Now convert HTML to Markdown - $md = new Converter(Converter::LINK_AFTER_CONTENT, false, false); - $Text = $md->parseString($Text); - - - // It also adds backslashes to our attempt at getting around the html entity preservation for some weird reason. - - $Text = str_replace(array('&\\_lt\\_;','&\\_gt\\_;','&\\_amp\\_;'),array('<','>','&'),$Text); - - // If the text going into bbcode() has a plain URL in it, i.e. - // with no [url] tags around it, it will come out of parseString() - // looking like: <http://url.com>, which gets removed by strip_tags(). - // So take off the angle brackets of any such URL - $Text = preg_replace("/<http(.*?)>/is", "http$1", $Text); - - // Remove empty zrl links - $Text = preg_replace("/\[zrl\=\].*?\[\/zrl\]/is", "", $Text); - - // Remove all unconverted tags - $Text = strip_tags($Text); - - // Remove any leading or trailing whitespace, as this will mess up - // the Diaspora signature verification and cause the item to disappear - - $Text = trim($Text); - - call_hooks('bb2diaspora', $Text); - - return $Text; -} - -function unescape_underscores_in_links($m) { - $y = str_replace('\\_','_', $m[2]); - return('[' . $m[1] . '](' . $y . ')'); -} - -function format_event_diaspora($ev) { - - if(! ((is_array($ev)) && count($ev))) - return ''; - - $bd_format = t('l F d, Y \@ g:i A') ; // Friday January 18, 2011 @ 8 AM - - $o = t('$Projectname event notification:') . "\n"; - - $o .= '**' . (($ev['summary']) ? bb2diaspora($ev['summary']) : bb2diaspora($ev['desc'])) . '**' . "\n"; - - $o .= t('Starts:') . ' ' . '[' - . (($ev['adjust']) ? day_translate(datetime_convert('UTC', 'UTC', - $ev['start'] , $bd_format )) - : day_translate(datetime_convert('UTC', 'UTC', - $ev['start'] , $bd_format))) - . '](' . z_root() . '/localtime/?f=&time=' . urlencode(datetime_convert('UTC','UTC',$ev['start'])) . ")\n"; - - if(! $ev['nofinish']) - $o .= t('Finishes:') . ' ' . '[' - . (($ev['adjust']) ? day_translate(datetime_convert('UTC', 'UTC', - $ev['finish'] , $bd_format )) - : day_translate(datetime_convert('UTC', 'UTC', - $ev['finish'] , $bd_format ))) - . '](' . z_root() . '/localtime/?f=&time=' . urlencode(datetime_convert('UTC','UTC',$ev['finish'])) . ")\n"; - - if(strlen($ev['location'])) - $o .= t('Location:') . bb2diaspora($ev['location']) - . "\n"; - - $o .= "\n"; - - return $o; -} diff --git a/include/network.php b/include/network.php index 6d1a05e9f..bce59d38c 100644 --- a/include/network.php +++ b/include/network.php @@ -984,40 +984,6 @@ function email_header_encode($in_str, $charset = 'UTF-8') { return $out_str; } -function email_send($addr, $subject, $headers, $item) { - //$headers .= 'MIME-Version: 1.0' . "\n"; - //$headers .= 'Content-Type: text/html; charset=UTF-8' . "\n"; - //$headers .= 'Content-Type: text/plain; charset=UTF-8' . "\n"; - //$headers .= 'Content-Transfer-Encoding: 8bit' . "\n\n"; - - $part = uniqid("", true); - - $html = prepare_body($item); - - $headers .= "Mime-Version: 1.0\n"; - $headers .= 'Content-Type: multipart/alternative; boundary="=_'.$part.'"'."\n\n"; - - $body = "\n--=_".$part."\n"; - $body .= "Content-Transfer-Encoding: 8bit\n"; - $body .= "Content-Type: text/plain; charset=utf-8; format=flowed\n\n"; - - $body .= html2plain($html)."\n"; - - $body .= "--=_".$part."\n"; - $body .= "Content-Transfer-Encoding: 8bit\n"; - $body .= "Content-Type: text/html; charset=utf-8\n\n"; - - $body .= '<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">'.$html."</body></html>\n"; - - $body .= "--=_".$part."--"; - - //$message = '<html><body>' . $html . '</body></html>'; - //$message = html2plain($html); - logger('notifier: email delivery to ' . $addr); - mail($addr, $subject, $body, $headers); -} - - function discover_by_url($url,$arr = null) { require_once('library/HTML5/Parser.php'); @@ -1027,10 +993,10 @@ function discover_by_url($url,$arr = null) { if(! $arr) return false; $network = (($arr['network']) ? $arr['network'] : 'unknown'); - $name = (($arr['name']) ? $arr['name'] : 'unknown'); - $photo = (($arr['photo']) ? $arr['photo'] : ''); - $addr = (($arr['addr']) ? $arr['addr'] : ''); - $guid = $url; + $name = (($arr['name']) ? $arr['name'] : 'unknown'); + $photo = (($arr['photo']) ? $arr['photo'] : ''); + $addr = (($arr['addr']) ? $arr['addr'] : ''); + $guid = $url; } $profile = $url; @@ -1067,8 +1033,8 @@ function discover_by_url($url,$arr = null) { if($feed->error()) logger('probe_url: scrape_feed: Error parsing XML: ' . $feed->error()); - $name = unxmlify(trim($feed->get_title())); - $photo = $feed->get_image_url(); + $name = unxmlify(trim($feed->get_title())); + $photo = $feed->get_image_url(); $author = $feed->get_author(); if($author) { @@ -1172,23 +1138,11 @@ function discover_by_url($url,$arr = null) { function discover_by_webbie($webbie) { - require_once('library/HTML5/Parser.php'); - $result = array(); + $result = []; $network = null; - $diaspora = false; - $gnusoc = false; - $dfrn = false; - - $has_salmon = false; - $salmon_key = false; - $atom_feed = false; - $diaspora_base = ''; - $diaspora_guid = ''; - $diaspora_key = ''; - $webbie = strtolower($webbie); $x = webfinger_rfc7033($webbie,true); @@ -1214,21 +1168,6 @@ function discover_by_webbie($webbie) { } } } - if($link['rel'] == NAMESPACE_DFRN) { - $dfrn = $link['href']; - } - if($link['rel'] == 'magic-public-key') { - if(substr($link['href'],0,5) === 'data:') { - $salmon_key = convert_salmon_key($link['href']); - } - } - if($link['rel'] == 'salmon') { - $has_salmon = true; - $salmon = $link['href']; - } - if($link['rel'] == 'http://schemas.google.com/g/2010#updates-from') { - $atom_feed = $link['href']; - } } } } @@ -1240,287 +1179,9 @@ function discover_by_webbie($webbie) { if($arr['success']) return true; - $aliases = array(); - - // Now let's make some decisions on what we may need - // to obtain further info - - $probe_atom = false; - $probe_old = false; - $probe_hcard = false; - - $address = ''; - $location = ''; - $nickname = ''; - $fullname = ''; - $avatar = ''; - $pubkey = ''; - - if(is_array($x)) { - if(array_key_exists('address',$x)) - $address = $x['address']; - if(array_key_exists('location',$x)) - $location = $x['location']; - if(array_key_exists('nickname',$x)) - $nickname = $x['nickname']; - } - - if(! $x) - $probe_old = true; - - - if((! $dfrn) && (! $has_salmon)) - $probe_old = true; - - if($probe_old) { - $y = old_webfinger($webbie); - if($y) { - logger('old_webfinger: ' . print_r($x,true)); - foreach($y as $link) { - if($link['@attributes']['rel'] === NAMESPACE_DFRN) - $dfrn = unamp($link['@attributes']['href']); - if($link['@attributes']['rel'] === 'salmon') - $notify = unamp($link['@attributes']['href']); - if($link['@attributes']['rel'] === NAMESPACE_FEED) - $poll = unamp($link['@attributes']['href']); - if($link['@attributes']['rel'] === 'http://microformats.org/profile/hcard') - $hcard = unamp($link['@attributes']['href']); - if($link['@attributes']['rel'] === 'http://webfinger.net/rel/profile-page') - $profile = unamp($link['@attributes']['href']); - if($link['@attributes']['rel'] === 'http://portablecontacts.net/spec/1.0') - $poco = unamp($link['@attributes']['href']); - if($link['@attributes']['rel'] === 'http://joindiaspora.com/seed_location') { - $diaspora_base = unamp($link['@attributes']['href']); - $diaspora = true; - } - if($link['@attributes']['rel'] === 'http://joindiaspora.com/guid') { - $diaspora_guid = unamp($link['@attributes']['href']); - $diaspora = true; - } - if($link['@attributes']['rel'] === 'diaspora-public-key') { - $diaspora_key = base64_decode(unamp($link['@attributes']['href'])); - if(strstr($diaspora_key,'RSA ')) - $pubkey = rsatopem($diaspora_key); - else - $pubkey = $diaspora_key; - $diaspora = true; - } - if($link['@attributes']['rel'] == 'magic-public-key') { - if(substr($link['@attributes']['href'],0,5) === 'data:') { - $salmon_key = convert_salmon_key($link['@attributes']['href']); - } - } - if($link['@attributes']['rel'] == 'salmon') { - $has_salmon = true; - $salmon = $link['@attributes']['href']; - } - - if($link['@attributes']['rel'] == 'http://schemas.google.com/g/2010#updates-from') { - $atom_feed = $link['@attributes']['href']; - } - if($link['@attributes']['rel'] === 'alias') { - $aliases[] = $link['@attributes']['href']; - } - if($link['@attributes']['rel'] === 'subject') { - $subject = $link['@attributes']['href']; - } - } - } - } - - if($subject || $aliases) { - if(strpos($webbie,'@')) { - $rhs = substr($webbie,strpos($webbie,'@')+1); - } - else { - $m = parse_url($webbie); - if($m) { - $rhs = $m['host'] . (($m['port']) ? ':' . $m['port'] : ''); - } - } - - $v = array('subject' => $subject,'aliases' => $aliases); - $address = find_webfinger_address($v,$rhs); - $location = find_webfinger_location($v,$rhs); - if($address) - $nickname = substr($address,0,strpos($address,'@')); - - } - - if($salmon_key && $has_salmon && $atom_feed && (! $dfrn) && (! $diaspora)) { - $gnusoc = true; - $probe_atom = true; - } - - if(! $pubkey) - $pubkey = $salmon_key; - - if(($dfrn || $diaspora) && $hcard) - $probe_hcard = true; - - if(! $fullname) - $fullname = $nickname; - - if($probe_atom) { - $k = z_fetch_url($atom_feed); - if($k['success']) - $feed_meta = feed_meta($k['body']); - if($feed_meta) { - - // stash any discovered pubsubhubbub hubs in case we need to follow them - // this will save an expensive lookup later - - if($feed_meta['hubs'] && $address) { - set_xconfig($address,'system','push_hubs',$feed_meta['hubs']); - set_xconfig($address,'system','feed_url',$atom_feed); - } - if($feed_meta['author']['author_name']) { - $fullname = $feed_meta['author']['author_name']; - } - if(! $avatar) { - if($feed_meta['author']['author_photo']) - $avatar = $feed_meta['author']['author_photo']; - } - - // for GNU-social over-ride any url aliases we may have picked up in webfinger - // The author.uri element in the feed is likely to be more accurate - - if($gnusoc && $feed_meta['author']['author_uri']) - $location = $feed_meta['author']['author_uri']; - } - } - else { - if($probe_hcard) { - $vcard = scrape_vcard($hcard); - if($vcard) { - logger('vcard: ' . print_r($vcard,true), LOGGER_DATA); - if($vcard['fn']) - $fullname = $vcard['fn']; - if($vcard['photo'] && (strpos($vcard['photo'],'http') !== 0)) - $vcard['photo'] = $diaspora_base . '/' . $vcard['photo']; - if(($vcard['public_key']) && (! $pubkey)) { - $diaspora_key = $vcard['public_key']; - if(strstr($diaspora_key,'RSA ')) - $pubkey = rsatopem($diaspora_key); - else - $pubkey = $diaspora_key; - } - if(! $avatar) - $avatar = $vcard['photo']; - if($diaspora) { - if(($vcard['uid']) && (! $diaspora_guid)) - $diaspora_guid = $vcard['uid']; - if(($vcard['url']) && (! $diaspora_base)) - $diaspora_base = $vcard['url']; - - - - - } - - } - } - } - - if(($profile) && (! $location)) - $location = $profile; - - if($location) { - $m = parse_url($location); - $base = $m['scheme'] . '://' . $m['host']; - $host = $m['host']; - } - - - if($diaspora && $diaspora_base && $diaspora_guid) { - if($dfrn) - $network = 'friendica-over-diaspora'; - else - $network = 'diaspora'; - - $base = trim($diaspora_base,'/'); - $notify = $base . '/receive'; - - } - else { - if($gnusoc) { - $network = 'gnusoc'; - $notify = $salmon; - } - } - - - logger('network: ' . $network); - logger('address: ' . $address); - logger('fullname: ' . $fullname); - logger('pubkey: ' . $pubkey); - logger('location: ' . $location); - - - - // if we have everything we need, let's create the records - - if($network && $address && $fullname && $pubkey && $location) { - $r = q("select * from xchan where xchan_hash = '%s' limit 1", - dbesc($address) - ); - if($r) { - $r = q("update xchan set xchan_name = '%s', xchan_network = '%s', xchan_name_date = '%s' where xchan_hash = '%s'", - dbesc($fullname), - dbesc($network), - dbesc(datetime_convert()), - dbesc($address) - ); - } - else { - $r = xchan_store_lowlevel( - [ - 'xchan_hash' => $address, - 'xchan_guid' => (($diaspora_guid) ? $diaspora_guid : $location), - 'xchan_pubkey' => $pubkey, - 'xchan_addr' => $address, - 'xchan_url' => $location, - 'xchan_name' => $fullname, - 'xchan_name_date' => datetime_convert(), - 'xchan_network' => $network - ] - ); - } - - $r = q("select * from hubloc where hubloc_hash = '%s' limit 1", - dbesc($address) - ); - - if(! $r) { - $r = hubloc_store_lowlevel( - [ - 'hubloc_guid' => (($diaspora_guid) ? $diaspora_guid : $location), - 'hubloc_hash' => $address, - 'hubloc_addr' => $address, - 'hubloc_network' => $network, - 'hubloc_url' => $base, - 'hubloc_host' => $host, - 'hubloc_callback' => $notify, - 'hubloc_updated' => datetime_convert(), - 'hubloc_primary' => 1 - ] - ); - } - $photos = import_xchan_photo($avatar,$address); - $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'", - dbescdate(datetime_convert()), - dbesc($photos[0]), - dbesc($photos[1]), - dbesc($photos[2]), - dbesc($photos[3]), - dbesc($address) - ); - return true; - } return false; -} - +} function webfinger_rfc7033($webbie,$zot = false) { @@ -1547,88 +1208,13 @@ function webfinger_rfc7033($webbie,$zot = false) { if($s['success']) { $j = json_decode($s['body'],true); - - // We could have a number of URL aliases and webbies - // make an executive decision about the most likely "best" of each - // by comparing against some examples from known networks we're likely to encounter. - // Otherwise we have to store every alias that we may ever encounter and - // validate every URL we ever find against every possible alias - - // @fixme pump.io is going to be a real bugger since it doesn't return subject or aliases - // or provide lookup by url - - $j['address'] = find_webfinger_address($j,$rhs); - $j['location'] = find_webfinger_location($j,$rhs); - if($j['address']) - $j['nickname'] = substr($j['address'],0,strpos($j['address'],'@')); - } - else - return false; - - return($j); -} - -function find_webfinger_address($j,$rhs) { - if(is_array($j) && ($j)) { - if(strpos($j['subject'],'acct:') !== false && strpos($j['subject'],'@' . $rhs)) - return str_replace('acct:','',$j['subject']); - if($j['aliases']) { - foreach($j['aliases'] as $alias) { - if(strpos($alias,'acct:') !== false && strpos($alias,'@' . $rhs)) { - return str_replace('acct:','',$alias); - } - } - } - } - return ''; -} - - -function find_webfinger_location($j,$rhs) { - if(is_array($j) && ($j)) { - if(strpos($j['subject'],'http') === 0) { - $x = match_webfinger_location($j['subject'],$rhs); - if($x) - return $x; - } - if($j['aliases']) { - foreach($j['aliases'] as $alias) { - if(strpos($alias,'http') === 0) { - $x = match_webfinger_location($alias,$rhs); - if($x) - return($x); - } - } - } + return($j); } - return ''; -} -function match_webfinger_location($s,$h) { - - // GNU-social and the older StatusNet - the $host/user/123 form doesn't work - if(preg_match('|' . $h . '/index.php/user/([0-9]*?)$|',$s)) - return $s; - // Redmatrix / hubzilla - if(preg_match('|' . $h . '/channel/|',$s)) - return $s; - // Friendica - if(preg_match('|' . $h . '/profile/|',$s)) - return $s; + return false; - $arr = array('test' => $s, 'host' => $h, 'success' => false); - call_hooks('match_webfinger_location',$arr); - if($arr['success']) - return $s; - return ''; } - - - - - - function old_webfinger($webbie) { $host = ''; @@ -1696,9 +1282,6 @@ function fetch_xrd_links($url) { if ((! $xml) || (! stristr($xml,'<xrd'))) return array(); - // fix diaspora's bad xml - $xml = str_replace(array('href="','"/>'),array('href="','"/>'),$xml); - $h = parse_xml_string($xml); if(! $h) return array(); @@ -1738,85 +1321,6 @@ function fetch_xrd_links($url) { } -function scrape_vcard($url) { - - $ret = array(); - - logger('scrape_vcard: url=' . $url); - - $x = z_fetch_url($url); - if(! $x['success']) - return $ret; - - $s = $x['body']; - - if(! $s) - return $ret; - - $headers = $x['header']; - $lines = explode("\n",$headers); - if(count($lines)) { - foreach($lines as $line) { - // don't try and run feeds through the html5 parser - if(stristr($line,'content-type:') && ((stristr($line,'application/atom+xml')) || (stristr($line,'application/rss+xml')))) - return ret; - } - } - - try { - $dom = HTML5_Parser::parse($s); - } catch (DOMException $e) { - logger('scrape_vcard: parse error: ' . $e); - } - - if(! $dom) - return $ret; - - // Pull out hCard profile elements - - $largest_photo = 0; - - $items = $dom->getElementsByTagName('*'); - foreach($items as $item) { - if(attribute_contains($item->getAttribute('class'), 'vcard')) { - $level2 = $item->getElementsByTagName('*'); - foreach($level2 as $x) { - if(attribute_contains($x->getAttribute('id'),'pod_location')) - $ret['pod_location'] = $x->textContent; - if(attribute_contains($x->getAttribute('class'),'fn')) - $ret['fn'] = $x->textContent; - if(attribute_contains($x->getAttribute('class'),'uid')) - $ret['uid'] = $x->textContent; - if(attribute_contains($x->getAttribute('class'),'nickname')) - $ret['nick'] = $x->textContent; - if(attribute_contains($x->getAttribute('class'),'searchable')) - $ret['searchable'] = $x->textContent; - if(attribute_contains($x->getAttribute('class'),'key')) - $ret['public_key'] = $x->textContent; - if(attribute_contains($x->getAttribute('class'),'given_name')) - $ret['given_name'] = $x->textContent; - if(attribute_contains($x->getAttribute('class'),'family_name')) - $ret['family_name'] = $x->textContent; - if(attribute_contains($x->getAttribute('class'),'url')) - $ret['url'] = $x->textContent; - - if((attribute_contains($x->getAttribute('class'),'photo')) - || (attribute_contains($x->getAttribute('class'),'avatar'))) { - $size = intval($x->getAttribute('width')); - if(($size > $largest_photo) || (! $largest_photo)) { - $ret['photo'] = $x->getAttribute('src'); - $largest_photo = $size; - } - } - } - } - } - - return $ret; -} - - - function scrape_feed($url) { $ret = array(); @@ -1910,31 +1414,6 @@ function scrape_feed($url) { } - -function service_plink($contact, $guid) { - - $plink = ''; - - $m = parse_url($contact['xchan_url']); - if($m) { - $url = $m['scheme'] . '://' . $m['host'] . (($m['port']) ? ':' . $m['port'] : ''); - } - else - $url = 'https://' . substr($contact['xchan_addr'],strpos($contact['xchan_addr'],'@')+1); - - $handle = substr($contact['xchan_addr'], 0, strpos($contact['xchan_addr'],'@')); - - if($contact['xchan_network'] === 'diaspora') - $plink = $url . '/posts/' . $guid; - if($contact['xchan_network'] === 'friendica-over-diaspora') - $plink = $url . '/display/' . $handle . '/' . $guid; - if($contact['xchan_network'] === 'zot') - $plink = $url . '/channel/' . $handle . '?f=&mid=' . $guid; - - return $plink; -} - - function format_and_send_email($sender,$xchan,$item) { $title = $item['title']; @@ -1944,7 +1423,7 @@ function format_and_send_email($sender,$xchan,$item) { $htmlversion = bbcode(str_replace(array("\\r","\\n"), array("","<br />\n"),$body)); - $banner = t('$Projectname Notification'); + $banner = t('$Projectname Notification'); $product = t('$projectname'); // PLATFORM_NAME; $siteurl = z_root(); $thanks = t('Thank You,'); @@ -2132,33 +1611,33 @@ function get_site_info() { - $data = Array( - 'version' => $version, - 'version_tag' => $tag, - 'server_role' => Zotlabs\Lib\System::get_server_role(), - 'commit' => $commit, - 'url' => z_root(), - 'plugins' => $visible_plugins, - 'register_policy' => $register_policy[get_config('system','register_policy')], - 'invitation_only' => intval(get_config('system','invitation_only')), - 'directory_mode' => $directory_mode[get_config('system','directory_mode')], - 'language' => get_config('system','language'), - 'rss_connections' => intval(get_config('system','feed_contacts')), - 'expiration' => $site_expire, + $data = [ + 'url' => z_root(), + 'platform' => Zotlabs\Lib\System::get_platform_name(), + 'site_name' => (($site_name) ? $site_name : ''), + 'version' => $version, + 'version_tag' => $tag, + 'server_role' => Zotlabs\Lib\System::get_server_role(), + 'commit' => $commit, + 'plugins' => $visible_plugins, + 'register_policy' => $register_policy[get_config('system','register_policy')], + 'invitation_only' => intval(get_config('system','invitation_only')), + 'directory_mode' => $directory_mode[get_config('system','directory_mode')], + 'language' => get_config('system','language'), + 'rss_connections' => intval(get_config('system','feed_contacts')), + 'expiration' => $site_expire, 'default_service_restrictions' => $service_class, - 'locked_features' => $locked_features, - 'admin' => $admin, - 'site_name' => (($site_name) ? $site_name : ''), - 'platform' => Zotlabs\Lib\System::get_platform_name(), - 'dbdriver' => DBA::$dba->getdriver(), - 'lastpoll' => get_config('system','lastpoll'), - 'info' => (($site_info) ? $site_info : ''), - 'channels_total' => $channels_total_stat, - 'channels_active_halfyear' => $channels_active_halfyear_stat, - 'channels_active_monthly' => $channels_active_monthly_stat, - 'local_posts' => $local_posts_stat, - 'hide_in_statistics' => $hide_in_statistics - ); + 'locked_features' => $locked_features, + 'admin' => $admin, + 'dbdriver' => DBA::$dba->getdriver(), + 'lastpoll' => get_config('system','lastpoll'), + 'info' => (($site_info) ? $site_info : ''), + 'channels_total' => $channels_total_stat, + 'channels_active_halfyear' => $channels_active_halfyear_stat, + 'channels_active_monthly' => $channels_active_monthly_stat, + 'local_posts' => $local_posts_stat, + 'hide_in_statistics' => $hide_in_statistics + ]; return $data; } diff --git a/include/photo/photo_driver.php b/include/photo/photo_driver.php index c8b3c3782..923e34dbe 100644 --- a/include/photo/photo_driver.php +++ b/include/photo/photo_driver.php @@ -380,7 +380,7 @@ abstract class photo_driver { dbesc($p['album']), intval($this->getHeight()), intval($this->getWidth()), - (intval($p['os_storage']) ? dbescbin($p['os_path']) : dbescbin($this->imageString())), + (intval($p['os_storage']) ? dbescbin($p['os_syspath']) : dbescbin($this->imageString())), intval($p['os_storage']), intval(strlen($this->imageString())), intval($p['imgscale']), @@ -411,7 +411,7 @@ abstract class photo_driver { dbesc($p['album']), intval($this->getHeight()), intval($this->getWidth()), - (intval($p['os_storage']) ? dbescbin($p['os_path']) : dbescbin($this->imageString())), + (intval($p['os_storage']) ? dbescbin($p['os_syspath']) : dbescbin($this->imageString())), intval($p['os_storage']), intval(strlen($this->imageString())), intval($p['imgscale']), @@ -429,90 +429,6 @@ abstract class photo_driver { return $r; } - - // should be obsolete now - - public function store($aid, $uid, $xchan, $rid, $filename, $album, $scale, $usage = PHOTO_NORMAL, $allow_cid = '', $allow_gid = '', $deny_cid = '', $deny_gid = '') { - - $x = q("select id from photo where resource_id = '%s' and uid = %d and xchan = '%s' and imgscale = %d limit 1", - dbesc($rid), - intval($uid), - dbesc($xchan), - intval($scale) - ); - if(count($x)) { - $r = q("UPDATE photo - set aid = %d, - uid = %d, - xchan = '%s', - resource_id = '%s', - created = '%s', - edited = '%s', - filename = '%s', - mimetype = '%s', - album = '%s', - height = %d, - width = %d, - content = '%s', - filesize = %d, - imgscale = %d, - photo_usage = %d, - allow_cid = '%s', - allow_gid = '%s', - deny_cid = '%s', - deny_gid = '%s' - where id = %d", - - intval($aid), - intval($uid), - dbesc($xchan), - dbesc($rid), - dbesc(datetime_convert()), - dbesc(datetime_convert()), - dbesc(basename($filename)), - dbesc($this->getType()), - dbesc($album), - intval($this->getHeight()), - intval($this->getWidth()), - dbescbin($this->imageString()), - intval(strlen($this->imageString())), - intval($scale), - intval($photo_usage), - dbesc($allow_cid), - dbesc($allow_gid), - dbesc($deny_cid), - dbesc($deny_gid), - intval($x[0]['id']) - ); - } - else { - $r = q("INSERT INTO photo - ( aid, uid, xchan, resource_id, created, edited, filename, mimetype, album, height, width, content, filesize, imgscale, photo_usage, allow_cid, allow_gid, deny_cid, deny_gid ) - VALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, '%s', %d, %d, %d, '%s', '%s', '%s', '%s' )", - intval($aid), - intval($uid), - dbesc($xchan), - dbesc($rid), - dbesc(datetime_convert()), - dbesc(datetime_convert()), - dbesc(basename($filename)), - dbesc($this->getType()), - dbesc($album), - intval($this->getHeight()), - intval($this->getWidth()), - dbescbin($this->imageString()), - intval(strlen($this->imageString())), - intval($scale), - intval($photo_usage), - dbesc($allow_cid), - dbesc($allow_gid), - dbesc($deny_cid), - dbesc($deny_gid) - ); - } - return $r; - } - } diff --git a/include/photos.php b/include/photos.php index c0f7dc8c4..eae9689a9 100644 --- a/include/photos.php +++ b/include/photos.php @@ -17,6 +17,7 @@ require_once('include/text.php'); * @param array $args * @return array */ + function photo_upload($channel, $observer, $args) { $ret = array('success' => false); @@ -28,9 +29,6 @@ function photo_upload($channel, $observer, $args) { return $ret; } - -//call_hooks('photo_upload_begin', $args); - /* * Determine the album to use */ @@ -67,8 +65,8 @@ function photo_upload($channel, $observer, $args) { $os_storage = 0; - if($args['os_path'] && $args['getimagesize']) { - $imagedata = @file_get_contents($args['os_path']); + if($args['os_syspath'] && $args['getimagesize']) { + $imagedata = @file_get_contents($args['os_syspath']); $filename = $args['filename']; $filesize = strlen($imagedata); // this is going to be deleted if it exists @@ -90,8 +88,6 @@ function photo_upload($channel, $observer, $args) { } else { $f = array('src' => '', 'filename' => '', 'filesize' => 0, 'type' => ''); -// call_hooks('photo_upload_file',$f); - if (x($f,'src') && x($f,'filesize')) { $src = $f['src']; $filename = $f['filename']; @@ -153,7 +149,7 @@ function photo_upload($channel, $observer, $args) { return $ret; } - $exif = $ph->orient(($args['os_path']) ? $args['os_path'] : $src); + $exif = $ph->orient(($args['os_syspath']) ? $args['os_syspath'] : $src); @unlink($src); @@ -180,7 +176,8 @@ function photo_upload($channel, $observer, $args) { 'filename' => $filename, 'album' => $album, 'imgscale' => 0, 'photo_usage' => PHOTO_NORMAL, 'allow_cid' => $ac['allow_cid'], 'allow_gid' => $ac['allow_gid'], 'deny_cid' => $ac['deny_cid'], 'deny_gid' => $ac['deny_gid'], - 'os_storage' => $os_storage, 'os_path' => $args['os_path'] + 'os_storage' => $os_storage, 'os_syspath' => $args['os_syspath'], + 'os_path' => $args['os_path'], 'display_path' => $args['display_path'] ); if($args['created']) $p['created'] = $args['created']; @@ -205,7 +202,7 @@ function photo_upload($channel, $observer, $args) { $errors = true; unset($p['os_storage']); - unset($p['os_path']); + unset($p['os_syspath']); if(($width > 1024 || $height > 1024) && (! $errors)) $ph->scaleImage(1024); @@ -336,19 +333,13 @@ function photo_upload($channel, $observer, $args) { if($item['mid'] === $item['parent_mid']) { $item['body'] = $summary; + $item['mimetype'] = 'text/bbcode'; $item['obj_type'] = ACTIVITY_OBJ_PHOTO; $item['obj'] = json_encode($object); $item['tgt_type'] = ACTIVITY_OBJ_ALBUM; $item['target'] = json_encode($target); - if($item['author_xchan'] === $channel['channel_hash']) { - $item['sig'] = base64url_encode(rsa_sign($item['body'],$channel['channel_prvkey'])); - $item['item_verified'] = 1; - } - else { - $item['sig'] = ''; - } $force = true; } @@ -374,37 +365,37 @@ function photo_upload($channel, $observer, $args) { else { $mid = item_message_id(); - $arr = array(); + $arr = [ + 'aid' => $account_id, + 'uid' => $channel_id, + 'mid' => $mid, + 'parent_mid' => $mid, + 'item_hidden' => $item_hidden, + 'resource_type' => 'photo', + 'resource_id' => $photo_hash, + 'owner_xchan' => $channel['channel_hash'], + 'author_xchan' => $observer['xchan_hash'], + 'title' => $title, + 'allow_cid' => $ac['allow_cid'], + 'allow_gid' => $ac['allow_gid'], + 'deny_cid' => $ac['deny_cid'], + 'deny_gid' => $ac['deny_gid'], + 'verb' => ACTIVITY_POST, + 'obj_type' => ACTIVITY_OBJ_PHOTO, + 'obj' => json_encode($object), + 'tgt_type' => ACTIVITY_OBJ_ALBUM, + 'target' => json_encode($target), + 'item_wall' => $visible, + 'item_origin' => 1, + 'item_thread_top' => 1, + 'item_private' => intval($acl->is_private()), + 'body' => $summary + ]; - if($lat && $lon) - $arr['coord'] = $lat . ' ' . $lon; - - $arr['aid'] = $account_id; - $arr['uid'] = $channel_id; - $arr['mid'] = $mid; - $arr['parent_mid'] = $mid; - $arr['item_hidden'] = $item_hidden; - $arr['resource_type'] = 'photo'; - $arr['resource_id'] = $photo_hash; - $arr['owner_xchan'] = $channel['channel_hash']; - $arr['author_xchan'] = $observer['xchan_hash']; - $arr['title'] = $title; - $arr['allow_cid'] = $ac['allow_cid']; - $arr['allow_gid'] = $ac['allow_gid']; - $arr['deny_cid'] = $ac['deny_cid']; - $arr['deny_gid'] = $ac['deny_gid']; - $arr['verb'] = ACTIVITY_POST; - $arr['obj_type'] = ACTIVITY_OBJ_PHOTO; - $arr['obj'] = json_encode($object); - $arr['tgt_type'] = ACTIVITY_OBJ_ALBUM; - $arr['target'] = json_encode($target); - $arr['item_wall'] = 1; - $arr['item_origin'] = 1; - $arr['item_thread_top'] = 1; - $arr['item_private'] = intval($acl->is_private()); $arr['plink'] = z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . urlencode($arr['mid']); - $arr['body'] = $summary; + if($lat && $lon) + $arr['coord'] = $lat . ' ' . $lon; // this one is tricky because the item and the photo have the same permissions, those of the photo. // Use the channel read_stream permissions to get the correct public_policy for the item and recalculate the @@ -451,7 +442,8 @@ function photo_upload($channel, $observer, $args) { * * \e boolean \b success * * \e array \b albums */ -function photos_albums_list($channel, $observer, $sort_key = 'album', $direction = 'asc') { + +function photos_albums_list($channel, $observer, $sort_key = 'display_path', $direction = 'asc') { $channel_id = $channel['channel_id']; $observer_xchan = (($observer) ? $observer['xchan_hash'] : ''); @@ -464,17 +456,33 @@ function photos_albums_list($channel, $observer, $sort_key = 'album', $direction $sort_key = dbesc($sort_key); $direction = dbesc($direction); - //$albums = q("SELECT count( distinct resource_id ) as total, album from photo where uid = %d and photo_usage IN ( %d, %d ) $sql_extra group by album order by $sort_key $direction", - // intval($channel_id), - // intval(PHOTO_NORMAL), - // intval(PHOTO_PROFILE) - //); - - // this query provides the same results but might perform better - $albums = q("SELECT count( distinct resource_id ) as total, album from photo where uid = %d and os_storage = 1 $sql_extra group by album order by $sort_key $direction", + $r = q("select display_path, hash from attach where is_dir = 1 and uid = %d $sql_extra order by $sort_key $direction", intval($channel_id) ); + array_unshift($r,[ 'display_path' => '/', 'hash' => '' ]); + $str = ids_to_querystr($r,'hash',true); + + $albums = []; + + if($str) { + $x = q("select count( distinct hash ) as total, folder from attach where is_photo = 1 and uid = %d and folder in ( $str ) $sql_extra group by folder ", + intval($channel_id) + ); + if($x) { + foreach($r as $rv) { + foreach($x as $xv) { + if($xv['folder'] === $rv['hash']) { + if($xv['total'] != 0 && attach_can_view_folder($channel_id,$observer_xchan,$xv['folder'])) { + $albums[] = [ 'album' => $rv['display_path'], 'folder' => $xv['folder'], 'total' => $xv['total'] ]; + } + continue; + } + } + } + } + } + // add various encodings to the array so we can just loop through and pick them out in a template $ret = array('success' => false); @@ -485,11 +493,12 @@ function photos_albums_list($channel, $observer, $sort_key = 'album', $direction foreach($albums as $k => $album) { $entry = array( 'text' => (($album['album']) ? $album['album'] : '/'), + 'shorttext' => (($album['album']) ? ellipsify($album['album'],28) : '/'), 'jstext' => (($album['album']) ? addslashes($album['album']) : '/'), 'total' => $album['total'], - 'url' => z_root() . '/photos/' . $channel['channel_address'] . '/album/' . bin2hex($album['album']), + 'url' => z_root() . '/photos/' . $channel['channel_address'] . '/album/' . $album['folder'], 'urlencode' => urlencode($album['album']), - 'bin2hex' => bin2hex($album['album']) + 'bin2hex' => $album['folder'] ); $ret['albums'][] = $entry; } @@ -500,7 +509,7 @@ function photos_albums_list($channel, $observer, $sort_key = 'album', $direction return $ret; } -function photos_album_widget($channelx,$observer,$sortkey = 'album',$direction = 'asc') { +function photos_album_widget($channelx,$observer,$sortkey = 'display_path',$direction = 'asc') { $o = ''; @@ -513,6 +522,7 @@ function photos_album_widget($channelx,$observer,$sortkey = 'album',$direction = $o = replace_macros(get_markup_template('photo_albums.tpl'),array( '$nick' => $channelx['channel_address'], '$title' => t('Photo Albums'), + '$recent' => t('Recent Photos'), '$albums' => $albums['albums'], '$baseurl' => z_root(), '$upload' => ((perm_is_allowed($channelx['channel_id'],(($observer) ? $observer['xchan_hash'] : ''),'write_storage')) @@ -531,6 +541,7 @@ function photos_album_widget($channelx,$observer,$sortkey = 'album',$direction = * @param string $album default empty * @return boolean|array */ + function photos_list_photos($channel, $observer, $album = '') { $channel_id = $channel['channel_id']; @@ -570,13 +581,17 @@ function photos_list_photos($channel, $observer, $album = '') { * @param string $album name of the album * @return boolean */ -function photos_album_exists($channel_id, $album) { - $r = q("SELECT id FROM photo WHERE album = '%s' AND uid = %d limit 1", + +function photos_album_exists($channel_id, $observer_hash, $album) { + + $sql_extra = permissions_sql($channel_id,$observer_hash); + + $r = q("SELECT folder, hash, is_dir, filename, os_path, display_path FROM attach WHERE hash = '%s' AND is_dir = 1 AND uid = %d $sql_extra limit 1", dbesc($album), intval($channel_id) ); - return (($r) ? true : false); + return (($r) ? $r[0] : false); } /** @@ -589,6 +604,7 @@ function photos_album_exists($channel_id, $album) { * @param string $newname The new name of the album * @return bool|array */ + function photos_album_rename($channel_id, $oldname, $newname) { return q("UPDATE photo SET album = '%s' WHERE album = '%s' AND uid = %d", dbesc($newname), @@ -607,16 +623,18 @@ function photos_album_rename($channel_id, $oldname, $newname) { * @param string $remote_xchan * @return string|boolean */ + function photos_album_get_db_idstr($channel_id, $album, $remote_xchan = '') { - if ($remote_xchan) { - $r = q("SELECT distinct resource_id from photo where xchan = '%s' and uid = %d and album = '%s' ", + if($remote_xchan) { + $r = q("SELECT hash from attach where creator = '%s' and uid = %d and folder = '%s' ", dbesc($remote_xchan), intval($channel_id), dbesc($album) ); - } else { - $r = q("SELECT distinct resource_id from photo where uid = %d and album = '%s' ", + } + else { + $r = q("SELECT hash from attach where uid = %d and folder = '%s' ", intval($channel_id), dbesc($album) ); @@ -624,7 +642,7 @@ function photos_album_get_db_idstr($channel_id, $album, $remote_xchan = '') { if ($r) { $arr = array(); foreach ($r as $rr) { - $arr[] = "'" . dbesc($rr['resource_id']) . "'" ; + $arr[] = "'" . dbesc($rr['hash']) . "'" ; } $str = implode(',',$arr); return $str; @@ -642,6 +660,7 @@ function photos_album_get_db_idstr($channel_id, $album, $remote_xchan = '') { * @param boolean $visible default false * @return int item_id */ + function photos_create_item($channel, $creator_hash, $photo, $visible = false) { // Create item container @@ -697,7 +716,7 @@ function getGps($exifCoord, $hemi) { function getGpstimestamp($exifCoord) { - $hours = count($exifCoord) > 0 ? gps2Num($exifCoord[0]) : 0; + $hours = count($exifCoord) > 0 ? gps2Num($exifCoord[0]) : 0; $minutes = count($exifCoord) > 1 ? gps2Num($exifCoord[1]) : 0; $seconds = count($exifCoord) > 2 ? gps2Num($exifCoord[2]) : 0; diff --git a/include/text.php b/include/text.php index 224ba17d0..2b22df2ea 100644 --- a/include/text.php +++ b/include/text.php @@ -3,6 +3,7 @@ * @file include/text.php */ +use \Zotlabs\Lib as Zlib; use \Michelf\MarkdownExtra; require_once("include/bbcode.php"); @@ -89,12 +90,10 @@ function escape_tags($string) { } -function z_input_filter($channel_id,$s,$type = 'text/bbcode') { +function z_input_filter($s,$type = 'text/bbcode',$allow_code = false) { if($type === 'text/bbcode') return escape_tags($s); - if($type === 'text/markdown') - return escape_tags($s); if($type == 'text/plain') return escape_tags($s); if($type == 'application/x-pdl') @@ -104,15 +103,15 @@ function z_input_filter($channel_id,$s,$type = 'text/bbcode') { return $s; } - $r = q("select account_id, account_roles, channel_pageflags from account left join channel on channel_account_id = account_id where channel_id = %d limit 1", - intval($channel_id) - ); - if($r) { - if(($r[0]['account_roles'] & ACCOUNT_ROLE_ALLOWCODE) || ($r[0]['channel_pageflags'] & PAGE_ALLOWCODE)) { - if(local_channel() && (get_account_id() == $r[0]['account_id'])) { - return $s; - } - } + if($allow_code) { + if($type === 'text/markdown') + return htmlspecialchars($s,ENT_QUOTES); + return $s; + } + + if($type === 'text/markdown') { + $x = new Zlib\MarkdownSoap($s); + return $x->clean(); } if($type === 'text/html') @@ -1183,8 +1182,7 @@ function list_smilies() { ':coffee', ':facepalm', ':like', - ':dislike', - ':hubzilla' + ':dislike' ); $icons = array( @@ -1219,8 +1217,7 @@ function list_smilies() { '<img class="smiley" src="' . z_root() . '/images/emoticons/coffee.gif" alt=":coffee" />', '<img class="smiley" src="' . z_root() . '/images/emoticons/smiley-facepalm.gif" alt=":facepalm" />', '<img class="smiley" src="' . z_root() . '/images/emoticons/like.gif" alt=":like" />', - '<img class="smiley" src="' . z_root() . '/images/emoticons/dislike.gif" alt=":dislike" />', - '<img class="smiley" src="' . z_root() . '/images/hz-16.png" alt=":hubzilla" />', + '<img class="smiley" src="' . z_root() . '/images/emoticons/dislike.gif" alt=":dislike" />' ); @@ -1639,6 +1636,7 @@ function prepare_text($text, $content_type = 'text/bbcode', $cache = false) { break; case 'text/markdown': + $text = Zlib\MarkdownSoap::unescape($text); $s = MarkdownExtra::defaultTransform($text); break; @@ -1794,23 +1792,9 @@ function mimetype_select($channel_id, $current = 'text/bbcode') { ); - if(App::$is_sys) { + if((App::$is_sys) || (channel_codeallowed($channel_id) && $channel_id == local_channel())){ $x[] = 'application/x-php'; } - else { - $r = q("select account_id, account_roles, channel_pageflags from account left join channel on account_id = channel_account_id where - channel_id = %d limit 1", - intval($channel_id) - ); - - if($r) { - if(($r[0]['account_roles'] & ACCOUNT_ROLE_ALLOWCODE) || ($r[0]['channel_pageflags'] & PAGE_ALLOWCODE)) { - if(local_channel() && get_account_id() == $r[0]['account_id']) { - $x[] = 'application/x-php'; - } - } - } - } foreach($x as $y) { $selected = (($y == $current) ? ' selected="selected" ' : ''); @@ -3126,3 +3110,14 @@ function array_escape_tags(&$v,$k) { $v = escape_tags($v); } +function ellipsify($s,$maxlen) { + if($maxlen & 1) + $maxlen --; + if($maxlen < 4) + $maxlen = 4; + + if(mb_strlen($s) < $maxlen) + return $s; + + return mb_substr($s,0,$maxlen / 2) . '...' . mb_substr($s,mb_strlen($s) - ($maxlen / 2)); +}
\ No newline at end of file |