diff options
-rw-r--r-- | CHANGELOG | 35 | ||||
-rw-r--r-- | Zotlabs/Daemon/Cron.php | 2 | ||||
-rw-r--r-- | Zotlabs/Daemon/Cron_weekly.php | 15 | ||||
-rw-r--r-- | Zotlabs/Module/Acl.php | 11 | ||||
-rw-r--r-- | Zotlabs/Module/Directory.php | 5 | ||||
-rw-r--r-- | Zotlabs/Module/Item.php | 9 | ||||
-rw-r--r-- | Zotlabs/Storage/File.php | 9 | ||||
-rw-r--r-- | Zotlabs/Widget/Conversations.php | 12 | ||||
-rw-r--r-- | Zotlabs/Widget/Wiki_pages.php | 2 | ||||
-rw-r--r-- | include/activities.php | 2 | ||||
-rw-r--r-- | include/attach.php | 2 | ||||
-rw-r--r-- | include/bbcode.php | 6 | ||||
-rw-r--r-- | include/channel.php | 60 | ||||
-rw-r--r-- | include/conversation.php | 19 | ||||
-rwxr-xr-x | include/items.php | 304 | ||||
-rw-r--r-- | include/markdown.php | 4 | ||||
-rw-r--r-- | include/message.php | 5 | ||||
-rw-r--r-- | include/text.php | 14 | ||||
-rw-r--r-- | view/theme/redbasic/schema/dark.css | 6 | ||||
-rw-r--r-- | view/theme/redbasic/schema/simple_black_on_white.css | 6 | ||||
-rw-r--r-- | view/theme/redbasic/schema/simple_green_on_black.css | 6 | ||||
-rw-r--r-- | view/theme/redbasic/schema/simple_white_on_black.css | 6 | ||||
-rwxr-xr-x | view/tpl/cover_photo_widget.tpl | 5 |
23 files changed, 318 insertions, 227 deletions
@@ -1,4 +1,37 @@ -Hubzilla 2.8 (????-??-??) +Hubzilla 2.8.1 (2017-11-11) + - Rename channel app events to calendar and add nav_set_selected() to /cal + - Load notifications links to /display via ajax if we are already in /display + - Add location info to the navbar for remote visitors + - Bring back tabindex to submit comments + - Add spanish translations for context help + - Added mode to portfolio widget + + Bugfixes + - Fix os_syspath in DAV file put operation so that photos will scale correctly + - Fix unicode characters in urls tripping up url regexes - github issue #901 + - Fix wiki pages not updating after creating new page + - Fix notifications covered by cover photo on medium size screens - github issue #906 + - Fix unable to change permissions on wiki with space in name + - Fix only show nav app link if we have a selected app + - Fix unable to mark all messages read + - Fix imagedata not set correctly if large photo and imagick is not installed + - Fix issues with diaspora xchans + - Fix profile photo issue triggered by a previous bug + + Plugins/Addon + N-S-F-W: improve the undocumented n-s-f-w author::word feature + Diaspora: update the import_diaspora tool for the version 2.0 account export files + Diaspora: fix comments are partly containing "diaspora_handle" instead of "author" - github issue #69 + Pubcrawl: provide feature setting for downgrade_media option + Pubcrawl: fix issue where replies to replies did not find its parent + Diaspora: fix friendica likes on comments + Diaspora: fix private mail + Diaspora: fix third party deletes/retractions not propagating + Diaspora: likes not working - github issue #895 in core + Diaspora: fix comments from unknown persons not accepted if allow public comments is enabled - github issue #68 + XMPP: fix php warning + +Hubzilla 2.8 (2017-10-25) - Redirect to be moderated items to /moderate - Update notifications if notifications area remains open - Create an actual logout module instead of relying on internal variables diff --git a/Zotlabs/Daemon/Cron.php b/Zotlabs/Daemon/Cron.php index 65edbedfa..01c43262a 100644 --- a/Zotlabs/Daemon/Cron.php +++ b/Zotlabs/Daemon/Cron.php @@ -78,7 +78,7 @@ class Cron { // channels and sites that quietly vanished and prevent the directory from accumulating stale // or dead entries. - $r = q("select channel_id from channel where channel_dirdate < %s - INTERVAL %s", + $r = q("select channel_id from channel where channel_dirdate < %s - INTERVAL %s and channel_removed = 0", db_utcnow(), db_quoteinterval('30 DAY') ); diff --git a/Zotlabs/Daemon/Cron_weekly.php b/Zotlabs/Daemon/Cron_weekly.php index 5b185f475..d44400767 100644 --- a/Zotlabs/Daemon/Cron_weekly.php +++ b/Zotlabs/Daemon/Cron_weekly.php @@ -21,6 +21,21 @@ class Cron_weekly { mark_orphan_hubsxchans(); + // Find channels that were removed in the last three weeks, but + // haven't been finally cleaned up. These should be older than 10 + // days to ensure that "purgeall" messages have gone out or bounced + // or timed out. + + $r = q("select channel_id from channel where channel_removed = 1 and + channel_deleted > %s - INTERVAL %s and channel_deleted < %s - INTERVAL %s", + db_utcnow(), db_quoteinterval('21 DAY'), + db_utcnow(), db_quoteinterval('10 DAY') + ); + if($r) { + foreach($r as $rv) { + channel_remove_final($rv['channel_id']); + } + } // get rid of really old poco records diff --git a/Zotlabs/Module/Acl.php b/Zotlabs/Module/Acl.php index e164875e8..ad1c8b8cd 100644 --- a/Zotlabs/Module/Acl.php +++ b/Zotlabs/Module/Acl.php @@ -176,11 +176,18 @@ class Acl extends \Zotlabs\Web\Controller { $extra_channels_sql = " OR (abook_channel IN ($extra_channels_sql)) and abook_hidden = 0 "; - // Add atokens belonging to the local channel @TODO restrict by search + // Add atokens belonging to the local channel + + if($search) { + $sql_extra_atoken = "AND ( atoken_name LIKE " . protect_sprintf( "'%" . dbesc($search) . "%'" ) . ") "; + } + else { + $sql_extra_atoken = ''; + } $r2 = null; - $r1 = q("select * from atoken where atoken_uid = %d", + $r1 = q("select * from atoken where atoken_uid = %d $sql_extra_atoken", intval(local_channel()) ); diff --git a/Zotlabs/Module/Directory.php b/Zotlabs/Module/Directory.php index 256667ef3..b1552a694 100644 --- a/Zotlabs/Module/Directory.php +++ b/Zotlabs/Module/Directory.php @@ -64,6 +64,11 @@ class Directory extends \Zotlabs\Web\Controller { return; } + if(get_config('system','block_public_directory',false) && (! get_observer_hash())) { + notice( t('Public access denied.') . EOL); + return; + } + $observer = get_observer_hash(); $globaldir = get_directory_setting($observer, 'globaldir'); diff --git a/Zotlabs/Module/Item.php b/Zotlabs/Module/Item.php index b54de0fb9..f2b850ffc 100644 --- a/Zotlabs/Module/Item.php +++ b/Zotlabs/Module/Item.php @@ -577,15 +577,6 @@ class Item extends \Zotlabs\Web\Controller { * so we'll set the permissions regardless and realise that the media may not be * referenced in the post. * - * What is preventing us from being able to upload photos into comments is dealing with - * the photo and attachment permissions, since we don't always know who was in the - * distribution for the top level post. - * - * We might be able to provide this functionality with a lot of fiddling: - * - if the top level post is public (make the photo public) - * - if the top level post was written by us or a wall post that belongs to us (match the top level post) - * - if the top level post has privacy mentions, add those to the permissions. - * - otherwise disallow the photo *or* make the photo public. This is the part that gets messy. */ if(! $preview) { diff --git a/Zotlabs/Storage/File.php b/Zotlabs/Storage/File.php index 332bf6896..947a9fde3 100644 --- a/Zotlabs/Storage/File.php +++ b/Zotlabs/Storage/File.php @@ -127,12 +127,15 @@ class File extends DAV\Node implements DAV\IFile { $is_photo = false; $album = ''; + $os_path = ''; - $r = q("SELECT flags, folder, os_storage, filename, is_photo FROM attach WHERE hash = '%s' AND uid = %d LIMIT 1", + $r = q("SELECT flags, folder, os_storage, os_path, filename, is_photo FROM attach WHERE hash = '%s' AND uid = %d LIMIT 1", dbesc($this->data['hash']), intval($c[0]['channel_id']) ); if ($r) { + $os_path = $r[0]['os_path']; + if (intval($r[0]['os_storage'])) { $d = q("select folder, content from attach where hash = '%s' and uid = %d limit 1", dbesc($this->data['hash']), @@ -150,7 +153,7 @@ class File extends DAV\Node implements DAV\IFile { } } $fname = dbunescbin($d[0]['content']); - if(strpos($fname,'store') === false) + if(strpos($fname,'store/') === false) $f = 'store/' . $this->auth->owner_nick . '/' . $fname ; else $f = $fname; @@ -196,7 +199,7 @@ class File extends DAV\Node implements DAV\IFile { if($is_photo) { require_once('include/photos.php'); - $args = array( 'resource_id' => $this->data['hash'], 'album' => $album, 'os_path' => $f, 'filename' => $r[0]['filename'], 'getimagesize' => $gis, 'directory' => $direct ); + $args = array( 'resource_id' => $this->data['hash'], 'album' => $album, 'os_syspath' => $f, 'os_path' => $os_path, 'filename' => $r[0]['filename'], 'getimagesize' => $gis, 'directory' => $direct ); $p = photo_upload($c[0],\App::get_observer(),$args); } diff --git a/Zotlabs/Widget/Conversations.php b/Zotlabs/Widget/Conversations.php index 56510750f..267d50fa0 100644 --- a/Zotlabs/Widget/Conversations.php +++ b/Zotlabs/Widget/Conversations.php @@ -28,6 +28,8 @@ class Conversations { require_once('include/message.php'); + $o = ''; + // private_messages_list() can do other more complicated stuff, for now keep it simple $r = private_messages_list(local_channel(), $mailbox, \App::$pager['start'], \App::$pager['itemspage']); @@ -36,13 +38,13 @@ class Conversations { return $o; } - $messages = array(); + $messages = []; foreach($r as $rr) { $selected = ((argc() == 3) ? intval(argv(2)) == intval($rr['id']) : $r[0]['id'] == $rr['id']); - $messages[] = array( + $messages[] = [ 'mailbox' => $mailbox, 'id' => $rr['id'], 'from_name' => $rr['from']['xchan_name'], @@ -57,14 +59,14 @@ class Conversations { 'date' => datetime_convert('UTC',date_default_timezone_get(),$rr['created'], 'c'), 'seen' => $rr['seen'], 'selected' => ((argv(1) != 'new') ? $selected : '') - ); + ]; } $tpl = get_markup_template('mail_head.tpl'); - $o .= replace_macros($tpl, array( + $o .= replace_macros($tpl, [ '$header' => $header, '$messages' => $messages - )); + ]); } return $o; diff --git a/Zotlabs/Widget/Wiki_pages.php b/Zotlabs/Widget/Wiki_pages.php index ac44b8d88..39d4b1717 100644 --- a/Zotlabs/Widget/Wiki_pages.php +++ b/Zotlabs/Widget/Wiki_pages.php @@ -12,7 +12,7 @@ class Wiki_pages { if(! $arr['resource_id']) { $c = channelx_by_nick(argv(1)); - $w = \Zotlabs\Lib\NativeWiki::exists_by_name($c['channel_id'],argv(2)); + $w = \Zotlabs\Lib\NativeWiki::exists_by_name($c['channel_id'],urldecode(argv(2))); $arr = array( 'resource_id' => $w['resource_id'], 'channel_id' => $c['channel_id'], diff --git a/include/activities.php b/include/activities.php index 2671e668c..9b83f7a5c 100644 --- a/include/activities.php +++ b/include/activities.php @@ -50,7 +50,7 @@ function profile_activity($changed, $value) { if($t == 1 && strlen($value)) { // if it's a url, the HTML quotes will mess it up, so link it and don't try and zidify it because we don't know what it points to. - $value = preg_replace_callback("/([^\]\='".'"'."]|^|\#\^)(https?\:\/\/[a-zA-Z0-9\:\/\-\?\&\;\.\=\@\_\~\#\%\$\!\+\,]+)/ism", 'red_zrl_callback', $value); + $value = preg_replace_callback("/([^\]\='".'"'."]|^|\#\^)(https?\:\/\/[a-zA-Z0-9\pL\:\/\-\?\&\;\.\=\@\_\~\#\%\$\!\+\,]+)/ismu", 'red_zrl_callback', $value); // take out the bookmark indicator if(substr($value,0,2) === '#^') $value = str_replace('#^','',$value); diff --git a/include/attach.php b/include/attach.php index 179a57a90..2bb57722b 100644 --- a/include/attach.php +++ b/include/attach.php @@ -1366,7 +1366,7 @@ function attach_delete($channel_id, $resource, $is_photo = 0) { return; } - $url = get_cloudpath($channel_id, $channel_address, $resource); + $url = get_cloud_url($channel_id, $channel_address, $resource); $object = get_file_activity_object($channel_id, $resource, $url); // If resource is a directory delete everything in the directory recursive diff --git a/include/bbcode.php b/include/bbcode.php index 9a2a6eb9b..050ab2d29 100644 --- a/include/bbcode.php +++ b/include/bbcode.php @@ -838,13 +838,13 @@ function bbcode($Text, $preserve_nl = false, $tryoembed = true, $cache = false) // Perform URL Search - $urlchars = '[a-zA-Z0-9\:\/\-\?\&\;\.\=\_\~\#\%\$\!\+\,\@\(\)]'; + $urlchars = '[a-zA-Z0-9\pL\:\/\-\?\&\;\.\=\_\~\#\%\$\!\+\,\@\(\)]'; if (strpos($Text,'http') !== false) { if($tryoembed) { - $Text = preg_replace_callback("/([^\]\='".'"'."\/]|^|\#\^)(https?\:\/\/$urlchars+)/ism", 'tryoembed', $Text); + $Text = preg_replace_callback("/([^\]\='".'"'."\/]|^|\#\^)(https?\:\/\/$urlchars+)/ismu", 'tryoembed', $Text); } - $Text = preg_replace("/([^\]\='".'"'."\/]|^|\#\^)(https?\:\/\/$urlchars+)/ism", '$1<a href="$2" target="_blank" rel="nofollow noopener">$2</a>', $Text); + $Text = preg_replace("/([^\]\='".'"'."\/]|^|\#\^)(https?\:\/\/$urlchars+)/ismu", '$1<a href="$2" target="_blank" rel="nofollow noopener">$2</a>', $Text); } if (strpos($Text,'[/share]') !== false) { diff --git a/include/channel.php b/include/channel.php index 6a6022aba..4f0e8ec6a 100644 --- a/include/channel.php +++ b/include/channel.php @@ -2527,19 +2527,43 @@ function channel_remove($channel_id, $local = true, $unset_session = false) { } } + q("DELETE FROM app WHERE app_channel = %d", intval($channel_id)); + q("DELETE FROM atoken WHERE atoken_uid = %d", intval($channel_id)); + q("DELETE FROM chatroom WHERE cr_uid = %d", intval($channel_id)); + q("DELETE FROM conv WHERE uid = %d", intval($channel_id)); q("DELETE FROM groups WHERE uid = %d", intval($channel_id)); q("DELETE FROM group_member WHERE uid = %d", intval($channel_id)); q("DELETE FROM event WHERE uid = %d", intval($channel_id)); - q("DELETE FROM item WHERE uid = %d", intval($channel_id)); q("DELETE FROM mail WHERE channel_id = %d", intval($channel_id)); + q("DELETE FROM menu WHERE menu_channel_id = %d", intval($channel_id)); + q("DELETE FROM menu_item WHERE mitem_channel_id = %d", intval($channel_id)); + q("DELETE FROM notify WHERE uid = %d", intval($channel_id)); + q("DELETE FROM obj WHERE obj_channel = %d", intval($channel_id)); + + q("DELETE FROM photo WHERE uid = %d", intval($channel_id)); q("DELETE FROM attach WHERE uid = %d", intval($channel_id)); q("DELETE FROM profile WHERE uid = %d", intval($channel_id)); - q("DELETE FROM pconfig WHERE uid = %d", intval($channel_id)); + q("DELETE FROM src WHERE src_channel_id = %d", intval($channel_id)); + + $r = q("select resource_id FROM attach WHERE uid = %d", intval($channel_id)); + if($r) { + foreach($r as $rv) { + attach_delete($channel_id,$rv['resource_id']); + } + } + + + + $r = q("select id from item where uid = %d", intval($channel_id)); + if($r) { + foreach($r as $rv) { + drop_item($rv['id'],false); + } + } - /// @FIXME At this stage we need to remove the file resources located under /store/$nickname q("delete from abook where abook_xchan = '%s' and abook_self = 1 ", dbesc($channel['channel_hash']) @@ -2593,19 +2617,11 @@ function channel_remove($channel_id, $local = true, $unset_session = false) { } //remove from file system - $r = q("select channel_address from channel where channel_id = %d limit 1", - intval($channel_id) - ); - if($r) { - $channel_address = $r[0]['channel_address'] ; - } - if($channel_address) { - $f = 'store/' . $channel_address.'/'; - logger('delete '. $f); - if(is_dir($f)) { - @rrmdir($f); - } + + $f = 'store/' . $channel['channel_address']; + if(is_dir($f)) { + @rrmdir($f); } Zotlabs\Daemon\Master::Summon(array('Directory',$channel_id)); @@ -2616,6 +2632,20 @@ function channel_remove($channel_id, $local = true, $unset_session = false) { } } +// execute this at least a week after removing a channel + +function channel_remove_final($channel_id) { + + q("delete from abook where abook_channel = %d", intval($channel_id)); + q("delete from abconfig where chan = %d", intval($channel_id)); + q("delete from pconfig where uid = %d", intval($channel_id)); + + +} + + + + /** * @brief This checks if a channel is allowed to publish executable code. * diff --git a/include/conversation.php b/include/conversation.php index 2ce4dacef..1cbd9116c 100644 --- a/include/conversation.php +++ b/include/conversation.php @@ -573,19 +573,16 @@ function conversation($items, $mode, $update, $page_mode = 'traditional', $prepa if (! feature_enabled($profile_owner,'multi_delete')) $page_dropping = false; - $uploading = true; - - if($profile_owner > 0) { - $owner_channel = channelx_by_n($profile_owner); - if($owner_channel['channel_allow_cid'] || $owner_channel['channel_allow_gid'] - || $owner_channel['channel_deny_cid'] || $owner_channel['channel_deny_gid']) { - $uploading = false; + $uploading = false; + + if(local_channel()) { + $cur_channel = App::get_channel(); + if($cur_channel['channel_allow_cid'] === '' && $cur_channel['channel_allow_gid'] === '' + && $cur_channel['channel_deny_cid'] === '' && $cur_channel['channel_deny_gid'] === '' + && intval(\Zotlabs\Access\PermissionLimits::Get(local_channel(),'view_storage')) === PERMS_PUBLIC) { + $uploading = true; } } - else { - $uploading = false; - } - $channel = App::get_channel(); $observer = App::get_observer(); diff --git a/include/items.php b/include/items.php index 5d592c736..b1b40e977 100755 --- a/include/items.php +++ b/include/items.php @@ -2571,148 +2571,149 @@ function tag_deliver($uid, $item_id) { if($terms) logger('Post mentions: ' . print_r($terms,true), LOGGER_DATA); + + $max_forums = get_config('system','max_tagged_forums',2); + $matched_forums = 0; + + $link = normalise_link($u[0]['xchan_url']); + if($terms) { foreach($terms as $term) { - if(link_compare($term['url'],$link)) { - $mention = true; - break; + if(! link_compare($term['url'],$link)) { + continue; } - } - } - if($mention) { - logger('Mention found for ' . $u[0]['channel_name']); + $mention = true; - $r = q("update item set item_mentionsme = 1 where id = %d", - intval($item_id) - ); + logger('Mention found for ' . $u[0]['channel_name']); - // At this point we've determined that the person receiving this post was mentioned in it or it is a union. - // Now let's check if this mention was inside a reshare so we don't spam a forum - // If it's private we may have to unobscure it momentarily so that we can parse it. + $r = q("update item set item_mentionsme = 1 where id = %d", + intval($item_id) + ); - $body = $item['body']; + // At this point we've determined that the person receiving this post was mentioned in it or it is a union. + // Now let's check if this mention was inside a reshare so we don't spam a forum + // If it's private we may have to unobscure it momentarily so that we can parse it. - $body = preg_replace('/\[share(.*?)\[\/share\]/','',$body); + $body = preg_replace('/\[share(.*?)\[\/share\]/','',$item['body']); - $tagged = false; - $plustagged = false; - $matches = array(); + $tagged = false; + $plustagged = false; + $matches = array(); - $pattern = '/[\!@]\!?\[zrl\=' . preg_quote($term['url'],'/') . '\]' . preg_quote($term['term'],'/') . '\[\/zrl\]/'; - if(preg_match($pattern,$body,$matches)) - $tagged = true; + $pattern = '/[\!@]\!?\[zrl\=' . preg_quote($term['url'],'/') . '\]' . preg_quote($term['term'],'/') . '\[\/zrl\]/'; + if(preg_match($pattern,$body,$matches)) + $tagged = true; - // original red forum tagging sequence @forumname+ - // standard forum tagging sequence !forumname + // original red forum tagging sequence @forumname+ + // standard forum tagging sequence !forumname - $pluspattern = '/@\!?\[zrl\=([^\]]*?)\]((?:.(?!\[zrl\=))*?)\+\[\/zrl\]/'; + $pluspattern = '/@\!?\[zrl\=([^\]]*?)\]((?:.(?!\[zrl\=))*?)\+\[\/zrl\]/'; - $forumpattern = '/\!\!?\[zrl\=([^\]]*?)\]((?:.(?!\[zrl\=))*?)\[\/zrl\]/'; + $forumpattern = '/\!\!?\[zrl\=([^\]]*?)\]((?:.(?!\[zrl\=))*?)\[\/zrl\]/'; - $found = false; + $found = false; - $max_forums = get_config('system','max_tagged_forums'); - if(! $max_forums) - $max_forums = 2; - $matched_forums = 0; - $matches = array(); + $matches = array(); - if(preg_match_all($pluspattern,$body,$matches,PREG_SET_ORDER)) { - foreach($matches as $match) { - $matched_forums ++; - if($term['url'] === $match[1] && $term['term'] === $match[2]) { - if($matched_forums <= $max_forums) { - $plustagged = true; - $found = true; - break; + if(preg_match_all($pluspattern,$body,$matches,PREG_SET_ORDER)) { + foreach($matches as $match) { + $matched_forums ++; + if($term['url'] === $match[1] && $term['term'] === $match[2] && intval($term['ttype']) === TERM_MENTION) { + if($matched_forums <= $max_forums) { + $plustagged = true; + $found = true; + break; + } + logger('forum ' . $term['term'] . ' exceeded max_tagged_forums - ignoring'); } - logger('forum ' . $term['term'] . ' exceeded max_tagged_forums - ignoring'); } } - } - if(preg_match_all($forumpattern,$body,$matches,PREG_SET_ORDER)) { - foreach($matches as $match) { - $matched_forums ++; - if($term['url'] === $match[1] && $term['term'] === $match[2]) { - if($matched_forums <= $max_forums) { - $plustagged = true; - $found = true; - break; + if(preg_match_all($forumpattern,$body,$matches,PREG_SET_ORDER)) { + foreach($matches as $match) { + $matched_forums ++; + if($term['url'] === $match[1] && $term['term'] === $match[2] && intval($term['ttype']) === TERM_FORUM) { + if($matched_forums <= $max_forums) { + $plustagged = true; + $found = true; + break; + } + logger('forum ' . $term['term'] . ' exceeded max_tagged_forums - ignoring'); } - logger('forum ' . $term['term'] . ' exceeded max_tagged_forums - ignoring'); } } - } - if(! ($tagged || $plustagged)) { - logger('Mention was in a reshare or exceeded max_tagged_forums - ignoring'); - return; - } + if(! ($tagged || $plustagged)) { + logger('Mention was in a reshare or exceeded max_tagged_forums - ignoring'); + continue; + } - $arr = [ - 'channel_id' => $uid, - 'item' => $item, - 'body' => $body - ]; - /** - * @hooks tagged - * Called when a delivery is processed which results in you being tagged. - * * \e number \b channel_id - * * \e array \b item - * * \e string \b body - */ - call_hooks('tagged', $arr); + $arr = [ + 'channel_id' => $uid, + 'item' => $item, + 'body' => $body + ]; + /** + * @hooks tagged + * Called when a delivery is processed which results in you being tagged. + * * \e number \b channel_id + * * \e array \b item + * * \e string \b body + */ + call_hooks('tagged', $arr); + + /* + * Kill two birds with one stone. As long as we're here, send a mention notification. + */ - /* - * Kill two birds with one stone. As long as we're here, send a mention notification. - */ + Zlib\Enotify::submit(array( + 'to_xchan' => $u[0]['channel_hash'], + 'from_xchan' => $item['author_xchan'], + 'type' => NOTIFY_TAGSELF, + 'item' => $item, + 'link' => $i[0]['llink'], + 'verb' => ACTIVITY_TAG, + 'otype' => 'item' + )); - Zlib\Enotify::submit(array( - 'to_xchan' => $u[0]['channel_hash'], - 'from_xchan' => $item['author_xchan'], - 'type' => NOTIFY_TAGSELF, - 'item' => $item, - 'link' => $i[0]['llink'], - 'verb' => ACTIVITY_TAG, - 'otype' => 'item' - )); - - // Just a normal tag? - - if(! $plustagged) { - logger('Not a plus tag', LOGGER_DEBUG); - return; - } + // Just a normal tag? - // plustagged - keep going, next check permissions + if(! $plustagged) { + logger('Not a plus tag', LOGGER_DEBUG); + continue; + } - if(! perm_is_allowed($uid,$item['author_xchan'],'tag_deliver')) { - logger('tag_delivery denied for uid ' . $uid . ' and xchan ' . $item['author_xchan']); - return; - } - } + // plustagged - keep going, next check permissions + + if(! perm_is_allowed($uid,$item['author_xchan'],'tag_deliver')) { + logger('tag_delivery denied for uid ' . $uid . ' and xchan ' . $item['author_xchan']); + continue; + } - if((! $mention) && (! $union)) { - logger('No mention for ' . $u[0]['channel_name'] . ' and no union.'); - return; - } - // tgroup delivery - setup a second delivery chain - // prevent delivery looping - only proceed - // if the message originated elsewhere and is a top-level post + if((! $mention) && (! $union)) { + logger('No mention for ' . $u[0]['channel_name'] . ' and no union.'); + continue; + } + // tgroup delivery - setup a second delivery chain + // prevent delivery looping - only proceed + // if the message originated elsewhere and is a top-level post - if(intval($item['item_wall']) || intval($item['item_origin']) || (! intval($item['item_thread_top'])) || ($item['id'] != $item['parent'])) { - logger('Item was local or a comment. rejected.'); - return; - } - logger('Creating second delivery chain.'); - start_delivery_chain($u[0],$item,$item_id,null); + if(intval($item['item_wall']) || intval($item['item_origin']) || (! intval($item['item_thread_top'])) || ($item['id'] != $item['parent'])) { + logger('Item was local or a comment. rejected.'); + continue; + } + + logger('Creating second delivery chain.'); + start_delivery_chain($u[0],$item,$item_id,null); + + } + } } /** @@ -2760,78 +2761,73 @@ function tgroup_check($uid, $item) { if($terms) logger('tgroup_check: post mentions: ' . print_r($terms,true), LOGGER_DATA); + $max_forums = get_config('system','max_tagged_forums',2); + $matched_forums = 0; + $link = normalise_link($u[0]['xchan_url']); if($terms) { foreach($terms as $term) { - if(link_compare($term['url'],$link)) { - $mention = true; - break; + if(! link_compare($term['url'],$link)) { + continue; } - } - } - - if($mention) { - logger('tgroup_check: mention found for ' . $u[0]['channel_name']); - } - else - return false; - // At this point we've determined that the person receiving this post was mentioned in it. - // Now let's check if this mention was inside a reshare so we don't spam a forum - // note: $term has been set to the matching term + $mention = true; + logger('tgroup_check: mention found for ' . $u[0]['channel_name']); + // At this point we've determined that the person receiving this post was mentioned in it. + // Now let's check if this mention was inside a reshare so we don't spam a forum + // note: $term has been set to the matching term - $body = $item['body']; - $body = preg_replace('/\[share(.*?)\[\/share\]/','',$body); + $body = preg_replace('/\[share(.*?)\[\/share\]/','',$item['body']); - $pluspattern = '/@\!?\[zrl\=([^\]]*?)\]((?:.(?!\[zrl\=))*?)\+\[\/zrl\]/'; + $pluspattern = '/@\!?\[zrl\=([^\]]*?)\]((?:.(?!\[zrl\=))*?)\+\[\/zrl\]/'; - $forumpattern = '/\!\!?\[zrl\=([^\]]*?)\]((?:.(?!\[zrl\=))*?)\[\/zrl\]/'; + $forumpattern = '/\!\!?\[zrl\=([^\]]*?)\]((?:.(?!\[zrl\=))*?)\[\/zrl\]/'; + $found = false; - $found = false; + $matches = array(); - $max_forums = get_config('system','max_tagged_forums'); - if(! $max_forums) - $max_forums = 2; - $matched_forums = 0; - $matches = array(); - - if(preg_match_all($pluspattern,$body,$matches,PREG_SET_ORDER)) { - foreach($matches as $match) { - $matched_forums ++; - if($term['url'] === $match[1] && $term['term'] === $match[2]) { - if($matched_forums <= $max_forums) { - $found = true; - break; + if(preg_match_all($pluspattern,$body,$matches,PREG_SET_ORDER)) { + foreach($matches as $match) { + $matched_forums ++; + if($term['url'] === $match[1] && $term['term'] === $match[2] && intval($term['ttype']) === TERM_MENTION) { + if($matched_forums <= $max_forums) { + $found = true; + break; + } + logger('forum ' . $term['term'] . ' exceeded max_tagged_forums - ignoring'); + } } - logger('forum ' . $term['term'] . ' exceeded max_tagged_forums - ignoring'); } - } - } - if(preg_match_all($forumpattern,$body,$matches,PREG_SET_ORDER)) { - foreach($matches as $match) { - $matched_forums ++; - if($term['url'] === $match[1] && $term['term'] === $match[2]) { - if($matched_forums <= $max_forums) { - $found = true; - break; + if(preg_match_all($forumpattern,$body,$matches,PREG_SET_ORDER)) { + foreach($matches as $match) { + $matched_forums ++; + if($term['url'] === $match[1] && $term['term'] === $match[2] && intval($term['ttype']) === TERM_FORUM) { + if($matched_forums <= $max_forums) { + $found = true; + break; + } + logger('forum ' . $term['term'] . ' exceeded max_tagged_forums - ignoring'); + } } - logger('forum ' . $term['term'] . ' exceeded max_tagged_forums - ignoring'); } + + if(! $found) { + logger('tgroup_check: mention was in a reshare or exceeded max_tagged_forums - ignoring'); + continue; + } + + return true; } } - if(! $found) { - logger('tgroup_check: mention was in a reshare or exceeded max_tagged_forums - ignoring'); - return false; - } + return false; - return true; } /** diff --git a/include/markdown.php b/include/markdown.php index 865727b20..f398d279e 100644 --- a/include/markdown.php +++ b/include/markdown.php @@ -75,10 +75,10 @@ function markdown_to_bb($s, $use_zrl = false, $options = []) { // Convert everything that looks like a link to a link if($use_zrl) { $s = str_replace(['[img', '/img]'], ['[zmg', '/zmg]'], $s); - $s = preg_replace("/([^\]\=]|^)(https?\:\/\/)([a-zA-Z0-9\:\/\-\?\&\;\.\=\_\~\#\%\$\!\+\,\@\(\)]+)/ism", '$1[zrl=$2$3]$2$3[/zrl]',$s); + $s = preg_replace("/([^\]\=]|^)(https?\:\/\/)([a-zA-Z0-9\pL\:\/\-\?\&\;\.\=\_\~\#\%\$\!\+\,\@\(\)]+)/ismu", '$1[zrl=$2$3]$2$3[/zrl]',$s); } else { - $s = preg_replace("/([^\]\=]|^)(https?\:\/\/)([a-zA-Z0-9\:\/\-\?\&\;\.\=\_\~\#\%\$\!\+\,\@\(\)]+)/ism", '$1[url=$2$3]$2$3[/url]',$s); + $s = preg_replace("/([^\]\=]|^)(https?\:\/\/)([a-zA-Z0-9\pL\:\/\-\?\&\;\.\=\_\~\#\%\$\!\+\,\@\(\)]+)/ismu", '$1[url=$2$3]$2$3[/url]',$s); } // remove duplicate adjacent code tags diff --git a/include/message.php b/include/message.php index 477c7172c..b57d2e068 100644 --- a/include/message.php +++ b/include/message.php @@ -335,12 +335,9 @@ function private_messages_list($uid, $mailbox = '', $start = 0, $numitems = 0) { case 'combined': default: - - $parents = q("SELECT parent_mid FROM mail WHERE mid = parent_mid AND channel_id = %d ORDER BY created DESC", + $parents = q("SELECT mail.parent_mid FROM mail LEFT JOIN conv ON mail.conv_guid = conv.guid WHERE mail.mid = mail.parent_mid AND mail.channel_id = %d ORDER BY conv.updated DESC $limit", dbesc($local_channel) ); - //FIXME: We need the latest mail of a thread here. This query throws errors in postgres. We now look for the latest in php until somebody can fix this... - //$sql = "SELECT * FROM ( SELECT * FROM mail WHERE channel_id = $local_channel ORDER BY created DESC $limit ) AS temp_table GROUP BY parent_mid ORDER BY created DESC"; break; } diff --git a/include/text.php b/include/text.php index 746c35679..c74e515d2 100644 --- a/include/text.php +++ b/include/text.php @@ -819,7 +819,7 @@ function get_tags($s) { // added ; to single word tags to allow emojis and other unicode character constructs in bbcode // (this would actually be &#xnnnnn; but the ampersand will have been escaped to & by the time we see it.) - if(preg_match_all('/(?<![a-zA-Z0-9=\/\?])(@[^ \x0D\x0A,:?\[]+ [^ \x0D\x0A@,:?\[]+)/',$s,$match)) { + if(preg_match_all('/(?<![a-zA-Z0-9=\pL\/\?])(@[^ \x0D\x0A,:?\[]+ [^ \x0D\x0A@,:?\[]+)/u',$s,$match)) { foreach($match[1] as $mtch) { if(substr($mtch,-1,1) === '.') $ret[] = substr($mtch,0,-1); @@ -831,7 +831,7 @@ function get_tags($s) { // Otherwise pull out single word tags. These can be @nickname, @first_last // and #hash tags. - if(preg_match_all('/(?<![a-zA-Z0-9=\/\?\;])([@#\!][^ \x0D\x0A,;:?\[]+)/',$s,$match)) { + if(preg_match_all('/(?<![a-zA-Z0-9=\pL\/\?\;])([@#\!][^ \x0D\x0A,;:?\[]+)/u',$s,$match)) { foreach($match[1] as $mtch) { if(substr($mtch,-1,1) === '.') $mtch = substr($mtch,0,-1); @@ -1052,7 +1052,7 @@ function searchbox($s,$id='search-box',$url='/search',$save = false) { * @return string */ function linkify($s, $me = false) { - $s = preg_replace("/(https?\:\/\/[a-zA-Z0-9\:\/\-\?\&\;\.\=\_\@\~\#\'\%\$\!\+\,\@]*)/", (($me) ? ' <a href="$1" rel="me" >$1</a>' : ' <a href="$1" >$1</a>'), $s); + $s = preg_replace("/(https?\:\/\/[a-zA-Z0-9\pL\:\/\-\?\&\;\.\=\_\@\~\#\'\%\$\!\+\,\@]*)/u", (($me) ? ' <a href="$1" rel="me" >$1</a>' : ' <a href="$1" >$1</a>'), $s); $s = preg_replace("/\<(.*?)(src|href)=(.*?)\&\;(.*?)\>/ism",'<$1$2=$3&$4>',$s); return($s); @@ -3099,10 +3099,10 @@ function cleanup_bbcode($body) { $body = preg_replace_callback('/\[zrl(.*?)\[\/(zrl)\]/ism','\red_escape_codeblock',$body); - $body = preg_replace_callback("/([^\]\='".'"'."\/]|^|\#\^)(https?\:\/\/[a-zA-Z0-9\:\/\-\?\&\;\.\=\@\_\~\#\%\$\!\\ -+\,\(\)]+)/ism", '\nakedoembed', $body); - $body = preg_replace_callback("/([^\]\='".'"'."\/]|^|\#\^)(https?\:\/\/[a-zA-Z0-9\:\/\-\?\&\;\.\=\@\_\~\#\%\$\!\\ -+\,\(\)]+)/ism", '\red_zrl_callback', $body); + $body = preg_replace_callback("/([^\]\='".'"'."\/]|^|\#\^)(https?\:\/\/[a-zA-Z0-9\pL\:\/\-\?\&\;\.\=\@\_\~\#\%\$\!\\ ++\,\(\)]+)/ismu", '\nakedoembed', $body); + $body = preg_replace_callback("/([^\]\='".'"'."\/]|^|\#\^)(https?\:\/\/[a-zA-Z0-9\pL\:\/\-\?\&\;\.\=\@\_\~\#\%\$\!\\ ++\,\(\)]+)/ismu", '\red_zrl_callback', $body); $body = preg_replace_callback('/\[\$b64zrl(.*?)\[\/(zrl)\]/ism','\red_unescape_codeblock',$body); $body = preg_replace_callback('/\[\$b64url(.*?)\[\/(url)\]/ism','\red_unescape_codeblock',$body); diff --git a/view/theme/redbasic/schema/dark.css b/view/theme/redbasic/schema/dark.css index b1aa5e07a..a921f42af 100644 --- a/view/theme/redbasic/schema/dark.css +++ b/view/theme/redbasic/schema/dark.css @@ -301,7 +301,11 @@ a, a:visited, a:link, .fakelink, .fakelink:visited, .fakelink:link { font-weight: bold; } -.group-selected, .fileas-selected, .categories-selected, .search-selected, .active { +.list-group-item { + background-color: #222; +} + +.group-selected, .fileas-selected, .categories-selected, .search-selected, a.active { color: #fff !important; text-decoration: underline !important; } diff --git a/view/theme/redbasic/schema/simple_black_on_white.css b/view/theme/redbasic/schema/simple_black_on_white.css index 915cc4e18..ab819d774 100644 --- a/view/theme/redbasic/schema/simple_black_on_white.css +++ b/view/theme/redbasic/schema/simple_black_on_white.css @@ -198,11 +198,15 @@ aside .nav > li > a:hover, aside .nav > li > a:focus { background-color: #F5F5F5; } +.list-group-item { + background-color: #F5F5F5; +} + a, a:visited, a:link, .fakelink, .fakelink:visited, .fakelink:link { font-weight: bold; } -.group-selected, .fileas-selected, .categories-selected, .search-selected, .active { +.group-selected, .fileas-selected, .categories-selected, .search-selected, a.active { color: #000 !important; text-decoration: underline !important; } diff --git a/view/theme/redbasic/schema/simple_green_on_black.css b/view/theme/redbasic/schema/simple_green_on_black.css index 7f3f99fce..c8ea87050 100644 --- a/view/theme/redbasic/schema/simple_green_on_black.css +++ b/view/theme/redbasic/schema/simple_green_on_black.css @@ -259,11 +259,15 @@ aside .nav > li > a:hover, aside .nav > li > a:focus { background-color: #143D12; } +.list-group-item { + background-color: #143D12; +} + a, a:visited, a:link, .fakelink, .fakelink:visited, .fakelink:link { font-weight: bold; } -.group-selected, .fileas-selected, .categories-selected, .search-selected, .active { +.group-selected, .fileas-selected, .categories-selected, .search-selected, a.active { color: #50f148 !important; text-decoration: underline !important; } diff --git a/view/theme/redbasic/schema/simple_white_on_black.css b/view/theme/redbasic/schema/simple_white_on_black.css index 7e7f80f2f..ea04d4d9e 100644 --- a/view/theme/redbasic/schema/simple_white_on_black.css +++ b/view/theme/redbasic/schema/simple_white_on_black.css @@ -237,11 +237,15 @@ aside .nav > li > a:hover, aside .nav > li > a:focus { background-color: #030303; } +.list-group-item { + background-color: #030303; +} + a, a:visited, a:link, .fakelink, .fakelink:visited, .fakelink:link { font-weight: bold; } -.group-selected, .fileas-selected, .categories-selected, .search-selected, .active { +.group-selected, .fileas-selected, .categories-selected, .search-selected, a.active { color: #fff !important; text-decoration: underline !important; } diff --git a/view/tpl/cover_photo_widget.tpl b/view/tpl/cover_photo_widget.tpl index 7404a740c..3aaad5ae5 100755 --- a/view/tpl/cover_photo_widget.tpl +++ b/view/tpl/cover_photo_widget.tpl @@ -8,8 +8,7 @@ aside_padding_top = parseInt($('aside').css('padding-top')); section_padding_top = parseInt($('section').css('padding-top')); - $('#cover-photo').on('click', slideUpCover); - $('#cover-photo').on('keyup', slideUpCover); + $(document).on('click mouseup keyup', slideUpCover); if($('#cover-photo').length && $(window).width() > 755) { if($(window).scrollTop() < $('#cover-photo').height()) { @@ -63,7 +62,7 @@ if(coverSlid) { return; } - $('html, body').animate({scrollTop: Math.ceil($('#cover-photo').height()) + 'px' }); + $('html, body').animate({scrollTop: Math.ceil($('#cover-photo').height()) + 'px' }, 'fast'); return; } </script> |